From 9c0695f56b433177ffea2e634524cdf9a122d00d Mon Sep 17 00:00:00 2001 From: hieuho Date: Fri, 28 Aug 2026 12:05:59 +0700 Subject: [PATCH 01/68] feat(tts): add remote OmniVoice backend --- README.md | 31 ++++- agent/api/tts.py | 4 + agent/config.py | 16 +++ agent/omnivoice_api.py | 224 ++++++++++++++++++++++++++++++ agent/services/tts.py | 248 +++++++++++++++++++++++++++++----- requirements.txt | 1 + run-omnivoice-api.sh | 23 ++++ skills/fk-gen-tts-template.md | 36 +++-- tests/unit/test_tts.py | 187 +++++++++++++++++++++++++ 9 files changed, 714 insertions(+), 56 deletions(-) create mode 100644 agent/omnivoice_api.py create mode 100755 run-omnivoice-api.sh create mode 100644 tests/unit/test_tts.py diff --git a/README.md b/README.md index c94e3a18d..bf1249b99 100644 --- a/README.md +++ b/README.md @@ -666,19 +666,35 @@ Optional narrator voice for scenes. Uses [OmniVoice](https://github.com/tuannguy ### Setup -See `skills/fk-gen-tts-template.md` for full install guide. Quick version: +See `skills/fk-gen-tts-template.md` for the full install guide. The launcher uses the FlowKit venv +at `$HOME/.venvs/flowkit`; install OmniVoice there: ```bash -pip install torch==2.8.0 torchaudio==2.8.0 # or +cu128 for NVIDIA -pip install omnivoice -python3 -c "from omnivoice import OmniVoice; print('OK')" +$HOME/.venvs/flowkit/bin/python -m pip install torch==2.8.0 torchaudio==2.8.0 +$HOME/.venvs/flowkit/bin/python -m pip install omnivoice +$HOME/.venvs/flowkit/bin/python -c 'from omnivoice import OmniVoice; print("OmniVoice OK")' ``` -If OmniVoice is in a separate venv, point to it: +The local subprocess defaults to the interpreter that launched FlowKit, so `TTS_PYTHON_BIN` is +optional. Set it only when OmniVoice intentionally lives in a separate venv. + +### Optional remote OmniVoice API + +`agent/omnivoice_api.py` is a standalone warm FastAPI service. It loads the model once and exposes +`POST /v1/tts` as multipart form data (`text`, `speed`, optional `instruct`, `ref_text`, and WAV +file `ref_audio`), returning raw `audio/wav` bytes. Run it from the FlowKit checkout: + ```bash -export TTS_PYTHON_BIN=/path/to/omnivoice-venv/bin/python3 +$HOME/.venvs/flowkit/bin/python -m pip install python-multipart +./flowkit/run-omnivoice-api.sh ``` +The main FlowKit API can call it by setting `TTS_BACKEND=remote` and `TTS_REMOTE_URL=http://127.0.0.1:8200`. +The remote backend reads each local `ref_audio` WAV, uploads its bytes, validates the returned WAV, +and writes it atomically to the existing local output path. For a non-loopback deployment, set +`OMNIVOICE_API_TOKEN` on the inference service and the matching `TTS_REMOTE_TOKEN` on FlowKit, +use HTTPS, and do not expose the service publicly without authentication. + ### Workflow 1. **Create voice template** — `/fk-gen-tts-template` — generates an anchor voice WAV @@ -686,7 +702,8 @@ export TTS_PYTHON_BIN=/path/to/omnivoice-venv/bin/python3 3. **Generate narration** — `/fk-gen-narrator` — voice-clones the template for each scene 4. **Concat with narration** — `/fk-concat-fit-narrator` — trims scene videos to match TTS duration -CPU-only recommended (MPS produces artifacts). ~15-30s per scene. +CPU-only is recommended for the local backend (MPS produces artifacts). Remote mode is serialized +per scene and keeps the model warm in the standalone inference service. ## YouTube Upload Pipeline diff --git a/agent/api/tts.py b/agent/api/tts.py index e2d3d068f..342acfea9 100644 --- a/agent/api/tts.py +++ b/agent/api/tts.py @@ -146,6 +146,10 @@ async def narrate_video(vid: str, body: NarrateVideoRequest): logger.info("Auto-resolved ref_text from template '%s'", tmpl["name"]) break + # The project/template fallback is operator data too; revalidate after resolution so remote TTS + # can never read and upload a path that bypassed the request-body check above. + if ref_audio: + _validate_ref_audio(ref_audio) project_name = project.get("name") or "unnamed_project" project_slug = slugify(project_name) out_dir = OUTPUT_DIR / project_slug / "tts" diff --git a/agent/config.py b/agent/config.py index 0e779f2de..79b6927c8 100644 --- a/agent/config.py +++ b/agent/config.py @@ -59,9 +59,25 @@ MUSIC_OUTPUT_DIR = SHARED_OUTPUT_DIR / "music" # ─── TTS (OmniVoice) ───────────────────────────────────────── +TTS_BACKEND = os.environ.get("TTS_BACKEND", "local").strip().lower() TTS_MODEL = os.environ.get("TTS_MODEL", "k2-fsa/OmniVoice") TTS_DEVICE = os.environ.get("TTS_DEVICE", "cpu") # MPS produces gibberish; CPU+fp32 works TTS_SAMPLE_RATE = int(os.environ.get("TTS_SAMPLE_RATE", "24000")) +TTS_REMOTE_URL = os.environ.get("TTS_REMOTE_URL", "").strip().rstrip("/") +TTS_REMOTE_TOKEN = os.environ.get("TTS_REMOTE_TOKEN", "") +TTS_REMOTE_TIMEOUT_S = float(os.environ.get("TTS_REMOTE_TIMEOUT_S", "180")) +TTS_REMOTE_MAX_BYTES = int(os.environ.get("TTS_REMOTE_MAX_BYTES", str(50 * 1024 * 1024))) + +# ─── Standalone OmniVoice API ──────────────────────────────── +OMNIVOICE_API_HOST = os.environ.get("OMNIVOICE_API_HOST", "127.0.0.1") +OMNIVOICE_API_PORT = int(os.environ.get("OMNIVOICE_API_PORT", "8200")) +OMNIVOICE_API_TOKEN = os.environ.get("OMNIVOICE_API_TOKEN", "") +OMNIVOICE_MAX_REF_AUDIO_BYTES = int( + os.environ.get("OMNIVOICE_MAX_REF_AUDIO_BYTES", str(10 * 1024 * 1024)) +) +OMNIVOICE_MAX_REQUEST_BYTES = int( + os.environ.get("OMNIVOICE_MAX_REQUEST_BYTES", str(12 * 1024 * 1024)) +) # ─── Review / Claude Vision ────────────────────────────────── ANTHROPIC_API_KEY = os.environ.get("ANTHROPIC_API_KEY", "") diff --git a/agent/omnivoice_api.py b/agent/omnivoice_api.py new file mode 100644 index 000000000..50c1d9d91 --- /dev/null +++ b/agent/omnivoice_api.py @@ -0,0 +1,224 @@ +"""Standalone warm OmniVoice HTTP service for remote FlowKit TTS.""" +from __future__ import annotations + +import asyncio +import hmac +import io +import math +import tempfile +import wave +from contextlib import asynccontextmanager +from pathlib import Path +from typing import Optional + +from fastapi import FastAPI, File, Form, HTTPException, Request, UploadFile +from fastapi.responses import JSONResponse, Response + +from agent.config import ( + OMNIVOICE_API_HOST, + OMNIVOICE_API_PORT, + OMNIVOICE_API_TOKEN, + OMNIVOICE_MAX_REF_AUDIO_BYTES, + OMNIVOICE_MAX_REQUEST_BYTES, + TTS_DEVICE, + TTS_MODEL, + TTS_SAMPLE_RATE, +) + +_model = None +_inference_lock = asyncio.Lock() + + +def _validate_wav_bytes(audio_bytes: bytes) -> None: + if len(audio_bytes) < 12 or audio_bytes[:4] != b"RIFF" or audio_bytes[8:12] != b"WAVE": + raise HTTPException(status_code=400, detail="ref_audio must be a WAV file") + try: + with wave.open(io.BytesIO(audio_bytes), "rb") as wav: + frame_count = wav.getnframes() + frame_width = wav.getnchannels() * wav.getsampwidth() + if frame_count <= 0 or wav.getframerate() <= 0 or frame_width <= 0: + raise HTTPException(status_code=400, detail="ref_audio must contain audio") + if len(wav.readframes(frame_count)) != frame_count * frame_width: + raise HTTPException(status_code=400, detail="ref_audio is truncated") + except (wave.Error, EOFError) as error: + raise HTTPException(status_code=400, detail="ref_audio is an invalid WAV file") from error + + +def _load_model(): + global _model + import torch + from omnivoice import OmniVoice + + dtype = torch.float16 if TTS_DEVICE.startswith("cuda") else torch.float32 + _model = OmniVoice.from_pretrained(TTS_MODEL, device_map=TTS_DEVICE, dtype=dtype) + + +def _generate_wav_bytes( + text: str, + instruct: Optional[str], + ref_text: Optional[str], + ref_audio_bytes: Optional[bytes], + speed: float, +) -> bytes: + import torchaudio + + if _model is None: + raise RuntimeError("OmniVoice model is not loaded") + + with tempfile.TemporaryDirectory(prefix="omnivoice-") as temp_dir: + ref_audio_path = None + if ref_audio_bytes is not None: + ref_audio_path = Path(temp_dir) / "reference.wav" + ref_audio_path.write_bytes(ref_audio_bytes) + + output_path = Path(temp_dir) / "output.wav" + kwargs = {"text": text} + if ref_audio_path is not None and ref_text: + kwargs["ref_audio"] = str(ref_audio_path) + kwargs["ref_text"] = ref_text + elif instruct: + kwargs["instruct"] = instruct + if speed != 1.0: + kwargs["speed"] = speed + + audio = _model.generate(**kwargs) + torchaudio.save(str(output_path), audio[0], TTS_SAMPLE_RATE) + return output_path.read_bytes() + + +def _authorization_header_valid(actual: str) -> bool: + if not OMNIVOICE_API_TOKEN: + return True + return hmac.compare_digest(actual, f"Bearer {OMNIVOICE_API_TOKEN}") + + +def _authorization_valid(request: Request) -> bool: + return _authorization_header_valid(request.headers.get("authorization", "")) + + +async def _require_authorized(request: Request) -> None: + if not _authorization_valid(request): + raise HTTPException(status_code=401, detail="Invalid bearer token") + + +@asynccontextmanager +async def lifespan(app: FastAPI): + if OMNIVOICE_API_HOST not in {"127.0.0.1", "localhost", "::1"} and not OMNIVOICE_API_TOKEN: + raise RuntimeError("OMNIVOICE_API_TOKEN is required when the API is not loopback-only") + await asyncio.to_thread(_load_model) + yield + + +app = FastAPI(title="OmniVoice TTS", version="1.0.0", lifespan=lifespan) + + +class _RequestTooLarge(Exception): + pass + + +async def _send_json_error(send, status_code: int, detail: str) -> None: + body = f'{{"detail":"{detail}"}}'.encode("utf-8") + await send({"type": "http.response.start", "status": status_code, "headers": [ + (b"content-type", b"application/json"), + (b"content-length", str(len(body)).encode("ascii")), + ]}) + await send({"type": "http.response.body", "body": body}) + + +class _TtsRequestLimitMiddleware: + def __init__(self, app): + self.app = app + + async def __call__(self, scope, receive, send): + if scope.get("type") != "http" or scope.get("path") != "/v1/tts": + await self.app(scope, receive, send) + return + + request_headers = {key.lower(): value for key, value in scope.get("headers", [])} + authorization = request_headers.get(b"authorization", b"").decode("latin-1") + if not _authorization_header_valid(authorization): + await _send_json_error(send, 401, "Invalid bearer token") + return + + content_length = request_headers.get(b"content-length") + if content_length is not None: + try: + if int(content_length) > OMNIVOICE_MAX_REQUEST_BYTES: + await _send_json_error(send, 413, "request is too large") + return + except ValueError: + await _send_json_error(send, 400, "invalid content-length") + return + + received = 0 + + async def limited_receive(): + nonlocal received + message = await receive() + if message["type"] == "http.request": + received += len(message.get("body", b"")) + if received > OMNIVOICE_MAX_REQUEST_BYTES: + raise _RequestTooLarge + return message + + try: + await self.app(scope, limited_receive, send) + except _RequestTooLarge: + await _send_json_error(send, 413, "request is too large") + + +app.add_middleware(_TtsRequestLimitMiddleware) + +@app.get("/health") +async def health(): + return {"ok": _model is not None, "model": TTS_MODEL, "device": TTS_DEVICE} + + +@app.post("/v1/tts", response_class=Response) +async def synthesize( + request: Request, + text: str = Form(...), + speed: float = Form(1.0), + instruct: Optional[str] = Form(None), + ref_text: Optional[str] = Form(None), + ref_audio: Optional[UploadFile] = File(None), +): + await _require_authorized(request) + if not text or len(text) > 5000: + raise HTTPException(status_code=422, detail="text must contain 1-5000 characters") + if not math.isfinite(speed) or speed < 0.5 or speed > 3.0: + raise HTTPException(status_code=422, detail="speed must be between 0.5 and 3.0") + if instruct is not None and len(instruct) > 200: + raise HTTPException(status_code=422, detail="instruct must contain at most 200 characters") + if ref_text is not None and len(ref_text) > 5000: + raise HTTPException(status_code=422, detail="ref_text is too long") + + ref_audio_bytes = None + if ref_audio is not None: + ref_audio_bytes = await ref_audio.read(OMNIVOICE_MAX_REF_AUDIO_BYTES + 1) + if len(ref_audio_bytes) > OMNIVOICE_MAX_REF_AUDIO_BYTES: + raise HTTPException(status_code=413, detail="ref_audio is too large") + _validate_wav_bytes(ref_audio_bytes) + + async with _inference_lock: + try: + wav_bytes = await asyncio.to_thread( + _generate_wav_bytes, + text, + instruct, + ref_text, + ref_audio_bytes, + speed, + ) + except HTTPException: + raise + except Exception: + raise HTTPException(status_code=500, detail="OmniVoice synthesis failed") + + return Response(content=wav_bytes, media_type="audio/wav") + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host=OMNIVOICE_API_HOST, port=OMNIVOICE_API_PORT) diff --git a/agent/services/tts.py b/agent/services/tts.py index 14a729856..4283ebbfe 100644 --- a/agent/services/tts.py +++ b/agent/services/tts.py @@ -1,20 +1,37 @@ -"""OmniVoice TTS service — subprocess-based for compatibility.""" +"""OmniVoice TTS service with local and remote backends.""" import asyncio +import io import json import logging import os import subprocess +import sys +import tempfile +import urllib.parse +import wave from pathlib import Path from typing import Optional -from agent.config import TTS_MODEL, TTS_SAMPLE_RATE +import httpx + +from agent.config import ( + TTS_MODEL, + TTS_REMOTE_MAX_BYTES, + TTS_REMOTE_TOKEN, + TTS_REMOTE_TIMEOUT_S, + TTS_REMOTE_URL, + TTS_SAMPLE_RATE, + TTS_BACKEND, +) logger = logging.getLogger(__name__) -# Default to python3.10 (has torch/torchaudio/omnivoice); override with TTS_PYTHON_BIN if needed -PYTHON_BIN = os.environ.get("TTS_PYTHON_BIN", "python3.10") +# The launcher starts FlowKit with its venv interpreter. Keep the override for deployments that +# intentionally use a separate OmniVoice environment, but never require an executable named +# python3.10 to be present on PATH. +PYTHON_BIN = os.environ.get("TTS_PYTHON_BIN", sys.executable) -# Inline script template for TTS generation via subprocess +# Inline script template for local subprocess generation. _TTS_SCRIPT = """ import sys, json, torch, torchaudio @@ -37,7 +54,7 @@ print(json.dumps({"ok": True, "path": args["output"]})) """ -# Batch script — loads model once, generates for multiple texts +# Batch script — loads model once for local generation of multiple texts. _TTS_BATCH_SCRIPT = """ import sys, json, torch, torchaudio from pathlib import Path @@ -73,6 +90,131 @@ """ +def _remote_endpoint() -> str: + if TTS_BACKEND != "remote": + raise RuntimeError(f"Unsupported TTS_BACKEND: {TTS_BACKEND!r}") + if not TTS_REMOTE_URL: + raise RuntimeError("TTS_REMOTE_URL is required when TTS_BACKEND=remote") + parsed = urllib.parse.urlparse(TTS_REMOTE_URL) + if parsed.scheme not in {"http", "https"} or not parsed.netloc: + raise RuntimeError("TTS_REMOTE_URL must be an absolute http(s) URL") + if parsed.username or parsed.password or parsed.query or parsed.fragment: + raise RuntimeError("TTS_REMOTE_URL must not contain credentials, query, or fragment") + root = TTS_REMOTE_URL.rstrip("/") + return root if root.endswith("/v1/tts") else f"{root}/v1/tts" + + +def _validate_wav_bytes(audio_bytes: bytes) -> None: + if len(audio_bytes) < 12 or audio_bytes[:4] != b"RIFF" or audio_bytes[8:12] != b"WAVE": + raise RuntimeError("Remote TTS returned a non-WAVE response") + try: + with wave.open(io.BytesIO(audio_bytes), "rb") as wav: + frame_count = wav.getnframes() + frame_width = wav.getnchannels() * wav.getsampwidth() + if frame_count <= 0 or wav.getframerate() <= 0 or frame_width <= 0: + raise RuntimeError("Remote TTS returned an empty WAV") + if len(wav.readframes(frame_count)) != frame_count * frame_width: + raise RuntimeError("Remote TTS returned a truncated WAV") + except (wave.Error, EOFError) as error: + raise RuntimeError("Remote TTS returned an invalid WAV") from error + + +def _write_wav_atomically(output_path: str, audio_bytes: bytes) -> None: + _validate_wav_bytes(audio_bytes) + destination = Path(output_path) + destination.parent.mkdir(parents=True, exist_ok=True) + temporary_path: Path | None = None + try: + with tempfile.NamedTemporaryFile( + mode="wb", + dir=destination.parent, + prefix=f".{destination.name}.", + suffix=".tmp", + delete=False, + ) as temporary: + temporary_path = Path(temporary.name) + temporary.write(audio_bytes) + temporary.flush() + os.fsync(temporary.fileno()) + os.replace(temporary_path, destination) + temporary_path = None + finally: + if temporary_path is not None: + temporary_path.unlink(missing_ok=True) + + +def _read_limited(path: Path, max_bytes: int) -> bytes: + with path.open("rb") as source: + return source.read(max_bytes + 1) + + +async def _read_reference_audio(ref_audio: str) -> tuple[str, bytes]: + reference = Path(ref_audio) + if not reference.is_file(): + raise RuntimeError("Reference audio file does not exist") + try: + audio_bytes = await asyncio.to_thread(_read_limited, reference, TTS_REMOTE_MAX_BYTES) + except OSError as error: + raise RuntimeError("Reference audio could not be read") from error + if len(audio_bytes) > TTS_REMOTE_MAX_BYTES: + raise RuntimeError("Reference audio exceeds the remote TTS size limit") + _validate_wav_bytes(audio_bytes) + return reference.name, audio_bytes + + +async def _generate_remote( + text: str, + output_path: str, + instruct: Optional[str] = None, + ref_audio: Optional[str] = None, + ref_text: Optional[str] = None, + speed: float = 1.0, +) -> str: + data = {"text": text, "speed": str(speed)} + if instruct: + data["instruct"] = instruct + if ref_text: + data["ref_text"] = ref_text + + files = None + # OmniVoice cloning requires both fields. Preserve local compatibility when a caller supplies + # only ref_audio by following the instruct/generic path rather than leaking a local path. + if ref_audio and ref_text: + filename, audio_bytes = await _read_reference_audio(ref_audio) + files = {"ref_audio": (filename, audio_bytes, "audio/wav")} + + headers = {} + if TTS_REMOTE_TOKEN: + headers["authorization"] = f"Bearer {TTS_REMOTE_TOKEN}" + + timeout = httpx.Timeout(TTS_REMOTE_TIMEOUT_S) + try: + async with httpx.AsyncClient(timeout=timeout) as client: + async with client.stream( + "POST", + _remote_endpoint(), + data=data, + files=files, + headers=headers, + ) as response: + if response.status_code < 200 or response.status_code >= 300: + raise RuntimeError(f"Remote TTS failed with HTTP {response.status_code}") + content_type = response.headers.get("content-type", "").split(";", 1)[0].lower() + if content_type != "audio/wav": + raise RuntimeError("Remote TTS returned an unexpected content type") + audio = bytearray() + async for chunk in response.aiter_bytes(): + if len(audio) + len(chunk) > TTS_REMOTE_MAX_BYTES: + raise RuntimeError("Remote TTS response exceeds the size limit") + audio.extend(chunk) + except httpx.HTTPError as error: + raise RuntimeError("Remote TTS request failed") from error + + _write_wav_atomically(output_path, bytes(audio)) + logger.info("Remote TTS saved to %s", output_path) + return output_path + + async def generate_speech( text: str, output_path: str, @@ -81,9 +223,13 @@ async def generate_speech( ref_text: Optional[str] = None, speed: float = 1.0, ) -> str: - """Generate speech for text via subprocess. Returns path to WAV file.""" - Path(output_path).parent.mkdir(parents=True, exist_ok=True) + """Generate speech and return a local WAV path.""" + if TTS_BACKEND == "remote": + return await _generate_remote(text, output_path, instruct, ref_audio, ref_text, speed) + if TTS_BACKEND != "local": + raise RuntimeError(f"Unsupported TTS_BACKEND: {TTS_BACKEND!r}") + Path(output_path).parent.mkdir(parents=True, exist_ok=True) args = { "model": TTS_MODEL, "text": text, @@ -98,9 +244,8 @@ async def generate_speech( if ref_text: args["ref_text"] = ref_text - loop = asyncio.get_event_loop() + loop = asyncio.get_running_loop() result = await loop.run_in_executor(None, _run_tts_subprocess, args) - if not result.get("ok"): raise RuntimeError(f"TTS failed: {result.get('error', 'unknown')}") @@ -109,10 +254,12 @@ async def generate_speech( def _run_tts_subprocess(args: dict) -> dict: - """Run TTS subprocess.""" + """Run one local TTS subprocess.""" proc = subprocess.run( [PYTHON_BIN, "-c", _TTS_SCRIPT, json.dumps(args)], - capture_output=True, text=True, timeout=120, + capture_output=True, + text=True, + timeout=120, ) if proc.returncode != 0: return {"ok": False, "error": proc.stderr[-500:] if proc.stderr else "unknown error"} @@ -122,6 +269,11 @@ def _run_tts_subprocess(args: dict) -> dict: return {"ok": False, "error": proc.stdout[-200:] + proc.stderr[-200:]} +def _wav_duration_seconds(path: str) -> float: + with wave.open(path, "rb") as wav: + return wav.getnframes() / wav.getframerate() + + async def generate_video_narration( scenes: list[dict], output_dir: str, @@ -130,15 +282,12 @@ async def generate_video_narration( ref_text: Optional[str] = None, speed: float = 1.0, ) -> list[dict]: - """Generate narration WAVs for scenes with narrator_text. - - Uses batch subprocess — loads model once for all scenes. - Returns list of result dicts. - """ + """Generate narration WAVs for scenes with narrator_text.""" out_dir = Path(output_dir) out_dir.mkdir(parents=True, exist_ok=True) + if TTS_BACKEND not in {"local", "remote"}: + raise RuntimeError(f"Unsupported TTS_BACKEND: {TTS_BACKEND!r}") - # Build batch items (only scenes with narrator_text) items = [] scene_map = {} for scene in scenes: @@ -150,17 +299,41 @@ async def generate_video_narration( continue wav_path = str(out_dir / f"scene_{display_order:03d}_{scene_id}.wav") - # Skip if WAV already exists and is non-trivial (>1KB) if Path(wav_path).exists() and Path(wav_path).stat().st_size > 1024: logger.info("Skipping scene %03d (WAV exists: %s)", display_order, wav_path) - scene_map[scene_id] = {"display_order": display_order, "narrator_text": narrator_text, "skipped": True, "wav_path": wav_path} + scene_map[scene_id] = { + "display_order": display_order, + "narrator_text": narrator_text, + "skipped": True, + "wav_path": wav_path, + } continue items.append({"id": scene_id, "text": narrator_text, "output": wav_path}) scene_map[scene_id] = {"display_order": display_order, "narrator_text": narrator_text} - # Run batch subprocess if there are items batch_results = {} - if items: + if items and TTS_BACKEND == "remote": + # Keep one request per scene so failures remain attributable and the remote service's + # single warm model is not driven concurrently. + for item in items: + try: + await generate_speech( + text=item["text"], + output_path=item["output"], + instruct=instruct, + ref_audio=ref_audio, + ref_text=ref_text, + speed=speed, + ) + batch_results[item["id"]] = { + "id": item["id"], + "ok": True, + "path": item["output"], + "duration": _wav_duration_seconds(item["output"]), + } + except Exception as error: + batch_results[item["id"]] = {"id": item["id"], "ok": False, "error": str(error)} + elif items: args = { "model": TTS_MODEL, "sample_rate": TTS_SAMPLE_RATE, @@ -174,12 +347,11 @@ async def generate_video_narration( if ref_text: args["ref_text"] = ref_text - loop = asyncio.get_event_loop() + loop = asyncio.get_running_loop() raw = await loop.run_in_executor(None, _run_batch_subprocess, args) - for r in raw: - batch_results[r["id"]] = r + for result in raw: + batch_results[result["id"]] = result - # Build final results for all scenes results = [] for scene in scenes: scene_id = scene.get("id") @@ -198,27 +370,27 @@ async def generate_video_narration( }) continue - sm = scene_map.get(scene_id, {}) - if sm.get("skipped"): + scene_result = scene_map.get(scene_id, {}) + if scene_result.get("skipped"): results.append({ "scene_id": scene_id, "display_order": display_order, "narrator_text": narrator_text, - "audio_path": sm["wav_path"], + "audio_path": scene_result["wav_path"], "duration": None, "status": "COMPLETED", "error": None, }) continue - br = batch_results.get(scene_id, {}) - if br.get("ok"): + batch_result = batch_results.get(scene_id, {}) + if batch_result.get("ok"): results.append({ "scene_id": scene_id, "display_order": display_order, "narrator_text": narrator_text, - "audio_path": br.get("path"), - "duration": br.get("duration"), + "audio_path": batch_result.get("path"), + "duration": batch_result.get("duration"), "status": "COMPLETED", "error": None, }) @@ -230,18 +402,20 @@ async def generate_video_narration( "audio_path": None, "duration": None, "status": "FAILED", - "error": br.get("error", "not processed"), + "error": batch_result.get("error", "not processed"), }) return results def _run_batch_subprocess(args: dict) -> list[dict]: - """Run batch TTS subprocess. Model loads once.""" - timeout = 180 + len(args.get("items", [])) * 45 # ~180s model load + ~45s per scene + """Run local batch TTS subprocess. Model loads once.""" + timeout = 180 + len(args.get("items", [])) * 45 proc = subprocess.run( [PYTHON_BIN, "-c", _TTS_BATCH_SCRIPT, json.dumps(args)], - capture_output=True, text=True, timeout=timeout, + capture_output=True, + text=True, + timeout=timeout, ) if proc.returncode != 0: error = proc.stderr[-500:] if proc.stderr else "unknown" diff --git a/requirements.txt b/requirements.txt index c2cd265b7..be00c9dbd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ pydantic>=2.5.0 aiohttp>=3.9.0 httpx>=0.25.0 anthropic>=0.40.0 +python-multipart>=0.0.9 diff --git a/run-omnivoice-api.sh b/run-omnivoice-api.sh new file mode 100755 index 000000000..630ffa649 --- /dev/null +++ b/run-omnivoice-api.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# Start the standalone warm OmniVoice inference API. +set -euo pipefail + +FLOWKIT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PYTHON_BIN="${OMNIVOICE_PYTHON:-${TTS_PYTHON_BIN:-$HOME/.venvs/flowkit/bin/python}}" + +if [[ ! -x "$PYTHON_BIN" ]]; then + echo "OmniVoice Python not found at $PYTHON_BIN" >&2 + echo "Install FlowKit's Python 3.10+ environment or set OMNIVOICE_PYTHON." >&2 + exit 1 +fi + +if ! "$PYTHON_BIN" -c 'import multipart' >/dev/null 2>&1; then + echo "python-multipart is missing from $PYTHON_BIN" >&2 + echo "Install it with: $PYTHON_BIN -m pip install python-multipart" >&2 + exit 1 +fi + +cd "$FLOWKIT_DIR" +exec "$PYTHON_BIN" -m uvicorn agent.omnivoice_api:app \ + --host "${OMNIVOICE_API_HOST:-127.0.0.1}" \ + --port "${OMNIVOICE_API_PORT:-8200}" diff --git a/skills/fk-gen-tts-template.md b/skills/fk-gen-tts-template.md index 8b101a47e..8be3892ab 100644 --- a/skills/fk-gen-tts-template.md +++ b/skills/fk-gen-tts-template.md @@ -16,43 +16,55 @@ Source: https://github.com/tuannguyenhoangit-droid/OmniVoice > **Windows users:** Run all setup commands inside **WSL** or **Git Bash** (not CMD/PowerShell). The project's `setup.sh` and all bash scripts require a Unix shell. -**Step 1 — Install PyTorch** (in a fresh venv recommended): +**Step 1 — Install PyTorch** (in the FlowKit launcher venv, or a separate venv if you set +`TTS_PYTHON_BIN`): ```bash # macOS Apple Silicon (CPU — recommended for GLA, MPS produces gibberish) -pip install torch==2.8.0 torchaudio==2.8.0 +$HOME/.venvs/flowkit/bin/python -m pip install torch==2.8.0 torchaudio==2.8.0 # Linux / WSL with NVIDIA GPU -pip install torch==2.8.0+cu128 torchaudio==2.8.0+cu128 --extra-index-url https://download.pytorch.org/whl/cu128 +python -m pip install torch==2.8.0+cu128 torchaudio==2.8.0+cu128 \ + --extra-index-url https://download.pytorch.org/whl/cu128 # Linux / WSL CPU-only -pip install torch==2.8.0 torchaudio==2.8.0 +python -m pip install torch==2.8.0 torchaudio==2.8.0 ``` **Step 2 — Install OmniVoice** (choose one): ```bash # From PyPI (stable) -pip install omnivoice +$HOME/.venvs/flowkit/bin/python -m pip install omnivoice # From source -pip install git+https://github.com/k2-fsa/OmniVoice.git +$HOME/.venvs/flowkit/bin/python -m pip install \ + git+https://github.com/k2-fsa/OmniVoice.git # Dev install -git clone https://github.com/k2-fsa/OmniVoice.git && cd OmniVoice && pip install -e . +git clone https://github.com/k2-fsa/OmniVoice.git +cd OmniVoice +$HOME/.venvs/flowkit/bin/python -m pip install -e . ``` -**Step 3 — Point GLA to the right Python** (if OmniVoice is in a separate venv): +**Step 3 — Verify installation:** ```bash -export TTS_PYTHON_BIN=/path/to/omnivoice-venv/bin/python3 +$HOME/.venvs/flowkit/bin/python -c \ + 'from omnivoice import OmniVoice; print("OmniVoice OK")' ``` -If OmniVoice is installed in the same env as the agent, no extra config needed. +FlowKit's local TTS subprocess defaults to the interpreter that launched FlowKit +(`sys.executable`). `TTS_PYTHON_BIN` is optional and is only needed when OmniVoice +is installed in another venv. -**Verify installation:** +For remote GPU inference, run `agent/omnivoice_api.py` as a separate FastAPI service. +The FlowKit remote backend uploads `ref_audio` bytes and expects raw `audio/wav` bytes +back; it never sends a local filesystem path to the remote service. + +**HuggingFace mirror** (if model download is slow): ```bash -python3 -c "from omnivoice import OmniVoice; print('OK')" +export HF_ENDPOINT="https://hf-mirror.com" ``` **HuggingFace mirror** (if model download is slow): diff --git a/tests/unit/test_tts.py b/tests/unit/test_tts.py new file mode 100644 index 000000000..e97912906 --- /dev/null +++ b/tests/unit/test_tts.py @@ -0,0 +1,187 @@ +"""Focused tests for local-path and remote OmniVoice TTS contracts.""" + +import io +import wave + +import pytest +from agent import omnivoice_api +from agent.services import tts + + +def _wav_bytes() -> bytes: + output = io.BytesIO() + with wave.open(output, "wb") as wav: + wav.setnchannels(1) + wav.setsampwidth(2) + wav.setframerate(24000) + wav.writeframes(b"\x00\x00" * 240) + return output.getvalue() + + +class _FakeResponse: + def __init__(self, body: bytes, status_code: int = 200, content_type: str = "audio/wav"): + self.status_code = status_code + self.headers = {"content-type": content_type} + self._body = body + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + return False + + async def aread(self): + return self._body + + async def aiter_bytes(self): + yield self._body + + +class _FakeClient: + response = _FakeResponse(_wav_bytes()) + calls = [] + + def __init__(self, **kwargs): + self.timeout = kwargs["timeout"] + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + return False + + def stream(self, method, url, **kwargs): + self.calls.append((method, url, kwargs)) + return self.response + + +@pytest.mark.asyncio +async def test_remote_generation_uploads_reference_bytes_and_writes_local_wav(tmp_path, monkeypatch): + reference = tmp_path / "reference.wav" + reference.write_bytes(_wav_bytes()) + output = tmp_path / "scene.wav" + _FakeClient.calls = [] + + monkeypatch.setattr(tts, "TTS_BACKEND", "remote") + monkeypatch.setattr(tts, "TTS_REMOTE_URL", "https://tts.example.test") + monkeypatch.setattr(tts, "TTS_REMOTE_TOKEN", "secret") + monkeypatch.setattr(tts.httpx, "AsyncClient", _FakeClient) + + result = await tts._generate_remote( + text="Xin chao", + output_path=str(output), + ref_audio=str(reference), + ref_text="Mau transcript", + speed=1.1, + ) + + assert result == str(output) + + + assert output.read_bytes() == _wav_bytes() + method, url, request = _FakeClient.calls[0] + assert method == "POST" + assert url == "https://tts.example.test/v1/tts" + assert request["headers"] == {"authorization": "Bearer secret"} + assert request["data"] == {"text": "Xin chao", "speed": "1.1", "ref_text": "Mau transcript"} + assert request["files"]["ref_audio"][1] == _wav_bytes() + + +@pytest.mark.asyncio +async def test_remote_generation_does_not_replace_target_on_invalid_response(tmp_path, monkeypatch): + output = tmp_path / "scene.wav" + original = b"previous audio" + output.write_bytes(original) + + class InvalidClient(_FakeClient): + response = _FakeResponse(b"not wav", content_type="audio/wav") + + monkeypatch.setattr(tts, "TTS_BACKEND", "remote") + monkeypatch.setattr(tts, "TTS_REMOTE_URL", "http://127.0.0.1:8200") + monkeypatch.setattr(tts.httpx, "AsyncClient", InvalidClient) + + with pytest.raises(RuntimeError, match="non-WAVE"): + await tts._generate_remote("Xin chao", str(output)) + + assert output.read_bytes() == original + + +def test_write_wav_atomically_creates_valid_wav(tmp_path): + output = tmp_path / "nested" / "scene.wav" + + tts._write_wav_atomically(str(output), _wav_bytes()) + + assert output.exists() + with wave.open(str(output), "rb") as wav: + assert wav.getnframes() == 240 + assert wav.getframerate() == 24000 + + +def test_wav_validator_rejects_truncated_payload(): + with pytest.raises(RuntimeError, match="truncated"): + tts._validate_wav_bytes(_wav_bytes()[:-10]) + + +def test_standalone_api_auth_and_wav_response(monkeypatch): + from fastapi.testclient import TestClient + + monkeypatch.setattr(omnivoice_api, "OMNIVOICE_API_TOKEN", "secret") + monkeypatch.setattr(omnivoice_api, "_load_model", lambda: None) + monkeypatch.setattr(omnivoice_api, "_generate_wav_bytes", lambda *args: _wav_bytes()) + + with TestClient(omnivoice_api.app) as client: + unauthorized = client.post("/v1/tts", data={"text": "Xin chao"}, headers={}) + assert unauthorized.status_code == 401 + + authorized = client.post( + "/v1/tts", + data={"text": "Xin chao", "speed": "1.0", "ref_text": "Mau transcript"}, + files={"ref_audio": ("reference.wav", _wav_bytes(), "audio/wav")}, + headers={"Authorization": "Bearer secret"}, + ) + assert authorized.status_code == 200 + assert authorized.headers["content-type"] == "audio/wav" + assert authorized.content == _wav_bytes() + + +def test_standalone_api_rejects_oversized_request(monkeypatch): + from fastapi.testclient import TestClient + + monkeypatch.setattr(omnivoice_api, "OMNIVOICE_API_TOKEN", "") + monkeypatch.setattr(omnivoice_api, "OMNIVOICE_MAX_REQUEST_BYTES", 100) + monkeypatch.setattr(omnivoice_api, "_load_model", lambda: None) + + with TestClient(omnivoice_api.app) as client: + response = client.post("/v1/tts", data={"text": "x" * 1000}) + + assert response.status_code == 413 + + +def test_standalone_api_rejects_nonfinite_speed(monkeypatch): + from fastapi.testclient import TestClient + + monkeypatch.setattr(omnivoice_api, "OMNIVOICE_API_TOKEN", "") + monkeypatch.setattr(omnivoice_api, "_load_model", lambda: None) + + with TestClient(omnivoice_api.app) as client: + response = client.post("/v1/tts", data={"text": "Xin chao", "speed": "nan"}) + + assert response.status_code == 422 + + +@pytest.mark.asyncio +async def test_remote_generation_bounds_reference_read(tmp_path, monkeypatch): + reference = tmp_path / "reference.wav" + reference.write_bytes(b"x" * 11) + + monkeypatch.setattr(tts, "TTS_BACKEND", "remote") + monkeypatch.setattr(tts, "TTS_REMOTE_URL", "http://127.0.0.1:8200") + monkeypatch.setattr(tts, "TTS_REMOTE_MAX_BYTES", 10) + + with pytest.raises(RuntimeError, match="size limit"): + await tts._generate_remote( + "Xin chao", + str(tmp_path / "scene.wav"), + ref_audio=str(reference), + ref_text="Mau transcript", + ) From 8566126358db59ffd4182d0fa37f3b2647866708 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Tue, 8 Sep 2026 08:09:41 +0300 Subject: [PATCH 02/68] feat(flow): port Omni text video to migrated API --- README.md | 3 +- agent/api/flow.py | 33 +++++++++ agent/services/flow_batch.py | 39 +++++++++++ agent/services/omni_flash.py | 123 ++++++++++++++++++++++++++++++---- docs/OMNI_FLASH.md | 51 ++++++++------ tests/unit/test_flow_batch.py | 25 +++++++ tests/unit/test_omni_flash.py | 62 ++++++++++++++--- 7 files changed, 291 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index e4dd67eab..48c7a3b51 100644 --- a/README.md +++ b/README.md @@ -254,7 +254,8 @@ Three capabilities have no captured payload, so they fail with | 4K/1080p upscale (`/fk-pipeline` last step) | unported | none — keep the 1080p render | | Reference-to-video (r2v) | unported | `FLOW_ALLOW_DEGRADED=1` → i2v off the first reference | | Start+end-frame chaining (`/fk-gen-chain-videos`) | unported | `FLOW_ALLOW_DEGRADED=1` → i2v off the start frame | -| Omni Flash (`model_family=omni_flash`) | unported | use `model_family=veo` | +| Omni Flash text-to-video | ported | `POST /api/flow/generate-video-omni-text` (4/6/8/10s) | +| Omni Flash frame/reference modes | unported | use Veo or text-to-video until their batch payloads are captured | Restoring one starts with a capture, not a guess: [`docs/CAPTURE.md`](docs/CAPTURE.md). diff --git a/agent/api/flow.py b/agent/api/flow.py index 99394096a..c0a71025d 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -9,6 +9,7 @@ check_omni_flash_status, generate_omni_flash_first_frame_video, generate_omni_flash_first_last_video, + generate_omni_flash_text_video, generate_omni_flash_video, ) @@ -59,6 +60,15 @@ class GenerateOmniFlashVideoRequest(BaseModel): user_paygate_tier: str = "PAYGATE_TIER_ONE" +class GenerateOmniFlashTextVideoRequest(BaseModel): + prompt: str + project_id: str + scene_id: str = "" + duration_s: int = 8 + aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT" + user_paygate_tier: str = "PAYGATE_TIER_ONE" + + class UpscaleVideoRequest(BaseModel): media_id: str scene_id: str @@ -219,6 +229,29 @@ async def generate_video_refs(body: GenerateVideoRefsRequest): return result.get("data", result) +@router.post("/generate-video-omni-text") +async def generate_video_omni_text(body: GenerateOmniFlashTextVideoRequest): + """Submit Omni 1.1 Flash text-to-video on flow.google.com. + + Durations 4/6/8/10 seconds map to Flow's ``abra_t2v_s`` models. + """ + client = get_flow_client() + if not client.connected: + raise HTTPException(503, "Extension not connected") + try: + result = await generate_omni_flash_text_video(**body.model_dump()) + except ValueError as exc: + raise HTTPException(400, str(exc)) from exc + if result.get("error") or ( + isinstance(result.get("status"), int) and result["status"] >= 400 + ): + raise HTTPException( + result.get("status", 502), + result.get("error", result.get("data")), + ) + return result.get("data", result) + + @router.post("/generate-video-omni") async def generate_video_omni(body: GenerateOmniFlashVideoRequest): """Submit Gemini Omni Flash reference-to-video generation. diff --git a/agent/services/flow_batch.py b/agent/services/flow_batch.py index f01116320..538f77e1c 100644 --- a/agent/services/flow_batch.py +++ b/agent/services/flow_batch.py @@ -36,6 +36,7 @@ RPC_GEN_IMAGE = "ogiZ0b" RPC_GEN_VIDEO = "eb1hJf" +RPC_GEN_VIDEO_TEXT = "YhhmEf" RPC_OPERATION = "jwpduf" RPC_PROJECT_MEDIA = "Zzl0ze" RPC_MEDIA = "as29s" @@ -357,6 +358,24 @@ def video_request(prompt: str, project_id: str, source_media_id: str, return build_envelope(RPC_GEN_VIDEO, inner) +def text_video_request(prompt: str, project_id: str, + aspect: Any = VIDEO_ASPECT_LANDSCAPE, + model: str = "abra_t2v_4s") -> str: + """Build the migrated text-to-video submit (YhhmEf).""" + request = [ + [None, None, [[[prompt]]]], + model, + resolve_video_aspect(aspect), + None, + [None, None, None, None, _client_uuid(), _client_uuid()], + ] + return build_envelope(RPC_GEN_VIDEO_TEXT, [ + [request], + _context(project_id), + [_client_uuid(), 1], + ]) + + def upload_request(image_b64: str, project_id: str, mime_type: str = "image/jpeg", file_name: str = "upload.jpg") -> str: """Put a local image into the project so it can be used as a reference. @@ -429,6 +448,26 @@ def read_uploaded_media_id(payload: Any) -> str: return media_id +def read_text_video_submit(payload: Any) -> dict: + """Read YhhmEf's submitted media/workflow record.""" + records = payload[3] if isinstance(payload, list) and len(payload) > 3 else None + record = records[0] if isinstance(records, list) and records else None + if not isinstance(record, list) or not record: + raise FlowBatchError("text-video submit carried no generation record") + media_id = record[0] if len(record) > 0 else None + project_id = record[1] if len(record) > 1 else None + workflow_id = record[2] if len(record) > 2 else None + status = record[3] if len(record) > 3 else None + if not isinstance(media_id, str) or not media_id: + raise FlowBatchError("text-video submit carried no media id") + return { + "media_id": media_id, + "project_id": project_id if isinstance(project_id, str) else None, + "workflow_id": workflow_id if isinstance(workflow_id, str) else media_id, + "status": status if isinstance(status, str) else None, + } + + def read_operation(payload: Any) -> Operation: """`[null, 50, [[opId, projectId, sceneId, status, …]]]`. diff --git a/agent/services/omni_flash.py b/agent/services/omni_flash.py index 0db4c8cbe..796d6a312 100644 --- a/agent/services/omni_flash.py +++ b/agent/services/omni_flash.py @@ -27,6 +27,7 @@ from urllib.parse import quote from agent.config import USE_BATCH_RPC +from agent.services import flow_batch as fb from agent.services.flow_client import get_flow_client from agent.services.headers import random_headers @@ -39,10 +40,10 @@ #: captured off the new frontend, so on the batch path these fail with a #: name rather than dying on a 401 five retries deep. _UNSUPPORTED_ON_BATCH = ( - "UNSUPPORTED_ON_BATCH_API: Omni Flash — it speaks the pre-migration REST " - "and tRPC endpoints, and no batchexecute payload for it has been captured; " - "see docs/CAPTURE.md. Use the Veo path (model_family=veo), or set " - "USE_BATCH_RPC=0 on a profile that still holds a bearer token." + "UNSUPPORTED_ON_BATCH_API: Omni Flash frame/reference generation is not yet " + "ported to flow.google.com batchexecute. Omni text-to-video is supported on " + "the batch path; frame-to-video, start+end and reference-to-video still need " + "their migrated payload captures." ) @@ -217,6 +218,54 @@ def _annotate_polling(result: dict, project_id: str) -> dict: return result +async def generate_omni_flash_text_video( + prompt: str, + project_id: str, + scene_id: str = "", + duration_s: int = 8, + aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", + user_paygate_tier: str = "PAYGATE_TIER_ONE", + seed: int | None = None, +) -> dict: + """Submit Omni 1.1 Flash text-to-video on the migrated Flow batch API.""" + _validate_duration(duration_s) + _validate_aspect(aspect_ratio) + if not USE_BATCH_RPC: + return {"error": "Omni text-to-video is implemented on the flow.google.com batch path only"} + + client = get_flow_client() + try: + pid = client._batch_project_id(project_id) + model_key = f"abra_t2v_{duration_s}s" + freq = fb.text_video_request(prompt, pid, aspect=aspect_ratio, model=model_key) + payload = await client._batch_payload( + fb.RPC_GEN_VIDEO_TEXT, freq, fb.CAPTCHA_VIDEO, timeout=120) + submitted = fb.read_text_video_submit(payload) + except Exception as exc: + return {"status": 502, "error": f"{type(exc).__name__}: {exc}"} + + media_id = submitted["media_id"] + workflow = { + "name": submitted.get("workflow_id") or media_id, + "primary_media_id": media_id, + "project_id": pid, + } + return { + "status": 200, + "data": { + "media": [{"name": media_id}], + "workflows": [workflow], + "model": model_key, + "duration_s": duration_s, + "flowkitPolling": { + "mode": "batch_media", + "project_id": pid, + "workflows": [workflow], + }, + }, + } + + async def _submit_omni_frame_video( *, start_image_media_id: str, @@ -398,20 +447,68 @@ async def generate_omni_flash_video( return _annotate_polling(result, project_id) -async def check_omni_flash_status( +async def _check_omni_batch_media( workflows: list[dict], include_encoded_video: bool = False, project_id: str = "", ) -> dict: - """Perform one non-blocking poll pass for Omni workflow-backed jobs. + normalized = [item for workflow in (workflows or []) if (item := _normalize_workflow(workflow))] + if not normalized: + raise ValueError("Omni polling requires workflow descriptors with name and primary_media_id") + resolved_project_id = project_id or next( + (item.get("project_id", "") for item in normalized if item.get("project_id")), "") + client = get_flow_client() + items = [] + for workflow in normalized: + media_id = workflow["primary_media_id"] + response = await client.get_media(media_id) + data = response.get("data") if isinstance(response, dict) else None + video = data.get("video") if isinstance(data, dict) else None + url = video.get("fifeUrl") if isinstance(video, dict) else None + if isinstance(url, str) and url.startswith("https://flow-content.google/video/"): + media = { + "media_id": media_id, + "url": url, + "encoded_video_available": False, + "resolved_via": "as29s", + } + if include_encoded_video: + media["encoded_video"] = None + items.append({ + "name": workflow["name"], + "primary_media_id": media_id, + "project_id": workflow.get("project_id") or resolved_project_id, + "done": True, + "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL", + "error": None, + "media": media, + }) + else: + items.append({ + "name": workflow["name"], + "primary_media_id": media_id, + "project_id": workflow.get("project_id") or resolved_project_id, + "done": False, + "status": "PENDING", + "error": None, + }) + all_done = bool(items) and all(item["done"] for item in items) + return { + "project_id": resolved_project_id or None, + "done": all_done, + "status": "COMPLETED" if all_done else "PENDING", + "workflows": items, + } - Flow's production UI exposes workflow status through its authenticated - ``flow.projectInitialData`` tRPC response. The old ``/v1/media`` transport - currently returns ``INVALID_ARGUMENT`` for these workflow media IDs. - """ - blocked = _batch_path_blocks_omni() - if blocked: - return blocked + +async def check_omni_flash_status( + workflows: list[dict], + include_encoded_video: bool = False, + project_id: str = "", +) -> dict: + """Perform one non-blocking poll pass for Omni workflow-backed jobs.""" + if USE_BATCH_RPC: + return await _check_omni_batch_media(workflows, include_encoded_video, project_id) normalized = [] for workflow in workflows or []: item = _normalize_workflow(workflow) diff --git a/docs/OMNI_FLASH.md b/docs/OMNI_FLASH.md index 93aa1e94c..64d3c040d 100644 --- a/docs/OMNI_FLASH.md +++ b/docs/OMNI_FLASH.md @@ -11,46 +11,55 @@ curl -fsS "$FLOWKIT_BASE_URL/health" curl -fsS "$FLOWKIT_BASE_URL/api/flow/status" ``` -Expected state: +Expected state on the migrated Flow transport: ```json {"status":"ok","extension_connected":true} -{"connected":true,"flow_key_present":true} +{"connected":true,"transport":"batch"} ``` Use `http://127.0.0.1:8100` when the caller runs on the FlowKit host. For a remote integration, set `FLOWKIT_BASE_URL` to the protected HTTPS reverse-proxy URL and allow only the required source IPs or private network. Do not expose Chrome, VNC/noVNC, the extension WebSocket, or port 8100 publicly. ## Supported modes -| Mode | Inputs | Endpoint | Internal model family | -|---|---|---|---| -| First frame to video | one uploaded start image | `POST /api/flow/generate-video` | `abra_i2v_s` | -| First + Last frame to video | uploaded start and end images | `POST /api/flow/generate-video` | `abra_i2v_s` | -| References to video | 1-7 uploaded reference images | `POST /api/flow/generate-video-omni` | `abra_r2v_s` | - -Supported durations are `4`, `6`, `8`, and `10` seconds. Supported aspect ratios are: +On `flow.google.com`, Omni **text-to-video** is migrated and live-verified. The older frame/reference implementations still use the pre-migration REST transport and remain fail-fast while `USE_BATCH_RPC=1`. -- `VIDEO_ASPECT_RATIO_PORTRAIT` (`9:16`) -- `VIDEO_ASPECT_RATIO_LANDSCAPE` (`16:9`) +| Mode | Batch status | Endpoint | Internal model family | +|---|---|---|---| +| Text to video | **supported** | `POST /api/flow/generate-video-omni-text` | `abra_t2v_s` | +| First frame to video | not yet ported | `POST /api/flow/generate-video` | `abra_i2v_s` (legacy only) | +| First + Last frame to video | not yet ported | `POST /api/flow/generate-video` | `abra_i2v_s` (legacy only) | +| References to video | not yet ported | `POST /api/flow/generate-video-omni` | `abra_r2v_s` (legacy only) | -First + Last generation with `batchAsyncGenerateVideoStartAndEndImage` and the current `abra_i2v_*` mapping has been verified with a real Flow generation. +Text-to-video supports `4`, `6`, `8`, and `10` seconds, with portrait and landscape aspect ratios. The migrated `YhhmEf` wire was live-verified with `abra_t2v_4s`; the downloaded result was exactly 4.000 seconds at 1280×720/24 fps. Completed media resolves through the migrated `as29s` media lookup. ## End-to-end integration flow -An integration agent should implement this state machine: - 1. Check `/health` and `/api/flow/status`. -2. Make each source image readable on the FlowKit server. -3. Call `/api/flow/upload-image` for every source image and retain each returned `media_id`. -4. Submit exactly one Omni request and persist its complete `flowkitPolling` object. -5. Poll `/api/flow/check-omni-status` every 10-20 seconds using `project_id` and `workflows` from `flowkitPolling`. -6. On `PENDING`, continue polling. On `FAILED`, stop and report the returned error. On `COMPLETED`, immediately download every non-null `media.url`. -7. Store the downloaded video in the project's own durable storage. The returned Google URL is signed and short-lived. +2. Submit `POST /api/flow/generate-video-omni-text` with prompt, project ID, duration and aspect ratio. +3. Persist the returned `flowkitPolling` object. +4. Poll `/api/flow/check-omni-status` every 10–20 seconds with its `project_id` and `workflows`. +5. On `COMPLETED`, immediately download `workflows[].media.url`; the signed URL is short-lived. -Do not send Omni workflow names to the legacy Veo `batchCheckAsyncVideoGenerationStatus` operation poller. Do not use the obsolete `/v1/media/` polling path. +Example: + +```bash +curl -fsS -X POST "$FLOWKIT_BASE_URL/api/flow/generate-video-omni-text" \ + -H 'Content-Type: application/json' \ + -d '{ + "prompt": "A small red paper boat gently drifts across a calm pond", + "project_id": "FLOW_PROJECT_ID", + "duration_s": 4, + "aspect_ratio": "VIDEO_ASPECT_RATIO_LANDSCAPE" + }' +``` + +Do not feed Omni workflow names to the legacy Veo operation poller. ## Supplying images +This section applies to the legacy frame/reference Omni modes, which are not yet ported to the migrated batch transport. + `POST /api/flow/upload-image` is not a multipart upload endpoint. Its `file_path` is an absolute path on the **FlowKit server**, not on the calling server. For a remote integration, first stage the file on the FlowKit host using an authenticated transfer such as SFTP/SCP, a private shared volume, or a separately secured upload service. Use a unique per-job directory, validate file size/type, and make the file readable by the FlowKit service account. Then call: diff --git a/tests/unit/test_flow_batch.py b/tests/unit/test_flow_batch.py index 63b8761dc..a221023f3 100644 --- a/tests/unit/test_flow_batch.py +++ b/tests/unit/test_flow_batch.py @@ -121,6 +121,22 @@ def test_a_hand_reframed_crop_overrides_the_default(self): crop = [None, 0.1, 1, 0.9] assert inner(fb.video_request("go", self.PID, "mid", crop=crop))[0][0][4][5] == crop + def test_text_video_matches_the_captured_yhhmef_shape(self): + payload = inner(fb.text_video_request( + "a boat", self.PID, + aspect="VIDEO_ASPECT_RATIO_LANDSCAPE", + model="abra_t2v_4s", + )) + request = payload[0][0] + assert request[0] == [None, None, [[["a boat"]]]] + assert request[1] == "abra_t2v_4s" + assert request[2] == fb.VIDEO_ASPECT_LANDSCAPE + assert request[3] is None + assert len(request[4]) == 6 + assert payload[1][5] == self.PID + assert payload[2][1] == 1 + assert fb.CAPTCHA_SLOT in json.dumps(payload) + class TestReaders: OP = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" @@ -135,6 +151,15 @@ def test_a_repeated_url_is_not_a_second_variant(self): url = f"https://{fb.MEDIA_HOST}/image/{self.MID}?sig=x" assert len(fb.read_images([url, url])) == 1 + def test_text_video_submit_reads_media_and_workflow_ids(self): + payload = [None, 10, [], [[self.MID, "project-1", self.OP, "CAE"]]] + assert fb.read_text_video_submit(payload) == { + "media_id": self.MID, + "project_id": "project-1", + "workflow_id": self.OP, + "status": "CAE", + } + def test_operation_reads_the_id_and_status(self): op = fb.read_operation([None, 50, [[self.OP, "proj", "scene", "CAE"]]]) assert (op.operation_id, op.status, op.done) == (self.OP, "CAE", True) diff --git a/tests/unit/test_omni_flash.py b/tests/unit/test_omni_flash.py index 2333e6ee4..cf3b2fb14 100644 --- a/tests/unit/test_omni_flash.py +++ b/tests/unit/test_omni_flash.py @@ -20,6 +20,7 @@ extract_omni_workflows, generate_omni_flash_first_frame_video, generate_omni_flash_first_last_video, + generate_omni_flash_text_video, generate_omni_flash_video, ) @@ -132,6 +133,36 @@ def _mock_submit_client(): return client +@pytest.mark.asyncio +async def test_batch_text_video_builds_4s_yhhmef_submit(monkeypatch): + monkeypatch.setattr(omni_flash, "USE_BATCH_RPC", True) + client = MagicMock() + client._batch_project_id.return_value = "11111111-2222-3333-4444-555555555555" + client._batch_payload = AsyncMock(return_value=[ + None, 10, [], [[ + "22222222-3333-4444-5555-666666666666", + "11111111-2222-3333-4444-555555555555", + "77777777-8888-9999-aaaa-bbbbbbbbbbbb", "CAE", + ]], + ]) + with patch("agent.services.omni_flash.get_flow_client", return_value=client): + result = await generate_omni_flash_text_video( + prompt="A red paper boat drifts across a pond", + project_id="11111111-2222-3333-4444-555555555555", + duration_s=4, + aspect_ratio="VIDEO_ASPECT_RATIO_LANDSCAPE", + ) + assert result["status"] == 200 + assert result["data"]["model"] == "abra_t2v_4s" + assert result["data"]["duration_s"] == 4 + assert result["data"]["flowkitPolling"]["mode"] == "batch_media" + rpcid, freq, captcha = client._batch_payload.await_args.args[:3] + assert rpcid == omni_flash.fb.RPC_GEN_VIDEO_TEXT + assert captcha == omni_flash.fb.CAPTCHA_VIDEO + payload = __import__("json").loads(__import__("json").loads(freq)[0][0][1]) + assert payload[0][0][1] == "abra_t2v_4s" + + @pytest.mark.asyncio async def test_submit_builds_flow_omni_first_frame_request_and_poll_descriptor(): client = _mock_submit_client() @@ -353,6 +384,23 @@ async def test_media_redirect_fetch_requests_url_only_mode(): ) +@pytest.mark.asyncio +async def test_batch_omni_poll_uses_as29s_media(monkeypatch): + monkeypatch.setattr(omni_flash, "USE_BATCH_RPC", True) + client = MagicMock() + client.get_media = AsyncMock(return_value={ + "status": 200, + "data": {"video": {"fifeUrl": "https://flow-content.google/video/media-1?Signature=test"}}, + }) + with patch("agent.services.omni_flash.get_flow_client", return_value=client): + result = await check_omni_flash_status([{ + "name": "workflow-1", "primary_media_id": "media-1", "project_id": "project-1", + }]) + assert result["done"] is True + assert result["workflows"][0]["media"]["resolved_via"] == "as29s" + client.get_media.assert_awaited_once_with("media-1") + + @pytest.mark.asyncio async def test_omni_poll_pending_uses_project_snapshot_not_legacy_transports(): client = MagicMock() @@ -477,7 +525,7 @@ async def test_submit_rejects_empty_reference_set(): ) -class TestBatchPathIsRefusedRatherThanAttempted: +class TestUnportedOmniBatchModesAreRefusedRatherThanAttempted: """Flow stopped minting the bearer these endpoints need, and no Omni payload has been captured off the new frontend. Saying so beats a 401 five retries deep.""" @@ -513,14 +561,8 @@ async def test_reference_to_video_names_the_gap_and_sends_nothing(self, client): assert "UNSUPPORTED_ON_BATCH_API" in result["error"] client._send.assert_not_called() - async def test_polling_names_the_gap_and_sends_nothing(self, client): - result = await check_omni_flash_status( - [{"name": "wf", "primary_media_id": "mid", "project_id": "pid"}]) - assert "UNSUPPORTED_ON_BATCH_API" in result["error"] - client._send.assert_not_called() - - async def test_the_message_points_at_both_ways_out(self, client): + async def test_the_message_points_to_supported_text_to_video(self, client): result = await generate_omni_flash_video( reference_media_ids=["a"], prompt="go", project_id="pid") - assert "docs/CAPTURE.md" in result["error"] - assert "USE_BATCH_RPC=0" in result["error"] + assert "text-to-video is supported" in result["error"] + assert "reference-to-video" in result["error"] From d5a33d2477c0df4209c7aa279f0130accdd83e3c Mon Sep 17 00:00:00 2001 From: hieuho Date: Tue, 8 Sep 2026 16:26:39 +0700 Subject: [PATCH 03/68] chore(gitignore): ignore local dev artifacts (.DS_Store, venv, extension metadata) --- .gitignore | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 766c04bdc..9675c485c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,9 @@ GEMINI.md ds-bundle/ .design-sync/.cache/ .design-sync/learnings/ -.design-sync/node_modules \ No newline at end of file +.design-sync/node_modules + +# Local dev artifacts (never commit) +.DS_Store +venv/ +extension/_metadata/ \ No newline at end of file From 82f8cfaff78fb38c3ca6323e8c487a95695f59b2 Mon Sep 17 00:00:00 2001 From: hieuho Date: Tue, 8 Sep 2026 16:34:07 +0700 Subject: [PATCH 04/68] docs(tts): note remote OmniVoice backend in narrator and import-voice skills --- skills/fk-gen-narrator.md | 6 ++++++ skills/fk-import-voice.md | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/skills/fk-gen-narrator.md b/skills/fk-gen-narrator.md index 4e49f55d2..5a874ea21 100644 --- a/skills/fk-gen-narrator.md +++ b/skills/fk-gen-narrator.md @@ -163,6 +163,12 @@ Ask user: "Review OK? Type 'yes' to generate TTS, or 'edit N' to modify scene N' **CRITICAL: Always pass BOTH `ref_audio` AND `ref_text` together.** Without `ref_text`, OmniVoice falls back to generic voice → each scene sounds different. +> **Backend is transparent here.** `/api/tts/generate` uses whatever backend FlowKit +> is configured with (`TTS_BACKEND=local` default, or `remote` for a GPU inference +> service). This skill is identical either way — no request changes. See +> `fk-gen-tts-template.md` and the README "Optional remote OmniVoice API" section for +> backend setup. + ### Proven workflow (per-scene via `/api/tts/generate`): The batch endpoint (`/api/videos//narrate`) can timeout on large batches (40+ scenes). diff --git a/skills/fk-import-voice.md b/skills/fk-import-voice.md index 6772e0fa2..5ce23da3d 100644 --- a/skills/fk-import-voice.md +++ b/skills/fk-import-voice.md @@ -110,6 +110,6 @@ Play the output for user to verify voice quality matches the original. ## Notes - **Transcript accuracy matters** — `ref_text` must match the audio closely for good voice cloning. Always confirm with the user. -- **CPU only** — whisper large-v3 and OmniVoice both run on CPU. MPS produces artifacts. +- **CPU by default** — whisper large-v3 and local OmniVoice both run on CPU (MPS produces artifacts). For GPU speed, run OmniVoice as a remote service and set `TTS_BACKEND=remote` (see `fk-gen-tts-template.md`); transcription still runs locally on CPU. - **3-10s audio** — shorter clips lack enough voice characteristics; longer clips slow down cloning. - **One template per voice** — don't register multiple templates for the same voice. Update instead. From 2eb04f900ad8e563216ec46c223200eb028fc66d Mon Sep 17 00:00:00 2001 From: hieuho Date: Tue, 8 Sep 2026 21:47:34 +0700 Subject: [PATCH 05/68] feat(flow): create and delete Flow projects on the batchexecute path Port the jHPbke (create) and QI2zvc (delete) RPCs captured off the Flow UI: - flow_batch: RPC_CREATE_PROJECT/RPC_DELETE_PROJECT, request builders, and read_created_project_id (slot 0, uuid fullmatch, raises otherwise). - flow_client.create_project mints a project via jHPbke when unpinned (pin still reused first); rejects non-default tool_name on batch; delete_project via QI2zvc. - projects DELETE route: preflight get_project (404 before any RPC), remote-first delete of every project except the pinned/shared one, local row kept on failure. Verified: 100 unit tests + a live create/delete round trip on Flow. --- agent/api/projects.py | 25 +++++-- agent/services/flow_batch.py | 38 ++++++++++ agent/services/flow_client.py | 50 ++++++++++--- tests/unit/test_flow_batch.py | 23 ++++++ tests/unit/test_flow_client_batch.py | 67 ++++++++++++++++- tests/unit/test_projects_route.py | 103 +++++++++++++++++++++++++++ 6 files changed, 289 insertions(+), 17 deletions(-) create mode 100644 tests/unit/test_projects_route.py diff --git a/agent/api/projects.py b/agent/api/projects.py index 600ebe8a9..9a69955f7 100644 --- a/agent/api/projects.py +++ b/agent/api/projects.py @@ -7,7 +7,7 @@ from fastapi import APIRouter, HTTPException from pydantic import BaseModel -from agent.config import BASE_DIR, USE_BATCH_RPC +from agent.config import BASE_DIR, USE_BATCH_RPC, FLOW_PROJECT_ID from agent.models.project import Project, ProjectCreate, ProjectUpdate from agent.models.character import Character from agent.sdk.persistence.sqlite_repository import SQLiteRepository @@ -172,8 +172,9 @@ async def create(body: ProjectCreate): detected_tier = await _detect_user_tier(client) - # On the batch path Flow no longer creates projects for us — the uuid comes - # from the request or from FLOW_PROJECT_ID. The legacy path still mints one. + # On the batch path a pinned FLOW_PROJECT_ID (or a uuid passed in the request) + # is reused; with neither, create_project now mints one via jHPbke. The legacy + # path always mints one. flow_project_id = client.flow_project_id(body.flow_project_id) if USE_BATCH_RPC else None if flow_project_id: logger.info("Flow project reused: %s", flow_project_id) @@ -259,9 +260,25 @@ async def update(pid: str, body: ProjectUpdate): @router.delete("/{pid}") async def delete(pid: str): + """Delete a project locally, and on Flow too when it is safe. + + The project must exist locally before anything is deleted, so a stray uuid + cannot reach through to Flow — only projects Flow Kit already tracks are + eligible. Flow is then deleted first (except the pinned FLOW_PROJECT_ID, the + shared/operator project, which is only ever removed locally) so a remote + failure leaves the local row in place rather than letting the two drift. + """ repo = _get_repo() - if not await repo.delete_project(pid): + if not await repo.get_project(pid): raise HTTPException(404, "Project not found") + if USE_BATCH_RPC and pid != (FLOW_PROJECT_ID or None): + client = get_flow_client() + if not client.connected: + raise HTTPException(503, "Extension not connected — cannot delete this project on Google Flow") + result = await client.delete_project(pid) + if result.get("error"): + raise HTTPException(502, f"Flow delete failed: {result['error']}") + await repo.delete_project(pid) return {"ok": True} diff --git a/agent/services/flow_batch.py b/agent/services/flow_batch.py index f01116320..b50bf510e 100644 --- a/agent/services/flow_batch.py +++ b/agent/services/flow_batch.py @@ -40,6 +40,8 @@ RPC_PROJECT_MEDIA = "Zzl0ze" RPC_MEDIA = "as29s" RPC_UPLOAD_IMAGE = "maseQ" +RPC_CREATE_PROJECT = "jHPbke" +RPC_DELETE_PROJECT = "QI2zvc" CAPTCHA_IMAGE = "IMAGE_GENERATION" CAPTCHA_VIDEO = "VIDEO_GENERATION" @@ -382,6 +384,23 @@ def media_request(media_id: str) -> str: return build_envelope(RPC_MEDIA, [media_id]) +def create_project_request(title: str) -> str: + """Make a new Flow project titled ``title``. + + Captured off the UI's "New project" button. Inner payload is + ``["projects/*", [None, [title]], [None, SURFACE_ID]]`` — the trailing ``22`` + is the same surface id every other call stamps, not a tool type. This path + carries no tool slot, so it can only ask for the surface's default; a caller + that needs a specific tool cannot get it here (see FlowClient.create_project). + """ + return build_envelope(RPC_CREATE_PROJECT, ["projects/*", [None, [title]], [None, SURFACE_ID]]) + + +def delete_project_request(project_id: str) -> str: + """Delete a Flow project. Inner payload is ``["projects/"]``.""" + return build_envelope(RPC_DELETE_PROJECT, [f"projects/{project_id}"]) + + # ── response readers ───────────────────────────────────────────────────────── def _walk_strings(node: Any): @@ -429,6 +448,25 @@ def read_uploaded_media_id(payload: Any) -> str: return media_id +#: A Flow project id is a plain uuid; the create response leads with it. +_PROJECT_ID_RE = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", re.I) + + +def read_created_project_id(payload: Any) -> str: + """The uuid of a freshly created project. + + Captured shape: ``["", [""]]`` — the id leads the payload and + equals the ``/project/<uuid>`` the UI navigates to. Read that one slot and + nothing else: a 200 with the id somewhere unexpected is accepted and then + silently useless, so a non-uuid here is a failure rather than a cue to scan + the envelope for the first uuid-looking string. + """ + first = payload[0] if isinstance(payload, list) and payload else None + if isinstance(first, str) and _PROJECT_ID_RE.fullmatch(first): + return first + raise FlowBatchError(f"create response carried no project id: {payload!r}") + + def read_operation(payload: Any) -> Operation: """`[null, 50, [[opId, projectId, sceneId, status, …]]]`. diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index 667e2d51d..7d7c092d8 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -560,14 +560,50 @@ def flow_project_id(self, requested: str | None = None) -> str | None: return FLOW_PROJECT_ID or None async def create_project(self, project_title: str, tool_name: str = "PINHOLE") -> dict: + """Create a Flow project, or reuse the pinned one. + + Pin precedence: a pinned FLOW_PROJECT_ID (or a uuid the caller passes) is + reused rather than minting a new project every call — the route only + falls through to here when nothing is pinned. Unpinned, the batch path + now creates one for real via the ``jHPbke`` RPC captured off the UI's + "New project" button and hands back its uuid. ``tool_name`` is honoured + only on the legacy path; the batch create carries no tool slot, so a + non-default value is rejected rather than silently ignored. + """ if not USE_BATCH_RPC: return await self._legacy_create_project(project_title, tool_name) - pid = self.flow_project_id() - if not pid: - return {"error": _UNSUPPORTED_CREATE_PROJECT} - logger.info("Reusing pinned Flow project %s for '%s'", pid[:12], project_title) + pinned = self.flow_project_id() + if pinned: + logger.info("Reusing pinned Flow project %s for '%s'", pinned[:12], project_title) + return {"status": 200, "data": {"projectId": pinned}} + if tool_name and tool_name != "PINHOLE": + return {"error": "UNSUPPORTED_ON_BATCH_API: batch create carries no tool slot, " + f"cannot honour tool_name={tool_name!r}"} + try: + payload = await self._batch_payload(fb.RPC_CREATE_PROJECT, + fb.create_project_request(project_title)) + pid = fb.read_created_project_id(payload) + except (fb.FlowBatchError, fb.RpcError) as exc: + return {"error": f"CREATE_PROJECT_FAILED: {exc}"} + logger.info("Flow project created %s for '%s'", pid[:12], project_title) return {"status": 200, "data": {"projectId": pid}} + async def delete_project(self, project_id: str) -> dict: + """Delete a Flow project via the ``QI2zvc`` RPC (batch path only). + + A successful delete answers with an empty payload — there is nothing to + read back, so a clean return is success and a transport error surfaces as + ``{"error": …}`` like the rest of the client. + """ + if not USE_BATCH_RPC: + return {"error": "UNSUPPORTED_ON_BATCH_API: delete_project needs the batchexecute transport"} + try: + await self._batch_payload(fb.RPC_DELETE_PROJECT, fb.delete_project_request(project_id)) + except (fb.FlowBatchError, fb.RpcError) as exc: + return {"error": f"DELETE_PROJECT_FAILED: {exc}"} + logger.info("Flow project deleted %s", project_id[:12]) + return {"status": 200, "data": {"projectId": project_id}} + async def generate_images(self, prompt: str, project_id: str, aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT", user_paygate_tier: str = "PAYGATE_TIER_TWO", @@ -1207,12 +1243,6 @@ async def _legacy_upload_image(self, image_base64: str, mime_type: str = "image/ _CAPTURE_HINT = "see docs/CAPTURE.md to record its payload off the new UI" -_UNSUPPORTED_CREATE_PROJECT = ( - "NO_FLOW_PROJECT: Flow's project.createProject endpoint went with the September 2026 " - "migration, so Flow Kit cannot create one. Make a project in the Flow UI, then either " - "pass its uuid as flow_project_id or pin it as FLOW_PROJECT_ID." -) - def _unsupported(feature: str, why: str) -> str: return f"UNSUPPORTED_ON_BATCH_API: {feature} — {why}; {_CAPTURE_HINT}." diff --git a/tests/unit/test_flow_batch.py b/tests/unit/test_flow_batch.py index 63b8761dc..47c75245d 100644 --- a/tests/unit/test_flow_batch.py +++ b/tests/unit/test_flow_batch.py @@ -231,3 +231,26 @@ def test_every_resolved_video_model_is_one_flow_accepts(self): from agent.config import VIDEO_MODELS key = VIDEO_MODELS.get(tier, {}).get(gen, {}).get(aspect) assert fb.resolve_video_model(key) in fb.VIDEO_MODELS + + +class TestProjectRpcs: + def test_create_request_carries_the_captured_slots(self): + assert inner(fb.create_project_request("My Film")) == [ + "projects/*", [None, ["My Film"]], [None, fb.SURFACE_ID]] + + def test_delete_request_names_the_project_path(self): + assert inner(fb.delete_project_request("11111111-2222-3333-4444-555555555555")) == [ + "projects/11111111-2222-3333-4444-555555555555"] + + def test_read_created_id_takes_the_leading_uuid(self): + pid = "8e30afb8-92d0-4d0b-b652-f0a79faca9f5" + assert fb.read_created_project_id([pid, ["My Film"]]) == pid + + def test_read_created_id_rejects_a_trailing_newline(self): + r"""`$` would let "<uuid>\n" through; fullmatch must reject it.""" + with pytest.raises(fb.FlowBatchError): + fb.read_created_project_id(["8e30afb8-92d0-4d0b-b652-f0a79faca9f5\n", ["x"]]) + + def test_read_created_id_rejects_a_non_uuid_lead(self): + with pytest.raises(fb.FlowBatchError): + fb.read_created_project_id([["My Film"], "not-a-uuid"]) diff --git a/tests/unit/test_flow_client_batch.py b/tests/unit/test_flow_client_batch.py index 733f52440..40b972eae 100644 --- a/tests/unit/test_flow_client_batch.py +++ b/tests/unit/test_flow_client_batch.py @@ -311,12 +311,73 @@ async def test_create_project_hands_back_the_pinned_one(self, client): result = await client.create_project("My Film") assert result["data"]["projectId"] == PROJECT - async def test_create_project_without_a_pin_explains_itself(self, client, monkeypatch): + async def test_create_project_without_a_pin_creates_one(self, client, monkeypatch): + """Unpinned, the batch path mints a real project and hands back its uuid.""" import agent.services.flow_client as module monkeypatch.setattr(module, "FLOW_PROJECT_ID", "") + new_pid = "8e30afb8-92d0-4d0b-b652-f0a79faca9f5" + client.responses[fb.RPC_CREATE_PROJECT] = { + "data": envelope(fb.RPC_CREATE_PROJECT, [new_pid, ["My Film"]]) + } result = await client.create_project("My Film") - assert "NO_FLOW_PROJECT" in result["error"] - assert "FLOW_PROJECT_ID" in result["error"] + assert result["data"]["projectId"] == new_pid + + async def test_create_project_sends_the_captured_request(self, client, monkeypatch): + """The jHPbke envelope carries ["projects/*", [None, [title]], [None, 22]].""" + import agent.services.flow_client as module + monkeypatch.setattr(module, "FLOW_PROJECT_ID", "") + client.responses[fb.RPC_CREATE_PROJECT] = { + "data": envelope(fb.RPC_CREATE_PROJECT, ["8e30afb8-92d0-4d0b-b652-f0a79faca9f5", ["My Film"]]) + } + await client.create_project("My Film") + assert client.calls[0]["rpcid"] == fb.RPC_CREATE_PROJECT + inner = json.loads(json.loads(client.calls[0]["freq"])[0][0][1]) + assert inner == ["projects/*", [None, ["My Film"]], [None, fb.SURFACE_ID]] + + async def test_create_project_rejects_an_id_less_response(self, client, monkeypatch): + """A 200 whose lead slot is not a uuid is a failure, not a guess (accepted != used).""" + import agent.services.flow_client as module + monkeypatch.setattr(module, "FLOW_PROJECT_ID", "") + client.responses[fb.RPC_CREATE_PROJECT] = { + "data": envelope(fb.RPC_CREATE_PROJECT, ["not-a-uuid", ["My Film"]]) + } + result = await client.create_project("My Film") + assert "CREATE_PROJECT_FAILED" in result["error"] + + async def test_create_project_refuses_a_non_default_tool_on_batch(self, client, monkeypatch): + """The batch create has no tool slot, so it will not pretend to honour one.""" + import agent.services.flow_client as module + monkeypatch.setattr(module, "FLOW_PROJECT_ID", "") + result = await client.create_project("My Film", tool_name="WHISK") + assert "UNSUPPORTED_ON_BATCH_API" in result["error"] + assert not client.calls, "nothing should have been sent" + + async def test_create_project_uses_the_legacy_path_when_batch_is_off(self, client, monkeypatch): + """USE_BATCH_RPC=0 still routes to the (post-mortem) tRPC create, untouched.""" + import agent.services.flow_client as module + monkeypatch.setattr(module, "USE_BATCH_RPC", False) + seen = {} + async def fake_legacy(title, tool): + seen["args"] = (title, tool) + return {"status": 200, "data": {"projectId": "legacy"}} + client._legacy_create_project = fake_legacy + result = await client.create_project("My Film", tool_name="PINHOLE") + assert seen["args"] == ("My Film", "PINHOLE") + assert result["data"]["projectId"] == "legacy" + assert not client.calls, "the batch transport should be untouched" + + async def test_delete_project_calls_QI2zvc_with_the_project_path(self, client): + client.responses[fb.RPC_DELETE_PROJECT] = {"data": envelope(fb.RPC_DELETE_PROJECT, [])} + result = await client.delete_project(PROJECT) + assert client.calls[0]["rpcid"] == fb.RPC_DELETE_PROJECT + inner = json.loads(json.loads(client.calls[0]["freq"])[0][0][1]) + assert inner == [f"projects/{PROJECT}"] + assert result["data"]["projectId"] == PROJECT + + async def test_delete_project_surfaces_a_transport_error(self, client): + client.responses[fb.RPC_DELETE_PROJECT] = {"error": "NO_FLOW_TAB"} + result = await client.delete_project(PROJECT) + assert "DELETE_PROJECT_FAILED" in result["error"] async def test_credits_answers_the_configured_tier_rather_than_guessing(self, client): result = await client.get_credits() diff --git a/tests/unit/test_projects_route.py b/tests/unit/test_projects_route.py new file mode 100644 index 000000000..05b48326b --- /dev/null +++ b/tests/unit/test_projects_route.py @@ -0,0 +1,103 @@ +"""The project DELETE route's Flow-side gate. + +The route reaches through to Google Flow, so these lock down when it does and, +more importantly, when it must not: never for a project it does not already +track, never for the pinned shared project, and never leaving local and remote +out of step when the remote call fails. +""" +import pytest + +from agent.api import projects + + +class FakeRepo: + def __init__(self, exists=True): + self._exists = exists + self.deleted = [] + + async def get_project(self, pid): + return {"id": pid} if self._exists else None + + async def delete_project(self, pid): + self.deleted.append(pid) + return True + + +class FakeClient: + def __init__(self, connected=True, error=None): + self.connected = connected + self._error = error + self.deleted = [] + + async def delete_project(self, pid): + self.deleted.append(pid) + if self._error: + return {"error": self._error} + return {"status": 200, "data": {"projectId": pid}} + + +@pytest.fixture +def wire(monkeypatch): + """Point the route at fake collaborators; batch path with a pinned project.""" + def _wire(*, repo, client, batch=True, pin="pinned-project"): + monkeypatch.setattr(projects, "USE_BATCH_RPC", batch) + monkeypatch.setattr(projects, "FLOW_PROJECT_ID", pin) + monkeypatch.setattr(projects, "_get_repo", lambda: repo) + monkeypatch.setattr(projects, "get_flow_client", lambda: client) + return _wire + + +async def test_missing_project_is_404_before_any_remote_call(wire): + repo, client = FakeRepo(exists=False), FakeClient() + wire(repo=repo, client=client) + with pytest.raises(projects.HTTPException) as exc: + await projects.delete("nope") + assert exc.value.status_code == 404 + assert client.deleted == [], "a stray id must not reach Flow" + assert repo.deleted == [] + + +async def test_pinned_project_is_removed_locally_only(wire): + repo, client = FakeRepo(), FakeClient() + wire(repo=repo, client=client, pin="pinned-project") + result = await projects.delete("pinned-project") + assert result == {"ok": True} + assert client.deleted == [], "the shared project is never deleted on Flow" + assert repo.deleted == ["pinned-project"] + + +async def test_tracked_project_is_deleted_remote_first_then_local(wire): + repo, client = FakeRepo(), FakeClient() + wire(repo=repo, client=client) + result = await projects.delete("proj-1") + assert result == {"ok": True} + assert client.deleted == ["proj-1"] + assert repo.deleted == ["proj-1"] + + +async def test_remote_failure_keeps_the_local_row(wire): + repo, client = FakeRepo(), FakeClient(error="NO_FLOW_TAB") + wire(repo=repo, client=client) + with pytest.raises(projects.HTTPException) as exc: + await projects.delete("proj-1") + assert exc.value.status_code == 502 + assert repo.deleted == [], "local row stays put so the two do not drift" + + +async def test_offline_extension_deletes_nothing(wire): + repo, client = FakeRepo(), FakeClient(connected=False) + wire(repo=repo, client=client) + with pytest.raises(projects.HTTPException) as exc: + await projects.delete("proj-1") + assert exc.value.status_code == 503 + assert client.deleted == [] + assert repo.deleted == [] + + +async def test_legacy_path_deletes_locally_without_touching_flow(wire): + repo, client = FakeRepo(), FakeClient() + wire(repo=repo, client=client, batch=False) + result = await projects.delete("proj-1") + assert result == {"ok": True} + assert client.deleted == [] + assert repo.deleted == ["proj-1"] From e631fb78f6b026f5031245520f936c522fbb6837 Mon Sep 17 00:00:00 2001 From: hieuho <hieuhd1003@gmail.com> Date: Tue, 8 Sep 2026 22:19:16 +0700 Subject: [PATCH 06/68] fix(api): reuse existing local project instead of re-inserting A pinned or request-supplied Flow project id may already have a local row; the bare INSERT then raised UNIQUE constraint failed and surfaced as a 500. Return the existing row when the id is already tracked. --- agent/api/projects.py | 9 +++++++++ tests/unit/test_projects_route.py | 28 +++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/agent/api/projects.py b/agent/api/projects.py index 9a69955f7..1d51fc590 100644 --- a/agent/api/projects.py +++ b/agent/api/projects.py @@ -187,6 +187,15 @@ async def create(body: ProjectCreate): repo = _get_repo() + # Reuse is idempotent: a pinned or request-supplied project id may already + # have a local row. Re-inserting that id violates the primary key + # (sqlite3.IntegrityError -> 500), so hand back the row we already have. A + # freshly minted id never matches, so this is a no-op on the create path. + existing = await repo.get_project(flow_project_id) + if existing: + logger.info("Flow project already tracked, reusing: %s", flow_project_id) + return existing + # Step 2: Create local project with the Flow-assigned ID and detected tier create_data = body.model_dump(exclude_none=True) create_data.pop("tool_name", None) diff --git a/tests/unit/test_projects_route.py b/tests/unit/test_projects_route.py index 05b48326b..eeb64ccdf 100644 --- a/tests/unit/test_projects_route.py +++ b/tests/unit/test_projects_route.py @@ -14,21 +14,33 @@ class FakeRepo: def __init__(self, exists=True): self._exists = exists self.deleted = [] + self.created = [] async def get_project(self, pid): return {"id": pid} if self._exists else None + async def create_project(self, **kw): + self.created.append(kw) + return {"id": kw.get("id")} + async def delete_project(self, pid): self.deleted.append(pid) return True class FakeClient: - def __init__(self, connected=True, error=None): + def __init__(self, connected=True, error=None, pin="pinned-project"): self.connected = connected self._error = error + self._pin = pin self.deleted = [] + def flow_project_id(self, requested=None): + return requested or self._pin + + async def get_credits(self): + return {"status": 200, "data": {"userPaygateTier": "PAYGATE_TIER_TWO"}} + async def delete_project(self, pid): self.deleted.append(pid) if self._error: @@ -101,3 +113,17 @@ async def test_legacy_path_deletes_locally_without_touching_flow(wire): assert result == {"ok": True} assert client.deleted == [] assert repo.deleted == ["proj-1"] + + +async def test_create_reuses_an_existing_local_project_instead_of_reinserting(wire): + """A pinned/request project already in the DB is returned, not re-INSERTed. + + The bare INSERT in crud.create_project raises `UNIQUE constraint failed: + project.id` on a duplicate id, which surfaced as an uncaught 500. + """ + from agent.models.project import ProjectCreate + repo, client = FakeRepo(exists=True), FakeClient(pin="pinned-project") + wire(repo=repo, client=client, pin="pinned-project") + result = await projects.create(ProjectCreate(name="anything", material="realistic")) + assert result == {"id": "pinned-project"}, "returned the existing project row" + assert repo.created == [], "must not attempt a second INSERT of the same id" From 666ea33040f9b26b667b2d9991c3ee67ae3aa700 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Thu, 10 Sep 2026 11:31:37 +0300 Subject: [PATCH 07/68] fix(extension): prevent idle Flow tab leaks --- README.md | 2 +- agent/services/flow_client.py | 27 +++++++++- dashboard/src/i18n/translations.ts | 70 +++++++++++++------------- extension/background.js | 65 ++++++++++++++++-------- extension/manifest.json | 2 +- setup.sh | 2 +- skills/fk-doctor.md | 4 +- tests/extension_mv3_bootstrap.test.cjs | 20 +++++++- 8 files changed, 128 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index e4dd67eab..512241a2e 100644 --- a/README.md +++ b/README.md @@ -789,7 +789,7 @@ These arrive in the response body as `data.error.details[].reason`. The worker a | `Requested entity was not found` | Uploaded `media_id` expired (~1h TTL) | Auto-recover via `_recover_entity_not_found` — re-uploads from `image_url`, re-queues PENDING | | `Internal error encountered` | Flow backend transient 500 | Exponential backoff retry: `2^retry * 10s`, capped 300s | | `reCAPTCHA failed` / `captcha` | Extension couldn't solve CAPTCHA | Retry up to 10× without incrementing `retry_count` (processor.py:454-464) | -| `PUBLIC_ERROR_UNUSUAL_ACTIVITY` (403, message `reCAPTCHA evaluation failed`) | Google flagged the session as bot-like — usually rapid bursts of submits, VPN/shared IP, or stale auth cookies | NOT auto-recoverable. Pause submits, clear cookies for `google.com` + `labs.google` in Chrome, sign back in at `labs.google/fx/tools/flow`, then resubmit with ≥1s gap and ≤5 concurrent. See `/fk-doctor` for full playbook. | +| `PUBLIC_ERROR_UNUSUAL_ACTIVITY` (403, message `reCAPTCHA evaluation failed`) | Google flagged the session as bot-like — usually rapid bursts of submits, VPN/shared IP, or stale auth cookies | NOT auto-recoverable. Pause submits, clear cookies for `google.com` + `labs.google` in Chrome, sign back in at `flow.google.com`, then resubmit with ≥1s gap and ≤5 concurrent. See `/fk-doctor` for full playbook. | ### HTTP Status Codes diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index 667e2d51d..68a139931 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -62,6 +62,8 @@ def set_extension(self, ws): "connected_at": time.time(), "flow_key": None, "token_captured_at": None, + "extension_version": None, + "flow_url_supported": None, "unavailable_until": 0, } # A new unauthenticated profile must not displace an already @@ -185,6 +187,16 @@ def ws_stats(self) -> dict: uptime = None if self._ws_connected_at and self.connected: uptime = int(time.time() - self._ws_connected_at) + versions = sorted({ + str(session["extension_version"]) + for session in self._extensions.values() + if session.get("extension_version") + }) + flow_url_support = [ + session.get("flow_url_supported") + for session in self._extensions.values() + if session.get("flow_url_supported") is not None + ] return { "connected": self.connected, "active_connections": len(self._extensions), @@ -192,6 +204,8 @@ def ws_stats(self) -> dict: 1 for session in self._extensions.values() if session.get("flow_key") ), + "extension_versions": versions, + "flow_url_supported": all(flow_url_support) if flow_url_support else None, "connects": self._ws_connect_count, "disconnects": self._ws_disconnect_count, "uptime_s": uptime, @@ -212,7 +226,18 @@ async def handle_message(self, data: dict, websocket=None): return if data.get("type") == "extension_ready": - logger.info("Extension ready, flowKey=%s", "yes" if data.get("flowKeyPresent") else "no") + source_ws = websocket or self._extension_ws + version = data.get("extensionVersion") + flow_supported = data.get("flowUrlSupported") + if source_ws is not None and source_ws in self._extensions: + self._extensions[source_ws]["extension_version"] = version + self._extensions[source_ws]["flow_url_supported"] = flow_supported + logger.info( + "Extension ready, flowKey=%s version=%s flow.google.com=%s", + "yes" if data.get("flowKeyPresent") else "no", + version or "unknown", + "yes" if flow_supported is True else "no" if flow_supported is False else "unknown", + ) asyncio.create_task(self._sync_tier()) return diff --git a/dashboard/src/i18n/translations.ts b/dashboard/src/i18n/translations.ts index 30348cb15..695be91a7 100644 --- a/dashboard/src/i18n/translations.ts +++ b/dashboard/src/i18n/translations.ts @@ -164,7 +164,7 @@ const en = { // ---- Guide ---- 'guide.title': 'Chrome Extension Setup Guide', - 'guide.intro': "Flow Kit needs a companion Chrome extension running alongside your browser to capture the login token, solve reCAPTCHA, and relay API calls to Google Flow (labs.google/fx/tools/flow). This extension is built/loaded manually — it isn't on the Chrome Web Store.", + 'guide.intro': "Flow Kit needs a companion Chrome extension running alongside your browser to capture the login token, solve reCAPTCHA, and relay API calls to Google Flow (flow.google.com). This extension is built/loaded manually — it isn't on the Chrome Web Store.", 'guide.status.title': 'Current status', 'guide.status.desc': 'auto-refreshes every 4s from GET /health', 'guide.status.unreachable': "Can't reach the agent at 127.0.0.1:8100 — run python -m agent.main.", @@ -176,7 +176,7 @@ const en = { 'guide.step1.title': 'Install the Chrome extension (Developer mode / unpacked)', 'guide.step1.body': 'Open chrome://extensions → enable "Developer mode" (top right) → click "Load unpacked" → select the extension/ folder in this repo.', 'guide.step2.title': 'Sign in to Google Flow', - 'guide.step2.body': "Open https://labs.google/fx/tools/flow and sign in with your Google account. The extension captures the login token from this tab — if you're not signed in, the agent will report a NO_FLOW_KEY error.", + 'guide.step2.body': "Open https://flow.google.com/ and sign in with your Google account. The extension captures the login token from this tab — if you're not signed in, the agent will report a NO_FLOW_KEY error.", 'guide.step3.title': 'Run the agent (backend)', 'guide.step3.body': 'From the repo root: source venv/bin/activate (if using ./setup.sh), then python -m agent.main. The agent runs the REST API on port 8100 and a WebSocket bridge to the extension on port 9222.', 'guide.step4.title': 'Verify the connection', @@ -185,13 +185,13 @@ const en = { 'guide.trouble1.problem': 'Extension shows "Agent disconnected"', 'guide.trouble1.solution': "Run python -m agent.main (the agent isn't running or crashed).", 'guide.trouble2.problem': 'Extension shows "No token"', - 'guide.trouble2.solution': 'Open labs.google/fx/tools/flow and sign in again.', + 'guide.trouble2.solution': 'Open flow.google.com and sign in again.', 'guide.trouble3.problem': 'CAPTCHA_FAILED: NO_FLOW_TAB error', - 'guide.trouble3.solution': 'Open a Google Flow tab (labs.google/fx/tools/flow) and try again.', + 'guide.trouble3.solution': 'Open a Google Flow tab (flow.google.com) and try again.', 'guide.trouble4.problem': '"Extension not connected"', 'guide.trouble4.solution': 'Go to chrome://extensions and click the reload icon on the Flow Kit card — the extension will reconnect automatically.', 'guide.trouble5.problem': '403 PUBLIC_ERROR_UNUSUAL_ACTIVITY error', - 'guide.trouble5.solution': 'Pause submissions → chrome://settings/cookies → remove cookies for google.com and labs.google → reopen labs.google/fx/tools/flow, sign in, solve the captcha if shown → resubmit more slowly.', + 'guide.trouble5.solution': 'Pause submissions → chrome://settings/cookies → remove cookies for google.com and labs.google → reopen flow.google.com, sign in, solve the captcha if shown → resubmit more slowly.', 'guide.trouble6.problem': 'curl: (7) Failed to connect to 127.0.0.1:8100', 'guide.trouble6.solution': "The agent isn't running — run python -m agent.main.", @@ -448,7 +448,7 @@ const vi: Partial<Record<TranslationKey, string>> = { 'videoPlayer.next': 'Sau', 'guide.title': 'Hướng dẫn cài đặt Chrome Extension', - 'guide.intro': 'Flow Kit cần một Chrome extension chạy song song để bắt token đăng nhập, giải reCAPTCHA và chuyển tiếp API call tới Google Flow (labs.google/fx/tools/flow). Extension này được tự build/load thủ công, không có trên Chrome Web Store.', + 'guide.intro': 'Flow Kit cần một Chrome extension chạy song song để bắt token đăng nhập, giải reCAPTCHA và chuyển tiếp API call tới Google Flow (flow.google.com). Extension này được tự build/load thủ công, không có trên Chrome Web Store.', 'guide.status.title': 'Trạng thái hiện tại', 'guide.status.desc': 'tự động cập nhật mỗi 4 giây từ GET /health', 'guide.status.unreachable': 'Không kết nối được tới agent ở 127.0.0.1:8100 — hãy chạy python -m agent.main.', @@ -460,7 +460,7 @@ const vi: Partial<Record<TranslationKey, string>> = { 'guide.step1.title': 'Cài Chrome extension (chế độ Developer / unpacked)', 'guide.step1.body': 'Mở chrome://extensions → bật "Developer mode" (góc trên phải) → bấm "Load unpacked" → chọn thư mục extension/ trong repo này.', 'guide.step2.title': 'Đăng nhập Google Flow', - 'guide.step2.body': 'Mở https://labs.google/fx/tools/flow và đăng nhập tài khoản Google của bạn. Extension bắt token đăng nhập từ tab này — nếu chưa đăng nhập, agent sẽ báo lỗi NO_FLOW_KEY.', + 'guide.step2.body': 'Mở https://flow.google.com/ và đăng nhập tài khoản Google của bạn. Extension bắt token đăng nhập từ tab này — nếu chưa đăng nhập, agent sẽ báo lỗi NO_FLOW_KEY.', 'guide.step3.title': 'Chạy agent (backend)', 'guide.step3.body': 'Từ thư mục gốc repo: source venv/bin/activate (nếu dùng ./setup.sh) rồi python -m agent.main. Agent chạy REST API ở cổng 8100 và WebSocket cầu nối với extension ở cổng 9222.', 'guide.step4.title': 'Kiểm tra kết nối', @@ -469,13 +469,13 @@ const vi: Partial<Record<TranslationKey, string>> = { 'guide.trouble1.problem': 'Extension báo "Agent disconnected"', 'guide.trouble1.solution': 'Chạy python -m agent.main (agent chưa chạy hoặc bị crash).', 'guide.trouble2.problem': 'Extension báo "No token"', - 'guide.trouble2.solution': 'Mở labs.google/fx/tools/flow và đăng nhập lại.', + 'guide.trouble2.solution': 'Mở flow.google.com và đăng nhập lại.', 'guide.trouble3.problem': 'Lỗi CAPTCHA_FAILED: NO_FLOW_TAB', - 'guide.trouble3.solution': 'Mở một tab Google Flow (labs.google/fx/tools/flow) rồi thử lại.', + 'guide.trouble3.solution': 'Mở một tab Google Flow (flow.google.com) rồi thử lại.', 'guide.trouble4.problem': '"Extension not connected"', 'guide.trouble4.solution': 'Vào chrome://extensions, bấm reload icon trên thẻ Flow Kit — extension sẽ tự kết nối lại.', 'guide.trouble5.problem': 'Lỗi 403 PUBLIC_ERROR_UNUSUAL_ACTIVITY', - 'guide.trouble5.solution': 'Tạm dừng gửi request → chrome://settings/cookies → xoá cookie của google.com và labs.google → mở lại labs.google/fx/tools/flow, đăng nhập, giải captcha nếu có → gửi lại chậm hơn.', + 'guide.trouble5.solution': 'Tạm dừng gửi request → chrome://settings/cookies → xoá cookie của google.com và labs.google → mở lại flow.google.com, đăng nhập, giải captcha nếu có → gửi lại chậm hơn.', 'guide.trouble6.problem': 'curl: (7) Failed to connect to 127.0.0.1:8100', 'guide.trouble6.solution': 'Agent chưa chạy — chạy python -m agent.main.', @@ -722,7 +722,7 @@ const hi: Partial<Record<TranslationKey, string>> = { 'videoPlayer.next': 'अगला', 'guide.title': 'Chrome Extension सेटअप गाइड', - 'guide.intro': 'Flow Kit को लॉगिन टोकन कैप्चर करने, reCAPTCHA हल करने और Google Flow (labs.google/fx/tools/flow) पर API कॉल भेजने के लिए एक साथ चलने वाला Chrome extension चाहिए। यह extension मैन्युअली बनाया/लोड किया जाता है — यह Chrome Web Store पर नहीं है।', + 'guide.intro': 'Flow Kit को लॉगिन टोकन कैप्चर करने, reCAPTCHA हल करने और Google Flow (flow.google.com) पर API कॉल भेजने के लिए एक साथ चलने वाला Chrome extension चाहिए। यह extension मैन्युअली बनाया/लोड किया जाता है — यह Chrome Web Store पर नहीं है।', 'guide.status.title': 'वर्तमान स्थिति', 'guide.status.desc': 'हर 4 सेकंड में GET /health से स्वतः रीफ्रेश होता है', 'guide.status.unreachable': '127.0.0.1:8100 पर एजेंट से कनेक्ट नहीं हो पा रहा — python -m agent.main चलाएं।', @@ -734,7 +734,7 @@ const hi: Partial<Record<TranslationKey, string>> = { 'guide.step1.title': 'Chrome extension इंस्टॉल करें (Developer mode / unpacked)', 'guide.step1.body': 'chrome://extensions खोलें → "Developer mode" चालू करें (ऊपर दाईं ओर) → "Load unpacked" पर क्लिक करें → इस repo में extension/ फ़ोल्डर चुनें।', 'guide.step2.title': 'Google Flow में साइन इन करें', - 'guide.step2.body': 'https://labs.google/fx/tools/flow खोलें और अपने Google अकाउंट से साइन इन करें। extension इस टैब से लॉगिन टोकन कैप्चर करता है — यदि साइन इन नहीं है तो एजेंट NO_FLOW_KEY एरर देगा।', + 'guide.step2.body': 'https://flow.google.com/ खोलें और अपने Google अकाउंट से साइन इन करें। extension इस टैब से लॉगिन टोकन कैप्चर करता है — यदि साइन इन नहीं है तो एजेंट NO_FLOW_KEY एरर देगा।', 'guide.step3.title': 'एजेंट (backend) चलाएं', 'guide.step3.body': 'repo के रूट से: source venv/bin/activate (यदि ./setup.sh उपयोग कर रहे हैं) फिर python -m agent.main चलाएं। एजेंट पोर्ट 8100 पर REST API और पोर्ट 9222 पर extension से WebSocket ब्रिज चलाता है।', 'guide.step4.title': 'कनेक्शन सत्यापित करें', @@ -743,13 +743,13 @@ const hi: Partial<Record<TranslationKey, string>> = { 'guide.trouble1.problem': 'एक्सटेंशन "Agent disconnected" दिखा रहा है', 'guide.trouble1.solution': 'python -m agent.main चलाएं (एजेंट नहीं चल रहा या क्रैश हो गया है)।', 'guide.trouble2.problem': 'एक्सटेंशन "No token" दिखा रहा है', - 'guide.trouble2.solution': 'labs.google/fx/tools/flow खोलें और फिर से साइन इन करें।', + 'guide.trouble2.solution': 'flow.google.com खोलें और फिर से साइन इन करें।', 'guide.trouble3.problem': 'CAPTCHA_FAILED: NO_FLOW_TAB एरर', - 'guide.trouble3.solution': 'एक Google Flow टैब खोलें (labs.google/fx/tools/flow) और फिर से प्रयास करें।', + 'guide.trouble3.solution': 'एक Google Flow टैब खोलें (flow.google.com) और फिर से प्रयास करें।', 'guide.trouble4.problem': '"Extension not connected"', 'guide.trouble4.solution': 'chrome://extensions पर जाएं और Flow Kit कार्ड पर reload आइकन क्लिक करें — extension स्वतः फिर से जुड़ जाएगा।', 'guide.trouble5.problem': '403 PUBLIC_ERROR_UNUSUAL_ACTIVITY एरर', - 'guide.trouble5.solution': 'सबमिशन रोकें → chrome://settings/cookies → google.com और labs.google के कुकीज़ हटाएं → labs.google/fx/tools/flow फिर से खोलें, साइन इन करें, दिखे तो captcha हल करें → धीरे-धीरे फिर से सबमिट करें।', + 'guide.trouble5.solution': 'सबमिशन रोकें → chrome://settings/cookies → google.com और labs.google के कुकीज़ हटाएं → flow.google.com फिर से खोलें, साइन इन करें, दिखे तो captcha हल करें → धीरे-धीरे फिर से सबमिट करें।', 'guide.trouble6.problem': 'curl: (7) Failed to connect to 127.0.0.1:8100', 'guide.trouble6.solution': 'एजेंट नहीं चल रहा — python -m agent.main चलाएं।', @@ -996,7 +996,7 @@ const id: Partial<Record<TranslationKey, string>> = { 'videoPlayer.next': 'Berikutnya', 'guide.title': 'Panduan Pengaturan Ekstensi Chrome', - 'guide.intro': 'Flow Kit membutuhkan ekstensi Chrome pendamping yang berjalan di browser untuk menangkap token login, menyelesaikan reCAPTCHA, dan meneruskan panggilan API ke Google Flow (labs.google/fx/tools/flow). Ekstensi ini dibuat/dimuat secara manual — tidak tersedia di Chrome Web Store.', + 'guide.intro': 'Flow Kit membutuhkan ekstensi Chrome pendamping yang berjalan di browser untuk menangkap token login, menyelesaikan reCAPTCHA, dan meneruskan panggilan API ke Google Flow (flow.google.com). Ekstensi ini dibuat/dimuat secara manual — tidak tersedia di Chrome Web Store.', 'guide.status.title': 'Status saat ini', 'guide.status.desc': 'diperbarui otomatis setiap 4 detik dari GET /health', 'guide.status.unreachable': 'Tidak dapat terhubung ke agent di 127.0.0.1:8100 — jalankan python -m agent.main.', @@ -1008,7 +1008,7 @@ const id: Partial<Record<TranslationKey, string>> = { 'guide.step1.title': 'Instal ekstensi Chrome (mode Developer / unpacked)', 'guide.step1.body': 'Buka chrome://extensions → aktifkan "Developer mode" (kanan atas) → klik "Load unpacked" → pilih folder extension/ di repo ini.', 'guide.step2.title': 'Masuk ke Google Flow', - 'guide.step2.body': 'Buka https://labs.google/fx/tools/flow dan masuk dengan akun Google Anda. Ekstensi menangkap token login dari tab ini — jika belum masuk, agent akan melaporkan error NO_FLOW_KEY.', + 'guide.step2.body': 'Buka https://flow.google.com/ dan masuk dengan akun Google Anda. Ekstensi menangkap token login dari tab ini — jika belum masuk, agent akan melaporkan error NO_FLOW_KEY.', 'guide.step3.title': 'Jalankan agent (backend)', 'guide.step3.body': 'Dari root repo: source venv/bin/activate (jika menggunakan ./setup.sh), lalu python -m agent.main. Agent menjalankan REST API di port 8100 dan jembatan WebSocket ke ekstensi di port 9222.', 'guide.step4.title': 'Verifikasi koneksi', @@ -1017,13 +1017,13 @@ const id: Partial<Record<TranslationKey, string>> = { 'guide.trouble1.problem': 'Ekstensi menampilkan "Agent disconnected"', 'guide.trouble1.solution': 'Jalankan python -m agent.main (agent tidak berjalan atau crash).', 'guide.trouble2.problem': 'Ekstensi menampilkan "No token"', - 'guide.trouble2.solution': 'Buka labs.google/fx/tools/flow dan masuk kembali.', + 'guide.trouble2.solution': 'Buka flow.google.com dan masuk kembali.', 'guide.trouble3.problem': 'Error CAPTCHA_FAILED: NO_FLOW_TAB', - 'guide.trouble3.solution': 'Buka tab Google Flow (labs.google/fx/tools/flow) dan coba lagi.', + 'guide.trouble3.solution': 'Buka tab Google Flow (flow.google.com) dan coba lagi.', 'guide.trouble4.problem': '"Extension not connected"', 'guide.trouble4.solution': 'Buka chrome://extensions dan klik ikon reload pada kartu Flow Kit — ekstensi akan terhubung kembali secara otomatis.', 'guide.trouble5.problem': 'Error 403 PUBLIC_ERROR_UNUSUAL_ACTIVITY', - 'guide.trouble5.solution': 'Hentikan sementara pengiriman → chrome://settings/cookies → hapus cookie untuk google.com dan labs.google → buka kembali labs.google/fx/tools/flow, masuk, selesaikan captcha jika muncul → kirim ulang lebih lambat.', + 'guide.trouble5.solution': 'Hentikan sementara pengiriman → chrome://settings/cookies → hapus cookie untuk google.com dan labs.google → buka kembali flow.google.com, masuk, selesaikan captcha jika muncul → kirim ulang lebih lambat.', 'guide.trouble6.problem': 'curl: (7) Failed to connect to 127.0.0.1:8100', 'guide.trouble6.solution': 'Agent tidak berjalan — jalankan python -m agent.main.', @@ -1270,7 +1270,7 @@ const zh: Partial<Record<TranslationKey, string>> = { 'videoPlayer.next': '下一个', 'guide.title': 'Chrome 扩展安装指南', - 'guide.intro': 'Flow Kit 需要一个配套的 Chrome 扩展在浏览器中运行,用于捕获登录令牌、解决 reCAPTCHA 并转发 API 请求到 Google Flow (labs.google/fx/tools/flow)。该扩展需手动构建/加载 — 未上架 Chrome 网上应用店。', + 'guide.intro': 'Flow Kit 需要一个配套的 Chrome 扩展在浏览器中运行,用于捕获登录令牌、解决 reCAPTCHA 并转发 API 请求到 Google Flow (flow.google.com)。该扩展需手动构建/加载 — 未上架 Chrome 网上应用店。', 'guide.status.title': '当前状态', 'guide.status.desc': '每 4 秒自动从 GET /health 刷新', 'guide.status.unreachable': '无法连接到 127.0.0.1:8100 的 agent — 请运行 python -m agent.main。', @@ -1282,7 +1282,7 @@ const zh: Partial<Record<TranslationKey, string>> = { 'guide.step1.title': '安装 Chrome 扩展(开发者模式 / 未打包)', 'guide.step1.body': '打开 chrome://extensions → 开启右上角的"开发者模式" → 点击"加载已解压的扩展程序" → 选择本仓库中的 extension/ 文件夹。', 'guide.step2.title': '登录 Google Flow', - 'guide.step2.body': '打开 https://labs.google/fx/tools/flow 并使用你的 Google 账号登录。扩展会从该标签页捕获登录令牌 — 如果未登录,agent 会报 NO_FLOW_KEY 错误。', + 'guide.step2.body': '打开 https://flow.google.com/ 并使用你的 Google 账号登录。扩展会从该标签页捕获登录令牌 — 如果未登录,agent 会报 NO_FLOW_KEY 错误。', 'guide.step3.title': '运行 agent(后端)', 'guide.step3.body': '在仓库根目录:source venv/bin/activate(如果使用了 ./setup.sh),然后运行 python -m agent.main。agent 会在 8100 端口运行 REST API,并在 9222 端口与扩展建立 WebSocket 桥接。', 'guide.step4.title': '验证连接', @@ -1291,13 +1291,13 @@ const zh: Partial<Record<TranslationKey, string>> = { 'guide.trouble1.problem': '扩展显示 "Agent disconnected"', 'guide.trouble1.solution': '运行 python -m agent.main(agent 未运行或已崩溃)。', 'guide.trouble2.problem': '扩展显示 "No token"', - 'guide.trouble2.solution': '打开 labs.google/fx/tools/flow 并重新登录。', + 'guide.trouble2.solution': '打开 flow.google.com 并重新登录。', 'guide.trouble3.problem': 'CAPTCHA_FAILED: NO_FLOW_TAB 错误', - 'guide.trouble3.solution': '打开一个 Google Flow 标签页(labs.google/fx/tools/flow)后重试。', + 'guide.trouble3.solution': '打开一个 Google Flow 标签页(flow.google.com)后重试。', 'guide.trouble4.problem': '"Extension not connected"', 'guide.trouble4.solution': '前往 chrome://extensions,点击 Flow Kit 卡片上的重新加载图标 — 扩展会自动重新连接。', 'guide.trouble5.problem': '403 PUBLIC_ERROR_UNUSUAL_ACTIVITY 错误', - 'guide.trouble5.solution': '暂停提交 → 打开 chrome://settings/cookies → 删除 google.com 和 labs.google 的 cookie → 重新打开 labs.google/fx/tools/flow,登录,如出现验证码请完成 → 放慢速度重新提交。', + 'guide.trouble5.solution': '暂停提交 → 打开 chrome://settings/cookies → 删除 google.com 和 labs.google 的 cookie → 重新打开 flow.google.com,登录,如出现验证码请完成 → 放慢速度重新提交。', 'guide.trouble6.problem': 'curl: (7) Failed to connect to 127.0.0.1:8100', 'guide.trouble6.solution': 'Agent 未运行 — 请运行 python -m agent.main。', @@ -1544,7 +1544,7 @@ const ko: Partial<Record<TranslationKey, string>> = { 'videoPlayer.next': '다음', 'guide.title': 'Chrome 확장 프로그램 설치 가이드', - 'guide.intro': 'Flow Kit는 로그인 토큰을 캡처하고, reCAPTCHA를 해결하며, Google Flow(labs.google/fx/tools/flow)로 API 호출을 전달하기 위해 함께 실행되는 Chrome 확장 프로그램이 필요합니다. 이 확장 프로그램은 직접 빌드/로드해야 하며 Chrome 웹 스토어에는 없습니다.', + 'guide.intro': 'Flow Kit는 로그인 토큰을 캡처하고, reCAPTCHA를 해결하며, Google Flow(flow.google.com)로 API 호출을 전달하기 위해 함께 실행되는 Chrome 확장 프로그램이 필요합니다. 이 확장 프로그램은 직접 빌드/로드해야 하며 Chrome 웹 스토어에는 없습니다.', 'guide.status.title': '현재 상태', 'guide.status.desc': 'GET /health로부터 4초마다 자동 갱신됩니다', 'guide.status.unreachable': '127.0.0.1:8100의 agent에 연결할 수 없습니다 — python -m agent.main을 실행하세요.', @@ -1556,7 +1556,7 @@ const ko: Partial<Record<TranslationKey, string>> = { 'guide.step1.title': 'Chrome 확장 프로그램 설치 (개발자 모드 / 압축해제됨)', 'guide.step1.body': 'chrome://extensions를 열고 → 우측 상단의 "개발자 모드"를 켠 다음 → "압축해제된 확장 프로그램을 로드합니다"를 클릭하고 → 이 저장소의 extension/ 폴더를 선택하세요.', 'guide.step2.title': 'Google Flow에 로그인', - 'guide.step2.body': 'https://labs.google/fx/tools/flow를 열고 Google 계정으로 로그인하세요. 확장 프로그램이 이 탭에서 로그인 토큰을 캡처합니다 — 로그인하지 않으면 agent가 NO_FLOW_KEY 오류를 표시합니다.', + 'guide.step2.body': 'https://flow.google.com/를 열고 Google 계정으로 로그인하세요. 확장 프로그램이 이 탭에서 로그인 토큰을 캡처합니다 — 로그인하지 않으면 agent가 NO_FLOW_KEY 오류를 표시합니다.', 'guide.step3.title': 'Agent(백엔드) 실행', 'guide.step3.body': '저장소 루트에서: source venv/bin/activate (./setup.sh를 사용한 경우) 후 python -m agent.main을 실행하세요. agent는 8100번 포트에서 REST API를, 9222번 포트에서 확장 프로그램과의 WebSocket 브리지를 실행합니다.', 'guide.step4.title': '연결 확인', @@ -1565,13 +1565,13 @@ const ko: Partial<Record<TranslationKey, string>> = { 'guide.trouble1.problem': '확장 프로그램에 "Agent disconnected"가 표시됨', 'guide.trouble1.solution': 'python -m agent.main을 실행하세요 (agent가 실행 중이 아니거나 충돌했습니다).', 'guide.trouble2.problem': '확장 프로그램에 "No token"이 표시됨', - 'guide.trouble2.solution': 'labs.google/fx/tools/flow를 열고 다시 로그인하세요.', + 'guide.trouble2.solution': 'flow.google.com를 열고 다시 로그인하세요.', 'guide.trouble3.problem': 'CAPTCHA_FAILED: NO_FLOW_TAB 오류', - 'guide.trouble3.solution': 'Google Flow 탭(labs.google/fx/tools/flow)을 열고 다시 시도하세요.', + 'guide.trouble3.solution': 'Google Flow 탭(flow.google.com)을 열고 다시 시도하세요.', 'guide.trouble4.problem': '"Extension not connected"', 'guide.trouble4.solution': 'chrome://extensions로 이동하여 Flow Kit 카드의 새로고침 아이콘을 클릭하세요 — 확장 프로그램이 자동으로 다시 연결됩니다.', 'guide.trouble5.problem': '403 PUBLIC_ERROR_UNUSUAL_ACTIVITY 오류', - 'guide.trouble5.solution': '제출을 일시 중지 → chrome://settings/cookies 열기 → google.com 및 labs.google의 쿠키 삭제 → labs.google/fx/tools/flow를 다시 열고 로그인, 캡차가 표시되면 해결 → 더 천천히 다시 제출하세요.', + 'guide.trouble5.solution': '제출을 일시 중지 → chrome://settings/cookies 열기 → google.com 및 labs.google의 쿠키 삭제 → flow.google.com를 다시 열고 로그인, 캡차가 표시되면 해결 → 더 천천히 다시 제출하세요.', 'guide.trouble6.problem': 'curl: (7) Failed to connect to 127.0.0.1:8100', 'guide.trouble6.solution': 'Agent가 실행 중이 아닙니다 — python -m agent.main을 실행하세요.', @@ -1818,7 +1818,7 @@ const ja: Partial<Record<TranslationKey, string>> = { 'videoPlayer.next': '次へ', 'guide.title': 'Chrome拡張機能セットアップガイド', - 'guide.intro': 'Flow Kitは、ログイントークンの取得、reCAPTCHAの解決、Google Flow(labs.google/fx/tools/flow)へのAPI呼び出しの中継のために、ブラウザ上で並行して動作するChrome拡張機能を必要とします。この拡張機能は手動でビルド/読み込みする必要があり、Chromeウェブストアには公開されていません。', + 'guide.intro': 'Flow Kitは、ログイントークンの取得、reCAPTCHAの解決、Google Flow(flow.google.com)へのAPI呼び出しの中継のために、ブラウザ上で並行して動作するChrome拡張機能を必要とします。この拡張機能は手動でビルド/読み込みする必要があり、Chromeウェブストアには公開されていません。', 'guide.status.title': '現在のステータス', 'guide.status.desc': 'GET /health から4秒ごとに自動更新されます', 'guide.status.unreachable': '127.0.0.1:8100 の agent に接続できません — python -m agent.main を実行してください。', @@ -1830,7 +1830,7 @@ const ja: Partial<Record<TranslationKey, string>> = { 'guide.step1.title': 'Chrome拡張機能をインストール(デベロッパーモード / パッケージ化されていない拡張機能)', 'guide.step1.body': 'chrome://extensions を開き → 右上の「デベロッパーモード」を有効にし → 「パッケージ化されていない拡張機能を読み込む」をクリックし → このリポジトリの extension/ フォルダを選択してください。', 'guide.step2.title': 'Google Flow にサインイン', - 'guide.step2.body': 'https://labs.google/fx/tools/flow を開き、Googleアカウントでサインインしてください。拡張機能はこのタブからログイントークンを取得します — サインインしていない場合、agentはNO_FLOW_KEYエラーを報告します。', + 'guide.step2.body': 'https://flow.google.com/ を開き、Googleアカウントでサインインしてください。拡張機能はこのタブからログイントークンを取得します — サインインしていない場合、agentはNO_FLOW_KEYエラーを報告します。', 'guide.step3.title': 'Agent(バックエンド)を実行', 'guide.step3.body': 'リポジトリのルートから: source venv/bin/activate(./setup.sh を使用した場合)を実行後、python -m agent.main を実行してください。agentはポート8100でREST APIを、ポート9222で拡張機能とのWebSocketブリッジを実行します。', 'guide.step4.title': '接続を確認', @@ -1839,13 +1839,13 @@ const ja: Partial<Record<TranslationKey, string>> = { 'guide.trouble1.problem': '拡張機能に "Agent disconnected" と表示される', 'guide.trouble1.solution': 'python -m agent.main を実行してください(agentが実行されていないかクラッシュしています)。', 'guide.trouble2.problem': '拡張機能に "No token" と表示される', - 'guide.trouble2.solution': 'labs.google/fx/tools/flow を開いて再度サインインしてください。', + 'guide.trouble2.solution': 'flow.google.com を開いて再度サインインしてください。', 'guide.trouble3.problem': 'CAPTCHA_FAILED: NO_FLOW_TAB エラー', - 'guide.trouble3.solution': 'Google Flow のタブ(labs.google/fx/tools/flow)を開いてから再試行してください。', + 'guide.trouble3.solution': 'Google Flow のタブ(flow.google.com)を開いてから再試行してください。', 'guide.trouble4.problem': '"Extension not connected"', 'guide.trouble4.solution': 'chrome://extensions を開き、Flow Kit カードの再読み込みアイコンをクリックしてください — 拡張機能が自動的に再接続されます。', 'guide.trouble5.problem': '403 PUBLIC_ERROR_UNUSUAL_ACTIVITY エラー', - 'guide.trouble5.solution': '送信を一時停止 → chrome://settings/cookies を開く → google.com と labs.google のCookieを削除 → labs.google/fx/tools/flow を再度開いてサインインし、captchaが表示されたら解決 → ゆっくりと再送信してください。', + 'guide.trouble5.solution': '送信を一時停止 → chrome://settings/cookies を開く → google.com と labs.google のCookieを削除 → flow.google.com を再度開いてサインインし、captchaが表示されたら解決 → ゆっくりと再送信してください。', 'guide.trouble6.problem': 'curl: (7) Failed to connect to 127.0.0.1:8100', 'guide.trouble6.solution': 'Agent が実行されていません — python -m agent.main を実行してください。', diff --git a/extension/background.js b/extension/background.js index 98228da85..7ec7bfbd2 100644 --- a/extension/background.js +++ b/extension/background.js @@ -92,7 +92,9 @@ chrome.alarms.onAlarm.addListener(async (alarm) => { if (alarm.name === 'reconnect') connectToAgent(); if (alarm.name === 'keepAlive') keepAlive(); if (alarm.name === 'token-refresh') { - await captureTokenFromFlowTab(); + // Passive maintenance must never create browser tabs. If the user has no + // Flow tab open, wait for an explicit action or an actual RPC to open one. + await captureTokenFromFlowTab({ createIfMissing: false }); } }); @@ -151,25 +153,29 @@ chrome.webRequest.onBeforeSendHeaders.addListener( let _openingFlowTab = false; -async function captureTokenFromFlowTab() { - const tabs = await chrome.tabs.query({ url: flowUrls }); +async function captureTokenFromFlowTab({ createIfMissing = false } = {}) { + let tabs = await chrome.tabs.query({ url: flowUrls }); if (!tabs.length) { + if (!createIfMissing) { + console.log('[FlowAgent] No Flow tab found — passive refresh skipped'); + return { skipped: 'NO_FLOW_TAB' }; + } if (_openingFlowTab) { console.log('[FlowAgent] Flow tab already opening, skipping'); return; } _openingFlowTab = true; try { - console.log('[FlowAgent] No Flow tab found — opening one in background'); - await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); + console.log('[FlowAgent] No Flow tab found — opening one for explicit refresh'); + const opened = await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); await sleep(3000); - const retryTabs = await chrome.tabs.query({ url: flowUrls }); - if (!retryTabs.length) { + const target = opened?.id ? await chrome.tabs.get(opened.id).catch(() => null) : null; + if (!target) { console.log('[FlowAgent] Flow tab not ready yet after open'); return; } await chrome.scripting.executeScript({ - target: { tabId: retryTabs[0].id }, + target: { tabId: target.id }, files: ['content.js'], }); console.log('[FlowAgent] Token refresh triggered on newly opened Flow tab'); @@ -218,6 +224,8 @@ function connectToAgent() { ws.send(JSON.stringify({ type: 'extension_ready', flowKeyPresent: !!flowKey, + extensionVersion: chrome.runtime.getManifest().version, + flowUrlSupported: chrome.runtime.getManifest().host_permissions?.includes('https://flow.google.com/*') === true, tokenAge: flowKey && metrics.tokenCapturedAt ? Date.now() - metrics.tokenCapturedAt : null, })); if (flowKey) { @@ -359,16 +367,19 @@ function captchaFromTab(tabId, requestId, captchaAction) { async function solveCaptcha(requestId, captchaAction) { let tabs = await chrome.tabs.query({ url: flowUrls }); - // No Flow tab at all — spawn one and let it settle. + // No Flow tab at all — spawn one and let it settle. Keep the exact tab id: + // a redirected or stale tab must not make us select some older candidate. if (!tabs.length) { + let opened; try { - await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); + opened = await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); await sleep(3000); - tabs = await chrome.tabs.query({ url: flowUrls }); } catch (e) { return { error: e.message || 'NO_FLOW_TAB' }; } - if (!tabs.length) return { error: 'NO_FLOW_TAB' }; + const target = opened?.id ? await chrome.tabs.get(opened.id).catch(() => null) : null; + if (!target) return { error: 'NO_FLOW_TAB' }; + tabs = [target]; } // Try each Flow tab in turn. A tab that answers "no grecaptcha" is a tab @@ -401,16 +412,25 @@ async function solveCaptcha(requestId, captchaAction) { } } - // Every candidate failed — last-ditch, spawn a fresh tab and try it once. + // Every candidate failed — last-ditch, spawn a fresh temporary tab and + // target THAT exact tab. Previously we re-queried all Flow tabs and picked + // fresh[0], which could select the same stale tab again while leaking the + // newly-created one on every retry. + let recoveryTab = null; try { - await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); + recoveryTab = await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); await sleep(3000); - const fresh = await chrome.tabs.query({ url: flowUrls }); - const target = fresh.find((t) => !t.discarded) || fresh[0]; - if (!target) return { error: 'NO_FLOW_TAB' }; + const target = await chrome.tabs.get(recoveryTab.id); + if (!target || target.discarded) return { error: 'NO_FLOW_TAB' }; return await captchaFromTab(target.id, requestId, captchaAction); } catch (e) { return { error: e?.message || errors[0] || 'NO_FLOW_TAB' }; + } finally { + // A recovery tab is disposable: there were already Flow tabs available + // for the signed RPC. Do not let CAPTCHA retries accumulate root tabs. + if (recoveryTab?.id) { + try { await chrome.tabs.remove(recoveryTab.id); } catch { /* already gone */ } + } } } @@ -447,12 +467,13 @@ async function runBatchRpc(cmd) { let candidate = tabs.find((t) => !t.discarded) || tabs[0]; if (!candidate) { // No Flow tab — open one and give the app a moment to boot, otherwise - // WIZ_global_data is not on the page yet and `at` comes back empty. + // WIZ_global_data is not on the page yet and `at` comes back empty. Keep + // the exact created tab id so redirects/stale tabs cannot hijack recovery. + let opened; try { - await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); + opened = await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); await sleep(5000); - const fresh = await chrome.tabs.query({ url: flowUrls }); - candidate = fresh.find((t) => !t.discarded) || fresh[0]; + candidate = opened?.id ? await chrome.tabs.get(opened.id).catch(() => null) : null; } catch (e) { return { error: e?.message || 'NO_FLOW_TAB' }; } @@ -804,7 +825,7 @@ chrome.runtime.onMessage.addListener((msg, _, reply) => { } if (msg.type === 'REFRESH_TOKEN') { - captureTokenFromFlowTab() + captureTokenFromFlowTab({ createIfMissing: true }) .then(() => reply({ ok: true })) .catch((e) => reply({ error: e.message })); return true; diff --git a/extension/manifest.json b/extension/manifest.json index 1ae492a63..a01b657e2 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Flow Kit", - "version": "0.3.0", + "version": "0.3.1", "description": "Local agent bridge for Google Flow \u2014 runs batchexecute RPCs inside a signed-in flow.google.com tab, mints reCAPTCHA, proxies API calls", "permissions": [ "storage", diff --git a/setup.sh b/setup.sh index 8e764ffb2..b5d2960a3 100755 --- a/setup.sh +++ b/setup.sh @@ -165,7 +165,7 @@ echo " 1. Load Chrome extension:" echo " chrome://extensions → Developer mode → Load unpacked → extension/" echo "" echo " 2. Open Google Flow:" -echo " https://labs.google/fx/tools/flow (sign in)" +echo " https://flow.google.com/ (sign in)" echo "" echo " 3. Start the agent:" echo " source venv/bin/activate" diff --git a/skills/fk-doctor.md b/skills/fk-doctor.md index c134a557b..6b92019c1 100644 --- a/skills/fk-doctor.md +++ b/skills/fk-doctor.md @@ -99,7 +99,7 @@ python3 -c "from agent.config import USE_BATCH_RPC, FLOW_PROJECT_ID; \ | `Requested entity was not found` | Uploaded `media_id` expired (~1h TTL on uploads) | `_recover_entity_not_found` re-uploads from `image_url`, re-queues PENDING | If auto-recovery fails: manually `POST /api/upload-image`, patch `media_id` | | `Internal error encountered` | Flow backend transient 500 | Exponential backoff: `2^retry * 10s`, capped 300s | None — wait, or retry manually after a minute | | `reCAPTCHA failed` / (contains `captcha`) | Extension couldn't solve reCAPTCHA | Retry ≤10× without consuming `retry_count` (processor.py:454-464) | Ensure a Google Flow tab is open and focused; reload extension | -| `PUBLIC_ERROR_UNUSUAL_ACTIVITY` (403, message `reCAPTCHA evaluation failed`) | Google flagged the session as bot-like — usually triggered by rapid bursts of submits (e.g. many GENERATE_VIDEO in <1 minute), shared/VPN IP, or stale auth cookies | NOT auto-handled — Google blocks even fresh requests until the trust signal recovers | (1) **Stop the worker / pipeline** so submits pause. (2) Open Chrome → `chrome://settings/cookies` (or the extension's Chrome profile) → search `google.com` and `labs.google` → **remove all cookies for both**. (3) Reload `https://labs.google/fx/tools/flow` and sign back in (re-solve any reCAPTCHA puzzles manually). (4) Slow down submission cadence (≥1s gap between submits, ≤5 concurrent). If still blocked, switch to a different network or wait 1–6 h | +| `PUBLIC_ERROR_UNUSUAL_ACTIVITY` (403, message `reCAPTCHA evaluation failed`) | Google flagged the session as bot-like — usually triggered by rapid bursts of submits (e.g. many GENERATE_VIDEO in <1 minute), shared/VPN IP, or stale auth cookies | NOT auto-handled — Google blocks even fresh requests until the trust signal recovers | (1) **Stop the worker / pipeline** so submits pause. (2) Open Chrome → `chrome://settings/cookies` (or the extension's Chrome profile) → search `google.com` and `labs.google` → **remove all cookies for both**. (3) Reload `https://flow.google.com` and sign back in (re-solve any reCAPTCHA puzzles manually). (4) Slow down submission cadence (≥1s gap between submits, ≤5 concurrent). If still blocked, switch to a different network or wait 1–6 h | ### B. HTTP status codes @@ -194,7 +194,7 @@ When the user describes a symptom in plain language, map it here first. | Extension shows "No token" | Expected on the batch path — there is no bearer any more. Only act on it with `USE_BATCH_RPC=0` | | `CAPTCHA_FAILED: NO_FLOW_TAB` | Open `https://flow.google.com/` — and check the extension is v0.3.0+, older builds only matched the dead labs.google URL and could not see the tab that was right there | | 403 `MODEL_ACCESS_DENIED` | Tier mismatch — `GET /api/flow/credits`, downgrade model in `models.json` via `/fk-change-model` | -| 403 `PUBLIC_ERROR_UNUSUAL_ACTIVITY` / `reCAPTCHA evaluation failed` | Google flagged the session as bot-like (rapid bursts, VPN/shared IP, stale cookies). **Pause submits**, then in Chrome: `chrome://settings/cookies` → remove cookies for `google.com` and `labs.google` → reload `labs.google/fx/tools/flow` → sign in & solve any captcha → resubmit with ≥1s gap and ≤5 concurrent. Switch network or wait 1–6 h if still blocked | +| 403 `PUBLIC_ERROR_UNUSUAL_ACTIVITY` / `reCAPTCHA evaluation failed` | Google flagged the session as bot-like (rapid bursts, VPN/shared IP, stale cookies). **Pause submits**, then in Chrome: `chrome://settings/cookies` → remove cookies for `google.com` and `labs.google` → reload `flow.google.com` → sign in & solve any captcha → resubmit with ≥1s gap and ≤5 concurrent. Switch network or wait 1–6 h if still blocked | | Scene images inconsistent across scenes | Check all refs have UUID `media_id` — run `/fk-fix-uuids` | | `media_id` starts with `CAMS...` | Run `/fk-fix-uuids` to extract UUID from URL | | Upscale fails on every scene | On the batch path upscale is unported (`UNSUPPORTED_ON_BATCH_API`) — no upsampler rpc has been captured. On the legacy path it needs `PAYGATE_TIER_TWO` | diff --git a/tests/extension_mv3_bootstrap.test.cjs b/tests/extension_mv3_bootstrap.test.cjs index 86a12f54d..2ac5381ce 100644 --- a/tests/extension_mv3_bootstrap.test.cjs +++ b/tests/extension_mv3_bootstrap.test.cjs @@ -11,6 +11,7 @@ const source = fs.readFileSync( const lifecycleListeners = { alarm: [], installed: [], startup: [] }; const sockets = []; let storageReads = 0; +let tabCreates = 0; class FakeWebSocket { static CONNECTING = 0; @@ -40,6 +41,12 @@ const chrome = { action: { setBadgeBackgroundColor() {}, setBadgeText() {} }, alarms: { clear() {}, create() {}, onAlarm: event(lifecycleListeners.alarm) }, runtime: { + getManifest() { + return { + version: '0.3.1', + host_permissions: ['https://flow.google.com/*'], + }; + }, onInstalled: event(lifecycleListeners.installed), onMessage: event(), onStartup: event(lifecycleListeners.startup), @@ -60,8 +67,14 @@ const chrome = { }, }, tabs: { - create: async () => ({}), + create: async () => { + tabCreates += 1; + return { id: 123, discarded: false }; + }, + get: async (id) => ({ id, discarded: false }), query: async () => [], + reload: async () => {}, + remove: async () => {}, sendMessage: async () => {}, update: async () => {}, }, @@ -100,8 +113,13 @@ setImmediate(async () => { socket.readyState = FakeWebSocket.OPEN; socket.onopen(); + await lifecycleListeners.alarm[0]({ name: 'token-refresh' }); + assert.equal(tabCreates, 0, 'passive token refresh must never create a Flow tab'); + assert.equal(socket.messages[0].type, 'extension_ready'); assert.equal(socket.messages[0].flowKeyPresent, true); + assert.equal(socket.messages[0].extensionVersion, '0.3.1'); + assert.equal(socket.messages[0].flowUrlSupported, true); assert.ok(socket.messages[0].tokenAge > 0); assert.deepEqual(socket.messages[1], { type: 'token_captured', From 208005026a6b991f72a872e2d3a477e5595d437b Mon Sep 17 00:00:00 2001 From: Cris <56645054+crisng95@users.noreply.github.com> Date: Tue, 15 Sep 2026 22:07:50 +0700 Subject: [PATCH 08/68] =?UTF-8?q?Revert=20"feat:=20OmniVoice=20TTS=20t?= =?UTF-8?q?=E1=BB=AB=20xa=20+=20t=E1=BA=A1o/xo=C3=A1=20Flow=20project=20tr?= =?UTF-8?q?=C3=AAn=20batchexecute"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 7 +- README.md | 31 +--- agent/api/projects.py | 34 +--- agent/api/tts.py | 4 - agent/config.py | 16 -- agent/omnivoice_api.py | 224 ------------------------ agent/services/flow_batch.py | 38 ---- agent/services/flow_client.py | 50 ++---- agent/services/tts.py | 248 ++++----------------------- requirements.txt | 1 - run-omnivoice-api.sh | 23 --- skills/fk-gen-narrator.md | 6 - skills/fk-gen-tts-template.md | 36 ++-- skills/fk-import-voice.md | 2 +- tests/unit/test_flow_batch.py | 23 --- tests/unit/test_flow_client_batch.py | 67 +------- tests/unit/test_projects_route.py | 129 -------------- tests/unit/test_tts.py | 187 -------------------- 18 files changed, 75 insertions(+), 1051 deletions(-) delete mode 100644 agent/omnivoice_api.py delete mode 100755 run-omnivoice-api.sh delete mode 100644 tests/unit/test_projects_route.py delete mode 100644 tests/unit/test_tts.py diff --git a/.gitignore b/.gitignore index 9675c485c..766c04bdc 100644 --- a/.gitignore +++ b/.gitignore @@ -21,9 +21,4 @@ GEMINI.md ds-bundle/ .design-sync/.cache/ .design-sync/learnings/ -.design-sync/node_modules - -# Local dev artifacts (never commit) -.DS_Store -venv/ -extension/_metadata/ \ No newline at end of file +.design-sync/node_modules \ No newline at end of file diff --git a/README.md b/README.md index ae09b502f..e4dd67eab 100644 --- a/README.md +++ b/README.md @@ -711,35 +711,19 @@ Optional narrator voice for scenes. Uses [OmniVoice](https://github.com/tuannguy ### Setup -See `skills/fk-gen-tts-template.md` for the full install guide. The launcher uses the FlowKit venv -at `$HOME/.venvs/flowkit`; install OmniVoice there: +See `skills/fk-gen-tts-template.md` for full install guide. Quick version: ```bash -$HOME/.venvs/flowkit/bin/python -m pip install torch==2.8.0 torchaudio==2.8.0 -$HOME/.venvs/flowkit/bin/python -m pip install omnivoice -$HOME/.venvs/flowkit/bin/python -c 'from omnivoice import OmniVoice; print("OmniVoice OK")' +pip install torch==2.8.0 torchaudio==2.8.0 # or +cu128 for NVIDIA +pip install omnivoice +python3 -c "from omnivoice import OmniVoice; print('OK')" ``` -The local subprocess defaults to the interpreter that launched FlowKit, so `TTS_PYTHON_BIN` is -optional. Set it only when OmniVoice intentionally lives in a separate venv. - -### Optional remote OmniVoice API - -`agent/omnivoice_api.py` is a standalone warm FastAPI service. It loads the model once and exposes -`POST /v1/tts` as multipart form data (`text`, `speed`, optional `instruct`, `ref_text`, and WAV -file `ref_audio`), returning raw `audio/wav` bytes. Run it from the FlowKit checkout: - +If OmniVoice is in a separate venv, point to it: ```bash -$HOME/.venvs/flowkit/bin/python -m pip install python-multipart -./flowkit/run-omnivoice-api.sh +export TTS_PYTHON_BIN=/path/to/omnivoice-venv/bin/python3 ``` -The main FlowKit API can call it by setting `TTS_BACKEND=remote` and `TTS_REMOTE_URL=http://127.0.0.1:8200`. -The remote backend reads each local `ref_audio` WAV, uploads its bytes, validates the returned WAV, -and writes it atomically to the existing local output path. For a non-loopback deployment, set -`OMNIVOICE_API_TOKEN` on the inference service and the matching `TTS_REMOTE_TOKEN` on FlowKit, -use HTTPS, and do not expose the service publicly without authentication. - ### Workflow 1. **Create voice template** — `/fk-gen-tts-template` — generates an anchor voice WAV @@ -747,8 +731,7 @@ use HTTPS, and do not expose the service publicly without authentication. 3. **Generate narration** — `/fk-gen-narrator` — voice-clones the template for each scene 4. **Concat with narration** — `/fk-concat-fit-narrator` — trims scene videos to match TTS duration -CPU-only is recommended for the local backend (MPS produces artifacts). Remote mode is serialized -per scene and keeps the model warm in the standalone inference service. +CPU-only recommended (MPS produces artifacts). ~15-30s per scene. ## YouTube Upload Pipeline diff --git a/agent/api/projects.py b/agent/api/projects.py index 1d51fc590..600ebe8a9 100644 --- a/agent/api/projects.py +++ b/agent/api/projects.py @@ -7,7 +7,7 @@ from fastapi import APIRouter, HTTPException from pydantic import BaseModel -from agent.config import BASE_DIR, USE_BATCH_RPC, FLOW_PROJECT_ID +from agent.config import BASE_DIR, USE_BATCH_RPC from agent.models.project import Project, ProjectCreate, ProjectUpdate from agent.models.character import Character from agent.sdk.persistence.sqlite_repository import SQLiteRepository @@ -172,9 +172,8 @@ async def create(body: ProjectCreate): detected_tier = await _detect_user_tier(client) - # On the batch path a pinned FLOW_PROJECT_ID (or a uuid passed in the request) - # is reused; with neither, create_project now mints one via jHPbke. The legacy - # path always mints one. + # On the batch path Flow no longer creates projects for us — the uuid comes + # from the request or from FLOW_PROJECT_ID. The legacy path still mints one. flow_project_id = client.flow_project_id(body.flow_project_id) if USE_BATCH_RPC else None if flow_project_id: logger.info("Flow project reused: %s", flow_project_id) @@ -187,15 +186,6 @@ async def create(body: ProjectCreate): repo = _get_repo() - # Reuse is idempotent: a pinned or request-supplied project id may already - # have a local row. Re-inserting that id violates the primary key - # (sqlite3.IntegrityError -> 500), so hand back the row we already have. A - # freshly minted id never matches, so this is a no-op on the create path. - existing = await repo.get_project(flow_project_id) - if existing: - logger.info("Flow project already tracked, reusing: %s", flow_project_id) - return existing - # Step 2: Create local project with the Flow-assigned ID and detected tier create_data = body.model_dump(exclude_none=True) create_data.pop("tool_name", None) @@ -269,25 +259,9 @@ async def update(pid: str, body: ProjectUpdate): @router.delete("/{pid}") async def delete(pid: str): - """Delete a project locally, and on Flow too when it is safe. - - The project must exist locally before anything is deleted, so a stray uuid - cannot reach through to Flow — only projects Flow Kit already tracks are - eligible. Flow is then deleted first (except the pinned FLOW_PROJECT_ID, the - shared/operator project, which is only ever removed locally) so a remote - failure leaves the local row in place rather than letting the two drift. - """ repo = _get_repo() - if not await repo.get_project(pid): + if not await repo.delete_project(pid): raise HTTPException(404, "Project not found") - if USE_BATCH_RPC and pid != (FLOW_PROJECT_ID or None): - client = get_flow_client() - if not client.connected: - raise HTTPException(503, "Extension not connected — cannot delete this project on Google Flow") - result = await client.delete_project(pid) - if result.get("error"): - raise HTTPException(502, f"Flow delete failed: {result['error']}") - await repo.delete_project(pid) return {"ok": True} diff --git a/agent/api/tts.py b/agent/api/tts.py index 342acfea9..e2d3d068f 100644 --- a/agent/api/tts.py +++ b/agent/api/tts.py @@ -146,10 +146,6 @@ async def narrate_video(vid: str, body: NarrateVideoRequest): logger.info("Auto-resolved ref_text from template '%s'", tmpl["name"]) break - # The project/template fallback is operator data too; revalidate after resolution so remote TTS - # can never read and upload a path that bypassed the request-body check above. - if ref_audio: - _validate_ref_audio(ref_audio) project_name = project.get("name") or "unnamed_project" project_slug = slugify(project_name) out_dir = OUTPUT_DIR / project_slug / "tts" diff --git a/agent/config.py b/agent/config.py index 790ff3802..5d6edf2fe 100644 --- a/agent/config.py +++ b/agent/config.py @@ -86,25 +86,9 @@ MUSIC_OUTPUT_DIR = SHARED_OUTPUT_DIR / "music" # ─── TTS (OmniVoice) ───────────────────────────────────────── -TTS_BACKEND = os.environ.get("TTS_BACKEND", "local").strip().lower() TTS_MODEL = os.environ.get("TTS_MODEL", "k2-fsa/OmniVoice") TTS_DEVICE = os.environ.get("TTS_DEVICE", "cpu") # MPS produces gibberish; CPU+fp32 works TTS_SAMPLE_RATE = int(os.environ.get("TTS_SAMPLE_RATE", "24000")) -TTS_REMOTE_URL = os.environ.get("TTS_REMOTE_URL", "").strip().rstrip("/") -TTS_REMOTE_TOKEN = os.environ.get("TTS_REMOTE_TOKEN", "") -TTS_REMOTE_TIMEOUT_S = float(os.environ.get("TTS_REMOTE_TIMEOUT_S", "180")) -TTS_REMOTE_MAX_BYTES = int(os.environ.get("TTS_REMOTE_MAX_BYTES", str(50 * 1024 * 1024))) - -# ─── Standalone OmniVoice API ──────────────────────────────── -OMNIVOICE_API_HOST = os.environ.get("OMNIVOICE_API_HOST", "127.0.0.1") -OMNIVOICE_API_PORT = int(os.environ.get("OMNIVOICE_API_PORT", "8200")) -OMNIVOICE_API_TOKEN = os.environ.get("OMNIVOICE_API_TOKEN", "") -OMNIVOICE_MAX_REF_AUDIO_BYTES = int( - os.environ.get("OMNIVOICE_MAX_REF_AUDIO_BYTES", str(10 * 1024 * 1024)) -) -OMNIVOICE_MAX_REQUEST_BYTES = int( - os.environ.get("OMNIVOICE_MAX_REQUEST_BYTES", str(12 * 1024 * 1024)) -) # ─── Review / Claude Vision ────────────────────────────────── ANTHROPIC_API_KEY = os.environ.get("ANTHROPIC_API_KEY", "") diff --git a/agent/omnivoice_api.py b/agent/omnivoice_api.py deleted file mode 100644 index 50c1d9d91..000000000 --- a/agent/omnivoice_api.py +++ /dev/null @@ -1,224 +0,0 @@ -"""Standalone warm OmniVoice HTTP service for remote FlowKit TTS.""" -from __future__ import annotations - -import asyncio -import hmac -import io -import math -import tempfile -import wave -from contextlib import asynccontextmanager -from pathlib import Path -from typing import Optional - -from fastapi import FastAPI, File, Form, HTTPException, Request, UploadFile -from fastapi.responses import JSONResponse, Response - -from agent.config import ( - OMNIVOICE_API_HOST, - OMNIVOICE_API_PORT, - OMNIVOICE_API_TOKEN, - OMNIVOICE_MAX_REF_AUDIO_BYTES, - OMNIVOICE_MAX_REQUEST_BYTES, - TTS_DEVICE, - TTS_MODEL, - TTS_SAMPLE_RATE, -) - -_model = None -_inference_lock = asyncio.Lock() - - -def _validate_wav_bytes(audio_bytes: bytes) -> None: - if len(audio_bytes) < 12 or audio_bytes[:4] != b"RIFF" or audio_bytes[8:12] != b"WAVE": - raise HTTPException(status_code=400, detail="ref_audio must be a WAV file") - try: - with wave.open(io.BytesIO(audio_bytes), "rb") as wav: - frame_count = wav.getnframes() - frame_width = wav.getnchannels() * wav.getsampwidth() - if frame_count <= 0 or wav.getframerate() <= 0 or frame_width <= 0: - raise HTTPException(status_code=400, detail="ref_audio must contain audio") - if len(wav.readframes(frame_count)) != frame_count * frame_width: - raise HTTPException(status_code=400, detail="ref_audio is truncated") - except (wave.Error, EOFError) as error: - raise HTTPException(status_code=400, detail="ref_audio is an invalid WAV file") from error - - -def _load_model(): - global _model - import torch - from omnivoice import OmniVoice - - dtype = torch.float16 if TTS_DEVICE.startswith("cuda") else torch.float32 - _model = OmniVoice.from_pretrained(TTS_MODEL, device_map=TTS_DEVICE, dtype=dtype) - - -def _generate_wav_bytes( - text: str, - instruct: Optional[str], - ref_text: Optional[str], - ref_audio_bytes: Optional[bytes], - speed: float, -) -> bytes: - import torchaudio - - if _model is None: - raise RuntimeError("OmniVoice model is not loaded") - - with tempfile.TemporaryDirectory(prefix="omnivoice-") as temp_dir: - ref_audio_path = None - if ref_audio_bytes is not None: - ref_audio_path = Path(temp_dir) / "reference.wav" - ref_audio_path.write_bytes(ref_audio_bytes) - - output_path = Path(temp_dir) / "output.wav" - kwargs = {"text": text} - if ref_audio_path is not None and ref_text: - kwargs["ref_audio"] = str(ref_audio_path) - kwargs["ref_text"] = ref_text - elif instruct: - kwargs["instruct"] = instruct - if speed != 1.0: - kwargs["speed"] = speed - - audio = _model.generate(**kwargs) - torchaudio.save(str(output_path), audio[0], TTS_SAMPLE_RATE) - return output_path.read_bytes() - - -def _authorization_header_valid(actual: str) -> bool: - if not OMNIVOICE_API_TOKEN: - return True - return hmac.compare_digest(actual, f"Bearer {OMNIVOICE_API_TOKEN}") - - -def _authorization_valid(request: Request) -> bool: - return _authorization_header_valid(request.headers.get("authorization", "")) - - -async def _require_authorized(request: Request) -> None: - if not _authorization_valid(request): - raise HTTPException(status_code=401, detail="Invalid bearer token") - - -@asynccontextmanager -async def lifespan(app: FastAPI): - if OMNIVOICE_API_HOST not in {"127.0.0.1", "localhost", "::1"} and not OMNIVOICE_API_TOKEN: - raise RuntimeError("OMNIVOICE_API_TOKEN is required when the API is not loopback-only") - await asyncio.to_thread(_load_model) - yield - - -app = FastAPI(title="OmniVoice TTS", version="1.0.0", lifespan=lifespan) - - -class _RequestTooLarge(Exception): - pass - - -async def _send_json_error(send, status_code: int, detail: str) -> None: - body = f'{{"detail":"{detail}"}}'.encode("utf-8") - await send({"type": "http.response.start", "status": status_code, "headers": [ - (b"content-type", b"application/json"), - (b"content-length", str(len(body)).encode("ascii")), - ]}) - await send({"type": "http.response.body", "body": body}) - - -class _TtsRequestLimitMiddleware: - def __init__(self, app): - self.app = app - - async def __call__(self, scope, receive, send): - if scope.get("type") != "http" or scope.get("path") != "/v1/tts": - await self.app(scope, receive, send) - return - - request_headers = {key.lower(): value for key, value in scope.get("headers", [])} - authorization = request_headers.get(b"authorization", b"").decode("latin-1") - if not _authorization_header_valid(authorization): - await _send_json_error(send, 401, "Invalid bearer token") - return - - content_length = request_headers.get(b"content-length") - if content_length is not None: - try: - if int(content_length) > OMNIVOICE_MAX_REQUEST_BYTES: - await _send_json_error(send, 413, "request is too large") - return - except ValueError: - await _send_json_error(send, 400, "invalid content-length") - return - - received = 0 - - async def limited_receive(): - nonlocal received - message = await receive() - if message["type"] == "http.request": - received += len(message.get("body", b"")) - if received > OMNIVOICE_MAX_REQUEST_BYTES: - raise _RequestTooLarge - return message - - try: - await self.app(scope, limited_receive, send) - except _RequestTooLarge: - await _send_json_error(send, 413, "request is too large") - - -app.add_middleware(_TtsRequestLimitMiddleware) - -@app.get("/health") -async def health(): - return {"ok": _model is not None, "model": TTS_MODEL, "device": TTS_DEVICE} - - -@app.post("/v1/tts", response_class=Response) -async def synthesize( - request: Request, - text: str = Form(...), - speed: float = Form(1.0), - instruct: Optional[str] = Form(None), - ref_text: Optional[str] = Form(None), - ref_audio: Optional[UploadFile] = File(None), -): - await _require_authorized(request) - if not text or len(text) > 5000: - raise HTTPException(status_code=422, detail="text must contain 1-5000 characters") - if not math.isfinite(speed) or speed < 0.5 or speed > 3.0: - raise HTTPException(status_code=422, detail="speed must be between 0.5 and 3.0") - if instruct is not None and len(instruct) > 200: - raise HTTPException(status_code=422, detail="instruct must contain at most 200 characters") - if ref_text is not None and len(ref_text) > 5000: - raise HTTPException(status_code=422, detail="ref_text is too long") - - ref_audio_bytes = None - if ref_audio is not None: - ref_audio_bytes = await ref_audio.read(OMNIVOICE_MAX_REF_AUDIO_BYTES + 1) - if len(ref_audio_bytes) > OMNIVOICE_MAX_REF_AUDIO_BYTES: - raise HTTPException(status_code=413, detail="ref_audio is too large") - _validate_wav_bytes(ref_audio_bytes) - - async with _inference_lock: - try: - wav_bytes = await asyncio.to_thread( - _generate_wav_bytes, - text, - instruct, - ref_text, - ref_audio_bytes, - speed, - ) - except HTTPException: - raise - except Exception: - raise HTTPException(status_code=500, detail="OmniVoice synthesis failed") - - return Response(content=wav_bytes, media_type="audio/wav") - - -if __name__ == "__main__": - import uvicorn - - uvicorn.run(app, host=OMNIVOICE_API_HOST, port=OMNIVOICE_API_PORT) diff --git a/agent/services/flow_batch.py b/agent/services/flow_batch.py index b50bf510e..f01116320 100644 --- a/agent/services/flow_batch.py +++ b/agent/services/flow_batch.py @@ -40,8 +40,6 @@ RPC_PROJECT_MEDIA = "Zzl0ze" RPC_MEDIA = "as29s" RPC_UPLOAD_IMAGE = "maseQ" -RPC_CREATE_PROJECT = "jHPbke" -RPC_DELETE_PROJECT = "QI2zvc" CAPTCHA_IMAGE = "IMAGE_GENERATION" CAPTCHA_VIDEO = "VIDEO_GENERATION" @@ -384,23 +382,6 @@ def media_request(media_id: str) -> str: return build_envelope(RPC_MEDIA, [media_id]) -def create_project_request(title: str) -> str: - """Make a new Flow project titled ``title``. - - Captured off the UI's "New project" button. Inner payload is - ``["projects/*", [None, [title]], [None, SURFACE_ID]]`` — the trailing ``22`` - is the same surface id every other call stamps, not a tool type. This path - carries no tool slot, so it can only ask for the surface's default; a caller - that needs a specific tool cannot get it here (see FlowClient.create_project). - """ - return build_envelope(RPC_CREATE_PROJECT, ["projects/*", [None, [title]], [None, SURFACE_ID]]) - - -def delete_project_request(project_id: str) -> str: - """Delete a Flow project. Inner payload is ``["projects/<uuid>"]``.""" - return build_envelope(RPC_DELETE_PROJECT, [f"projects/{project_id}"]) - - # ── response readers ───────────────────────────────────────────────────────── def _walk_strings(node: Any): @@ -448,25 +429,6 @@ def read_uploaded_media_id(payload: Any) -> str: return media_id -#: A Flow project id is a plain uuid; the create response leads with it. -_PROJECT_ID_RE = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", re.I) - - -def read_created_project_id(payload: Any) -> str: - """The uuid of a freshly created project. - - Captured shape: ``["<uuid>", ["<title>"]]`` — the id leads the payload and - equals the ``/project/<uuid>`` the UI navigates to. Read that one slot and - nothing else: a 200 with the id somewhere unexpected is accepted and then - silently useless, so a non-uuid here is a failure rather than a cue to scan - the envelope for the first uuid-looking string. - """ - first = payload[0] if isinstance(payload, list) and payload else None - if isinstance(first, str) and _PROJECT_ID_RE.fullmatch(first): - return first - raise FlowBatchError(f"create response carried no project id: {payload!r}") - - def read_operation(payload: Any) -> Operation: """`[null, 50, [[opId, projectId, sceneId, status, …]]]`. diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index 7d7c092d8..667e2d51d 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -560,50 +560,14 @@ def flow_project_id(self, requested: str | None = None) -> str | None: return FLOW_PROJECT_ID or None async def create_project(self, project_title: str, tool_name: str = "PINHOLE") -> dict: - """Create a Flow project, or reuse the pinned one. - - Pin precedence: a pinned FLOW_PROJECT_ID (or a uuid the caller passes) is - reused rather than minting a new project every call — the route only - falls through to here when nothing is pinned. Unpinned, the batch path - now creates one for real via the ``jHPbke`` RPC captured off the UI's - "New project" button and hands back its uuid. ``tool_name`` is honoured - only on the legacy path; the batch create carries no tool slot, so a - non-default value is rejected rather than silently ignored. - """ if not USE_BATCH_RPC: return await self._legacy_create_project(project_title, tool_name) - pinned = self.flow_project_id() - if pinned: - logger.info("Reusing pinned Flow project %s for '%s'", pinned[:12], project_title) - return {"status": 200, "data": {"projectId": pinned}} - if tool_name and tool_name != "PINHOLE": - return {"error": "UNSUPPORTED_ON_BATCH_API: batch create carries no tool slot, " - f"cannot honour tool_name={tool_name!r}"} - try: - payload = await self._batch_payload(fb.RPC_CREATE_PROJECT, - fb.create_project_request(project_title)) - pid = fb.read_created_project_id(payload) - except (fb.FlowBatchError, fb.RpcError) as exc: - return {"error": f"CREATE_PROJECT_FAILED: {exc}"} - logger.info("Flow project created %s for '%s'", pid[:12], project_title) + pid = self.flow_project_id() + if not pid: + return {"error": _UNSUPPORTED_CREATE_PROJECT} + logger.info("Reusing pinned Flow project %s for '%s'", pid[:12], project_title) return {"status": 200, "data": {"projectId": pid}} - async def delete_project(self, project_id: str) -> dict: - """Delete a Flow project via the ``QI2zvc`` RPC (batch path only). - - A successful delete answers with an empty payload — there is nothing to - read back, so a clean return is success and a transport error surfaces as - ``{"error": …}`` like the rest of the client. - """ - if not USE_BATCH_RPC: - return {"error": "UNSUPPORTED_ON_BATCH_API: delete_project needs the batchexecute transport"} - try: - await self._batch_payload(fb.RPC_DELETE_PROJECT, fb.delete_project_request(project_id)) - except (fb.FlowBatchError, fb.RpcError) as exc: - return {"error": f"DELETE_PROJECT_FAILED: {exc}"} - logger.info("Flow project deleted %s", project_id[:12]) - return {"status": 200, "data": {"projectId": project_id}} - async def generate_images(self, prompt: str, project_id: str, aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT", user_paygate_tier: str = "PAYGATE_TIER_TWO", @@ -1243,6 +1207,12 @@ async def _legacy_upload_image(self, image_base64: str, mime_type: str = "image/ _CAPTURE_HINT = "see docs/CAPTURE.md to record its payload off the new UI" +_UNSUPPORTED_CREATE_PROJECT = ( + "NO_FLOW_PROJECT: Flow's project.createProject endpoint went with the September 2026 " + "migration, so Flow Kit cannot create one. Make a project in the Flow UI, then either " + "pass its uuid as flow_project_id or pin it as FLOW_PROJECT_ID." +) + def _unsupported(feature: str, why: str) -> str: return f"UNSUPPORTED_ON_BATCH_API: {feature} — {why}; {_CAPTURE_HINT}." diff --git a/agent/services/tts.py b/agent/services/tts.py index 4283ebbfe..14a729856 100644 --- a/agent/services/tts.py +++ b/agent/services/tts.py @@ -1,37 +1,20 @@ -"""OmniVoice TTS service with local and remote backends.""" +"""OmniVoice TTS service — subprocess-based for compatibility.""" import asyncio -import io import json import logging import os import subprocess -import sys -import tempfile -import urllib.parse -import wave from pathlib import Path from typing import Optional -import httpx - -from agent.config import ( - TTS_MODEL, - TTS_REMOTE_MAX_BYTES, - TTS_REMOTE_TOKEN, - TTS_REMOTE_TIMEOUT_S, - TTS_REMOTE_URL, - TTS_SAMPLE_RATE, - TTS_BACKEND, -) +from agent.config import TTS_MODEL, TTS_SAMPLE_RATE logger = logging.getLogger(__name__) -# The launcher starts FlowKit with its venv interpreter. Keep the override for deployments that -# intentionally use a separate OmniVoice environment, but never require an executable named -# python3.10 to be present on PATH. -PYTHON_BIN = os.environ.get("TTS_PYTHON_BIN", sys.executable) +# Default to python3.10 (has torch/torchaudio/omnivoice); override with TTS_PYTHON_BIN if needed +PYTHON_BIN = os.environ.get("TTS_PYTHON_BIN", "python3.10") -# Inline script template for local subprocess generation. +# Inline script template for TTS generation via subprocess _TTS_SCRIPT = """ import sys, json, torch, torchaudio @@ -54,7 +37,7 @@ print(json.dumps({"ok": True, "path": args["output"]})) """ -# Batch script — loads model once for local generation of multiple texts. +# Batch script — loads model once, generates for multiple texts _TTS_BATCH_SCRIPT = """ import sys, json, torch, torchaudio from pathlib import Path @@ -90,131 +73,6 @@ """ -def _remote_endpoint() -> str: - if TTS_BACKEND != "remote": - raise RuntimeError(f"Unsupported TTS_BACKEND: {TTS_BACKEND!r}") - if not TTS_REMOTE_URL: - raise RuntimeError("TTS_REMOTE_URL is required when TTS_BACKEND=remote") - parsed = urllib.parse.urlparse(TTS_REMOTE_URL) - if parsed.scheme not in {"http", "https"} or not parsed.netloc: - raise RuntimeError("TTS_REMOTE_URL must be an absolute http(s) URL") - if parsed.username or parsed.password or parsed.query or parsed.fragment: - raise RuntimeError("TTS_REMOTE_URL must not contain credentials, query, or fragment") - root = TTS_REMOTE_URL.rstrip("/") - return root if root.endswith("/v1/tts") else f"{root}/v1/tts" - - -def _validate_wav_bytes(audio_bytes: bytes) -> None: - if len(audio_bytes) < 12 or audio_bytes[:4] != b"RIFF" or audio_bytes[8:12] != b"WAVE": - raise RuntimeError("Remote TTS returned a non-WAVE response") - try: - with wave.open(io.BytesIO(audio_bytes), "rb") as wav: - frame_count = wav.getnframes() - frame_width = wav.getnchannels() * wav.getsampwidth() - if frame_count <= 0 or wav.getframerate() <= 0 or frame_width <= 0: - raise RuntimeError("Remote TTS returned an empty WAV") - if len(wav.readframes(frame_count)) != frame_count * frame_width: - raise RuntimeError("Remote TTS returned a truncated WAV") - except (wave.Error, EOFError) as error: - raise RuntimeError("Remote TTS returned an invalid WAV") from error - - -def _write_wav_atomically(output_path: str, audio_bytes: bytes) -> None: - _validate_wav_bytes(audio_bytes) - destination = Path(output_path) - destination.parent.mkdir(parents=True, exist_ok=True) - temporary_path: Path | None = None - try: - with tempfile.NamedTemporaryFile( - mode="wb", - dir=destination.parent, - prefix=f".{destination.name}.", - suffix=".tmp", - delete=False, - ) as temporary: - temporary_path = Path(temporary.name) - temporary.write(audio_bytes) - temporary.flush() - os.fsync(temporary.fileno()) - os.replace(temporary_path, destination) - temporary_path = None - finally: - if temporary_path is not None: - temporary_path.unlink(missing_ok=True) - - -def _read_limited(path: Path, max_bytes: int) -> bytes: - with path.open("rb") as source: - return source.read(max_bytes + 1) - - -async def _read_reference_audio(ref_audio: str) -> tuple[str, bytes]: - reference = Path(ref_audio) - if not reference.is_file(): - raise RuntimeError("Reference audio file does not exist") - try: - audio_bytes = await asyncio.to_thread(_read_limited, reference, TTS_REMOTE_MAX_BYTES) - except OSError as error: - raise RuntimeError("Reference audio could not be read") from error - if len(audio_bytes) > TTS_REMOTE_MAX_BYTES: - raise RuntimeError("Reference audio exceeds the remote TTS size limit") - _validate_wav_bytes(audio_bytes) - return reference.name, audio_bytes - - -async def _generate_remote( - text: str, - output_path: str, - instruct: Optional[str] = None, - ref_audio: Optional[str] = None, - ref_text: Optional[str] = None, - speed: float = 1.0, -) -> str: - data = {"text": text, "speed": str(speed)} - if instruct: - data["instruct"] = instruct - if ref_text: - data["ref_text"] = ref_text - - files = None - # OmniVoice cloning requires both fields. Preserve local compatibility when a caller supplies - # only ref_audio by following the instruct/generic path rather than leaking a local path. - if ref_audio and ref_text: - filename, audio_bytes = await _read_reference_audio(ref_audio) - files = {"ref_audio": (filename, audio_bytes, "audio/wav")} - - headers = {} - if TTS_REMOTE_TOKEN: - headers["authorization"] = f"Bearer {TTS_REMOTE_TOKEN}" - - timeout = httpx.Timeout(TTS_REMOTE_TIMEOUT_S) - try: - async with httpx.AsyncClient(timeout=timeout) as client: - async with client.stream( - "POST", - _remote_endpoint(), - data=data, - files=files, - headers=headers, - ) as response: - if response.status_code < 200 or response.status_code >= 300: - raise RuntimeError(f"Remote TTS failed with HTTP {response.status_code}") - content_type = response.headers.get("content-type", "").split(";", 1)[0].lower() - if content_type != "audio/wav": - raise RuntimeError("Remote TTS returned an unexpected content type") - audio = bytearray() - async for chunk in response.aiter_bytes(): - if len(audio) + len(chunk) > TTS_REMOTE_MAX_BYTES: - raise RuntimeError("Remote TTS response exceeds the size limit") - audio.extend(chunk) - except httpx.HTTPError as error: - raise RuntimeError("Remote TTS request failed") from error - - _write_wav_atomically(output_path, bytes(audio)) - logger.info("Remote TTS saved to %s", output_path) - return output_path - - async def generate_speech( text: str, output_path: str, @@ -223,13 +81,9 @@ async def generate_speech( ref_text: Optional[str] = None, speed: float = 1.0, ) -> str: - """Generate speech and return a local WAV path.""" - if TTS_BACKEND == "remote": - return await _generate_remote(text, output_path, instruct, ref_audio, ref_text, speed) - if TTS_BACKEND != "local": - raise RuntimeError(f"Unsupported TTS_BACKEND: {TTS_BACKEND!r}") - + """Generate speech for text via subprocess. Returns path to WAV file.""" Path(output_path).parent.mkdir(parents=True, exist_ok=True) + args = { "model": TTS_MODEL, "text": text, @@ -244,8 +98,9 @@ async def generate_speech( if ref_text: args["ref_text"] = ref_text - loop = asyncio.get_running_loop() + loop = asyncio.get_event_loop() result = await loop.run_in_executor(None, _run_tts_subprocess, args) + if not result.get("ok"): raise RuntimeError(f"TTS failed: {result.get('error', 'unknown')}") @@ -254,12 +109,10 @@ async def generate_speech( def _run_tts_subprocess(args: dict) -> dict: - """Run one local TTS subprocess.""" + """Run TTS subprocess.""" proc = subprocess.run( [PYTHON_BIN, "-c", _TTS_SCRIPT, json.dumps(args)], - capture_output=True, - text=True, - timeout=120, + capture_output=True, text=True, timeout=120, ) if proc.returncode != 0: return {"ok": False, "error": proc.stderr[-500:] if proc.stderr else "unknown error"} @@ -269,11 +122,6 @@ def _run_tts_subprocess(args: dict) -> dict: return {"ok": False, "error": proc.stdout[-200:] + proc.stderr[-200:]} -def _wav_duration_seconds(path: str) -> float: - with wave.open(path, "rb") as wav: - return wav.getnframes() / wav.getframerate() - - async def generate_video_narration( scenes: list[dict], output_dir: str, @@ -282,12 +130,15 @@ async def generate_video_narration( ref_text: Optional[str] = None, speed: float = 1.0, ) -> list[dict]: - """Generate narration WAVs for scenes with narrator_text.""" + """Generate narration WAVs for scenes with narrator_text. + + Uses batch subprocess — loads model once for all scenes. + Returns list of result dicts. + """ out_dir = Path(output_dir) out_dir.mkdir(parents=True, exist_ok=True) - if TTS_BACKEND not in {"local", "remote"}: - raise RuntimeError(f"Unsupported TTS_BACKEND: {TTS_BACKEND!r}") + # Build batch items (only scenes with narrator_text) items = [] scene_map = {} for scene in scenes: @@ -299,41 +150,17 @@ async def generate_video_narration( continue wav_path = str(out_dir / f"scene_{display_order:03d}_{scene_id}.wav") + # Skip if WAV already exists and is non-trivial (>1KB) if Path(wav_path).exists() and Path(wav_path).stat().st_size > 1024: logger.info("Skipping scene %03d (WAV exists: %s)", display_order, wav_path) - scene_map[scene_id] = { - "display_order": display_order, - "narrator_text": narrator_text, - "skipped": True, - "wav_path": wav_path, - } + scene_map[scene_id] = {"display_order": display_order, "narrator_text": narrator_text, "skipped": True, "wav_path": wav_path} continue items.append({"id": scene_id, "text": narrator_text, "output": wav_path}) scene_map[scene_id] = {"display_order": display_order, "narrator_text": narrator_text} + # Run batch subprocess if there are items batch_results = {} - if items and TTS_BACKEND == "remote": - # Keep one request per scene so failures remain attributable and the remote service's - # single warm model is not driven concurrently. - for item in items: - try: - await generate_speech( - text=item["text"], - output_path=item["output"], - instruct=instruct, - ref_audio=ref_audio, - ref_text=ref_text, - speed=speed, - ) - batch_results[item["id"]] = { - "id": item["id"], - "ok": True, - "path": item["output"], - "duration": _wav_duration_seconds(item["output"]), - } - except Exception as error: - batch_results[item["id"]] = {"id": item["id"], "ok": False, "error": str(error)} - elif items: + if items: args = { "model": TTS_MODEL, "sample_rate": TTS_SAMPLE_RATE, @@ -347,11 +174,12 @@ async def generate_video_narration( if ref_text: args["ref_text"] = ref_text - loop = asyncio.get_running_loop() + loop = asyncio.get_event_loop() raw = await loop.run_in_executor(None, _run_batch_subprocess, args) - for result in raw: - batch_results[result["id"]] = result + for r in raw: + batch_results[r["id"]] = r + # Build final results for all scenes results = [] for scene in scenes: scene_id = scene.get("id") @@ -370,27 +198,27 @@ async def generate_video_narration( }) continue - scene_result = scene_map.get(scene_id, {}) - if scene_result.get("skipped"): + sm = scene_map.get(scene_id, {}) + if sm.get("skipped"): results.append({ "scene_id": scene_id, "display_order": display_order, "narrator_text": narrator_text, - "audio_path": scene_result["wav_path"], + "audio_path": sm["wav_path"], "duration": None, "status": "COMPLETED", "error": None, }) continue - batch_result = batch_results.get(scene_id, {}) - if batch_result.get("ok"): + br = batch_results.get(scene_id, {}) + if br.get("ok"): results.append({ "scene_id": scene_id, "display_order": display_order, "narrator_text": narrator_text, - "audio_path": batch_result.get("path"), - "duration": batch_result.get("duration"), + "audio_path": br.get("path"), + "duration": br.get("duration"), "status": "COMPLETED", "error": None, }) @@ -402,20 +230,18 @@ async def generate_video_narration( "audio_path": None, "duration": None, "status": "FAILED", - "error": batch_result.get("error", "not processed"), + "error": br.get("error", "not processed"), }) return results def _run_batch_subprocess(args: dict) -> list[dict]: - """Run local batch TTS subprocess. Model loads once.""" - timeout = 180 + len(args.get("items", [])) * 45 + """Run batch TTS subprocess. Model loads once.""" + timeout = 180 + len(args.get("items", [])) * 45 # ~180s model load + ~45s per scene proc = subprocess.run( [PYTHON_BIN, "-c", _TTS_BATCH_SCRIPT, json.dumps(args)], - capture_output=True, - text=True, - timeout=timeout, + capture_output=True, text=True, timeout=timeout, ) if proc.returncode != 0: error = proc.stderr[-500:] if proc.stderr else "unknown" diff --git a/requirements.txt b/requirements.txt index be00c9dbd..c2cd265b7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,3 @@ pydantic>=2.5.0 aiohttp>=3.9.0 httpx>=0.25.0 anthropic>=0.40.0 -python-multipart>=0.0.9 diff --git a/run-omnivoice-api.sh b/run-omnivoice-api.sh deleted file mode 100755 index 630ffa649..000000000 --- a/run-omnivoice-api.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash -# Start the standalone warm OmniVoice inference API. -set -euo pipefail - -FLOWKIT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PYTHON_BIN="${OMNIVOICE_PYTHON:-${TTS_PYTHON_BIN:-$HOME/.venvs/flowkit/bin/python}}" - -if [[ ! -x "$PYTHON_BIN" ]]; then - echo "OmniVoice Python not found at $PYTHON_BIN" >&2 - echo "Install FlowKit's Python 3.10+ environment or set OMNIVOICE_PYTHON." >&2 - exit 1 -fi - -if ! "$PYTHON_BIN" -c 'import multipart' >/dev/null 2>&1; then - echo "python-multipart is missing from $PYTHON_BIN" >&2 - echo "Install it with: $PYTHON_BIN -m pip install python-multipart" >&2 - exit 1 -fi - -cd "$FLOWKIT_DIR" -exec "$PYTHON_BIN" -m uvicorn agent.omnivoice_api:app \ - --host "${OMNIVOICE_API_HOST:-127.0.0.1}" \ - --port "${OMNIVOICE_API_PORT:-8200}" diff --git a/skills/fk-gen-narrator.md b/skills/fk-gen-narrator.md index 5a874ea21..4e49f55d2 100644 --- a/skills/fk-gen-narrator.md +++ b/skills/fk-gen-narrator.md @@ -163,12 +163,6 @@ Ask user: "Review OK? Type 'yes' to generate TTS, or 'edit N' to modify scene N' **CRITICAL: Always pass BOTH `ref_audio` AND `ref_text` together.** Without `ref_text`, OmniVoice falls back to generic voice → each scene sounds different. -> **Backend is transparent here.** `/api/tts/generate` uses whatever backend FlowKit -> is configured with (`TTS_BACKEND=local` default, or `remote` for a GPU inference -> service). This skill is identical either way — no request changes. See -> `fk-gen-tts-template.md` and the README "Optional remote OmniVoice API" section for -> backend setup. - ### Proven workflow (per-scene via `/api/tts/generate`): The batch endpoint (`/api/videos/<VID>/narrate`) can timeout on large batches (40+ scenes). diff --git a/skills/fk-gen-tts-template.md b/skills/fk-gen-tts-template.md index 8be3892ab..8b101a47e 100644 --- a/skills/fk-gen-tts-template.md +++ b/skills/fk-gen-tts-template.md @@ -16,55 +16,43 @@ Source: https://github.com/tuannguyenhoangit-droid/OmniVoice > **Windows users:** Run all setup commands inside **WSL** or **Git Bash** (not CMD/PowerShell). The project's `setup.sh` and all bash scripts require a Unix shell. -**Step 1 — Install PyTorch** (in the FlowKit launcher venv, or a separate venv if you set -`TTS_PYTHON_BIN`): +**Step 1 — Install PyTorch** (in a fresh venv recommended): ```bash # macOS Apple Silicon (CPU — recommended for GLA, MPS produces gibberish) -$HOME/.venvs/flowkit/bin/python -m pip install torch==2.8.0 torchaudio==2.8.0 +pip install torch==2.8.0 torchaudio==2.8.0 # Linux / WSL with NVIDIA GPU -python -m pip install torch==2.8.0+cu128 torchaudio==2.8.0+cu128 \ - --extra-index-url https://download.pytorch.org/whl/cu128 +pip install torch==2.8.0+cu128 torchaudio==2.8.0+cu128 --extra-index-url https://download.pytorch.org/whl/cu128 # Linux / WSL CPU-only -python -m pip install torch==2.8.0 torchaudio==2.8.0 +pip install torch==2.8.0 torchaudio==2.8.0 ``` **Step 2 — Install OmniVoice** (choose one): ```bash # From PyPI (stable) -$HOME/.venvs/flowkit/bin/python -m pip install omnivoice +pip install omnivoice # From source -$HOME/.venvs/flowkit/bin/python -m pip install \ - git+https://github.com/k2-fsa/OmniVoice.git +pip install git+https://github.com/k2-fsa/OmniVoice.git # Dev install -git clone https://github.com/k2-fsa/OmniVoice.git -cd OmniVoice -$HOME/.venvs/flowkit/bin/python -m pip install -e . +git clone https://github.com/k2-fsa/OmniVoice.git && cd OmniVoice && pip install -e . ``` -**Step 3 — Verify installation:** +**Step 3 — Point GLA to the right Python** (if OmniVoice is in a separate venv): ```bash -$HOME/.venvs/flowkit/bin/python -c \ - 'from omnivoice import OmniVoice; print("OmniVoice OK")' +export TTS_PYTHON_BIN=/path/to/omnivoice-venv/bin/python3 ``` -FlowKit's local TTS subprocess defaults to the interpreter that launched FlowKit -(`sys.executable`). `TTS_PYTHON_BIN` is optional and is only needed when OmniVoice -is installed in another venv. +If OmniVoice is installed in the same env as the agent, no extra config needed. -For remote GPU inference, run `agent/omnivoice_api.py` as a separate FastAPI service. -The FlowKit remote backend uploads `ref_audio` bytes and expects raw `audio/wav` bytes -back; it never sends a local filesystem path to the remote service. - -**HuggingFace mirror** (if model download is slow): +**Verify installation:** ```bash -export HF_ENDPOINT="https://hf-mirror.com" +python3 -c "from omnivoice import OmniVoice; print('OK')" ``` **HuggingFace mirror** (if model download is slow): diff --git a/skills/fk-import-voice.md b/skills/fk-import-voice.md index 5ce23da3d..6772e0fa2 100644 --- a/skills/fk-import-voice.md +++ b/skills/fk-import-voice.md @@ -110,6 +110,6 @@ Play the output for user to verify voice quality matches the original. ## Notes - **Transcript accuracy matters** — `ref_text` must match the audio closely for good voice cloning. Always confirm with the user. -- **CPU by default** — whisper large-v3 and local OmniVoice both run on CPU (MPS produces artifacts). For GPU speed, run OmniVoice as a remote service and set `TTS_BACKEND=remote` (see `fk-gen-tts-template.md`); transcription still runs locally on CPU. +- **CPU only** — whisper large-v3 and OmniVoice both run on CPU. MPS produces artifacts. - **3-10s audio** — shorter clips lack enough voice characteristics; longer clips slow down cloning. - **One template per voice** — don't register multiple templates for the same voice. Update instead. diff --git a/tests/unit/test_flow_batch.py b/tests/unit/test_flow_batch.py index 47c75245d..63b8761dc 100644 --- a/tests/unit/test_flow_batch.py +++ b/tests/unit/test_flow_batch.py @@ -231,26 +231,3 @@ def test_every_resolved_video_model_is_one_flow_accepts(self): from agent.config import VIDEO_MODELS key = VIDEO_MODELS.get(tier, {}).get(gen, {}).get(aspect) assert fb.resolve_video_model(key) in fb.VIDEO_MODELS - - -class TestProjectRpcs: - def test_create_request_carries_the_captured_slots(self): - assert inner(fb.create_project_request("My Film")) == [ - "projects/*", [None, ["My Film"]], [None, fb.SURFACE_ID]] - - def test_delete_request_names_the_project_path(self): - assert inner(fb.delete_project_request("11111111-2222-3333-4444-555555555555")) == [ - "projects/11111111-2222-3333-4444-555555555555"] - - def test_read_created_id_takes_the_leading_uuid(self): - pid = "8e30afb8-92d0-4d0b-b652-f0a79faca9f5" - assert fb.read_created_project_id([pid, ["My Film"]]) == pid - - def test_read_created_id_rejects_a_trailing_newline(self): - r"""`$` would let "<uuid>\n" through; fullmatch must reject it.""" - with pytest.raises(fb.FlowBatchError): - fb.read_created_project_id(["8e30afb8-92d0-4d0b-b652-f0a79faca9f5\n", ["x"]]) - - def test_read_created_id_rejects_a_non_uuid_lead(self): - with pytest.raises(fb.FlowBatchError): - fb.read_created_project_id([["My Film"], "not-a-uuid"]) diff --git a/tests/unit/test_flow_client_batch.py b/tests/unit/test_flow_client_batch.py index 40b972eae..733f52440 100644 --- a/tests/unit/test_flow_client_batch.py +++ b/tests/unit/test_flow_client_batch.py @@ -311,73 +311,12 @@ async def test_create_project_hands_back_the_pinned_one(self, client): result = await client.create_project("My Film") assert result["data"]["projectId"] == PROJECT - async def test_create_project_without_a_pin_creates_one(self, client, monkeypatch): - """Unpinned, the batch path mints a real project and hands back its uuid.""" + async def test_create_project_without_a_pin_explains_itself(self, client, monkeypatch): import agent.services.flow_client as module monkeypatch.setattr(module, "FLOW_PROJECT_ID", "") - new_pid = "8e30afb8-92d0-4d0b-b652-f0a79faca9f5" - client.responses[fb.RPC_CREATE_PROJECT] = { - "data": envelope(fb.RPC_CREATE_PROJECT, [new_pid, ["My Film"]]) - } - result = await client.create_project("My Film") - assert result["data"]["projectId"] == new_pid - - async def test_create_project_sends_the_captured_request(self, client, monkeypatch): - """The jHPbke envelope carries ["projects/*", [None, [title]], [None, 22]].""" - import agent.services.flow_client as module - monkeypatch.setattr(module, "FLOW_PROJECT_ID", "") - client.responses[fb.RPC_CREATE_PROJECT] = { - "data": envelope(fb.RPC_CREATE_PROJECT, ["8e30afb8-92d0-4d0b-b652-f0a79faca9f5", ["My Film"]]) - } - await client.create_project("My Film") - assert client.calls[0]["rpcid"] == fb.RPC_CREATE_PROJECT - inner = json.loads(json.loads(client.calls[0]["freq"])[0][0][1]) - assert inner == ["projects/*", [None, ["My Film"]], [None, fb.SURFACE_ID]] - - async def test_create_project_rejects_an_id_less_response(self, client, monkeypatch): - """A 200 whose lead slot is not a uuid is a failure, not a guess (accepted != used).""" - import agent.services.flow_client as module - monkeypatch.setattr(module, "FLOW_PROJECT_ID", "") - client.responses[fb.RPC_CREATE_PROJECT] = { - "data": envelope(fb.RPC_CREATE_PROJECT, ["not-a-uuid", ["My Film"]]) - } result = await client.create_project("My Film") - assert "CREATE_PROJECT_FAILED" in result["error"] - - async def test_create_project_refuses_a_non_default_tool_on_batch(self, client, monkeypatch): - """The batch create has no tool slot, so it will not pretend to honour one.""" - import agent.services.flow_client as module - monkeypatch.setattr(module, "FLOW_PROJECT_ID", "") - result = await client.create_project("My Film", tool_name="WHISK") - assert "UNSUPPORTED_ON_BATCH_API" in result["error"] - assert not client.calls, "nothing should have been sent" - - async def test_create_project_uses_the_legacy_path_when_batch_is_off(self, client, monkeypatch): - """USE_BATCH_RPC=0 still routes to the (post-mortem) tRPC create, untouched.""" - import agent.services.flow_client as module - monkeypatch.setattr(module, "USE_BATCH_RPC", False) - seen = {} - async def fake_legacy(title, tool): - seen["args"] = (title, tool) - return {"status": 200, "data": {"projectId": "legacy"}} - client._legacy_create_project = fake_legacy - result = await client.create_project("My Film", tool_name="PINHOLE") - assert seen["args"] == ("My Film", "PINHOLE") - assert result["data"]["projectId"] == "legacy" - assert not client.calls, "the batch transport should be untouched" - - async def test_delete_project_calls_QI2zvc_with_the_project_path(self, client): - client.responses[fb.RPC_DELETE_PROJECT] = {"data": envelope(fb.RPC_DELETE_PROJECT, [])} - result = await client.delete_project(PROJECT) - assert client.calls[0]["rpcid"] == fb.RPC_DELETE_PROJECT - inner = json.loads(json.loads(client.calls[0]["freq"])[0][0][1]) - assert inner == [f"projects/{PROJECT}"] - assert result["data"]["projectId"] == PROJECT - - async def test_delete_project_surfaces_a_transport_error(self, client): - client.responses[fb.RPC_DELETE_PROJECT] = {"error": "NO_FLOW_TAB"} - result = await client.delete_project(PROJECT) - assert "DELETE_PROJECT_FAILED" in result["error"] + assert "NO_FLOW_PROJECT" in result["error"] + assert "FLOW_PROJECT_ID" in result["error"] async def test_credits_answers_the_configured_tier_rather_than_guessing(self, client): result = await client.get_credits() diff --git a/tests/unit/test_projects_route.py b/tests/unit/test_projects_route.py deleted file mode 100644 index eeb64ccdf..000000000 --- a/tests/unit/test_projects_route.py +++ /dev/null @@ -1,129 +0,0 @@ -"""The project DELETE route's Flow-side gate. - -The route reaches through to Google Flow, so these lock down when it does and, -more importantly, when it must not: never for a project it does not already -track, never for the pinned shared project, and never leaving local and remote -out of step when the remote call fails. -""" -import pytest - -from agent.api import projects - - -class FakeRepo: - def __init__(self, exists=True): - self._exists = exists - self.deleted = [] - self.created = [] - - async def get_project(self, pid): - return {"id": pid} if self._exists else None - - async def create_project(self, **kw): - self.created.append(kw) - return {"id": kw.get("id")} - - async def delete_project(self, pid): - self.deleted.append(pid) - return True - - -class FakeClient: - def __init__(self, connected=True, error=None, pin="pinned-project"): - self.connected = connected - self._error = error - self._pin = pin - self.deleted = [] - - def flow_project_id(self, requested=None): - return requested or self._pin - - async def get_credits(self): - return {"status": 200, "data": {"userPaygateTier": "PAYGATE_TIER_TWO"}} - - async def delete_project(self, pid): - self.deleted.append(pid) - if self._error: - return {"error": self._error} - return {"status": 200, "data": {"projectId": pid}} - - -@pytest.fixture -def wire(monkeypatch): - """Point the route at fake collaborators; batch path with a pinned project.""" - def _wire(*, repo, client, batch=True, pin="pinned-project"): - monkeypatch.setattr(projects, "USE_BATCH_RPC", batch) - monkeypatch.setattr(projects, "FLOW_PROJECT_ID", pin) - monkeypatch.setattr(projects, "_get_repo", lambda: repo) - monkeypatch.setattr(projects, "get_flow_client", lambda: client) - return _wire - - -async def test_missing_project_is_404_before_any_remote_call(wire): - repo, client = FakeRepo(exists=False), FakeClient() - wire(repo=repo, client=client) - with pytest.raises(projects.HTTPException) as exc: - await projects.delete("nope") - assert exc.value.status_code == 404 - assert client.deleted == [], "a stray id must not reach Flow" - assert repo.deleted == [] - - -async def test_pinned_project_is_removed_locally_only(wire): - repo, client = FakeRepo(), FakeClient() - wire(repo=repo, client=client, pin="pinned-project") - result = await projects.delete("pinned-project") - assert result == {"ok": True} - assert client.deleted == [], "the shared project is never deleted on Flow" - assert repo.deleted == ["pinned-project"] - - -async def test_tracked_project_is_deleted_remote_first_then_local(wire): - repo, client = FakeRepo(), FakeClient() - wire(repo=repo, client=client) - result = await projects.delete("proj-1") - assert result == {"ok": True} - assert client.deleted == ["proj-1"] - assert repo.deleted == ["proj-1"] - - -async def test_remote_failure_keeps_the_local_row(wire): - repo, client = FakeRepo(), FakeClient(error="NO_FLOW_TAB") - wire(repo=repo, client=client) - with pytest.raises(projects.HTTPException) as exc: - await projects.delete("proj-1") - assert exc.value.status_code == 502 - assert repo.deleted == [], "local row stays put so the two do not drift" - - -async def test_offline_extension_deletes_nothing(wire): - repo, client = FakeRepo(), FakeClient(connected=False) - wire(repo=repo, client=client) - with pytest.raises(projects.HTTPException) as exc: - await projects.delete("proj-1") - assert exc.value.status_code == 503 - assert client.deleted == [] - assert repo.deleted == [] - - -async def test_legacy_path_deletes_locally_without_touching_flow(wire): - repo, client = FakeRepo(), FakeClient() - wire(repo=repo, client=client, batch=False) - result = await projects.delete("proj-1") - assert result == {"ok": True} - assert client.deleted == [] - assert repo.deleted == ["proj-1"] - - -async def test_create_reuses_an_existing_local_project_instead_of_reinserting(wire): - """A pinned/request project already in the DB is returned, not re-INSERTed. - - The bare INSERT in crud.create_project raises `UNIQUE constraint failed: - project.id` on a duplicate id, which surfaced as an uncaught 500. - """ - from agent.models.project import ProjectCreate - repo, client = FakeRepo(exists=True), FakeClient(pin="pinned-project") - wire(repo=repo, client=client, pin="pinned-project") - result = await projects.create(ProjectCreate(name="anything", material="realistic")) - assert result == {"id": "pinned-project"}, "returned the existing project row" - assert repo.created == [], "must not attempt a second INSERT of the same id" diff --git a/tests/unit/test_tts.py b/tests/unit/test_tts.py deleted file mode 100644 index e97912906..000000000 --- a/tests/unit/test_tts.py +++ /dev/null @@ -1,187 +0,0 @@ -"""Focused tests for local-path and remote OmniVoice TTS contracts.""" - -import io -import wave - -import pytest -from agent import omnivoice_api -from agent.services import tts - - -def _wav_bytes() -> bytes: - output = io.BytesIO() - with wave.open(output, "wb") as wav: - wav.setnchannels(1) - wav.setsampwidth(2) - wav.setframerate(24000) - wav.writeframes(b"\x00\x00" * 240) - return output.getvalue() - - -class _FakeResponse: - def __init__(self, body: bytes, status_code: int = 200, content_type: str = "audio/wav"): - self.status_code = status_code - self.headers = {"content-type": content_type} - self._body = body - - async def __aenter__(self): - return self - - async def __aexit__(self, exc_type, exc, tb): - return False - - async def aread(self): - return self._body - - async def aiter_bytes(self): - yield self._body - - -class _FakeClient: - response = _FakeResponse(_wav_bytes()) - calls = [] - - def __init__(self, **kwargs): - self.timeout = kwargs["timeout"] - - async def __aenter__(self): - return self - - async def __aexit__(self, exc_type, exc, tb): - return False - - def stream(self, method, url, **kwargs): - self.calls.append((method, url, kwargs)) - return self.response - - -@pytest.mark.asyncio -async def test_remote_generation_uploads_reference_bytes_and_writes_local_wav(tmp_path, monkeypatch): - reference = tmp_path / "reference.wav" - reference.write_bytes(_wav_bytes()) - output = tmp_path / "scene.wav" - _FakeClient.calls = [] - - monkeypatch.setattr(tts, "TTS_BACKEND", "remote") - monkeypatch.setattr(tts, "TTS_REMOTE_URL", "https://tts.example.test") - monkeypatch.setattr(tts, "TTS_REMOTE_TOKEN", "secret") - monkeypatch.setattr(tts.httpx, "AsyncClient", _FakeClient) - - result = await tts._generate_remote( - text="Xin chao", - output_path=str(output), - ref_audio=str(reference), - ref_text="Mau transcript", - speed=1.1, - ) - - assert result == str(output) - - - assert output.read_bytes() == _wav_bytes() - method, url, request = _FakeClient.calls[0] - assert method == "POST" - assert url == "https://tts.example.test/v1/tts" - assert request["headers"] == {"authorization": "Bearer secret"} - assert request["data"] == {"text": "Xin chao", "speed": "1.1", "ref_text": "Mau transcript"} - assert request["files"]["ref_audio"][1] == _wav_bytes() - - -@pytest.mark.asyncio -async def test_remote_generation_does_not_replace_target_on_invalid_response(tmp_path, monkeypatch): - output = tmp_path / "scene.wav" - original = b"previous audio" - output.write_bytes(original) - - class InvalidClient(_FakeClient): - response = _FakeResponse(b"not wav", content_type="audio/wav") - - monkeypatch.setattr(tts, "TTS_BACKEND", "remote") - monkeypatch.setattr(tts, "TTS_REMOTE_URL", "http://127.0.0.1:8200") - monkeypatch.setattr(tts.httpx, "AsyncClient", InvalidClient) - - with pytest.raises(RuntimeError, match="non-WAVE"): - await tts._generate_remote("Xin chao", str(output)) - - assert output.read_bytes() == original - - -def test_write_wav_atomically_creates_valid_wav(tmp_path): - output = tmp_path / "nested" / "scene.wav" - - tts._write_wav_atomically(str(output), _wav_bytes()) - - assert output.exists() - with wave.open(str(output), "rb") as wav: - assert wav.getnframes() == 240 - assert wav.getframerate() == 24000 - - -def test_wav_validator_rejects_truncated_payload(): - with pytest.raises(RuntimeError, match="truncated"): - tts._validate_wav_bytes(_wav_bytes()[:-10]) - - -def test_standalone_api_auth_and_wav_response(monkeypatch): - from fastapi.testclient import TestClient - - monkeypatch.setattr(omnivoice_api, "OMNIVOICE_API_TOKEN", "secret") - monkeypatch.setattr(omnivoice_api, "_load_model", lambda: None) - monkeypatch.setattr(omnivoice_api, "_generate_wav_bytes", lambda *args: _wav_bytes()) - - with TestClient(omnivoice_api.app) as client: - unauthorized = client.post("/v1/tts", data={"text": "Xin chao"}, headers={}) - assert unauthorized.status_code == 401 - - authorized = client.post( - "/v1/tts", - data={"text": "Xin chao", "speed": "1.0", "ref_text": "Mau transcript"}, - files={"ref_audio": ("reference.wav", _wav_bytes(), "audio/wav")}, - headers={"Authorization": "Bearer secret"}, - ) - assert authorized.status_code == 200 - assert authorized.headers["content-type"] == "audio/wav" - assert authorized.content == _wav_bytes() - - -def test_standalone_api_rejects_oversized_request(monkeypatch): - from fastapi.testclient import TestClient - - monkeypatch.setattr(omnivoice_api, "OMNIVOICE_API_TOKEN", "") - monkeypatch.setattr(omnivoice_api, "OMNIVOICE_MAX_REQUEST_BYTES", 100) - monkeypatch.setattr(omnivoice_api, "_load_model", lambda: None) - - with TestClient(omnivoice_api.app) as client: - response = client.post("/v1/tts", data={"text": "x" * 1000}) - - assert response.status_code == 413 - - -def test_standalone_api_rejects_nonfinite_speed(monkeypatch): - from fastapi.testclient import TestClient - - monkeypatch.setattr(omnivoice_api, "OMNIVOICE_API_TOKEN", "") - monkeypatch.setattr(omnivoice_api, "_load_model", lambda: None) - - with TestClient(omnivoice_api.app) as client: - response = client.post("/v1/tts", data={"text": "Xin chao", "speed": "nan"}) - - assert response.status_code == 422 - - -@pytest.mark.asyncio -async def test_remote_generation_bounds_reference_read(tmp_path, monkeypatch): - reference = tmp_path / "reference.wav" - reference.write_bytes(b"x" * 11) - - monkeypatch.setattr(tts, "TTS_BACKEND", "remote") - monkeypatch.setattr(tts, "TTS_REMOTE_URL", "http://127.0.0.1:8200") - monkeypatch.setattr(tts, "TTS_REMOTE_MAX_BYTES", 10) - - with pytest.raises(RuntimeError, match="size limit"): - await tts._generate_remote( - "Xin chao", - str(tmp_path / "scene.wav"), - ref_audio=str(reference), - ref_text="Mau transcript", - ) From 8af92c71d1674315fbb8fe3df245b2bc4a059937 Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Tue, 15 Sep 2026 23:11:40 +0700 Subject: [PATCH 09/68] test(flow): lock the wire envelopes before moving who builds them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The batch builders are about to gain a caller: Omni will submit through the same generate_video that Veo uses, differing only by a model key. That refactor can drop a trailing null and still look fine — Flow accepts a malformed payload and then ignores it, which reads exactly like success. test_flow_batch.py asserts positions, and positions survive that. So assert the whole string instead. Checked by flipping SURFACE_ID 22 -> 23: all three goldens fail, and all 48 position tests pass. Also adds requirements-dev.txt — the test deps were undeclared, so a fresh checkout could not run the suite that guards any of this. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DB27wvPQ195KGiQ6VZfCDf --- requirements-dev.txt | 6 ++ tests/unit/test_flow_batch_golden.py | 101 +++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 requirements-dev.txt create mode 100644 tests/unit/test_flow_batch_golden.py diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 000000000..a0e63bf28 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,6 @@ +# Test-only deps. Runtime deps live in requirements.txt. +# python -m venv .venv && .venv/bin/pip install -r requirements.txt -r requirements-dev.txt +# .venv/bin/python -m pytest tests/unit +pytest>=8.0.0 +pytest-asyncio>=0.23.0 # repo sets asyncio_mode=auto in pytest.ini +pytest-mock>=3.12.0 # `mocker` fixture, used by tests/unit/test_result_handler.py diff --git a/tests/unit/test_flow_batch_golden.py b/tests/unit/test_flow_batch_golden.py new file mode 100644 index 000000000..be4c0364b --- /dev/null +++ b/tests/unit/test_flow_batch_golden.py @@ -0,0 +1,101 @@ +"""Byte-for-byte locks on the envelopes Flow actually accepts. + +The tests in test_flow_batch.py assert *positions* — slot 3 is the seed, slot 5 +is the model. These assert the *whole string*, because the refactor these guard +moves who calls the builder, and a payload Flow accepts and then quietly ignores +looks exactly like one that worked. Position assertions pass through a dropped +trailing null; a golden string does not. + +If one of these fails, the question is never "update the golden". It is "did the +wire format change on purpose?" — and if it did, the new string belongs in +docs/CAPTURE.md with the capture that justifies it. + +Every id in a request is a fresh uuid4, so the fixture pins uuid4 to a counter. +That is the only thing pinned: the builders are otherwise pure. +""" +import uuid as _uuid + +import pytest + +from agent.services import flow_batch as fb + +PROJECT = "11111111-2222-3333-4444-555555555555" +MEDIA = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" + + +@pytest.fixture +def pinned_uuids(monkeypatch): + """uuid4 becomes a counter, so a built envelope is reproducible.""" + counter = iter(range(1, 999)) + monkeypatch.setattr( + fb.uuid, "uuid4", + lambda: _uuid.UUID(f"00000000-0000-4000-8000-{next(counter):012d}"), + ) + + +GOLDEN_IMAGE = ( + '[[["ogiZ0b","[null,[[null,null,[[\\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\\",null,' + 'null,null,1]],42,2,\\"GEM_PIX_2\\",null,[null,22,null,null,null,' + '\\"11111111-2222-3333-4444-555555555555\\",null,null,null,null,' + '[\\"__CAPTCHA__\\",1]],[[[\\"a cat\\"]]],null,null,null,' + '\\"00000000-0000-4000-8000-000000000001\\",' + '\\"00000000-0000-4000-8000-000000000002\\"]],1,[null,22,null,null,null,' + '\\"11111111-2222-3333-4444-555555555555\\",null,null,null,null,' + '[\\"__CAPTCHA__\\",1]],[\\"00000000-0000-4000-8000-000000000003\\"]]",' + 'null,"generic"]]]' +) + +GOLDEN_VIDEO = ( + '[[["eb1hJf","[[[[null,null,[[[\\"a cat walks\\"]]]],' + '\\"veo_3_1_i2v_lite_low_priority\\",1,null,[null,' + '\\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\\",null,null,null,' + '[null,0.0038759689922481244,1,0.9961240310077519]],' + '[null,null,null,null,\\"00000000-0000-4000-8000-000000000001\\",' + '\\"00000000-0000-4000-8000-000000000002\\"]]],[null,22,null,null,null,' + '\\"11111111-2222-3333-4444-555555555555\\",null,null,null,null,' + '[\\"__CAPTCHA__\\",1]],[\\"00000000-0000-4000-8000-000000000003\\",2]]",' + 'null,"generic"]]]' +) + +GOLDEN_TEXT_VIDEO = ( + '[[["YhhmEf","[[[[null,null,[[[\\"a cat walks\\"]]]],\\"abra_t2v_8s\\",1,null,' + '[null,null,null,null,\\"00000000-0000-4000-8000-000000000001\\",' + '\\"00000000-0000-4000-8000-000000000002\\"]]],[null,22,null,null,null,' + '\\"11111111-2222-3333-4444-555555555555\\",null,null,null,null,' + '[\\"__CAPTCHA__\\",1]],[\\"00000000-0000-4000-8000-000000000003\\",1]]",' + 'null,"generic"]]]' +) + + +def test_image_request_envelope_is_unchanged(pinned_uuids): + assert fb.image_request( + "a cat", PROJECT, count=1, aspect="IMAGE_ASPECT_RATIO_PORTRAIT", + seed=42, model="GEM_PIX_2", ref_media_ids=[MEDIA], + ) == GOLDEN_IMAGE + + +def test_video_request_envelope_is_unchanged(pinned_uuids): + """The i2v submit. This is the only video path running in production.""" + assert fb.video_request( + "a cat walks", PROJECT, MEDIA, aspect="VIDEO_ASPECT_RATIO_PORTRAIT", + model="veo_3_1_i2v_lite_low_priority", + ) == GOLDEN_VIDEO + + +def test_text_video_request_envelope_is_unchanged(pinned_uuids): + assert fb.text_video_request( + "a cat walks", PROJECT, aspect="VIDEO_ASPECT_RATIO_PORTRAIT", + model="abra_t2v_8s", + ) == GOLDEN_TEXT_VIDEO + + +def test_video_request_passes_the_model_key_through_untouched(pinned_uuids): + """Omni rides the same rpc as Veo, differing only by this string. + + video_request does NOT call resolve_video_model — the caller decides. That + is what lets one submit serve both families, so it is worth a test of its + own rather than being implied by the golden above. + """ + freq = fb.video_request("x", PROJECT, MEDIA, model="abra_i2v_8s") + assert '\\"abra_i2v_8s\\"' in freq + assert "veo_3_1" not in freq From ab6098563f4247a0b36143c72c9076a0aa1cf6ec Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Tue, 8 Sep 2026 09:14:03 +0300 Subject: [PATCH 10/68] feat(flow): expand migrated image API --- README.md | 8 ++ agent/api/flow.py | 68 +++++++++++++++-- agent/config.py | 5 +- agent/models.json | 3 +- agent/services/flow_batch.py | 106 +++++++++++++++++++++------ agent/services/flow_client.py | 69 +++++++++++++---- docs/IMAGE_API.md | 93 +++++++++++++++++++++++ tests/unit/test_flow_batch.py | 65 +++++++++++++++- tests/unit/test_flow_client_batch.py | 46 +++++++++++- 9 files changed, 409 insertions(+), 54 deletions(-) create mode 100644 docs/IMAGE_API.md diff --git a/README.md b/README.md index 012eef82f..8084b1de3 100644 --- a/README.md +++ b/README.md @@ -244,6 +244,14 @@ You can also pass `flow_project_id` per project on `POST /api/projects`. | `FLOW_ALLOW_DEGRADED` | `0` | `1` lets scene chaining and r2v fall back to plain i2v instead of failing. | | `DEFAULT_PAYGATE_TIER` | `PAYGATE_TIER_TWO` | Carried for the DB and dashboard; no longer selects a model. | +### Image API + +The migrated image path supports Nano Banana Pro, Nano Banana 2 and Nano Banana +2 Lite, all five current aspect ratios, 1-4 outputs, true base-image editing and +native 2K image export. Exact future Flow image model wire ids pass through +without being silently replaced by the default model. See +[`docs/IMAGE_API.md`](docs/IMAGE_API.md). + ### What does not work on the new API yet Three capabilities have no captured payload, so they fail with diff --git a/agent/api/flow.py b/agent/api/flow.py index c0a71025d..5aeed8fac 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -1,6 +1,6 @@ """Direct Flow API endpoints — for manual operations outside the queue.""" -from fastapi import APIRouter, HTTPException -from pydantic import BaseModel +from fastapi import APIRouter, HTTPException, Response +from pydantic import BaseModel, Field from typing import Literal, Optional from agent.config import USE_BATCH_RPC, FLOW_PROJECT_ID, FLOW_ALLOW_DEGRADED @@ -21,6 +21,10 @@ class GenerateImageRequest(BaseModel): project_id: str aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT" user_paygate_tier: str = "PAYGATE_TIER_ONE" + image_model: Optional[str] = None + count: int = Field(default=1, ge=1, le=4) + seed: Optional[int] = Field(default=None, ge=1, le=1_000_000_000) + reference_media_ids: Optional[list[str]] = None character_media_ids: Optional[list[str]] = None @@ -104,6 +108,16 @@ class EditImageRequest(BaseModel): project_id: str aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT" user_paygate_tier: str = "PAYGATE_TIER_ONE" + image_model: Optional[str] = None + count: int = Field(default=1, ge=1, le=4) + seed: Optional[int] = Field(default=None, ge=1, le=1_000_000_000) + reference_media_ids: Optional[list[str]] = None + + +class UpscaleImageRequest(BaseModel): + media_id: str + project_id: str + quality: Literal["2k", "4k"] = "2k" @router.get("/status") @@ -137,11 +151,14 @@ async def get_credits(): @router.post("/generate-image") async def generate_image(body: GenerateImageRequest): - """Generate image directly (bypasses queue).""" + """Generate 1-4 images with an explicit Flow image model.""" client = get_flow_client() if not client.connected: raise HTTPException(503, "Extension not connected") - result = await client.generate_images(**body.model_dump()) + data = body.model_dump(exclude={"reference_media_ids"}) + refs = list(dict.fromkeys((body.reference_media_ids or []) + (body.character_media_ids or []))) + data["character_media_ids"] = refs or None + result = await client.generate_images(**data) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) return result.get("data", result) @@ -368,20 +385,59 @@ async def get_media(media_id: str): @router.post("/edit-image") async def edit_image(body: EditImageRequest): - """Edit an existing image using IMAGE_INPUT_TYPE_BASE_IMAGE (bypasses queue).""" + """Edit an existing image using the current Flow BASE_IMAGE wire input.""" client = get_flow_client() if not client.connected: raise HTTPException(503, "Extension not connected") result = await client.edit_image( - body.prompt, body.source_media_id, body.project_id, + body.prompt, + body.source_media_id, + body.project_id, aspect_ratio=body.aspect_ratio, user_paygate_tier=body.user_paygate_tier, + character_media_ids=body.reference_media_ids, + image_model=body.image_model, + count=body.count, + seed=body.seed, ) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) return result.get("data", result) +@router.post("/export-image") +@router.post("/upscale-image", include_in_schema=False) +async def export_image(body: UpscaleImageRequest): + """Download a generated Flow image at 2K (or plan-gated 4K).""" + import base64 + import binascii + + client = get_flow_client() + if not client.connected: + raise HTTPException(503, "Extension not connected") + result = await client.upscale_image( + body.media_id, + body.project_id, + resolution=body.quality.upper(), + ) + if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): + raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) + data = result.get("data", result) + try: + content = base64.b64decode(data["encodedImage"], validate=True) + except (KeyError, TypeError, binascii.Error) as exc: + raise HTTPException(502, "Flow image upscale returned invalid image data") from exc + quality = body.quality.lower() + return Response( + content=content, + media_type=data.get("contentType", "image/jpeg"), + headers={ + "Content-Disposition": f'attachment; filename="flow-{body.media_id}-{quality}.jpg"', + "X-Flow-Image-Quality": quality, + }, + ) + + @router.post("/upload-image") async def upload_image(body: UploadImageRequest): """Upload a local image file to Google Flow and get a media_id.""" diff --git a/agent/config.py b/agent/config.py index 5d6edf2fe..a02a51bd7 100644 --- a/agent/config.py +++ b/agent/config.py @@ -61,8 +61,9 @@ VIDEO_MODELS = _MODELS["video_models"] UPSCALE_MODELS = _MODELS["upscale_models"] IMAGE_MODELS = _MODELS["image_models"] -# Nickname from image_models. The batch path accepts GEM_PIX_2 (Nano Banana Pro) -# and NARWHAL (Banana 2) and rejects everything else. +# Nickname from image_models. Known aliases live in models.json, while the +# batch path also accepts syntactically valid Flow wire model ids directly so +# newly introduced image models do not require a Flow Kit release. DEFAULT_IMAGE_MODEL = _MODELS.get("default_image_model", "NANO_BANANA_PRO") # ─── API Endpoints ─────────────────────────────────────────── diff --git a/agent/models.json b/agent/models.json index 8c690e59f..7830223ec 100644 --- a/agent/models.json +++ b/agent/models.json @@ -55,7 +55,8 @@ }, "image_models": { "NANO_BANANA_PRO": "GEM_PIX_2", - "NANO_BANANA_2": "NARWHAL" + "NANO_BANANA_2": "NARWHAL", + "NANO_BANANA_2_LITE": "HARBOR_SEAL" }, "default_image_model": "NANO_BANANA_PRO", "batch_video_models": { diff --git a/agent/services/flow_batch.py b/agent/services/flow_batch.py index 538f77e1c..f81c1e44e 100644 --- a/agent/services/flow_batch.py +++ b/agent/services/flow_batch.py @@ -41,6 +41,7 @@ RPC_PROJECT_MEDIA = "Zzl0ze" RPC_MEDIA = "as29s" RPC_UPLOAD_IMAGE = "maseQ" +RPC_UPSCALE_IMAGE = "SPrCad" CAPTCHA_IMAGE = "IMAGE_GENERATION" CAPTCHA_VIDEO = "VIDEO_GENERATION" @@ -50,15 +51,21 @@ #: happen in the page, moments before the request leaves. CAPTCHA_SLOT = "__CAPTCHA__" -#: Wire names this path accepts. Everything else is rejected outright by Flow. -#: ``GEM_PIX_2`` is Nano Banana Pro, ``NARWHAL`` is Banana 2. Flow Kit uses Pro -#: by default (see agent/models.json), which is also what the new path defaults -#: to; a caller that wants Banana 2 has to name it. -IMAGE_MODELS = {"GEM_PIX_2", "NARWHAL"} +#: Current image model wire ids observed in the Flow frontend. Unknown future +#: ids are accepted by ``resolve_image_model`` instead of being silently +#: replaced by the default, so callers can opt into a newly exposed model +#: before Flow Kit itself ships another release. +IMAGE_MODELS = {"GEM_PIX_2", "NARWHAL", "HARBOR_SEAL"} IMAGE_MODEL = "GEM_PIX_2" -#: The nicknames models.json speaks, resolved to wire names. -IMAGE_MODEL_BY_NICKNAME = {"NANO_BANANA_PRO": "GEM_PIX_2", "NANO_BANANA_2": "NARWHAL"} +#: Friendly aliases. Exact Flow wire ids work too. +IMAGE_MODEL_BY_NICKNAME = { + "NANO_BANANA_PRO": "GEM_PIX_2", + "NANO_BANANA_2": "NARWHAL", + "NANO_BANANA_2_LITE": "HARBOR_SEAL", + "NANO_BANANA_LITE": "HARBOR_SEAL", +} +IMAGE_MODEL_ID_RE = re.compile(r"^[A-Z][A-Z0-9_]{1,95}$") #: Image aspect ratios, measured by generating one of each and reading the #: JPEG header. This slot was mistaken for a variant count at first — 1 means @@ -74,8 +81,16 @@ "IMAGE_ASPECT_RATIO_SQUARE": ASPECT_SQUARE, "IMAGE_ASPECT_RATIO_PORTRAIT": ASPECT_PORTRAIT, "IMAGE_ASPECT_RATIO_LANDSCAPE": ASPECT_LANDSCAPE, + # Current spelling plus the old Flow Kit alias for compatibility. + "IMAGE_ASPECT_RATIO_PORTRAIT_THREE_FOUR": ASPECT_PORTRAIT_4_3, "IMAGE_ASPECT_RATIO_PORTRAIT_FOUR_THREE": ASPECT_PORTRAIT_4_3, "IMAGE_ASPECT_RATIO_LANDSCAPE_FOUR_THREE": ASPECT_LANDSCAPE_4_3, + # Friendly API aliases. + "1:1": ASPECT_SQUARE, + "9:16": ASPECT_PORTRAIT, + "16:9": ASPECT_LANDSCAPE, + "3:4": ASPECT_PORTRAIT_4_3, + "4:3": ASPECT_LANDSCAPE_4_3, } #: Video models this path accepts. The REST-era map was keyed by @@ -118,10 +133,11 @@ #: reframed by hand: a hair inside the edges, spanning 128/129 of the frame. FULL_FRAME_CROP = [None, 0.0038759689922481244, 1, 0.9961240310077519] -#: A reference image, as the UI sends it: the media id FIRST and a type flag -#: four slots later. Probing never found this — the id sat in the wrong -#: position, the payload was accepted, and the picture quietly ignored it. +#: Image inputs put the media id first and the input type four slots later. +#: Type 1 is a reference; type 2 is the image being edited (BASE_IMAGE). REF_TYPE_IMAGE = 1 +BASE_TYPE_IMAGE = 2 +IMAGE_UPSCALE_RESOLUTIONS = {"2K": 1, "4K": 2} class RpcError(RuntimeError): @@ -181,12 +197,18 @@ class MediaUrls: # ── model / aspect resolvers ───────────────────────────────────────────────── def resolve_image_model(key: Optional[str]) -> str: - """Nickname or wire name in, wire name out; anything unknown coerces.""" + """Nickname or wire id in, wire id out. + + Flow can add image models independently of Flow Kit releases. A + syntactically valid, previously unseen wire id therefore passes through + unchanged instead of being silently replaced by the default model. + """ if isinstance(key, str): - if key in IMAGE_MODEL_BY_NICKNAME: - return IMAGE_MODEL_BY_NICKNAME[key] - if key in IMAGE_MODELS: - return key + normalized = key.strip().upper().replace("-", "_") + if normalized in IMAGE_MODEL_BY_NICKNAME: + return IMAGE_MODEL_BY_NICKNAME[normalized] + if IMAGE_MODEL_ID_RE.fullmatch(normalized): + return normalized return IMAGE_MODEL @@ -212,8 +234,10 @@ def resolve_video_model(key: Optional[str]) -> str: def resolve_aspect(aspect: Any) -> int: - """Take either the wire value or the REST-era name.""" + """Take a current/legacy wire name, friendly ratio, or integer 1-5.""" if isinstance(aspect, int): + if aspect not in (1, 2, 3, 4, 5): + raise ValueError(f"image aspect must be 1-5, got {aspect}") return aspect try: return ASPECT_BY_NAME[aspect] @@ -314,15 +338,24 @@ def _context(project_id: str) -> list: [CAPTCHA_SLOT, 1]] +def _image_input(media_id: str, input_type: int) -> list: + return [media_id, None, None, None, input_type] + + def _reference(media_id: str) -> list: - return [media_id, None, None, None, REF_TYPE_IMAGE] + return _image_input(media_id, REF_TYPE_IMAGE) + + +def _base_image(media_id: str) -> list: + return _image_input(media_id, BASE_TYPE_IMAGE) def image_request(prompt: str, project_id: str, count: int = 1, aspect: Any = ASPECT_SQUARE, seed: Optional[int] = None, prompts: Optional[list[str]] = None, model: str = IMAGE_MODEL, - ref_media_ids: Optional[list[str]] = None) -> str: + ref_media_ids: Optional[list[str]] = None, + base_media_id: Optional[str] = None) -> str: """One request item per variant, exactly as the REST payload did it. There is no "how many" field: Flow returns one image per item in the list, @@ -330,19 +363,39 @@ def image_request(prompt: str, project_id: str, count: int = 1, the result on images already in the project — this is what keeps a character the same person from beat to beat. """ + if not isinstance(count, int) or isinstance(count, bool) or not 1 <= count <= 4: + raise ValueError("image count must be an integer from 1 to 4") ratio = resolve_aspect(aspect) + resolved_model = resolve_image_model(model) base = seed if seed is not None else random.randint(1, 10**9) items = [] - for index in range(max(1, count)): + for index in range(count): text = prompts[index] if prompts and index < len(prompts) else prompt - refs = [_reference(mid) for mid in (ref_media_ids or [])] or None - items.append([None, None, refs, base + index * 9973, ratio, model, None, - _context(project_id), [[[text]]], None, None, None, - _client_uuid(), _client_uuid()]) + image_inputs = [] + if base_media_id: + image_inputs.append(_base_image(base_media_id)) + image_inputs.extend( + _reference(mid) for mid in (ref_media_ids or []) if mid != base_media_id + ) + items.append([None, None, image_inputs or None, base + index * 9973, ratio, + resolved_model, None, _context(project_id), [[[text]]], + None, None, None, _client_uuid(), _client_uuid()]) return build_envelope(RPC_GEN_IMAGE, [None, items, 1, _context(project_id), [_client_uuid()]]) +def image_upscale_request(media_id: str, resolution: str = "2K") -> str: + """Build the current FlowService.UpsampleImage request (RPC SPrCad).""" + key = str(resolution).strip().upper() + if key.startswith("UPSAMPLE_IMAGE_RESOLUTION_"): + key = key.removeprefix("UPSAMPLE_IMAGE_RESOLUTION_") + try: + code = IMAGE_UPSCALE_RESOLUTIONS[key] + except KeyError: + raise ValueError("image upscale resolution must be 2K or 4K") from None + return build_envelope(RPC_UPSCALE_IMAGE, [media_id, code, _context(None)]) + + def video_request(prompt: str, project_id: str, source_media_id: str, crop: Optional[list] = None, aspect: Any = VIDEO_ASPECT_LANDSCAPE, @@ -467,6 +520,13 @@ def read_text_video_submit(payload: Any) -> dict: "status": status if isinstance(status, str) else None, } +def read_upscaled_image(payload: Any) -> str: + """Return the base64 image body from FlowService.UpsampleImage.""" + encoded = payload[1] if isinstance(payload, list) and len(payload) > 1 else None + if not isinstance(encoded, str) or len(encoded) < 100: + raise FlowBatchError("image upscale response carried no encoded image") + return encoded + def read_operation(payload: Any) -> Operation: """`[null, 50, [[opId, projectId, sceneId, status, …]]]`. diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index 68a139931..ee3d3c600 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -597,7 +597,10 @@ async def generate_images(self, prompt: str, project_id: str, aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT", user_paygate_tier: str = "PAYGATE_TIER_TWO", character_media_ids: list[str] = None, - image_model: str = None) -> dict: + image_model: str = None, + count: int = 1, + seed: int | None = None, + base_media_id: str | None = None) -> dict: """Generate image(s). ``character_media_ids`` are attached as reference images, which is what @@ -612,9 +615,10 @@ async def generate_images(self, prompt: str, project_id: str, try: pid = self._batch_project_id(project_id) freq = fb.image_request( - prompt, pid, count=1, aspect=aspect_ratio, + prompt, pid, count=count, aspect=aspect_ratio, seed=seed, model=self._batch_image_model(image_model), ref_media_ids=list(character_media_ids or []) or None, + base_media_id=base_media_id, ) payload = await self._batch_payload(fb.RPC_GEN_IMAGE, freq, fb.CAPTCHA_IMAGE) except Exception as e: @@ -629,29 +633,62 @@ async def edit_image(self, prompt: str, source_media_id: str, project_id: str, aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT", user_paygate_tier: str = "PAYGATE_TIER_ONE", - character_media_ids: list[str] = None) -> dict: - """Regenerate from an existing image plus any entity references. - - The REST path had a dedicated base-image input type; the new payload's - reference slot was captured but a base-image variant of it was not, so - here the source rides in as the first reference. In practice that - conditions the result on the source rather than editing it in place — - good enough for continuation scenes, not identical to the old edit. - Capturing the real slot is the fix; see docs/CAPTURE.md. + character_media_ids: list[str] = None, + image_model: str = None, + count: int = 1, + seed: int | None = None) -> dict: + """Edit an image with the source encoded as Flow's BASE_IMAGE input. + + Additional references remain REFERENCE inputs. Sending the source as a + generic reference conditions a fresh generation; BASE_IMAGE is the wire + shape the current Flow editor uses for an actual image edit/refine. """ if not USE_BATCH_RPC: return await self._legacy_edit_image( prompt, source_media_id, project_id, aspect_ratio, user_paygate_tier, character_media_ids) - refs = [source_media_id] + [ - mid for mid in (character_media_ids or []) if mid != source_media_id - ] + refs = [mid for mid in (character_media_ids or []) if mid != source_media_id] return await self.generate_images( - prompt=prompt, project_id=project_id, aspect_ratio=aspect_ratio, - user_paygate_tier=user_paygate_tier, character_media_ids=refs, + prompt=prompt, + project_id=project_id, + aspect_ratio=aspect_ratio, + user_paygate_tier=user_paygate_tier, + character_media_ids=refs, + image_model=image_model, + count=count, + seed=seed, + base_media_id=source_media_id, ) + async def upscale_image(self, media_id: str, project_id: str, + resolution: str = "2K") -> dict: + """Return Flow's synchronous 2K/4K image upscale as base64 JPEG data.""" + if not USE_BATCH_RPC: + return {"status": 400, "error": "Image upscale requires the flow.google.com batch transport"} + try: + pid = self._batch_project_id(project_id) + freq = fb.image_upscale_request(media_id, resolution) + payload = await self._batch_payload( + fb.RPC_UPSCALE_IMAGE, + freq, + fb.CAPTCHA_IMAGE, + timeout=150, + ) + encoded = fb.read_upscaled_image(payload) + except Exception as e: + return _batch_error(e) + return { + "status": 200, + "data": { + "media_id": media_id, + "project_id": pid, + "resolution": str(resolution).upper(), + "encodedImage": encoded, + "contentType": "image/jpeg", + }, + } + async def generate_video(self, start_image_media_id: str, prompt: str, project_id: str, scene_id: str, aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", diff --git a/docs/IMAGE_API.md b/docs/IMAGE_API.md new file mode 100644 index 000000000..e0447176a --- /dev/null +++ b/docs/IMAGE_API.md @@ -0,0 +1,93 @@ +# Migrated Image API + +Flow's September 2026 frontend exposes image generation through the +`flow.google.com` batchexecute transport. This document covers the image +capabilities currently wired by Flow Kit. + +## Generate images + +`POST /api/flow/generate-image` + +```json +{ + "prompt": "A red paper boat on a calm pond", + "project_id": "<flow-project-uuid>", + "image_model": "HARBOR_SEAL", + "aspect_ratio": "16:9", + "count": 2, + "seed": 12345, + "reference_media_ids": [] +} +``` + +Current Flow UI model ids observed on the migrated frontend: + +- `GEM_PIX_2` — Nano Banana Pro +- `NARWHAL` — Nano Banana 2 +- `HARBOR_SEAL` — Nano Banana 2 Lite + +Friendly aliases from `models.json` continue to work. Flow Kit also passes a +syntactically valid future wire model id through unchanged instead of silently +coercing it to the default, so a newly exposed model can be selected before the +next Flow Kit release once its id is known. + +`count` accepts 1-4, matching the Flow UI. Each output is a separate request +item with its own seed. + +## Aspect ratios + +All five current image ratios are supported, using either the friendly ratio or +wire enum: + +| Ratio | Wire name | +|---|---| +| `1:1` | `IMAGE_ASPECT_RATIO_SQUARE` | +| `9:16` | `IMAGE_ASPECT_RATIO_PORTRAIT` | +| `16:9` | `IMAGE_ASPECT_RATIO_LANDSCAPE` | +| `3:4` | `IMAGE_ASPECT_RATIO_PORTRAIT_THREE_FOUR` | +| `4:3` | `IMAGE_ASPECT_RATIO_LANDSCAPE_FOUR_THREE` | + +The older Flow Kit spelling `IMAGE_ASPECT_RATIO_PORTRAIT_FOUR_THREE` remains an +alias for compatibility. + +## Edit an image + +`POST /api/flow/edit-image` + +The source image is sent as Flow's `BASE_IMAGE` input (wire type 2). Additional +`reference_media_ids` remain reference inputs (wire type 1). This fixes the old +batch-path behavior where the source itself was only a generic reference and +therefore conditioned a fresh generation instead of performing a true edit. + +```json +{ + "prompt": "Make the paper boat blue", + "source_media_id": "<media-id>", + "project_id": "<flow-project-uuid>", + "image_model": "GEM_PIX_2", + "aspect_ratio": "16:9", + "count": 1 +} +``` + +## Export / upscale image + +`POST /api/flow/export-image` + +```json +{ + "media_id": "<generated-media-id>", + "project_id": "<flow-project-uuid>", + "quality": "2k" +} +``` + +The migrated frontend uses RPC `SPrCad` (`FlowService.UpsampleImage`). The call +is synchronous and returns the encoded JPEG, which the HTTP endpoint returns as +a downloadable image. + +- `2k` — standard high-resolution download; live verified +- `4k` — same RPC with target code 2; availability is account/plan-gated + +Live verification on the current Flow frontend produced a 2752x1536 JPEG from a +1376x768 source. diff --git a/tests/unit/test_flow_batch.py b/tests/unit/test_flow_batch.py index a221023f3..3b249ca09 100644 --- a/tests/unit/test_flow_batch.py +++ b/tests/unit/test_flow_batch.py @@ -85,6 +85,21 @@ def test_reference_puts_the_media_id_first_and_the_type_flag_fourth(self): item = inner(fb.image_request("a cat", self.PID, ref_media_ids=["mid-1"]))[1][0] assert item[2] == [["mid-1", None, None, None, fb.REF_TYPE_IMAGE]] + def test_base_image_and_references_use_distinct_wire_types(self): + item = inner(fb.image_request( + "make the boat blue", self.PID, + base_media_id="base-1", ref_media_ids=["ref-1", "base-1"], + ))[1][0] + assert item[2] == [ + ["base-1", None, None, None, fb.BASE_TYPE_IMAGE], + ["ref-1", None, None, None, fb.REF_TYPE_IMAGE], + ] + + @pytest.mark.parametrize("bad_count", [0, 5, -1, True]) + def test_count_outside_flow_ui_range_is_rejected(self, bad_count): + with pytest.raises(ValueError): + fb.image_request("a cat", self.PID, count=bad_count) + def test_no_references_leaves_the_slot_null_rather_than_empty(self): assert inner(fb.image_request("a cat", self.PID))[1][0][2] is None @@ -99,6 +114,25 @@ def test_the_model_is_named_in_slot_5(self): assert item[5] == "NARWHAL" +class TestImageUpscaleRequest: + @pytest.mark.parametrize("resolution,wire", [ + ("2k", 1), + ("4K", 2), + ("UPSAMPLE_IMAGE_RESOLUTION_2K", 1), + ]) + def test_resolution_maps_to_live_sprcad_wire(self, resolution, wire): + payload = inner(fb.image_upscale_request("media-1", resolution)) + assert payload[0] == "media-1" + assert payload[1] == wire + assert payload[2][1] == fb.SURFACE_ID + assert payload[2][5] is None + assert fb.CAPTCHA_SLOT in json.dumps(payload) + + def test_unknown_resolution_is_rejected(self): + with pytest.raises(ValueError): + fb.image_upscale_request("media-1", "8K") + + class TestVideoRequest: PID = "11111111-2222-3333-4444-555555555555" @@ -160,6 +194,11 @@ def test_text_video_submit_reads_media_and_workflow_ids(self): "status": "CAE", } +def test_image_upscale_reads_synchronous_encoded_image(self): + assert fb.read_upscaled_image([["media"], "A" * 200]) == "A" * 200 + with pytest.raises(fb.FlowBatchError): + fb.read_upscaled_image([["media"], "short"]) + def test_operation_reads_the_id_and_status(self): op = fb.read_operation([None, 50, [[self.OP, "proj", "scene", "CAE"]]]) assert (op.operation_id, op.status, op.done) == (self.OP, "CAE", True) @@ -229,12 +268,32 @@ def test_an_unknown_aspect_name_raises_rather_than_defaulting(self): def test_nicknames_resolve_to_wire_names(self): assert fb.resolve_image_model("NANO_BANANA_PRO") == "GEM_PIX_2" assert fb.resolve_image_model("NANO_BANANA_2") == "NARWHAL" + assert fb.resolve_image_model("NANO_BANANA_2_LITE") == "HARBOR_SEAL" - def test_a_wire_name_passes_through(self): + def test_wire_names_and_future_model_ids_pass_through(self): assert fb.resolve_image_model("NARWHAL") == "NARWHAL" + assert fb.resolve_image_model("harbor_seal") == "HARBOR_SEAL" + assert fb.resolve_image_model("FUTURE_BANANA_3") == "FUTURE_BANANA_3" + + def test_invalid_or_blank_model_falls_back_to_default(self): + assert fb.resolve_image_model("") == fb.IMAGE_MODEL + assert fb.resolve_image_model("not a wire id!") == fb.IMAGE_MODEL + + @pytest.mark.parametrize("name,expected", [ + ("1:1", fb.ASPECT_SQUARE), + ("9:16", fb.ASPECT_PORTRAIT), + ("16:9", fb.ASPECT_LANDSCAPE), + ("3:4", fb.ASPECT_PORTRAIT_4_3), + ("4:3", fb.ASPECT_LANDSCAPE_4_3), + ("IMAGE_ASPECT_RATIO_PORTRAIT_THREE_FOUR", fb.ASPECT_PORTRAIT_4_3), + ("IMAGE_ASPECT_RATIO_PORTRAIT_FOUR_THREE", fb.ASPECT_PORTRAIT_4_3), + ]) + def test_all_current_image_aspect_names_and_friendly_aliases(self, name, expected): + assert fb.resolve_aspect(name) == expected - def test_an_unknown_image_model_coerces_to_the_default(self): - assert fb.resolve_image_model("SOMETHING_ELSE") == fb.IMAGE_MODEL + def test_invalid_integer_image_aspect_is_rejected(self): + with pytest.raises(ValueError): + fb.resolve_aspect(6) @pytest.mark.parametrize("legacy,expected", [ ("veo_3_1_i2v_s_fast_ultra_relaxed", "veo_3_1_i2v_s_fast_ultra"), diff --git a/tests/unit/test_flow_client_batch.py b/tests/unit/test_flow_client_batch.py index 733f52440..a9ae44cdb 100644 --- a/tests/unit/test_flow_client_batch.py +++ b/tests/unit/test_flow_client_batch.py @@ -72,6 +72,26 @@ async def test_character_refs_ride_in_the_reference_slot(self, client): assert item[2] == [["ref-a", None, None, None, fb.REF_TYPE_IMAGE], ["ref-b", None, None, None, fb.REF_TYPE_IMAGE]] + async def test_explicit_model_and_count_reach_the_batch_wire(self, client): + second = "12345678-1234-1234-1234-1234567890ac" + client.responses[fb.RPC_GEN_IMAGE] = { + "data": envelope(fb.RPC_GEN_IMAGE, [[IMAGE_URL], [IMAGE_URL.replace(MEDIA, second)]]) + } + result = await client.generate_images( + "a cat", PROJECT, image_model="HARBOR_SEAL", count=2, seed=100, + ) + items = json.loads(json.loads(client.calls[0]["freq"])[0][0][1])[1] + assert len(items) == 2 + assert [item[5] for item in items] == ["HARBOR_SEAL", "HARBOR_SEAL"] + assert [item[3] for item in items] == [100, 100 + 9973] + assert len(result["data"]["media"]) == 2 + + async def test_future_wire_model_is_not_silently_replaced(self, client): + client.responses[fb.RPC_GEN_IMAGE] = {"data": envelope(fb.RPC_GEN_IMAGE, [[IMAGE_URL]])} + await client.generate_images("a cat", PROJECT, image_model="FUTURE_BANANA_3") + item = json.loads(json.loads(client.calls[0]["freq"])[0][0][1])[1][0] + assert item[5] == "FUTURE_BANANA_3" + async def test_a_project_less_call_falls_back_to_the_pinned_project(self, client): client.responses[fb.RPC_GEN_IMAGE] = {"data": envelope(fb.RPC_GEN_IMAGE, [[IMAGE_URL]])} await client.generate_images("a cat", "0") @@ -96,19 +116,39 @@ async def test_no_project_anywhere_is_a_named_failure(self, client, monkeypatch) class TestEditImage: - async def test_the_source_leads_the_reference_list(self, client): + async def test_source_is_base_image_and_extra_inputs_are_references(self, client): client.responses[fb.RPC_GEN_IMAGE] = {"data": envelope(fb.RPC_GEN_IMAGE, [[IMAGE_URL]])} await client.edit_image("redraw", "src-1", PROJECT, character_media_ids=["ref-a"]) item = json.loads(json.loads(client.calls[0]["freq"])[0][0][1])[1][0] - assert [ref[0] for ref in item[2]] == ["src-1", "ref-a"] + assert item[2] == [ + ["src-1", None, None, None, fb.BASE_TYPE_IMAGE], + ["ref-a", None, None, None, fb.REF_TYPE_IMAGE], + ] - async def test_the_source_is_not_repeated_when_it_is_also_a_character(self, client): + async def test_source_is_not_repeated_when_also_supplied_as_reference(self, client): client.responses[fb.RPC_GEN_IMAGE] = {"data": envelope(fb.RPC_GEN_IMAGE, [[IMAGE_URL]])} await client.edit_image("redraw", "src-1", PROJECT, character_media_ids=["src-1", "ref-a"]) item = json.loads(json.loads(client.calls[0]["freq"])[0][0][1])[1][0] assert [ref[0] for ref in item[2]] == ["src-1", "ref-a"] + assert [ref[4] for ref in item[2]] == [fb.BASE_TYPE_IMAGE, fb.REF_TYPE_IMAGE] + + +class TestUpscaleImage: + async def test_2k_upscale_uses_sprcad_and_returns_encoded_image(self, client): + encoded = "A" * 200 + client.responses[fb.RPC_UPSCALE_IMAGE] = { + "data": envelope(fb.RPC_UPSCALE_IMAGE, [["media-record"], encoded]) + } + result = await client.upscale_image(MEDIA, PROJECT, "2K") + assert result["data"]["encodedImage"] == encoded + assert result["data"]["resolution"] == "2K" + assert client.calls[0]["rpcid"] == fb.RPC_UPSCALE_IMAGE + assert client.calls[0]["captcha"] == fb.CAPTCHA_IMAGE + payload = json.loads(json.loads(client.calls[0]["freq"])[0][0][1]) + assert payload[0] == MEDIA + assert payload[1] == 1 class TestGenerateVideo: From 43b0406b6cac779287ed497c373cd2b976ce0dfc Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Tue, 8 Sep 2026 11:29:17 +0300 Subject: [PATCH 11/68] fix(flow): match image variant submit behavior --- agent/services/flow_client.py | 40 +++++++++++++++++++++------- docs/IMAGE_API.md | 8 ++++-- extension/background.js | 9 +++++-- extension/injected.js | 20 +++++++++++--- tests/unit/test_flow_client_batch.py | 39 ++++++++++++++++++++++----- 5 files changed, 92 insertions(+), 24 deletions(-) diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index ee3d3c600..27855b3e9 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -33,6 +33,11 @@ logger = logging.getLogger(__name__) +# Captured from the current Flow image composer. x4 launches independent +# ogiZ0b requests at roughly 0.0s, 0.5s, 1.5s and 2.5s rather than bursting +# all variants at once. The generation work still overlaps after submission. +IMAGE_UI_SUBMIT_OFFSETS_S = (0.0, 0.5, 1.5, 2.5) + class FlowClient: """Sends commands to Chrome extension via WebSocket.""" @@ -613,20 +618,35 @@ async def generate_images(self, prompt: str, project_id: str, prompt, project_id, aspect_ratio, user_paygate_tier, character_media_ids) try: + if not isinstance(count, int) or isinstance(count, bool) or not 1 <= count <= 4: + raise ValueError("image count must be an integer from 1 to 4") pid = self._batch_project_id(project_id) - freq = fb.image_request( - prompt, pid, count=count, aspect=aspect_ratio, seed=seed, - model=self._batch_image_model(image_model), - ref_media_ids=list(character_media_ids or []) or None, - base_media_id=base_media_id, - ) - payload = await self._batch_payload(fb.RPC_GEN_IMAGE, freq, fb.CAPTCHA_IMAGE) + model = self._batch_image_model(image_model) + refs = list(character_media_ids or []) or None + + async def submit_one(index: int): + # Flow UI implements x2/x3/x4 as independent single-image RPCs. + # It also staggers their launch to avoid an artificial burst. + offset = IMAGE_UI_SUBMIT_OFFSETS_S[index] + if offset: + await asyncio.sleep(offset) + request_seed = seed + index * 9973 if seed is not None else None + freq = fb.image_request( + prompt, pid, count=1, aspect=aspect_ratio, seed=request_seed, + model=model, ref_media_ids=refs, base_media_id=base_media_id, + ) + payload = await self._batch_payload( + fb.RPC_GEN_IMAGE, freq, fb.CAPTCHA_IMAGE + ) + generated = fb.read_images(payload) + if not generated: + raise fb.FlowBatchError("Image generation returned no media url") + return generated[0] + + images = await asyncio.gather(*(submit_one(i) for i in range(count))) except Exception as e: return _batch_error(e) - images = fb.read_images(payload) - if not images: - return {"status": 502, "error": "Image generation returned no media url"} return {"status": 200, "data": {"media": [_as_media_record(i) for i in images]}} async def edit_image(self, prompt: str, source_media_id: str, diff --git a/docs/IMAGE_API.md b/docs/IMAGE_API.md index e0447176a..e6c931a29 100644 --- a/docs/IMAGE_API.md +++ b/docs/IMAGE_API.md @@ -31,8 +31,12 @@ syntactically valid future wire model id through unchanged instead of silently coercing it to the default, so a newly exposed model can be selected before the next Flow Kit release once its id is known. -`count` accepts 1-4, matching the Flow UI. Each output is a separate request -item with its own seed. +`count` accepts 1-4, matching the Flow UI. Flow itself implements x2/x3/x4 +as independent single-image `ogiZ0b` RPCs, each with a single-use reCAPTCHA; +it also staggers x4 launches at roughly 0.0 / 0.5 / 1.5 / 2.5 seconds. FlowKit +mirrors that behavior instead of sending an unofficial multi-item burst inside +one RPC. Each variant keeps its own seed; when `seed` is supplied, later +variants use a deterministic stride. ## Aspect ratios diff --git a/extension/background.js b/extension/background.js index 7ec7bfbd2..79036f87b 100644 --- a/extension/background.js +++ b/extension/background.js @@ -501,10 +501,15 @@ async function runBatchRpc(cmd) { const bl = wiz.cfb2h; if (!at) return { error: 'NO_AT_TOKEN' }; const reqid = Math.floor(Math.random() * 900000) + 100000; + // Match Flow's own WIZ metadata. GEM_PIX_2 (Nano Banana Pro) rejects + // image generation when source-path is missing even though Lite may not. + const sourcePath = location.pathname || '/'; + const hl = (document.documentElement.lang || navigator.language || 'en').split('-')[0]; const url = `/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=${encodeURIComponent(rpcid)}` + - `&f.sid=${encodeURIComponent(sid || '')}&bl=${encodeURIComponent(bl || '')}` + - `&hl=en-AU&_reqid=${reqid}&rt=c`; + `&source-path=${encodeURIComponent(sourcePath)}` + + `&bl=${encodeURIComponent(bl || '')}&f.sid=${encodeURIComponent(sid || '')}` + + `&hl=${encodeURIComponent(hl)}&_reqid=${reqid}&rt=c`; const resp = await fetch(url, { method: 'POST', credentials: 'include', diff --git a/extension/injected.js b/extension/injected.js index e26b690a8..a955a5f82 100644 --- a/extension/injected.js +++ b/extension/injected.js @@ -34,13 +34,27 @@ window.fetch = async function (...args) { }; -window.addEventListener('GET_CAPTCHA', async ({ detail }) => { - const { requestId, pageAction } = detail; +let captchaMintTail = Promise.resolve(); + +async function mintCaptcha(pageAction) { + const previous = captchaMintTail.catch(() => {}); + let release; + captchaMintTail = new Promise((resolve) => { release = resolve; }); + await previous; try { await waitForGrecaptcha(); - const token = await window.grecaptcha.enterprise.execute(SITE_KEY, { + return await window.grecaptcha.enterprise.execute(SITE_KEY, { action: pageAction, }); + } finally { + release(); + } +} + +window.addEventListener('GET_CAPTCHA', async ({ detail }) => { + const { requestId, pageAction } = detail; + try { + const token = await mintCaptcha(pageAction); window.dispatchEvent(new CustomEvent('CAPTCHA_RESULT', { detail: { requestId, token }, })); diff --git a/tests/unit/test_flow_client_batch.py b/tests/unit/test_flow_client_batch.py index a9ae44cdb..a3235a7ea 100644 --- a/tests/unit/test_flow_client_batch.py +++ b/tests/unit/test_flow_client_batch.py @@ -72,20 +72,45 @@ async def test_character_refs_ride_in_the_reference_slot(self, client): assert item[2] == [["ref-a", None, None, None, fb.REF_TYPE_IMAGE], ["ref-b", None, None, None, fb.REF_TYPE_IMAGE]] - async def test_explicit_model_and_count_reach_the_batch_wire(self, client): - second = "12345678-1234-1234-1234-1234567890ac" + async def test_explicit_model_and_count_dispatch_as_ui_style_rpcs(self, client, monkeypatch): + import agent.services.flow_client as module + sleeps = [] + + async def fake_sleep(delay): + sleeps.append(delay) + + monkeypatch.setattr(module.asyncio, "sleep", fake_sleep) client.responses[fb.RPC_GEN_IMAGE] = { - "data": envelope(fb.RPC_GEN_IMAGE, [[IMAGE_URL], [IMAGE_URL.replace(MEDIA, second)]]) + "data": envelope(fb.RPC_GEN_IMAGE, [[IMAGE_URL]]) } result = await client.generate_images( "a cat", PROJECT, image_model="HARBOR_SEAL", count=2, seed=100, ) - items = json.loads(json.loads(client.calls[0]["freq"])[0][0][1])[1] - assert len(items) == 2 - assert [item[5] for item in items] == ["HARBOR_SEAL", "HARBOR_SEAL"] - assert [item[3] for item in items] == [100, 100 + 9973] + assert len(client.calls) == 2 + items = [json.loads(json.loads(call["freq"])[0][0][1])[1] for call in client.calls] + assert [len(group) for group in items] == [1, 1] + assert [group[0][5] for group in items] == ["HARBOR_SEAL", "HARBOR_SEAL"] + assert [group[0][3] for group in items] == [100, 100 + 9973] + assert all(call["captcha"] == fb.CAPTCHA_IMAGE for call in client.calls) + assert sleeps == [module.IMAGE_UI_SUBMIT_OFFSETS_S[1]] assert len(result["data"]["media"]) == 2 + async def test_count_four_uses_captured_ui_launch_offsets(self, client, monkeypatch): + import agent.services.flow_client as module + sleeps = [] + + async def fake_sleep(delay): + sleeps.append(delay) + + monkeypatch.setattr(module.asyncio, "sleep", fake_sleep) + client.responses[fb.RPC_GEN_IMAGE] = { + "data": envelope(fb.RPC_GEN_IMAGE, [[IMAGE_URL]]) + } + result = await client.generate_images("a cat", PROJECT, count=4) + assert len(client.calls) == 4 + assert sleeps == list(module.IMAGE_UI_SUBMIT_OFFSETS_S[1:4]) + assert len(result["data"]["media"]) == 4 + async def test_future_wire_model_is_not_silently_replaced(self, client): client.responses[fb.RPC_GEN_IMAGE] = {"data": envelope(fb.RPC_GEN_IMAGE, [[IMAGE_URL]])} await client.generate_images("a cat", PROJECT, image_model="FUTURE_BANANA_3") From b02a5f5f17371a67578fc0258f7cf047cfc21e52 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Tue, 8 Sep 2026 12:02:17 +0300 Subject: [PATCH 12/68] fix(flow): retry image failures by settled wave --- agent/services/flow_client.py | 79 +++++++++++++++++++++++++--- docs/IMAGE_API.md | 8 +++ tests/unit/test_flow_client_batch.py | 71 +++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 8 deletions(-) diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index 27855b3e9..be56e708a 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -38,6 +38,14 @@ # all variants at once. The generation work still overlaps after submission. IMAGE_UI_SUBMIT_OFFSETS_S = (0.0, 0.5, 1.5, 2.5) +# RPC [8] is a transient Flow-side generation rejection seen under image load. +# A short 6s retry was still rejected in live testing, so use one bounded +# cooldown retry rather than hot-looping or multiplying duplicate generations. +# This is FlowKit resilience policy; the current UI was not observed to retry +# automatically after the same failure. +IMAGE_TRANSIENT_RETRY_DELAY_S = 34.0 +IMAGE_TRANSIENT_MAX_ATTEMPTS = 2 + class FlowClient: """Sends commands to Chrome extension via WebSocket.""" @@ -624,12 +632,9 @@ async def generate_images(self, prompt: str, project_id: str, model = self._batch_image_model(image_model) refs = list(character_media_ids or []) or None - async def submit_one(index: int): - # Flow UI implements x2/x3/x4 as independent single-image RPCs. - # It also staggers their launch to avoid an artificial burst. - offset = IMAGE_UI_SUBMIT_OFFSETS_S[index] - if offset: - await asyncio.sleep(offset) + async def submit_once(index: int, launch_offset: float = 0.0): + if launch_offset: + await asyncio.sleep(launch_offset) request_seed = seed + index * 9973 if seed is not None else None freq = fb.image_request( prompt, pid, count=1, aspect=aspect_ratio, seed=request_seed, @@ -643,11 +648,69 @@ async def submit_one(index: int): raise fb.FlowBatchError("Image generation returned no media url") return generated[0] - images = await asyncio.gather(*(submit_one(i) for i in range(count))) + async def run_wave(indices: list[int]) -> dict[int, object]: + # Flow's UI starts variants as separate single-image RPCs with a + # short cadence instead of a burst. Apply the cadence relative + # to each wave, while Google still performs the generation work + # concurrently after each request has been accepted. + tasks = [ + submit_once(index, IMAGE_UI_SUBMIT_OFFSETS_S[position]) + for position, index in enumerate(indices) + ] + results = await asyncio.gather(*tasks, return_exceptions=True) + return dict(zip(indices, results)) + + results = await run_wave(list(range(count))) + retry_indices = [ + index for index, result in results.items() + if isinstance(result, fb.RpcError) + and result.rpcid == fb.RPC_GEN_IMAGE + and result.detail == [8] + ] + if retry_indices: + logger.warning( + "Flow image wave had transient [8] for variant(s) %s; " + "retrying after %.0fs cooldown once the first wave is fully settled", + ",".join(str(i + 1) for i in retry_indices), + IMAGE_TRANSIENT_RETRY_DELAY_S, + ) + await asyncio.sleep(IMAGE_TRANSIENT_RETRY_DELAY_S) + retried = await run_wave(retry_indices) + results.update(retried) + + images_by_index = { + index: result + for index, result in results.items() + if not isinstance(result, BaseException) + } + failures = { + index: result + for index, result in results.items() + if isinstance(result, BaseException) + } + if not images_by_index: + first_error = failures[min(failures)] if failures else fb.FlowBatchError( + "Image generation returned no media url" + ) + raise first_error + + images = [images_by_index[index] for index in sorted(images_by_index)] + except Exception as e: return _batch_error(e) - return {"status": 200, "data": {"media": [_as_media_record(i) for i in images]}} + data = { + "media": [_as_media_record(i) for i in images], + "requested_count": count, + "generated_count": len(images), + "complete": len(images) == count, + } + if failures: + data["failed_variants"] = [ + {"index": index + 1, "error": str(error)} + for index, error in sorted(failures.items()) + ] + return {"status": 200, "data": data} async def edit_image(self, prompt: str, source_media_id: str, project_id: str, diff --git a/docs/IMAGE_API.md b/docs/IMAGE_API.md index e6c931a29..64130dde6 100644 --- a/docs/IMAGE_API.md +++ b/docs/IMAGE_API.md @@ -38,6 +38,14 @@ mirrors that behavior instead of sending an unofficial multi-item burst inside one RPC. Each variant keeps its own seed; when `seed` is supplied, later variants use a deterministic stride. +FlowKit treats only image RPC `[8]` as transient. It waits for the entire first +variant wave to settle, cools down for 34 seconds, then retries only failed `[8]` +variants once with fresh request UUIDs and the same seed. This is a FlowKit +resilience policy; live UI capture did not show the same automatic retry. If a +multi-image request still has a failed variant after retry, already successful +images are preserved and the response reports `complete=false`, +`generated_count`, and `failed_variants` instead of discarding the whole batch. + ## Aspect ratios All five current image ratios are supported, using either the friendly ratio or diff --git a/tests/unit/test_flow_client_batch.py b/tests/unit/test_flow_client_batch.py index a3235a7ea..c38c09ed1 100644 --- a/tests/unit/test_flow_client_batch.py +++ b/tests/unit/test_flow_client_batch.py @@ -111,6 +111,77 @@ async def fake_sleep(delay): assert sleeps == list(module.IMAGE_UI_SUBMIT_OFFSETS_S[1:4]) assert len(result["data"]["media"]) == 4 + async def test_rpc_error_8_retries_once_after_cooldown(self, client, monkeypatch): + import agent.services.flow_client as module + + attempts = 0 + sleeps = [] + + async def fake_payload(rpcid, freq, captcha_action=None, timeout=300): + nonlocal attempts + attempts += 1 + if attempts == 1: + raise fb.RpcError(fb.RPC_GEN_IMAGE, [8]) + return [[IMAGE_URL]] + + async def fake_sleep(delay): + sleeps.append(delay) + + client._batch_payload = fake_payload + monkeypatch.setattr(module.asyncio, "sleep", fake_sleep) + + result = await client.generate_images("a cat", PROJECT, count=1) + assert not _is_error(result) + assert attempts == 2 + assert sleeps == [module.IMAGE_TRANSIENT_RETRY_DELAY_S] + + async def test_non_transient_rpc_error_is_not_retried(self, client, monkeypatch): + import agent.services.flow_client as module + + attempts = 0 + sleeps = [] + + async def fake_payload(rpcid, freq, captcha_action=None, timeout=300): + nonlocal attempts + attempts += 1 + raise fb.RpcError(fb.RPC_GEN_IMAGE, [5]) + + async def fake_sleep(delay): + sleeps.append(delay) + + client._batch_payload = fake_payload + monkeypatch.setattr(module.asyncio, "sleep", fake_sleep) + + result = await client.generate_images("a cat", PROJECT, count=1) + assert _is_error(result) + assert attempts == 1 + assert sleeps == [] + + async def test_partial_batch_keeps_successes_and_reports_failed_variants(self, client, monkeypatch): + import agent.services.flow_client as module + + async def fake_sleep(_delay): + return None + + async def fake_payload(rpcid, freq, captcha_action=None, timeout=300): + item = json.loads(json.loads(freq)[0][0][1])[1][0] + if item[3] == 100 + 9973: + raise fb.RpcError(fb.RPC_GEN_IMAGE, [5]) + return [[IMAGE_URL]] + + client._batch_payload = fake_payload + monkeypatch.setattr(module.asyncio, "sleep", fake_sleep) + + result = await client.generate_images("a cat", PROJECT, count=2, seed=100) + assert not _is_error(result) + data = result["data"] + assert len(data["media"]) == 1 + assert data["requested_count"] == 2 + assert data["generated_count"] == 1 + assert data["complete"] is False + assert data["failed_variants"][0]["index"] == 2 + assert "[5]" in data["failed_variants"][0]["error"] + async def test_future_wire_model_is_not_silently_replaced(self, client): client.responses[fb.RPC_GEN_IMAGE] = {"data": envelope(fb.RPC_GEN_IMAGE, [[IMAGE_URL]])} await client.generate_images("a cat", PROJECT, image_model="FUTURE_BANANA_3") From b7eda7acc07da5e6fb2c99047954c1a1661c606a Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Thu, 17 Sep 2026 09:40:08 +0300 Subject: [PATCH 13/68] fix(flow): resolve upstream image API conflicts --- tests/unit/test_flow_batch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_flow_batch.py b/tests/unit/test_flow_batch.py index 3b249ca09..db1f3457a 100644 --- a/tests/unit/test_flow_batch.py +++ b/tests/unit/test_flow_batch.py @@ -194,7 +194,7 @@ def test_text_video_submit_reads_media_and_workflow_ids(self): "status": "CAE", } -def test_image_upscale_reads_synchronous_encoded_image(self): + def test_image_upscale_reads_synchronous_encoded_image(self): assert fb.read_upscaled_image([["media"], "A" * 200]) == "A" * 200 with pytest.raises(fb.FlowBatchError): fb.read_upscaled_image([["media"], "short"]) From 365630115cecf4620b277070be15c9078b905ed0 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Mon, 14 Sep 2026 01:30:50 +0300 Subject: [PATCH 14/68] fix(flow): restore Omni first-frame video on batch API --- agent/services/omni_flash.py | 99 +++++++++++++++++++++++++---------- docs/OMNI_FLASH.md | 33 ++++++++---- tests/unit/test_omni_flash.py | 97 ++++++++++++++++++++++++++-------- 3 files changed, 167 insertions(+), 62 deletions(-) diff --git a/agent/services/omni_flash.py b/agent/services/omni_flash.py index 796d6a312..dcb8a8b48 100644 --- a/agent/services/omni_flash.py +++ b/agent/services/omni_flash.py @@ -12,10 +12,11 @@ that mapping is deliberately configurable separately so it can be changed without a code release if Google's rollout rotates the wire key. -Important: Omni submit responses may contain operation-looking handles, but -those handles are not compatible with the legacy -``batchCheckAsyncVideoGenerationStatus`` polling endpoint. Omni jobs are -workflow-backed and are polled through Flow's authenticated project data. +Important: on the migrated ``flow.google.com`` batch transport, first-frame +Omni I2V uses the same ``eb1hJf`` operation contract as migrated Veo, with the +wire model switched to ``abra_i2v_<duration>s``. Those jobs therefore use the +normal batch operation poller. Legacy Omni and migrated text-to-video keep their +workflow/media polling contracts. """ from __future__ import annotations @@ -33,23 +34,19 @@ _MODELS_FILE = Path(__file__).parent.parent / "models.json" -#: Every Omni surface here rides the pre-migration transports — the REST -#: endpoints on aisandbox-pa and the labs.google tRPC snapshot it polls -#: through. Flow moved to flow.google.com in September 2026 and stopped -#: minting the bearer both of those need, and no Omni payload has been -#: captured off the new frontend, so on the batch path these fail with a -#: name rather than dying on a 401 five retries deep. -_UNSUPPORTED_ON_BATCH = ( - "UNSUPPORTED_ON_BATCH_API: Omni Flash frame/reference generation is not yet " - "ported to flow.google.com batchexecute. Omni text-to-video is supported on " - "the batch path; frame-to-video, start+end and reference-to-video still need " - "their migrated payload captures." +#: First-frame I2V is live on the migrated batch transport. Start+end and +#: reference-image modes still need their current Flow UI payloads captured; +#: keep those explicitly blocked instead of falling through to dead legacy auth. +_UNSUPPORTED_START_END_ON_BATCH = ( + "UNSUPPORTED_ON_BATCH_API: Omni Flash first+last frame generation is not yet " + "ported to flow.google.com batchexecute. First-frame image-to-video and " + "text-to-video are supported on the batch path." +) +_UNSUPPORTED_REFERENCE_ON_BATCH = ( + "UNSUPPORTED_ON_BATCH_API: Omni Flash reference-to-video is not yet ported " + "to flow.google.com batchexecute. First-frame image-to-video and text-to-video " + "are supported on the batch path." ) - - -def _batch_path_blocks_omni() -> dict | None: - """The error to return instead of reaching for auth that is gone.""" - return {"error": _UNSUPPORTED_ON_BATCH} if USE_BATCH_RPC else None OMNI_FLASH_VALID_DURATIONS = (4, 6, 8, 10) OMNI_FLASH_VALID_ASPECTS = { @@ -278,10 +275,13 @@ async def _submit_omni_frame_video( user_paygate_tier: str = "PAYGATE_TIER_ONE", seed: int | None = None, ) -> dict: - """Submit Omni first-frame or First+Last generation.""" - blocked = _batch_path_blocks_omni() - if blocked: - return blocked + """Submit Omni first-frame or First+Last generation. + + Migrated first-frame I2V was recaptured from the live Flow UI on + 2026-09-14: it uses ``eb1hJf`` with the normal image-to-video payload and + ``abra_i2v_<duration>s`` as the wire model. Its response is a standard + batch operation, so poll it through ``/api/flow/check-status``. + """ _validate_frame_inputs( start_image_media_id, end_image_media_id, @@ -294,13 +294,55 @@ async def _submit_omni_frame_video( if end_image_media_id is not None else "frame_to_video" ) + model_key = _load_model_key(duration_s, mode=mode) + client = get_flow_client() + + if USE_BATCH_RPC: + if end_image_media_id is not None: + return {"error": _UNSUPPORTED_START_END_ON_BATCH} + try: + pid = client._batch_project_id(project_id) + freq = fb.video_request( + prompt, + pid, + start_image_media_id, + aspect=aspect_ratio, + model=model_key, + ) + payload = await client._batch_payload( + fb.RPC_GEN_VIDEO, + freq, + fb.CAPTCHA_VIDEO, + timeout=120, + ) + operation = fb.read_operation(payload) + client._remember_operation(operation.operation_id, pid) + except Exception as exc: + return {"status": 502, "error": f"{type(exc).__name__}: {exc}"} + + pending = { + "operation": {"name": operation.operation_id}, + "status": "MEDIA_GENERATION_STATUS_PENDING", + } + return { + "status": 200, + "data": { + "operations": [pending], + "model": model_key, + "duration_s": duration_s, + "flowkitPolling": { + "mode": "batch_operation", + "project_id": pid, + "operations": [pending], + }, + }, + } + endpoint = ( "generate_video_start_end" if end_image_media_id is not None else "generate_video" ) - model_key = _load_model_key(duration_s, mode=mode) - client = get_flow_client() ts = int(time.time() * 1000) request_item = { @@ -401,9 +443,8 @@ async def generate_omni_flash_video( the workflow names and primary media IDs required by the Omni polling path. Do not feed Omni operation handles to ``check_video_status``. """ - blocked = _batch_path_blocks_omni() - if blocked: - return blocked + if USE_BATCH_RPC: + return {"error": _UNSUPPORTED_REFERENCE_ON_BATCH} refs = _validate_reference_inputs(reference_media_ids, duration_s, aspect_ratio) model_key = _load_model_key(duration_s, mode="reference_to_video") client = get_flow_client() diff --git a/docs/OMNI_FLASH.md b/docs/OMNI_FLASH.md index 64d3c040d..57407be3d 100644 --- a/docs/OMNI_FLASH.md +++ b/docs/OMNI_FLASH.md @@ -15,33 +15,44 @@ Expected state on the migrated Flow transport: ```json {"status":"ok","extension_connected":true} -{"connected":true,"transport":"batch"} +{"connected":true,"transport":"batch","authenticated":true,"at_token_present":true} ``` Use `http://127.0.0.1:8100` when the caller runs on the FlowKit host. For a remote integration, set `FLOWKIT_BASE_URL` to the protected HTTPS reverse-proxy URL and allow only the required source IPs or private network. Do not expose Chrome, VNC/noVNC, the extension WebSocket, or port 8100 publicly. ## Supported modes -On `flow.google.com`, Omni **text-to-video** is migrated and live-verified. The older frame/reference implementations still use the pre-migration REST transport and remain fail-fast while `USE_BATCH_RPC=1`. +On the current `flow.google.com` batch transport, Omni **text-to-video** and **first-frame image-to-video** are live and verified. First+Last and multi-reference generation still depend on the pre-migration transport and remain explicitly refused while `USE_BATCH_RPC=1` until their current UI payloads are captured. | Mode | Batch status | Endpoint | Internal model family | |---|---|---|---| | Text to video | **supported** | `POST /api/flow/generate-video-omni-text` | `abra_t2v_<duration>s` | -| First frame to video | not yet ported | `POST /api/flow/generate-video` | `abra_i2v_<duration>s` (legacy only) | +| First frame to video | **supported** | `POST /api/flow/generate-video` with `model_family=omni_flash` | `abra_i2v_<duration>s` | | First + Last frame to video | not yet ported | `POST /api/flow/generate-video` | `abra_i2v_<duration>s` (legacy only) | | References to video | not yet ported | `POST /api/flow/generate-video-omni` | `abra_r2v_<duration>s` (legacy only) | -Text-to-video supports `4`, `6`, `8`, and `10` seconds, with portrait and landscape aspect ratios. The migrated `YhhmEf` wire was live-verified with `abra_t2v_4s`; the downloaded result was exactly 4.000 seconds at 1280×720/24 fps. Completed media resolves through the migrated `as29s` media lookup. +Text-to-video durations are `4`, `6`, `8`, and `10` seconds. Supported aspect ratios are: + +- `VIDEO_ASPECT_RATIO_PORTRAIT` (`9:16`) +- `VIDEO_ASPECT_RATIO_LANDSCAPE` (`16:9`) + +The migrated `YhhmEf` wire was live-verified with `abra_t2v_4s`; the downloaded result was exactly 4.000 seconds at 1280x720/24 fps. First-frame I2V was re-captured from the live Flow UI on 2026-09-14: it uses RPC `eb1hJf`, the normal migrated I2V payload shape, and `abra_i2v_<duration>s`. A live API smoke test completed successfully and resolved its signed video URL through the existing batch operation poller. + +Polling differs by migrated mode: text-to-video returns workflow/media descriptors and uses `/api/flow/check-omni-status`; first-frame I2V returns a `flowkitPolling.mode = batch_operation` descriptor and uses `/api/flow/check-status` with its `operations` array. ## End-to-end integration flow +For migrated Omni, an integration agent should use the polling mode returned by the submit response: + 1. Check `/health` and `/api/flow/status`. -2. Submit `POST /api/flow/generate-video-omni-text` with prompt, project ID, duration and aspect ratio. -3. Persist the returned `flowkitPolling` object. -4. Poll `/api/flow/check-omni-status` every 10–20 seconds with its `project_id` and `workflows`. -5. On `COMPLETED`, immediately download `workflows[].media.url`; the signed URL is short-lived. +2. Submit either text-to-video or first-frame I2V. +3. Persist the complete `flowkitPolling` object returned by the submit. +4. If `mode=batch_media`, poll `/api/flow/check-omni-status` using `project_id` + `workflows`. +5. If `mode=batch_operation`, poll `/api/flow/check-status` using `project_id` + `operations`. +6. On pending state, continue polling; on failure, stop; on success, immediately download the returned signed video URL. +7. Store the downloaded video in durable storage because Google URLs are signed and short-lived. -Example: +Example 4-second submit: ```bash curl -fsS -X POST "$FLOWKIT_BASE_URL/api/flow/generate-video-omni-text" \ @@ -54,11 +65,11 @@ curl -fsS -X POST "$FLOWKIT_BASE_URL/api/flow/generate-video-omni-text" \ }' ``` -Do not feed Omni workflow names to the legacy Veo operation poller. +Do not send Omni workflow names to the legacy Veo `batchCheckAsyncVideoGenerationStatus` operation poller. Do not use the obsolete `/v1/media/<primaryMediaId>` polling path. ## Supplying images -This section applies to the legacy frame/reference Omni modes, which are not yet ported to the migrated batch transport. +This section applies to the older frame/reference Omni modes. Those generation modes are currently refused on `USE_BATCH_RPC=1` until their migrated payloads are captured; image upload itself may still be used by supported Veo workflows. `POST /api/flow/upload-image` is not a multipart upload endpoint. Its `file_path` is an absolute path on the **FlowKit server**, not on the calling server. diff --git a/tests/unit/test_omni_flash.py b/tests/unit/test_omni_flash.py index cf3b2fb14..e1a2998a3 100644 --- a/tests/unit/test_omni_flash.py +++ b/tests/unit/test_omni_flash.py @@ -1,9 +1,8 @@ """Unit tests for Gemini Omni Flash Flow submissions and workflow polling. -Omni speaks the pre-migration transports — the REST endpoints on aisandbox-pa -and the labs.google tRPC snapshot it polls through — so the wire contracts -asserted here are legacy-path contracts and the module is pinned to that path -for the file. What happens on the batch path is one test at the bottom. +Most legacy Omni wire-contract tests stay pinned to the pre-migration path. +Batch-specific tests opt into ``USE_BATCH_RPC`` explicitly and lock down the +migrated Flow payloads separately. """ from unittest.mock import AsyncMock, MagicMock, patch @@ -27,7 +26,7 @@ @pytest.fixture(autouse=True) def legacy_transport(monkeypatch): - """Omni is only reachable on the pre-migration path; assert it there.""" + """Default to legacy for legacy wire-contract tests; batch tests opt in.""" monkeypatch.setattr(omni_flash, "USE_BATCH_RPC", False) @@ -139,12 +138,17 @@ async def test_batch_text_video_builds_4s_yhhmef_submit(monkeypatch): client = MagicMock() client._batch_project_id.return_value = "11111111-2222-3333-4444-555555555555" client._batch_payload = AsyncMock(return_value=[ - None, 10, [], [[ + None, + 10, + [], + [[ "22222222-3333-4444-5555-666666666666", "11111111-2222-3333-4444-555555555555", - "77777777-8888-9999-aaaa-bbbbbbbbbbbb", "CAE", + "77777777-8888-9999-aaaa-bbbbbbbbbbbb", + "CAE", ]], ]) + with patch("agent.services.omni_flash.get_flow_client", return_value=client): result = await generate_omni_flash_text_video( prompt="A red paper boat drifts across a pond", @@ -152,17 +156,63 @@ async def test_batch_text_video_builds_4s_yhhmef_submit(monkeypatch): duration_s=4, aspect_ratio="VIDEO_ASPECT_RATIO_LANDSCAPE", ) + assert result["status"] == 200 assert result["data"]["model"] == "abra_t2v_4s" assert result["data"]["duration_s"] == 4 assert result["data"]["flowkitPolling"]["mode"] == "batch_media" + assert result["data"]["flowkitPolling"]["workflows"][0]["primary_media_id"] == ( + "22222222-3333-4444-5555-666666666666" + ) rpcid, freq, captcha = client._batch_payload.await_args.args[:3] assert rpcid == omni_flash.fb.RPC_GEN_VIDEO_TEXT assert captcha == omni_flash.fb.CAPTCHA_VIDEO payload = __import__("json").loads(__import__("json").loads(freq)[0][0][1]) assert payload[0][0][1] == "abra_t2v_4s" + assert payload[0][0][2] == omni_flash.fb.VIDEO_ASPECT_LANDSCAPE + + +@pytest.mark.asyncio +async def test_batch_first_frame_video_uses_eb1hjf_abra_i2v(monkeypatch): + monkeypatch.setattr(omni_flash, "USE_BATCH_RPC", True) + client = MagicMock() + pid = "11111111-2222-3333-4444-555555555555" + client._batch_project_id.return_value = pid + client._batch_payload = AsyncMock(return_value=[ + None, + 50, + [["op-omni-1", pid, "scene-1", None]], + ]) + + with patch("agent.services.omni_flash.get_flow_client", return_value=client): + result = await generate_omni_flash_first_frame_video( + start_image_media_id="media-start", + prompt="Three children clap gently", + project_id=pid, + duration_s=6, + aspect_ratio="VIDEO_ASPECT_RATIO_LANDSCAPE", + ) + + assert result["status"] == 200 + assert result["data"]["model"] == "abra_i2v_6s" + assert result["data"]["duration_s"] == 6 + assert result["data"]["flowkitPolling"]["mode"] == "batch_operation" + assert result["data"]["flowkitPolling"]["project_id"] == pid + assert result["data"]["operations"][0]["operation"]["name"] == "op-omni-1" + client._remember_operation.assert_called_once_with("op-omni-1", pid) + + rpcid, freq, captcha = client._batch_payload.await_args.args[:3] + assert rpcid == omni_flash.fb.RPC_GEN_VIDEO + assert captcha == omni_flash.fb.CAPTCHA_VIDEO + payload = __import__("json").loads(__import__("json").loads(freq)[0][0][1]) + request = payload[0][0] + assert request[0][2][0][0][0] == "Three children clap gently" + assert request[1] == "abra_i2v_6s" + assert request[2] == omni_flash.fb.VIDEO_ASPECT_LANDSCAPE + assert request[4][1] == "media-start" + @pytest.mark.asyncio async def test_submit_builds_flow_omni_first_frame_request_and_poll_descriptor(): client = _mock_submit_client() @@ -390,13 +440,24 @@ async def test_batch_omni_poll_uses_as29s_media(monkeypatch): client = MagicMock() client.get_media = AsyncMock(return_value={ "status": 200, - "data": {"video": {"fifeUrl": "https://flow-content.google/video/media-1?Signature=test"}}, + "data": { + "video": { + "fifeUrl": "https://flow-content.google/video/media-1?Signature=test" + } + }, }) + with patch("agent.services.omni_flash.get_flow_client", return_value=client): - result = await check_omni_flash_status([{ - "name": "workflow-1", "primary_media_id": "media-1", "project_id": "project-1", - }]) + result = await check_omni_flash_status([ + { + "name": "workflow-1", + "primary_media_id": "media-1", + "project_id": "project-1", + } + ]) + assert result["done"] is True + assert result["status"] == "COMPLETED" assert result["workflows"][0]["media"]["resolved_via"] == "as29s" client.get_media.assert_awaited_once_with("media-1") @@ -525,10 +586,8 @@ async def test_submit_rejects_empty_reference_set(): ) -class TestUnportedOmniBatchModesAreRefusedRatherThanAttempted: - """Flow stopped minting the bearer these endpoints need, and no Omni - payload has been captured off the new frontend. Saying so beats a 401 - five retries deep.""" +class TestRemainingUnportedOmniBatchModesAreRefused: + """Only start+end/reference remain blocked; first-frame I2V is migrated.""" @pytest.fixture(autouse=True) def batch_transport(self, monkeypatch): @@ -542,12 +601,6 @@ def client(self): factory.return_value = stub yield stub - async def test_first_frame_names_the_gap_and_sends_nothing(self, client): - result = await generate_omni_flash_first_frame_video( - start_image_media_id="mid", prompt="go", project_id="pid") - assert "UNSUPPORTED_ON_BATCH_API" in result["error"] - client._send.assert_not_called() - async def test_first_last_names_the_gap_and_sends_nothing(self, client): result = await generate_omni_flash_first_last_video( start_image_media_id="a", end_image_media_id="b", @@ -564,5 +617,5 @@ async def test_reference_to_video_names_the_gap_and_sends_nothing(self, client): async def test_the_message_points_to_supported_text_to_video(self, client): result = await generate_omni_flash_video( reference_media_ids=["a"], prompt="go", project_id="pid") - assert "text-to-video is supported" in result["error"] + assert "image-to-video and text-to-video are supported" in result["error"] assert "reference-to-video" in result["error"] From b1db615757adfb2fdb85a2511a6cc9579119e0c4 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Mon, 14 Sep 2026 07:31:23 +0300 Subject: [PATCH 15/68] feat(flow): restore all Omni reference modes on batch API --- agent/api/flow.py | 17 ++-- agent/services/flow_batch.py | 97 ++++++++++++++++++ agent/services/omni_flash.py | 184 +++++++++++++++++----------------- docs/OMNI_FLASH.md | 121 ++++++++++------------ tests/unit/test_flow_batch.py | 36 +++++++ tests/unit/test_omni_flash.py | 77 ++++++++++---- 6 files changed, 345 insertions(+), 187 deletions(-) diff --git a/agent/api/flow.py b/agent/api/flow.py index 5aeed8fac..99d851de3 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -39,6 +39,7 @@ class GenerateVideoRequest(BaseModel): # Backward compatible: legacy requests remain Veo unless explicitly set. model_family: Literal["veo", "omni_flash"] = "veo" duration_s: int = 8 + resolution: Literal["360p", "720p"] = "720p" class GenerateVideoRefsRequest(BaseModel): @@ -52,6 +53,7 @@ class GenerateVideoRefsRequest(BaseModel): # explicitly opt into Omni Flash. model_family: Literal["veo", "omni_flash"] = "veo" duration_s: int = 8 + resolution: Literal["360p", "720p"] = "720p" class GenerateOmniFlashVideoRequest(BaseModel): @@ -60,6 +62,7 @@ class GenerateOmniFlashVideoRequest(BaseModel): project_id: str scene_id: str = "" duration_s: int = 8 + resolution: Literal["360p", "720p"] = "720p" aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT" user_paygate_tier: str = "PAYGATE_TIER_ONE" @@ -173,8 +176,8 @@ async def generate_video(body: GenerateVideoRequest): request uses Omni First frame. When ``end_image_media_id`` is also present, it uses Omni First+Last frames. - Omni responses include ``flowkitPolling.workflows`` and must use workflow - media polling rather than legacy operation polling. + On the migrated batch transport, Omni frame-conditioned responses return + ``flowkitPolling.mode=batch_operation`` and are polled through ``/check-status``. """ client = get_flow_client() if not client.connected: @@ -188,6 +191,7 @@ async def generate_video(body: GenerateVideoRequest): project_id=body.project_id, scene_id=body.scene_id, duration_s=body.duration_s, + resolution=body.resolution, aspect_ratio=body.aspect_ratio, user_paygate_tier=body.user_paygate_tier, ) @@ -202,7 +206,7 @@ async def generate_video(body: GenerateVideoRequest): raise HTTPException(400, str(exc)) from exc else: result = await client.generate_video( - **body.model_dump(exclude={"model_family", "duration_s"}, exclude_none=True) + **body.model_dump(exclude={"model_family", "duration_s", "resolution"}, exclude_none=True) ) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): @@ -216,8 +220,8 @@ async def generate_video_refs(body: GenerateVideoRefsRequest): Existing requests default to ``model_family=veo``. Set ``model_family=omni_flash`` and ``duration_s`` to 4/6/8/10 to use Omni. - Omni responses include ``flowkitPolling.workflows``; poll those workflows, - not the operation-looking handles in the raw Flow response. + Migrated Omni Ingredients/R2V returns ``flowkitPolling.mode=batch_operation``; + poll its operations through ``/check-status``. """ client = get_flow_client() if not client.connected: @@ -231,6 +235,7 @@ async def generate_video_refs(body: GenerateVideoRefsRequest): project_id=body.project_id, scene_id=body.scene_id, duration_s=body.duration_s, + resolution=body.resolution, aspect_ratio=body.aspect_ratio, user_paygate_tier=body.user_paygate_tier, ) @@ -238,7 +243,7 @@ async def generate_video_refs(body: GenerateVideoRefsRequest): raise HTTPException(400, str(exc)) from exc else: result = await client.generate_video_from_references( - **body.model_dump(exclude={"model_family", "duration_s"}) + **body.model_dump(exclude={"model_family", "duration_s", "resolution"}) ) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): diff --git a/agent/services/flow_batch.py b/agent/services/flow_batch.py index f81c1e44e..e2f41c00e 100644 --- a/agent/services/flow_batch.py +++ b/agent/services/flow_batch.py @@ -37,6 +37,8 @@ RPC_GEN_IMAGE = "ogiZ0b" RPC_GEN_VIDEO = "eb1hJf" RPC_GEN_VIDEO_TEXT = "YhhmEf" +RPC_GEN_VIDEO_FIRST_LAST = "nprQif" +RPC_GEN_VIDEO_REFERENCES = "MZZa6b" RPC_OPERATION = "jwpduf" RPC_PROJECT_MEDIA = "Zzl0ze" RPC_MEDIA = "as29s" @@ -411,6 +413,101 @@ def video_request(prompt: str, project_id: str, source_media_id: str, return build_envelope(RPC_GEN_VIDEO, inner) +def omni_first_frame_request(prompt: str, project_id: str, source_media_id: str, + *, duration_s: int = 8, resolution: str = "720p", + aspect: Any = VIDEO_ASPECT_LANDSCAPE, + crop: Optional[list] = None) -> str: + """Build current Omni first-frame I2V (RPC ``eb1hJf``). + + Live-captured from Flow on 2026-09-14. 720p uses ``abra_i2v_<N>s``; + 360p appends ``_360p`` and carries the UI's low-resolution option slot. + """ + if duration_s not in (4, 6, 8, 10): + raise ValueError("Omni duration must be 4, 6, 8 or 10 seconds") + res = str(resolution).strip().lower() + if res not in {"360p", "720p"}: + raise ValueError("Omni resolution must be 360p or 720p") + model = f"abra_i2v_{duration_s}s" + ("_360p" if res == "360p" else "") + request = [ + [None, None, [[[prompt]]]], + model, + resolve_video_aspect(aspect), + None, + [None, source_media_id, None, None, None, + FULL_FRAME_CROP if crop is None else crop], + [None, None, None, None, _client_uuid(), _client_uuid()], + ] + if res == "360p": + request.extend([None, None, None, [4]]) + return build_envelope(RPC_GEN_VIDEO, [ + [request], + _context(project_id), + [_client_uuid(), 2], + ]) + + +def omni_first_last_request(prompt: str, project_id: str, + start_media_id: str, end_media_id: str, + *, duration_s: int = 8, resolution: str = "720p", + aspect: Any = VIDEO_ASPECT_LANDSCAPE, + start_crop: Optional[list] = None, + end_crop: Optional[list] = None) -> str: + """Build Omni First+Last frames submit (RPC ``nprQif``).""" + if duration_s not in (4, 6, 8, 10): + raise ValueError("Omni duration must be 4, 6, 8 or 10 seconds") + res = str(resolution).strip().lower() + if res not in {"360p", "720p"}: + raise ValueError("Omni resolution must be 360p or 720p") + model = f"omni_flash_i2v_{duration_s}s_first_last" + ("_360p" if res == "360p" else "") + request = [ + [None, None, [[[prompt]]]], + model, + resolve_video_aspect(aspect), + None, + [None, start_media_id, None, None, None, + FULL_FRAME_CROP if start_crop is None else start_crop], + [None, end_media_id, None, None, None, + FULL_FRAME_CROP if end_crop is None else end_crop], + [None, None, None, None, _client_uuid(), _client_uuid()], + ] + return build_envelope(RPC_GEN_VIDEO_FIRST_LAST, [ + [request], + _context(project_id), + [_client_uuid(), 2], + ]) + + +def omni_reference_video_request(prompt: str, project_id: str, + reference_media_ids: list[str], + *, duration_s: int = 8, resolution: str = "720p", + aspect: Any = VIDEO_ASPECT_LANDSCAPE) -> str: + """Build Omni Ingredients/reference-to-video submit (RPC ``MZZa6b``).""" + refs = [str(mid) for mid in reference_media_ids if str(mid)] + if not refs: + raise ValueError("Omni reference-to-video requires at least one reference image") + if duration_s not in (4, 6, 8, 10): + raise ValueError("Omni duration must be 4, 6, 8 or 10 seconds") + res = str(resolution).strip().lower() + if res not in {"360p", "720p"}: + raise ValueError("Omni resolution must be 360p or 720p") + model = f"abra_r2v_{duration_s}s" + ("_360p" if res == "360p" else "") + request = [ + [None, None, [[[prompt]]]], + [[None, mid] for mid in refs], + model, + resolve_video_aspect(aspect), + None, + [None, None, None, None, _client_uuid(), _client_uuid()], + ] + if res == "360p": + request.extend([None, None, None, None, None, [4]]) + return build_envelope(RPC_GEN_VIDEO_REFERENCES, [ + [request], + _context(project_id), + [_client_uuid(), 2], + ]) + + def text_video_request(prompt: str, project_id: str, aspect: Any = VIDEO_ASPECT_LANDSCAPE, model: str = "abra_t2v_4s") -> str: diff --git a/agent/services/omni_flash.py b/agent/services/omni_flash.py index dcb8a8b48..fa078e41b 100644 --- a/agent/services/omni_flash.py +++ b/agent/services/omni_flash.py @@ -1,22 +1,15 @@ """Gemini Omni Flash video generation through the Google Flow bridge. -Supported Omni surfaces in this module: - -* first frame -> video via ``batchAsyncGenerateVideoStartImage`` -* first + last frame -> video via ``batchAsyncGenerateVideoStartAndEndImage`` -* reference images -> video via ``batchAsyncGenerateVideoReferenceImages`` - -Omni duration-specific model keys live in ``agent/models.json``. First-frame -Flow requests have been captured with ``abra_i2v_<duration>s``. The current -First+Last rollout uses the same Omni I2V family but the StartAndEnd endpoint; -that mapping is deliberately configurable separately so it can be changed -without a code release if Google's rollout rotates the wire key. - -Important: on the migrated ``flow.google.com`` batch transport, first-frame -Omni I2V uses the same ``eb1hJf`` operation contract as migrated Veo, with the -wire model switched to ``abra_i2v_<duration>s``. Those jobs therefore use the -normal batch operation poller. Legacy Omni and migrated text-to-video keep their -workflow/media polling contracts. +Migrated ``flow.google.com`` batch surfaces live-verified on 2026-09-14: + +* text -> video: ``YhhmEf`` + ``abra_t2v_<duration>s`` (workflow/media polling) +* first frame -> video: ``eb1hJf`` + ``abra_i2v_<duration>s`` +* first + last frame -> video: ``nprQif`` + ``omni_flash_i2v_<duration>s_first_last`` +* Ingredients/references -> video: ``MZZa6b`` + ``abra_r2v_<duration>s`` + +Reference-conditioned modes return normal batch operation receipts and use the +same operation/media poller as migrated Veo. The legacy REST implementations are +kept below for non-batch deployments, but are not used by current production. """ from __future__ import annotations @@ -34,20 +27,6 @@ _MODELS_FILE = Path(__file__).parent.parent / "models.json" -#: First-frame I2V is live on the migrated batch transport. Start+end and -#: reference-image modes still need their current Flow UI payloads captured; -#: keep those explicitly blocked instead of falling through to dead legacy auth. -_UNSUPPORTED_START_END_ON_BATCH = ( - "UNSUPPORTED_ON_BATCH_API: Omni Flash first+last frame generation is not yet " - "ported to flow.google.com batchexecute. First-frame image-to-video and " - "text-to-video are supported on the batch path." -) -_UNSUPPORTED_REFERENCE_ON_BATCH = ( - "UNSUPPORTED_ON_BATCH_API: Omni Flash reference-to-video is not yet ported " - "to flow.google.com batchexecute. First-frame image-to-video and text-to-video " - "are supported on the batch path." -) - OMNI_FLASH_VALID_DURATIONS = (4, 6, 8, 10) OMNI_FLASH_VALID_ASPECTS = { "VIDEO_ASPECT_RATIO_PORTRAIT", @@ -110,6 +89,34 @@ def _validate_aspect(aspect_ratio: str) -> None: ) +def _validate_resolution(resolution: str) -> str: + value = str(resolution or "720p").strip().lower() + if value not in {"360p", "720p"}: + raise ValueError("Omni Flash resolution must be 360p or 720p") + return value + + +def _batch_operation_result(operation, project_id: str, model: str, duration_s: int, resolution: str) -> dict: + pending = { + "operation": {"name": operation.operation_id}, + "status": "MEDIA_GENERATION_STATUS_PENDING", + } + return { + "status": 200, + "data": { + "operations": [pending], + "model": model, + "duration_s": duration_s, + "resolution": resolution, + "flowkitPolling": { + "mode": "batch_operation", + "project_id": project_id, + "operations": [pending], + }, + }, + } + + def _load_model_key(duration_s: int, mode: str = "reference_to_video") -> str: """Resolve a configured Omni Flash model key for ``mode`` + duration.""" _validate_duration(duration_s) @@ -271,80 +278,53 @@ async def _submit_omni_frame_video( project_id: str, scene_id: str = "", duration_s: int = 8, + resolution: str = "720p", aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", user_paygate_tier: str = "PAYGATE_TIER_ONE", seed: int | None = None, ) -> dict: """Submit Omni first-frame or First+Last generation. - Migrated first-frame I2V was recaptured from the live Flow UI on - 2026-09-14: it uses ``eb1hJf`` with the normal image-to-video payload and - ``abra_i2v_<duration>s`` as the wire model. Its response is a standard - batch operation, so poll it through ``/api/flow/check-status``. + Batch payloads were live-captured from ``flow.google.com`` on 2026-09-14: + first-frame uses ``eb1hJf``; First+Last uses ``nprQif``. Both return normal + batch operations and are polled through ``/api/flow/check-status``. """ - _validate_frame_inputs( - start_image_media_id, - end_image_media_id, - duration_s, - aspect_ratio, - ) - - mode = ( - "start_end_frame_to_video" - if end_image_media_id is not None - else "frame_to_video" - ) + _validate_frame_inputs(start_image_media_id, end_image_media_id, duration_s, aspect_ratio) + resolution = _validate_resolution(resolution) + mode = "start_end_frame_to_video" if end_image_media_id is not None else "frame_to_video" model_key = _load_model_key(duration_s, mode=mode) client = get_flow_client() if USE_BATCH_RPC: - if end_image_media_id is not None: - return {"error": _UNSUPPORTED_START_END_ON_BATCH} try: pid = client._batch_project_id(project_id) - freq = fb.video_request( - prompt, - pid, - start_image_media_id, - aspect=aspect_ratio, - model=model_key, - ) + if end_image_media_id is None: + freq = fb.omni_first_frame_request( + prompt, pid, start_image_media_id, duration_s=duration_s, + resolution=resolution, aspect=aspect_ratio, + ) + rpcid = fb.RPC_GEN_VIDEO + batch_model = f"abra_i2v_{duration_s}s" + ("_360p" if resolution == "360p" else "") + else: + freq = fb.omni_first_last_request( + prompt, pid, start_image_media_id, end_image_media_id, + duration_s=duration_s, resolution=resolution, aspect=aspect_ratio, + ) + rpcid = fb.RPC_GEN_VIDEO_FIRST_LAST + batch_model = f"omni_flash_i2v_{duration_s}s_first_last" + ( + "_360p" if resolution == "360p" else "" + ) payload = await client._batch_payload( - fb.RPC_GEN_VIDEO, - freq, - fb.CAPTCHA_VIDEO, - timeout=120, + rpcid, freq, fb.CAPTCHA_VIDEO, timeout=120, ) operation = fb.read_operation(payload) client._remember_operation(operation.operation_id, pid) except Exception as exc: return {"status": 502, "error": f"{type(exc).__name__}: {exc}"} + return _batch_operation_result(operation, pid, batch_model, duration_s, resolution) - pending = { - "operation": {"name": operation.operation_id}, - "status": "MEDIA_GENERATION_STATUS_PENDING", - } - return { - "status": 200, - "data": { - "operations": [pending], - "model": model_key, - "duration_s": duration_s, - "flowkitPolling": { - "mode": "batch_operation", - "project_id": pid, - "operations": [pending], - }, - }, - } - - endpoint = ( - "generate_video_start_end" - if end_image_media_id is not None - else "generate_video" - ) + endpoint = "generate_video_start_end" if end_image_media_id is not None else "generate_video" ts = int(time.time() * 1000) - request_item = { "aspectRatio": aspect_ratio, "textInput": {"structuredPrompt": {"parts": [{"text": prompt}]}}, @@ -355,7 +335,6 @@ async def _submit_omni_frame_video( } if end_image_media_id is not None: request_item["endImage"] = {"mediaId": end_image_media_id} - context = client._client_context(project_id, user_paygate_tier) body = { "mediaGenerationContext": {"batchId": str(uuid.uuid4())}, @@ -363,7 +342,6 @@ async def _submit_omni_frame_video( "requests": [request_item], "useV2ModelConfig": True, } - result = await client._send( "api_request", { @@ -384,6 +362,7 @@ async def generate_omni_flash_first_frame_video( project_id: str, scene_id: str = "", duration_s: int = 8, + resolution: str = "720p", aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", user_paygate_tier: str = "PAYGATE_TIER_ONE", seed: int | None = None, @@ -396,6 +375,7 @@ async def generate_omni_flash_first_frame_video( project_id=project_id, scene_id=scene_id, duration_s=duration_s, + resolution=resolution, aspect_ratio=aspect_ratio, user_paygate_tier=user_paygate_tier, seed=seed, @@ -409,6 +389,7 @@ async def generate_omni_flash_first_last_video( project_id: str, scene_id: str = "", duration_s: int = 8, + resolution: str = "720p", aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", user_paygate_tier: str = "PAYGATE_TIER_ONE", seed: int | None = None, @@ -421,6 +402,7 @@ async def generate_omni_flash_first_last_video( project_id=project_id, scene_id=scene_id, duration_s=duration_s, + resolution=resolution, aspect_ratio=aspect_ratio, user_paygate_tier=user_paygate_tier, seed=seed, @@ -433,22 +415,38 @@ async def generate_omni_flash_video( project_id: str, scene_id: str = "", duration_s: int = 8, + resolution: str = "720p", aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", user_paygate_tier: str = "PAYGATE_TIER_ONE", seed: int | None = None, ) -> dict: - """Submit an Omni Flash reference-to-video generation. + """Submit Omni Flash Ingredients/reference-to-video generation. - Successful responses are annotated with ``data.flowkitPolling`` containing - the workflow names and primary media IDs required by the Omni polling path. - Do not feed Omni operation handles to ``check_video_status``. + The migrated UI uses RPC ``MZZa6b`` with ``abra_r2v_<duration>s`` (720p) + or ``abra_r2v_<duration>s_360p``. Batch jobs use normal operation polling. """ - if USE_BATCH_RPC: - return {"error": _UNSUPPORTED_REFERENCE_ON_BATCH} refs = _validate_reference_inputs(reference_media_ids, duration_s, aspect_ratio) + resolution = _validate_resolution(resolution) model_key = _load_model_key(duration_s, mode="reference_to_video") client = get_flow_client() + if USE_BATCH_RPC: + try: + pid = client._batch_project_id(project_id) + freq = fb.omni_reference_video_request( + prompt, pid, refs, duration_s=duration_s, + resolution=resolution, aspect=aspect_ratio, + ) + payload = await client._batch_payload( + fb.RPC_GEN_VIDEO_REFERENCES, freq, fb.CAPTCHA_VIDEO, timeout=120, + ) + operation = fb.read_operation(payload) + client._remember_operation(operation.operation_id, pid) + except Exception as exc: + return {"status": 502, "error": f"{type(exc).__name__}: {exc}"} + batch_model = f"abra_r2v_{duration_s}s" + ("_360p" if resolution == "360p" else "") + return _batch_operation_result(operation, pid, batch_model, duration_s, resolution) + ts = int(time.time() * 1000) request_item = { "aspectRatio": aspect_ratio, @@ -461,7 +459,6 @@ async def generate_omni_flash_video( for mid in refs ], } - context = client._client_context(project_id, user_paygate_tier) body = { "mediaGenerationContext": { @@ -472,7 +469,6 @@ async def generate_omni_flash_video( "requests": [request_item], "useV2ModelConfig": True, } - url = client._build_url("generate_video_references") result = await client._send( "api_request", diff --git a/docs/OMNI_FLASH.md b/docs/OMNI_FLASH.md index 57407be3d..e83bb9805 100644 --- a/docs/OMNI_FLASH.md +++ b/docs/OMNI_FLASH.md @@ -22,37 +22,37 @@ Use `http://127.0.0.1:8100` when the caller runs on the FlowKit host. For a remo ## Supported modes -On the current `flow.google.com` batch transport, Omni **text-to-video** and **first-frame image-to-video** are live and verified. First+Last and multi-reference generation still depend on the pre-migration transport and remain explicitly refused while `USE_BATCH_RPC=1` until their current UI payloads are captured. +On the current `flow.google.com` batch transport, every Omni 1.1 Flash video mode exposed by Flow's Video composer is supported and live-verified: -| Mode | Batch status | Endpoint | Internal model family | +| Mode | Batch status | Endpoint | Current wire | |---|---|---|---| -| Text to video | **supported** | `POST /api/flow/generate-video-omni-text` | `abra_t2v_<duration>s` | -| First frame to video | **supported** | `POST /api/flow/generate-video` with `model_family=omni_flash` | `abra_i2v_<duration>s` | -| First + Last frame to video | not yet ported | `POST /api/flow/generate-video` | `abra_i2v_<duration>s` (legacy only) | -| References to video | not yet ported | `POST /api/flow/generate-video-omni` | `abra_r2v_<duration>s` (legacy only) | +| Text to video | **supported** | `POST /api/flow/generate-video-omni-text` | `YhhmEf` + `abra_t2v_<duration>s` | +| First frame to video | **supported** | `POST /api/flow/generate-video` with `model_family=omni_flash` | `eb1hJf` + `abra_i2v_<duration>s` | +| First + Last frame to video | **supported** | `POST /api/flow/generate-video` with `model_family=omni_flash` + `end_image_media_id` | `nprQif` + `omni_flash_i2v_<duration>s_first_last` | +| Ingredients / references to video | **supported** | `POST /api/flow/generate-video-omni` or `/generate-video-refs` | `MZZa6b` + `abra_r2v_<duration>s` | -Text-to-video durations are `4`, `6`, `8`, and `10` seconds. Supported aspect ratios are: +Reference-conditioned modes support durations `4`, `6`, `8`, and `10` seconds, resolutions `360p` and `720p`, and: - `VIDEO_ASPECT_RATIO_PORTRAIT` (`9:16`) - `VIDEO_ASPECT_RATIO_LANDSCAPE` (`16:9`) -The migrated `YhhmEf` wire was live-verified with `abra_t2v_4s`; the downloaded result was exactly 4.000 seconds at 1280x720/24 fps. First-frame I2V was re-captured from the live Flow UI on 2026-09-14: it uses RPC `eb1hJf`, the normal migrated I2V payload shape, and `abra_i2v_<duration>s`. A live API smoke test completed successfully and resolved its signed video URL through the existing batch operation poller. +For 360p Flow uses `_360p` model variants. The 360p first-frame and Ingredients payloads also carry the same low-resolution option slots captured from the live UI. First+Last uses its dedicated `nprQif` payload and model family. -Polling differs by migrated mode: text-to-video returns workflow/media descriptors and uses `/api/flow/check-omni-status`; first-frame I2V returns a `flowkitPolling.mode = batch_operation` descriptor and uses `/api/flow/check-status` with its `operations` array. +The migrated wires were re-captured from the live Flow UI on 2026-09-14. Live API smoke tests completed successfully for First frame, First+Last, and Ingredients/R2V and resolved signed `flow-content.google` video URLs through the batch operation poller. -## End-to-end integration flow +Polling differs only for text-to-video: text-to-video returns `flowkitPolling.mode=batch_media` and uses `/api/flow/check-omni-status`; all image/reference-conditioned modes return `flowkitPolling.mode=batch_operation` and use `/api/flow/check-status` with their `operations` array. -For migrated Omni, an integration agent should use the polling mode returned by the submit response: +## End-to-end integration flow 1. Check `/health` and `/api/flow/status`. -2. Submit either text-to-video or first-frame I2V. -3. Persist the complete `flowkitPolling` object returned by the submit. +2. Submit the desired Omni mode. +3. Persist the complete `flowkitPolling` object returned by the submit before doing anything else. 4. If `mode=batch_media`, poll `/api/flow/check-omni-status` using `project_id` + `workflows`. 5. If `mode=batch_operation`, poll `/api/flow/check-status` using `project_id` + `operations`. -6. On pending state, continue polling; on failure, stop; on success, immediately download the returned signed video URL. +6. Continue on pending state; stop on failure; on success immediately download the signed video URL. 7. Store the downloaded video in durable storage because Google URLs are signed and short-lived. -Example 4-second submit: +Example text-to-video submit: ```bash curl -fsS -X POST "$FLOWKIT_BASE_URL/api/flow/generate-video-omni-text" \ @@ -65,11 +65,11 @@ curl -fsS -X POST "$FLOWKIT_BASE_URL/api/flow/generate-video-omni-text" \ }' ``` -Do not send Omni workflow names to the legacy Veo `batchCheckAsyncVideoGenerationStatus` operation poller. Do not use the obsolete `/v1/media/<primaryMediaId>` polling path. +Do not convert workflow names into operation handles, and do not convert batch operation handles into workflow names. Persist and replay the polling descriptor exactly as FlowKit returns it. ## Supplying images -This section applies to the older frame/reference Omni modes. Those generation modes are currently refused on `USE_BATCH_RPC=1` until their migrated payloads are captured; image upload itself may still be used by supported Veo workflows. +Frame, First+Last, and Ingredients/R2V all consume Flow media IDs. Upload or reuse the reference images first, then pass their media IDs to the generation endpoint. `POST /api/flow/upload-image` is not a multipart upload endpoint. Its `file_path` is an absolute path on the **FlowKit server**, not on the calling server. @@ -117,12 +117,13 @@ curl -fsS -X POST "$FLOWKIT_BASE_URL/api/flow/generate-video" \ "project_id": "FLOW_PROJECT_ID", "scene_id": "JOB_ID", "duration_s": 4, + "resolution": "720p", "aspect_ratio": "VIDEO_ASPECT_RATIO_PORTRAIT", "user_paygate_tier": "PAYGATE_TIER_ONE" }' ``` -This uses `batchAsyncGenerateVideoStartImage`. +This uses batch RPC `eb1hJf` with `abra_i2v_<duration>s` (or the `_360p` variant). ## First + Last frame to video @@ -137,12 +138,13 @@ curl -fsS -X POST "$FLOWKIT_BASE_URL/api/flow/generate-video" \ "project_id": "FLOW_PROJECT_ID", "scene_id": "JOB_ID", "duration_s": 4, + "resolution": "720p", "aspect_ratio": "VIDEO_ASPECT_RATIO_PORTRAIT", "user_paygate_tier": "PAYGATE_TIER_ONE" }' ``` -This uses `batchAsyncGenerateVideoStartAndEndImage` and sends both `startImage` and `endImage`. +This uses batch RPC `nprQif` with the dedicated `omni_flash_i2v_<duration>s_first_last` model family. ## References to video @@ -157,86 +159,71 @@ curl -fsS -X POST "$FLOWKIT_BASE_URL/api/flow/generate-video-omni" \ "project_id": "FLOW_PROJECT_ID", "scene_id": "JOB_ID", "duration_s": 4, + "resolution": "720p", "aspect_ratio": "VIDEO_ASPECT_RATIO_LANDSCAPE", "user_paygate_tier": "PAYGATE_TIER_ONE" }' ``` -The compatible generic endpoint is `POST /api/flow/generate-video-refs` with the same fields plus `"model_family":"omni_flash"`. +The compatible generic endpoint is `POST /api/flow/generate-video-refs` with the same fields plus `"model_family":"omni_flash"`. Both routes use batch RPC `MZZa6b`. ## Submit response and polling -Persist the entire normalized polling descriptor returned by submit: +Image/reference-conditioned Omni submits return normal batch operation polling: ```json { + "operations": [ + {"operation":{"name":"OPERATION_ID"},"status":"MEDIA_GENERATION_STATUS_PENDING"} + ], + "model": "abra_r2v_4s", + "duration_s": 4, + "resolution": "720p", "flowkitPolling": { - "mode": "project_media", + "mode": "batch_operation", "project_id": "FLOW_PROJECT_ID", - "workflows": [ - { - "name": "WORKFLOW_NAME", - "primary_media_id": "PRIMARY_MEDIA_ID", - "project_id": "FLOW_PROJECT_ID" - } + "operations": [ + {"operation":{"name":"OPERATION_ID"},"status":"MEDIA_GENERATION_STATUS_PENDING"} ] } } ``` -Poll using those values without transforming workflow names into operation handles: +Poll that descriptor without transforming it: ```bash -curl -fsS -X POST "$FLOWKIT_BASE_URL/api/flow/check-omni-status" \ +curl -fsS -X POST "$FLOWKIT_BASE_URL/api/flow/check-status" \ -H 'Content-Type: application/json' \ -d '{ "project_id": "FLOW_PROJECT_ID", - "workflows": [ - { - "name": "WORKFLOW_NAME", - "primary_media_id": "PRIMARY_MEDIA_ID", - "project_id": "FLOW_PROJECT_ID" - } - ], - "include_encoded_video": false + "operations": [ + {"operation":{"name":"OPERATION_ID"},"status":"MEDIA_GENERATION_STATUS_PENDING"} + ] }' ``` -The generic `POST /api/flow/check-status` endpoint also accepts the same `workflows` and automatically selects Omni project polling. - -Pending response: - -```json -{ - "project_id": "FLOW_PROJECT_ID", - "done": false, - "status": "PENDING", - "workflows": [{"done":false,"status":"PENDING"}] -} -``` - -Successful response: +When complete, the operation contains the generated media ID and signed video URL: ```json { - "project_id": "FLOW_PROJECT_ID", - "done": true, - "status": "COMPLETED", - "workflows": [ + "operations": [ { - "done": true, - "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL", - "media": { - "media_id": "PRIMARY_MEDIA_ID", - "url": "https://flow-content.google/...", - "encoded_video_available": false - } + "operation": { + "name": "OPERATION_ID", + "metadata": { + "video": { + "mediaId": "MEDIA_ID", + "fifeUrl": "https://flow-content.google/video/..." + } + } + }, + "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL" } ] } ``` -Keep `include_encoded_video` set to `false`. FlowKit resolves the signed download URL without buffering the MP4 through Chrome or the extension bridge. +Text-to-video remains the exception: it returns `mode=batch_media` with workflow/media descriptors and is polled through `/api/flow/check-omni-status`. ## Retry and failure policy @@ -278,15 +265,15 @@ Mappings live in `agent/models.json`: } ``` -The mappings can be changed through `PATCH /api/models` if Google rotates internal keys. Treat configured credit-cost estimates as informational only: Google can change pricing, so use `GET /api/flow/credits` and the submit response's `remainingCredits` where available. +The legacy mappings above remain for the pre-migration transport. On the migrated batch transport, current Flow wire names are derived from duration + resolution exactly as live-captured: First frame uses `abra_i2v_*`, First+Last uses `omni_flash_i2v_*_first_last`, and Ingredients uses `abra_r2v_*`, with `_360p` appended for 360p. The mappings can still be changed through `PATCH /api/models` for legacy transport if Google rotates old keys. Treat configured credit-cost estimates as informational only: Google can change pricing, so use `GET /api/flow/credits` and the submit response's `remainingCredits` where available. ## Minimal agent checklist - Use the `/api/flow/...` paths exactly. - Select Omni explicitly with `model_family: "omni_flash"` on shared endpoints. - Upload inputs once and reuse returned Flow media IDs. -- Persist `project_id`, workflow `name`, and `primary_media_id` before polling. -- Poll workflows through project media status, never through legacy Veo operations. +- Persist the entire returned `flowkitPolling` descriptor before polling. +- Use `/check-status` for `batch_operation` and `/check-omni-status` for `batch_media`; never transform one receipt type into the other. - Download signed output URLs immediately into durable project storage. - Do not log Google auth data, extension messages, or complete signed URLs. - Use a stable `scene_id`/job ID for traceability. diff --git a/tests/unit/test_flow_batch.py b/tests/unit/test_flow_batch.py index db1f3457a..2a0804593 100644 --- a/tests/unit/test_flow_batch.py +++ b/tests/unit/test_flow_batch.py @@ -155,6 +155,42 @@ def test_a_hand_reframed_crop_overrides_the_default(self): crop = [None, 0.1, 1, 0.9] assert inner(fb.video_request("go", self.PID, "mid", crop=crop))[0][0][4][5] == crop + def test_omni_first_frame_360p_matches_live_eb1hjf_shape(self): + payload = inner(fb.omni_first_frame_request( + "move", self.PID, "start-mid", duration_s=4, resolution="360p", + aspect="VIDEO_ASPECT_RATIO_LANDSCAPE", + )) + request = payload[0][0] + assert request[1] == "abra_i2v_4s_360p" + assert request[2] == fb.VIDEO_ASPECT_LANDSCAPE + assert request[4][1] == "start-mid" + assert request[-1] == [4] + assert json.loads(fb.omni_first_frame_request("x", self.PID, "m"))[0][0][0] == fb.RPC_GEN_VIDEO + + def test_omni_first_last_matches_live_nprqif_shape(self): + freq = fb.omni_first_last_request( + "morph", self.PID, "start", "end", duration_s=6, resolution="720p", + aspect="VIDEO_ASPECT_RATIO_PORTRAIT", + ) + assert json.loads(freq)[0][0][0] == fb.RPC_GEN_VIDEO_FIRST_LAST + request = inner(freq)[0][0] + assert request[1] == "omni_flash_i2v_6s_first_last" + assert request[2] == fb.VIDEO_ASPECT_PORTRAIT + assert request[4][1] == "start" + assert request[5][1] == "end" + + def test_omni_reference_matches_live_mzza6b_shape(self): + freq = fb.omni_reference_video_request( + "keep refs", self.PID, ["a", "b"], duration_s=4, resolution="360p", + aspect="VIDEO_ASPECT_RATIO_LANDSCAPE", + ) + assert json.loads(freq)[0][0][0] == fb.RPC_GEN_VIDEO_REFERENCES + request = inner(freq)[0][0] + assert request[1] == [[None, "a"], [None, "b"]] + assert request[2] == "abra_r2v_4s_360p" + assert request[3] == fb.VIDEO_ASPECT_LANDSCAPE + assert request[-1] == [4] + def test_text_video_matches_the_captured_yhhmef_shape(self): payload = inner(fb.text_video_request( "a boat", self.PID, diff --git a/tests/unit/test_omni_flash.py b/tests/unit/test_omni_flash.py index e1a2998a3..805418fd4 100644 --- a/tests/unit/test_omni_flash.py +++ b/tests/unit/test_omni_flash.py @@ -586,9 +586,7 @@ async def test_submit_rejects_empty_reference_set(): ) -class TestRemainingUnportedOmniBatchModesAreRefused: - """Only start+end/reference remain blocked; first-frame I2V is migrated.""" - +class TestMigratedOmniReferenceBatchModes: @pytest.fixture(autouse=True) def batch_transport(self, monkeypatch): monkeypatch.setattr(omni_flash, "USE_BATCH_RPC", True) @@ -597,25 +595,64 @@ def batch_transport(self, monkeypatch): def client(self): with patch("agent.services.omni_flash.get_flow_client") as factory: stub = MagicMock() - stub._send = AsyncMock() + pid = "11111111-2222-3333-4444-555555555555" + stub._batch_project_id.return_value = pid + stub._batch_payload = AsyncMock(return_value=[ + None, 50, [["op-ref-1", pid, "scene-1", None]], + ]) factory.return_value = stub yield stub - async def test_first_last_names_the_gap_and_sends_nothing(self, client): + async def test_first_last_uses_nprqif_and_batch_operation_polling(self, client): result = await generate_omni_flash_first_last_video( - start_image_media_id="a", end_image_media_id="b", - prompt="go", project_id="pid") - assert "UNSUPPORTED_ON_BATCH_API" in result["error"] - client._send.assert_not_called() - - async def test_reference_to_video_names_the_gap_and_sends_nothing(self, client): + start_image_media_id="start", end_image_media_id="end", + prompt="morph", project_id="pid", duration_s=4, + resolution="360p", aspect_ratio="VIDEO_ASPECT_RATIO_LANDSCAPE") + assert result["status"] == 200 + assert result["data"]["model"] == "omni_flash_i2v_4s_first_last_360p" + assert result["data"]["resolution"] == "360p" + assert result["data"]["flowkitPolling"]["mode"] == "batch_operation" + rpcid, freq, captcha = client._batch_payload.await_args.args[:3] + assert rpcid == omni_flash.fb.RPC_GEN_VIDEO_FIRST_LAST + assert captcha == omni_flash.fb.CAPTCHA_VIDEO + payload = __import__("json").loads(__import__("json").loads(freq)[0][0][1]) + req = payload[0][0] + assert req[1] == "omni_flash_i2v_4s_first_last_360p" + assert req[4][1] == "start" + assert req[5][1] == "end" + client._remember_operation.assert_called_once_with( + "op-ref-1", "11111111-2222-3333-4444-555555555555") + + async def test_reference_to_video_uses_mzza6b_and_all_references(self, client): result = await generate_omni_flash_video( - reference_media_ids=["a"], prompt="go", project_id="pid") - assert "UNSUPPORTED_ON_BATCH_API" in result["error"] - client._send.assert_not_called() - - async def test_the_message_points_to_supported_text_to_video(self, client): - result = await generate_omni_flash_video( - reference_media_ids=["a"], prompt="go", project_id="pid") - assert "image-to-video and text-to-video are supported" in result["error"] - assert "reference-to-video" in result["error"] + reference_media_ids=["a", "b", "c"], prompt="keep all refs", + project_id="pid", duration_s=6, resolution="720p", + aspect_ratio="VIDEO_ASPECT_RATIO_PORTRAIT") + assert result["status"] == 200 + assert result["data"]["model"] == "abra_r2v_6s" + assert result["data"]["flowkitPolling"]["mode"] == "batch_operation" + rpcid, freq, _captcha = client._batch_payload.await_args.args[:3] + assert rpcid == omni_flash.fb.RPC_GEN_VIDEO_REFERENCES + payload = __import__("json").loads(__import__("json").loads(freq)[0][0][1]) + req = payload[0][0] + assert req[1] == [[None, "a"], [None, "b"], [None, "c"]] + assert req[2] == "abra_r2v_6s" + assert req[3] == omni_flash.fb.VIDEO_ASPECT_PORTRAIT + + async def test_reference_360p_uses_live_wire_model_and_quality_slot(self, client): + await generate_omni_flash_video( + reference_media_ids=["a", "b"], prompt="refs", project_id="pid", + duration_s=4, resolution="360p", + aspect_ratio="VIDEO_ASPECT_RATIO_LANDSCAPE") + _rpcid, freq, _captcha = client._batch_payload.await_args.args[:3] + payload = __import__("json").loads(__import__("json").loads(freq)[0][0][1]) + req = payload[0][0] + assert req[2] == "abra_r2v_4s_360p" + assert req[-1] == [4] + + async def test_invalid_resolution_is_rejected_before_submit(self, client): + with pytest.raises(ValueError, match="resolution must be 360p or 720p"): + await generate_omni_flash_first_frame_video( + start_image_media_id="a", prompt="go", project_id="pid", + resolution="1080p") + client._batch_payload.assert_not_called() From d56a5cc26ff296b8761771a96a8ae1b80744000d Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Tue, 15 Sep 2026 23:51:59 +0700 Subject: [PATCH 16/68] chore(flow): remove the REST transport Flow stopped authenticating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flow moved to flow.google.com in September 2026 and stopped minting the `Bearer ya29.…` the aisandbox-pa REST path needed. That path has been unreachable ever since, kept behind USE_BATCH_RPC=0 as a post-mortem tool. Keeping it cost more than it was worth. A dead implementation sitting beside a live one is a template: the Omni module was written against it, so when the migration landed on FlowClient it missed Omni entirely, and Omni frame and reference generation have been returning UNSUPPORTED_ON_BATCH_API since. Deleting the template is what stops the next copy. Removed: the ten _legacy_* methods, the twelve `if not USE_BATCH_RPC` branches in FlowClient (ten dispatching to those methods, one returning an inline note from refresh_project_urls, and upscale_image's, which arrived with the migrated image API this rebased onto), _build_url/_client_context, ENDPOINTS, GOOGLE_FLOW_API, GOOGLE_API_KEY, the browser-fingerprint pools and agent/services/headers.py that fed them, the tRPC polling branch in omni_flash, and omni_flash's _annotate_polling, whose only callers were the REST submits. RECAPTCHA_SITE_KEY went too: it had no Python caller, and the extension hardcodes its own copy in injected.js, so the env var was a knob that changed nothing. Git history has all of it if a payload is ever needed. One deliberate behavior change, in the unported Omni modes. Previously the capability check ran first, so a bad duration on frame-to-video answered 502 UNSUPPORTED_ON_BATCH_API. Now validation runs first, so it answers 400 "duration 5s is unsupported". A caller who can fix the duration should hear about the duration; the gap it cannot fix comes after. No caller exists today either way — the pipeline uses model_family=veo. The extension keeps its api_request and trpc_request handlers, so an extension updated ahead of its agent still serves an older one. To be clear about what that is worth: on any profile that postdates the migration nothing in the extension reaches aisandbox-pa either — sendTelemetry early-returns without a flowKey that is no longer minted. So the host permission is held by the backward-compat proxy alone, and the two now share one lifetime: when the oldest agent in the wild speaks batch_rpc, the handlers and manifest.json's aisandbox-pa entry go together. That is a manifest bump and a user-visible reload, so it is its own change. Tests: test_omni_flash.py was pinned to the legacy path by a module-level autouse fixture setting USE_BATCH_RPC=False, so all 34 of its tests would have errored on the missing attribute. 10 asserted REST or tRPC contracts for code this commit deletes and went with it; the remaining 24 — the model-key mapping, the input validation, the batch-path tests — were kept, and one new test pins the seven-reference boundary that a deleted test used to cover. Two tests added for the retry branch in generate_scene_video. It used to be gated on `bare_uuid and not USE_BATCH_RPC`, so it was dead on the only transport that exists and had no coverage — and it is the one branch where a wrong answer abandons a render Flow is already paying for and starts a second. Checked by forcing the branch off: the test fails. A comment in operations.py that described that resubmit was removed too; left in place it reads as an instruction to reintroduce it. agent/services/flow_client.py 1290 -> 921 agent/services/omni_flash.py 672 -> 350 agent/config.py 158 -> 111 211 passed, 3 failed — the 3 are pre-existing on main (test_processor.py patches processor._retry_state, which does not exist). Golden envelope tests pass, so the Veo submit payload is unchanged byte-for-byte. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DB27wvPQ195KGiQ6VZfCDf --- README.md | 11 +- agent/api/flow.py | 12 +- agent/api/projects.py | 8 +- agent/config.py | 57 +-- agent/sdk/services/operations.py | 21 +- agent/services/flow_client.py | 409 +--------------------- agent/services/headers.py | 40 --- agent/services/omni_flash.py | 364 ++------------------ docs/OMNI_FLASH.md | 2 +- extension/background.js | 14 +- skills/fk-doctor.md | 38 +- skills/fk-refresh-urls.md | 2 +- tests/unit/test_flow_client_batch.py | 1 - tests/unit/test_omni_flash.py | 497 +++++---------------------- tests/unit/test_operations.py | 54 +++ 15 files changed, 229 insertions(+), 1301 deletions(-) delete mode 100644 agent/services/headers.py diff --git a/README.md b/README.md index 8084b1de3..997f52246 100644 --- a/README.md +++ b/README.md @@ -189,8 +189,8 @@ One signed-in Flow tab has to stay open; nothing here works headless. > `aisandbox-pa.googleapis.com` REST API has no caller: the `Bearer ya29.…` it > needed stopped being minted. If you are upgrading from an older Flow Kit, > reload the extension (v0.3.0+) and pin `FLOW_PROJECT_ID` — see -> [Configuration](#configuration). The legacy path is still there behind -> `USE_BATCH_RPC=0`, but it is a post-mortem tool, not a fallback. +> [Configuration](#configuration). The REST path has been removed; `git log` +> has it if a payload is ever needed for reference. ## Quick Start @@ -240,7 +240,6 @@ You can also pass `flow_project_id` per project on `POST /api/projects`. | Env var | Default | What it does | |---------|---------|--------------| | `FLOW_PROJECT_ID` | — | The Flow project every RPC is scoped to. Required. | -| `USE_BATCH_RPC` | `1` | `0` falls back to the pre-migration REST path (dead auth). | | `FLOW_ALLOW_DEGRADED` | `0` | `1` lets scene chaining and r2v fall back to plain i2v instead of failing. | | `DEFAULT_PAYGATE_TIER` | `PAYGATE_TIER_TWO` | Carried for the DB and dashboard; no longer selects a model. | @@ -690,7 +689,6 @@ agent/ │ # flow, models, providers, reviews, materials, music, tts) ├── services/ │ ├── flow_client.py # WS bridge to extension -│ ├── headers.py # Randomized browser headers │ ├── tts.py # OmniVoice TTS (subprocess-based) │ ├── scene_chain.py # Continuation scene logic │ ├── video_reviewer.py # AI vision review — contact sheet + claude/agy/codex CLI dispatch @@ -805,13 +803,13 @@ These arrive in the response body as `data.error.details[].reason`. The worker a | Status | Source | Meaning | Handling | |--------|--------|---------|----------| | **400** | Flow API | Invalid payload, UNSAFE_GENERATION, entity not found (sometimes) | Route by `details.reason` — some are auto-recoverable, others terminal | -| **401** | Flow API (legacy path only) | Bearer expired — on a post-migration profile it was never minted | Switch to the batch path (`USE_BATCH_RPC=1`) | +| **401** | Flow API | Should not occur — batchexecute authenticates in the page, not with a bearer | Check the Flow tab is signed in; see `NO_AT_TOKEN` | | **403** | Extension (`background.js:432`) | `CAPTCHA_FAILED`, `NO_FLOW_TAB`, or `MODEL_ACCESS_DENIED` | CAPTCHA → retry loop; NO_FLOW_TAB → fail (user must open Flow); tier → fail | | **404** | Flow API | `media_id` not found (expired upload) | Same as "Requested entity was not found" — auto re-upload | | **429** | Flow API | Rate limited / quota | Back off + retry; if `USER_QUOTA_REACHED` appears, fail | | **500** | Flow backend **or** extension fetch exception (`background.js:504`) | Transient server error OR network drop during fetch | Retry with exponential backoff | | **502** | FastAPI default (`agent/api/flow.py:80,92`) | Extension returned error without explicit status | Retry; check extension health | -| **503** | FastAPI (`api/flow.py`) | "Extension not connected" or `NO_FLOW_KEY` | Worker waits for reconnect — status set to PENDING, not FAILED | +| **503** | FastAPI (`api/flow.py`) | "Extension not connected" | Worker waits for reconnect — status set to PENDING, not FAILED | | **504** | Agent | 60s timeout waiting for extension WS response | Treated as transient; re-queue PENDING | Status-code detection logic lives in `agent/worker/_parsing.py:_is_error` — a result is an error if `result.error` is set, `status >= 400`, **or** `data.error` is present. @@ -825,7 +823,6 @@ String patterns in `error_message` that the worker recognizes: | `Extension not connected` | Chrome extension offline or WS dropped | 503 returned; worker re-queues PENDING and waits | | `extension reconnected` / `extension disconnected` | WS bounce mid-request | Re-queue PENDING without incrementing `retry_count` | | `extension_switched` | User switched Flow tabs mid-generation | Re-queue PENDING | -| `NO_FLOW_KEY` | Extension has no captured bearer token — **legacy path only**, expected on the batch path | Only meaningful with `USE_BATCH_RPC=0` | | `NO_AT_TOKEN` | Flow tab is signed out, on an interstitial, or still booting | Open `flow.google.com`, sign in, let the app load | | `NO_FLOW_PROJECT` | No Flow project to scope the RPC to | Pin `FLOW_PROJECT_ID` — **terminal, not retried** | | `UNSUPPORTED_ON_BATCH_API` | Upscale / r2v / chaining — payload never captured | See `docs/CAPTURE.md` — **terminal, not retried** | diff --git a/agent/api/flow.py b/agent/api/flow.py index 5aeed8fac..0d94b780d 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -3,7 +3,7 @@ from pydantic import BaseModel, Field from typing import Literal, Optional -from agent.config import USE_BATCH_RPC, FLOW_PROJECT_ID, FLOW_ALLOW_DEGRADED +from agent.config import FLOW_PROJECT_ID, FLOW_ALLOW_DEGRADED from agent.services.flow_client import get_flow_client from agent.services.omni_flash import ( check_omni_flash_status, @@ -122,15 +122,17 @@ class UpscaleImageRequest(BaseModel): @router.get("/status") async def extension_status(): - """Extension health, and which transport it is being asked to speak. + """Extension health. - `flow_key_present` is a legacy-path signal: the batchexecute path has no - bearer token at all, so false is expected there rather than a fault. + `flow_key_present: false` is expected, not a fault: batchexecute + authenticates in the page and there is no bearer token to capture. """ client = get_flow_client() return { "connected": client.connected, - "transport": "batch" if USE_BATCH_RPC else "legacy_rest", + # One transport now. The key stays so the documented pre-flight check + # (CLAUDE.md) keeps reading {"transport": "batch", ...}. + "transport": "batch", "flow_project_id": FLOW_PROJECT_ID or None, "allow_degraded": FLOW_ALLOW_DEGRADED, "flow_key_present": client._flow_key is not None, diff --git a/agent/api/projects.py b/agent/api/projects.py index 600ebe8a9..4b87aa847 100644 --- a/agent/api/projects.py +++ b/agent/api/projects.py @@ -7,7 +7,7 @@ from fastapi import APIRouter, HTTPException from pydantic import BaseModel -from agent.config import BASE_DIR, USE_BATCH_RPC +from agent.config import BASE_DIR from agent.models.project import Project, ProjectCreate, ProjectUpdate from agent.models.character import Character from agent.sdk.persistence.sqlite_repository import SQLiteRepository @@ -172,9 +172,9 @@ async def create(body: ProjectCreate): detected_tier = await _detect_user_tier(client) - # On the batch path Flow no longer creates projects for us — the uuid comes - # from the request or from FLOW_PROJECT_ID. The legacy path still mints one. - flow_project_id = client.flow_project_id(body.flow_project_id) if USE_BATCH_RPC else None + # Flow no longer creates projects for us — the uuid comes from the request + # or from FLOW_PROJECT_ID. + flow_project_id = client.flow_project_id(body.flow_project_id) if flow_project_id: logger.info("Flow project reused: %s", flow_project_id) else: diff --git a/agent/config.py b/agent/config.py index a02a51bd7..743198e2d 100644 --- a/agent/config.py +++ b/agent/config.py @@ -15,19 +15,12 @@ WS_HOST = os.environ.get("WS_HOST", "127.0.0.1") WS_PORT = int(os.environ.get("WS_PORT", "9222")) -# ─── Google Flow API ──────────────────────────────────────── -# Legacy REST host. Flow moved to flow.google.com in September 2026 and stopped -# minting the `Bearer ya29.…` this host needs, so these are only reachable with -# USE_BATCH_RPC=0 on a browser profile that still has an old token. -GOOGLE_FLOW_API = "https://aisandbox-pa.googleapis.com" -GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY", "AIzaSyBtrm0o5ab1c-Ec8ZuLcGt3oJAA5VWt3pY") -RECAPTCHA_SITE_KEY = os.environ.get("RECAPTCHA_SITE_KEY", "6LdsFiUsAAAAAIjVDZcuLhaHiDn5nnHVXVRQGeMV") - -# ─── Flow batchexecute (the current path) ─────────────────── + +# ─── Flow batchexecute ────────────────────────────────────── # Every call is signed in the page with the session cookie plus a per-page `at` -# token, so the extension runs it inside a signed-in flow.google.com tab. Set -# USE_BATCH_RPC=0 only to fall back to the dead REST path for a post-mortem. -USE_BATCH_RPC = os.environ.get("USE_BATCH_RPC", "1") == "1" +# token, so the extension runs it inside a signed-in flow.google.com tab. This +# is the only transport; the REST path it replaced was removed once Flow stopped +# minting the bearer it needed. # The Flow project every RPC is scoped to. Project creation went with the old # labs.google tRPC endpoint, so a project is made once in the Flow UI and its @@ -66,20 +59,6 @@ # newly introduced image models do not require a Flow Kit release. DEFAULT_IMAGE_MODEL = _MODELS.get("default_image_model", "NANO_BANANA_PRO") -# ─── API Endpoints ─────────────────────────────────────────── -ENDPOINTS = { - "generate_images": "/v1/projects/{project_id}/flowMedia:batchGenerateImages", - "generate_video": "/v1/video:batchAsyncGenerateVideoStartImage", - "generate_video_start_end": "/v1/video:batchAsyncGenerateVideoStartAndEndImage", - "generate_video_references": "/v1/video:batchAsyncGenerateVideoReferenceImages", - "upscale_video": "/v1/video:batchAsyncGenerateVideoUpsampleVideo", - "upscale_image": "/v1/flow/upsampleImage", - "upload_image": "/v1/flow/uploadImage", - "check_video_status": "/v1/video:batchCheckAsyncVideoGenerationStatus", - "get_credits": "/v1/credits", - "get_media": "/v1/media/{media_id}", -} - # ─── Output Directories ───────────────────────────────────── OUTPUT_DIR = BASE_DIR / "output" SHARED_OUTPUT_DIR = OUTPUT_DIR / "_shared" @@ -131,29 +110,3 @@ def _load_suno_key() -> str: SUNO_POLL_INTERVAL = int(os.environ.get("SUNO_POLL_INTERVAL", "5")) SUNO_POLL_TIMEOUT = int(os.environ.get("SUNO_POLL_TIMEOUT", "600")) -# ─── Header Randomization Pools ───────────────────────────── -USER_AGENTS = [ - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36", - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36", - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", -] - -CHROME_VERSIONS = [ - '"Google Chrome";v="109", "Chromium";v="109"', - '"Google Chrome";v="110", "Chromium";v="110"', - '"Google Chrome";v="111", "Chromium";v="111"', - '"Google Chrome";v="113", "Not-A.Brand";v="24"', - '"Google Chrome";v="120", "Not-A.Brand";v="24"', - '"Google Chrome";v="141", "Not?A_Brand";v="8", "Chromium";v="141"', -] - -BROWSER_VALIDATIONS = [ - "SgDQo8mvrGRdD61Pwo8wyWVgYgs=", -] - -CLIENT_DATA = [ - "CKi1yQEIh7bJAQiktskBCKmdygEIvorLAQiUocsBCIagzQEYv6nKARjRp88BGKqwzwE=", -] diff --git a/agent/sdk/services/operations.py b/agent/sdk/services/operations.py index b0199e82e..e7157cd45 100644 --- a/agent/sdk/services/operations.py +++ b/agent/sdk/services/operations.py @@ -40,7 +40,7 @@ def _char_matches(c: dict, name_set: set) -> bool: import aiohttp from agent.db import crud -from agent.config import USE_BATCH_RPC, VIDEO_POLL_INTERVAL, VIDEO_POLL_TIMEOUT +from agent.config import VIDEO_POLL_INTERVAL, VIDEO_POLL_TIMEOUT from agent.utils.paths import scene_4k_path from agent.utils.slugify import slugify from agent.worker._parsing import ( @@ -447,28 +447,19 @@ async def generate_scene_video(self, scene: dict, orientation: str, base_prompt = scene.get("video_prompt") or scene.get("prompt", "") prompt = await _build_video_prompt(base_prompt, scene, pid) - # Check if already submitted (op_name saved from previous attempt) - # OLD schema (Lite/Fast/Ultra): op_name is "models/.../operations/..." → re-poll via check_video_status - # NEW schema (Low Priority workflow): op_name is bare UUID → cannot recover (need primary_media_id - # which isn't persisted yet); fall through and resubmit (Low Priority is free, duplicate is OK) + # Already submitted on a previous attempt? Re-poll it. existing_op = None if request_id: req_row = await crud.get_request(request_id) existing_op = req_row.get("request_id") if req_row else None - # A bare uuid means different things on the two transports. On the - # legacy path it is a Low Priority workflow name that cannot be - # re-polled, so the retry resubmits. On the batch path it is the - # operation id, and looking it up in the project listing is exactly - # what the status poll does — resubmitting there would abandon a - # running render and pay for a second one. - bare_uuid = bool(existing_op and len(existing_op) == 36 and existing_op.count("-") == 4) - looks_like_workflow_uuid = bare_uuid and not USE_BATCH_RPC - if existing_op and not looks_like_workflow_uuid: + # A bare uuid is the operation id, and looking it up in the project + # listing is exactly what the status poll does — resubmitting instead + # would abandon a running render and pay for a second one. + if existing_op: logger.info("Video gen already submitted (op=%s), re-polling", existing_op[:30]) operations = [{"operation": {"name": existing_op}, "status": "MEDIA_GENERATION_STATUS_PENDING"}] return await _poll_operations(self._client, operations) - # else: workflow UUID — fall through and resubmit fresh submit_result = await self._client.generate_video( start_image_media_id=image_media_id, diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index be56e708a..92c1b003f 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -4,15 +4,18 @@ Agent runs a WS server. Extension connects as client. Agent sends requests, extension executes them in browser context (residential IP, cookies, reCAPTCHA). -Two transports live here. The current one is Flow's ``batchexecute`` endpoint on -flow.google.com, whose calls only a signed-in page can sign — the agent builds -the envelope, the extension runs it in the tab (see :mod:`agent.services.flow_batch`). -The old REST path against ``aisandbox-pa.googleapis.com`` is kept behind -``USE_BATCH_RPC=0``; it needs a ``Bearer ya29.…`` that Flow stopped minting in -the September 2026 migration, so it is a post-mortem tool, not a fallback. - -Both shape their answers the same way, so everything downstream — the worker's -parsers, the operation poller, the scene/character updaters — is transport-blind. +One transport: Flow's ``batchexecute`` endpoint on flow.google.com, whose calls +only a signed-in page can sign — the agent builds the envelope, the extension +runs it in the tab (see :mod:`agent.services.flow_batch`). + +The REST path against ``aisandbox-pa.googleapis.com`` that preceded it is gone. +It needed a ``Bearer ya29.…`` that Flow stopped minting in the September 2026 +migration, so it could not run; keeping it only gave the next contributor a +second place to implement things. Git history has it if a payload is ever needed. + +Answers are shaped like the old REST ones, so everything downstream — the +worker's parsers, the operation poller, the scene/character updaters — reads one +shape and never learns where it came from. """ import asyncio import json @@ -22,14 +25,12 @@ from typing import Optional from agent.config import ( - GOOGLE_FLOW_API, GOOGLE_API_KEY, ENDPOINTS, - VIDEO_MODELS, UPSCALE_MODELS, IMAGE_MODELS, VIDEO_POLL_TIMEOUT, - USE_BATCH_RPC, FLOW_PROJECT_ID, FLOW_ALLOW_DEGRADED, + VIDEO_MODELS, + FLOW_PROJECT_ID, FLOW_ALLOW_DEGRADED, DEFAULT_PAYGATE_TIER, ) from agent import config as _config from agent.services import flow_batch as fb -from agent.services.headers import random_headers logger = logging.getLogger(__name__) @@ -368,17 +369,8 @@ async def refresh_project_urls(self, project_id: str) -> dict: The batch path can do this properly: the media rpc answers a media id with a freshly signed url, so we walk the project's scenes and entities - and refresh each id we hold. The legacy path could not — its media - endpoint returned base64 content rather than a url — so it still asks - the user to open the project in Chrome and let the intercept catch them. + and refresh each id we hold. """ - if not USE_BATCH_RPC: - logger.info("URL refresh requested for project %s — legacy path has no " - "url-serving media endpoint", project_id[:12]) - return {"refreshed": 0, "found": 0, "note": "Legacy REST path: no URL refresh. " - "Open the project in Google Flow in Chrome and let the extension " - "intercept fresh URLs, or set USE_BATCH_RPC=1."} - from agent.db import crud # (media_id, kind) -> the scene/character fields it should land in @@ -434,14 +426,10 @@ async def _send(self, method: str, params: dict, timeout: float = 300) -> dict: if not self.connected: return {"error": "Extension not connected"} - # A bearer token is only worth routing on when something is going to - # send one. The batchexecute path authenticates in the page with the - # session cookie, so demanding a flow key there would reject every - # profile — no profile on that path ever captures one. - needs_token = not USE_BATCH_RPC - extension_candidates = self._extension_candidates(require_token=needs_token) - if not extension_candidates and needs_token: - return {"error": "NO_FLOW_KEY"} + # No profile needs a bearer any more: batchexecute authenticates in the + # page with the session cookie. Demanding a flow key here would reject + # every profile, because none on this path ever captures one. + extension_candidates = self._extension_candidates(require_token=False) if not extension_candidates: return {"error": "Extension not connected"} @@ -489,25 +477,6 @@ async def _send(self, method: str, params: dict, timeout: float = 300) -> dict: return last_result - def _build_url(self, endpoint_key: str, **kwargs) -> str: - """Build full API URL.""" - path = ENDPOINTS[endpoint_key].format(**kwargs) - sep = "&" if "?" in path else "?" - return f"{GOOGLE_FLOW_API}{path}{sep}key={GOOGLE_API_KEY}" - - def _client_context(self, project_id: str, user_paygate_tier: str = "PAYGATE_TIER_TWO") -> dict: - """Build clientContext with recaptcha placeholder.""" - return { - "projectId": str(project_id), - "recaptchaContext": { - "applicationType": "RECAPTCHA_APPLICATION_TYPE_WEB", - "token": "", # Extension injects real token - }, - "sessionId": f";{int(time.time() * 1000)}", - "tool": "PINHOLE", - "userPaygateTier": user_paygate_tier, - } - # ─── batchexecute transport ────────────────────────────── # # Flow's rewritten frontend signs every call with the session cookie plus a @@ -598,8 +567,6 @@ def flow_project_id(self, requested: str | None = None) -> str | None: return FLOW_PROJECT_ID or None async def create_project(self, project_title: str, tool_name: str = "PINHOLE") -> dict: - if not USE_BATCH_RPC: - return await self._legacy_create_project(project_title, tool_name) pid = self.flow_project_id() if not pid: return {"error": _UNSUPPORTED_CREATE_PROJECT} @@ -621,9 +588,6 @@ async def generate_images(self, prompt: str, project_id: str, old REST one so the parsers downstream do not have to care which transport produced it. """ - if not USE_BATCH_RPC: - return await self._legacy_generate_images( - prompt, project_id, aspect_ratio, user_paygate_tier, character_media_ids) try: if not isinstance(count, int) or isinstance(count, bool) or not 1 <= count <= 4: @@ -726,10 +690,6 @@ async def edit_image(self, prompt: str, source_media_id: str, generic reference conditions a fresh generation; BASE_IMAGE is the wire shape the current Flow editor uses for an actual image edit/refine. """ - if not USE_BATCH_RPC: - return await self._legacy_edit_image( - prompt, source_media_id, project_id, aspect_ratio, - user_paygate_tier, character_media_ids) refs = [mid for mid in (character_media_ids or []) if mid != source_media_id] return await self.generate_images( @@ -747,8 +707,6 @@ async def edit_image(self, prompt: str, source_media_id: str, async def upscale_image(self, media_id: str, project_id: str, resolution: str = "2K") -> dict: """Return Flow's synchronous 2K/4K image upscale as base64 JPEG data.""" - if not USE_BATCH_RPC: - return {"status": 400, "error": "Image upscale requires the flow.google.com batch transport"} try: pid = self._batch_project_id(project_id) freq = fb.image_upscale_request(media_id, resolution) @@ -778,10 +736,6 @@ async def generate_video(self, start_image_media_id: str, prompt: str, end_image_media_id: str = None, user_paygate_tier: str = "PAYGATE_TIER_TWO") -> dict: """Submit an i2v generation. Returns operations for the poller.""" - if not USE_BATCH_RPC: - return await self._legacy_generate_video( - start_image_media_id, prompt, project_id, scene_id, - aspect_ratio, end_image_media_id, user_paygate_tier) if end_image_media_id: if not FLOW_ALLOW_DEGRADED: @@ -815,10 +769,6 @@ async def generate_video_from_references(self, reference_media_ids: list[str], aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", user_paygate_tier: str = "PAYGATE_TIER_TWO") -> dict: """Generate video from multiple reference images (r2v).""" - if not USE_BATCH_RPC: - return await self._legacy_generate_video_from_references( - reference_media_ids, prompt, project_id, scene_id, - aspect_ratio, user_paygate_tier) if not FLOW_ALLOW_DEGRADED: return {"error": _unsupported( @@ -841,8 +791,6 @@ async def upscale_video(self, media_id: str, scene_id: str, aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", resolution: str = "VIDEO_RESOLUTION_4K") -> dict: """Upscale a video.""" - if not USE_BATCH_RPC: - return await self._legacy_upscale_video(media_id, scene_id, aspect_ratio, resolution) return {"error": _unsupported( "video upscale", "no upsampler rpc appears in the new frontend's captures", @@ -865,8 +813,6 @@ async def check_video_status(self, operations: list[dict]) -> dict: Everything short of that is PENDING, and the caller's own poll loop owns the timeout. """ - if not USE_BATCH_RPC: - return await self._legacy_check_video_status(operations) out = [] for entry in operations or []: @@ -986,8 +932,6 @@ async def get_credits(self) -> dict: fixed — so on the batch path this answers with the configured default rather than pretending to know. """ - if not USE_BATCH_RPC: - return await self._legacy_get_credits() return {"status": 200, "data": { "userPaygateTier": DEFAULT_PAYGATE_TIER, "note": "batchexecute path: tier is configured (DEFAULT_PAYGATE_TIER), not fetched", @@ -1001,8 +945,6 @@ async def validate_media_id(self, media_id: str) -> bool: async def get_media(self, media_id: str) -> dict: """Fetch a media record, which is where a fresh signed url lives.""" - if not USE_BATCH_RPC: - return await self._legacy_get_media(media_id) try: urls = await self._batch_media_urls(media_id) except Exception as e: @@ -1019,8 +961,6 @@ async def get_media(self, media_id: str) -> dict: async def upload_image(self, image_base64: str, mime_type: str = "image/jpeg", project_id: str = "", file_name: str = "image.jpg") -> dict: """Upload an image into the project so it can be used as a reference.""" - if not USE_BATCH_RPC: - return await self._legacy_upload_image(image_base64, mime_type, project_id, file_name) try: pid = self._batch_project_id(project_id) payload = await self._batch_payload( @@ -1033,317 +973,6 @@ async def upload_image(self, image_base64: str, mime_type: str = "image/jpeg", return _batch_error(e) return {"status": 200, "data": {"media": {"name": media_id}}, "_mediaId": media_id} - # ─── Legacy REST methods (aisandbox-pa, pre-migration) ─── - - async def _legacy_create_project(self, project_title: str, tool_name: str = "PINHOLE") -> dict: - """Create a project on Google Flow via tRPC endpoint. - - Returns the full response including projectId. - """ - url = "https://labs.google/fx/api/trpc/project.createProject" - body = {"json": {"projectTitle": project_title, "toolName": tool_name}} - - return await self._send("trpc_request", { - "url": url, - "method": "POST", - "headers": { - "content-type": "application/json", - "accept": "*/*", - }, - "body": body, - }, timeout=30) - - async def _legacy_generate_images(self, prompt: str, project_id: str, - aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT", - user_paygate_tier: str = "PAYGATE_TIER_TWO", - character_media_ids: list[str] = None) -> dict: - """Generate image(s). - - If character_media_ids is provided, uses edit_image flow (batchGenerateImages - with imageInputs) — same endpoint, but includes character references. - Without characters, uses plain generate_images. - - Response structure: - data.media[].name = mediaId (used for video gen) - """ - ts = int(time.time() * 1000) - ctx = self._client_context(project_id, user_paygate_tier) - - request_item = { - "clientContext": {**ctx, "sessionId": f";{ts}"}, - "seed": ts % 1000000, - "structuredPrompt": {"parts": [{"text": prompt}]}, - "imageAspectRatio": aspect_ratio, - "imageModelName": IMAGE_MODELS["NANO_BANANA_PRO"], - } - - # Add character references if provided (edit_image flow) - if character_media_ids: - request_item["imageInputs"] = [ - {"name": mid, "imageInputType": "IMAGE_INPUT_TYPE_REFERENCE"} - for mid in character_media_ids - ] - - batch_id = f"{uuid.uuid4()}" if character_media_ids else None - body = { - "clientContext": ctx, - "requests": [request_item], - } - if batch_id: - body["mediaGenerationContext"] = {"batchId": batch_id} - body["useNewMedia"] = True - - url = self._build_url("generate_images", project_id=project_id) - return await self._send("api_request", { - "url": url, - "method": "POST", - "headers": random_headers(), - "body": body, - "captchaAction": "IMAGE_GENERATION", - }) - - async def _legacy_edit_image(self, prompt: str, source_media_id: str, - project_id: str, - aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT", - user_paygate_tier: str = "PAYGATE_TIER_ONE", - character_media_ids: list[str] = None) -> dict: - """Edit an existing image using IMAGE_INPUT_TYPE_BASE_IMAGE. - - If character_media_ids is provided, appends them as IMAGE_INPUT_TYPE_REFERENCE - after the base image. Order: [base_image, char_A, char_B, ...]. - This helps Google Flow detect characters for consistent edits. - """ - ts = int(time.time() * 1000) - ctx = self._client_context(project_id, user_paygate_tier) - - image_inputs = [ - {"name": source_media_id, "imageInputType": "IMAGE_INPUT_TYPE_BASE_IMAGE"} - ] - if character_media_ids: - for mid in character_media_ids: - image_inputs.append({"name": mid, "imageInputType": "IMAGE_INPUT_TYPE_REFERENCE"}) - - request_item = { - "clientContext": {**ctx, "sessionId": f";{ts}"}, - "seed": ts % 1000000, - "structuredPrompt": {"parts": [{"text": prompt}]}, - "imageAspectRatio": aspect_ratio, - "imageModelName": IMAGE_MODELS["NANO_BANANA_PRO"], - "imageInputs": image_inputs, - } - - body = { - "clientContext": ctx, - "mediaGenerationContext": {"batchId": f"{uuid.uuid4()}"}, - "useNewMedia": True, - "requests": [request_item], - } - - url = self._build_url("generate_images", project_id=project_id) - return await self._send("api_request", { - "url": url, - "method": "POST", - "headers": random_headers(), - "body": body, - "captchaAction": "IMAGE_GENERATION", - }) - - async def _legacy_generate_video(self, start_image_media_id: str, prompt: str, - project_id: str, scene_id: str, - aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", - end_image_media_id: str = None, - user_paygate_tier: str = "PAYGATE_TIER_TWO") -> dict: - """Generate video from start image (i2v). - - Two sub-types: - - frame_2_video (i2v): startImage only - - start_end_frame_2_video (i2v_fl): startImage + endImage (for scene chaining) - """ - gen_type = "start_end_frame_2_video" if end_image_media_id else "frame_2_video" - model_key = VIDEO_MODELS.get(user_paygate_tier, {}).get(gen_type, {}).get(aspect_ratio) - - if not model_key: - return {"error": f"No model for tier={user_paygate_tier} type={gen_type} ratio={aspect_ratio}"} - - request = { - "aspectRatio": aspect_ratio, - "seed": int(time.time()) % 10000, - "textInput": {"structuredPrompt": {"parts": [{"text": prompt}]}}, - "videoModelKey": model_key, - "startImage": {"mediaId": start_image_media_id}, - "metadata": {"sceneId": scene_id}, - } - - if end_image_media_id: - request["endImage"] = {"mediaId": end_image_media_id} - - endpoint_key = "generate_video_start_end" if end_image_media_id else "generate_video" - body = { - "mediaGenerationContext": {"batchId": f"{uuid.uuid4()}"}, - "clientContext": self._client_context(project_id, user_paygate_tier), - "requests": [request], - "useV2ModelConfig": True, - } - - url = self._build_url(endpoint_key) - return await self._send("api_request", { - "url": url, - "method": "POST", - "headers": random_headers(), - "body": body, - "captchaAction": "VIDEO_GENERATION", - }, timeout=60) # Submit only — polling is separate - - async def _legacy_generate_video_from_references(self, reference_media_ids: list[str], - prompt: str, project_id: str, scene_id: str, - aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", - user_paygate_tier: str = "PAYGATE_TIER_TWO") -> dict: - """Generate video from multiple reference images (r2v). - - Uses referenceImages instead of startImage — the model composes - a video from all provided reference character images. - - Args: - reference_media_ids: List of character media_ids (from uploadImage) - """ - gen_type = "reference_frame_2_video" - model_key = VIDEO_MODELS.get(user_paygate_tier, {}).get(gen_type, {}).get(aspect_ratio) - - if not model_key: - return {"error": f"No model for tier={user_paygate_tier} type={gen_type} ratio={aspect_ratio}"} - - request = { - "aspectRatio": aspect_ratio, - "seed": int(time.time()) % 10000, - "textInput": {"structuredPrompt": {"parts": [{"text": prompt}]}}, - "videoModelKey": model_key, - "referenceImages": [ - {"mediaId": mid, "imageUsageType": "IMAGE_USAGE_TYPE_ASSET"} - for mid in reference_media_ids - ], - "metadata": {}, - } - - body = { - "mediaGenerationContext": {"batchId": f"{uuid.uuid4()}"}, - "clientContext": self._client_context(project_id, user_paygate_tier), - "requests": [request], - "useV2ModelConfig": True, - } - - url = self._build_url("generate_video_references") - return await self._send("api_request", { - "url": url, - "method": "POST", - "headers": random_headers(), - "body": body, - "captchaAction": "VIDEO_GENERATION", - }, timeout=60) - - async def _legacy_upscale_video(self, media_id: str, scene_id: str, - aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", - resolution: str = "VIDEO_RESOLUTION_4K") -> dict: - """Upscale a video.""" - model_key = UPSCALE_MODELS.get(resolution, "veo_3_1_upsampler_4k") - - body = { - "clientContext": { - "sessionId": f";{int(time.time() * 1000)}", - "recaptchaContext": { - "applicationType": "RECAPTCHA_APPLICATION_TYPE_WEB", - "token": "", - }, - }, - "requests": [{ - "aspectRatio": aspect_ratio, - "resolution": resolution, - "seed": int(time.time()) % 100000, - "metadata": {"sceneId": scene_id}, - "videoInput": {"mediaId": media_id}, - "videoModelKey": model_key, - }], - } - - url = self._build_url("upscale_video") - return await self._send("api_request", { - "url": url, - "method": "POST", - "headers": random_headers(), - "body": body, - "captchaAction": "VIDEO_GENERATION", - }, timeout=60) - - async def _legacy_check_video_status(self, operations: list[dict]) -> dict: - """Check status of video generation operations.""" - body = {"operations": operations} - url = self._build_url("check_video_status") - return await self._send("api_request", { - "url": url, - "method": "POST", - "headers": random_headers(), - "body": body, - }, timeout=30) # No captcha needed - - async def _legacy_get_credits(self) -> dict: - """Get user credits and tier.""" - url = self._build_url("get_credits") - return await self._send("api_request", { - "url": url, - "method": "GET", - "headers": random_headers(), - }, timeout=15) - - async def _legacy_get_media(self, media_id: str) -> dict: - """Fetch media metadata from Google Flow. - - Returns the raw API response which contains a fresh signed URL - in data.fifeUrl or data.servingUri. - """ - url = f"{GOOGLE_FLOW_API}/v1/media/{media_id}?key={GOOGLE_API_KEY}&clientContext.tool=PINHOLE" - return await self._send("api_request", { - "url": url, - "method": "GET", - "headers": random_headers(), - }, timeout=15) - - async def _legacy_upload_image(self, image_base64: str, mime_type: str = "image/jpeg", - project_id: str = "", file_name: str = "image.jpg") -> dict: - """Upload an image for use as start/end frame. - - Uses /v1/flow/uploadImage endpoint. - Response: {media: {name: "uuid", ...}, workflow: {...}} - We store media.name as the mediaId for video generation. - """ - body = { - "clientContext": { - "projectId": project_id, - "tool": "PINHOLE", - }, - "fileName": file_name, - "imageBytes": image_base64, - "isHidden": False, - "isUserUploaded": True, - "mimeType": mime_type, - } - - url = self._build_url("upload_image") - result = await self._send("api_request", { - "url": url, - "method": "POST", - "headers": random_headers(), - "body": body, - }, timeout=60) - - # Extract media.name for convenience (used as mediaId in video gen) - if not _is_ws_error(result): - data = result.get("data", {}) - if isinstance(data, dict): - media = data.get("media", {}) - if isinstance(media, dict) and media.get("name"): - result["_mediaId"] = media["name"] - - return result - # ─── Response shaping ──────────────────────────────────────── # # The batch path answers in Flow's positional arrays; everything downstream diff --git a/agent/services/headers.py b/agent/services/headers.py deleted file mode 100644 index b7e1ac39c..000000000 --- a/agent/services/headers.py +++ /dev/null @@ -1,40 +0,0 @@ -"""Randomized browser headers to avoid detection.""" -import random -import time -from agent.config import USER_AGENTS, CHROME_VERSIONS, BROWSER_VALIDATIONS, CLIENT_DATA - - -def random_headers() -> dict: - """Generate randomized browser-like headers for Google Flow API.""" - ua = random.choice(USER_AGENTS) - chrome_ver = random.choice(CHROME_VERSIONS) - validation = random.choice(BROWSER_VALIDATIONS) - client_data = random.choice(CLIENT_DATA) - - if "Windows" in ua: - platform, mobile = '"Windows"', "?0" - elif "Macintosh" in ua: - platform, mobile = '"macOS"', "?0" - else: - platform, mobile = '"Linux"', "?0" - - return { - "accept": "*/*", - "accept-language": "en-US,en;q=0.9", - "content-type": "text/plain;charset=UTF-8", - "origin": "https://labs.google", - "priority": "u=1, i", - "referer": "https://labs.google/", - "sec-ch-ua": f'"Not;A=Brand";v="99", {chrome_ver}', - "sec-ch-ua-mobile": mobile, - "sec-ch-ua-platform": platform, - "sec-fetch-dest": "empty", - "sec-fetch-mode": "cors", - "sec-fetch-site": "cross-site", - "user-agent": ua, - "x-browser-channel": "stable", - "x-browser-copyright": "Copyright 2025 Google LLC. All rights reserved.", - "x-browser-validation": validation, - "x-browser-year": "2025", - "x-client-data": client_data, - } diff --git a/agent/services/omni_flash.py b/agent/services/omni_flash.py index 796d6a312..8de784447 100644 --- a/agent/services/omni_flash.py +++ b/agent/services/omni_flash.py @@ -1,44 +1,34 @@ """Gemini Omni Flash video generation through the Google Flow bridge. -Supported Omni surfaces in this module: - -* first frame -> video via ``batchAsyncGenerateVideoStartImage`` -* first + last frame -> video via ``batchAsyncGenerateVideoStartAndEndImage`` -* reference images -> video via ``batchAsyncGenerateVideoReferenceImages`` - -Omni duration-specific model keys live in ``agent/models.json``. First-frame -Flow requests have been captured with ``abra_i2v_<duration>s``. The current -First+Last rollout uses the same Omni I2V family but the StartAndEnd endpoint; -that mapping is deliberately configurable separately so it can be changed -without a code release if Google's rollout rotates the wire key. - -Important: Omni submit responses may contain operation-looking handles, but -those handles are not compatible with the legacy -``batchCheckAsyncVideoGenerationStatus`` polling endpoint. Omni jobs are -workflow-backed and are polled through Flow's authenticated project data. +What works today: **text-to-video**, on flow.google.com batchexecute. It submits +through ``fb.text_video_request`` like every other migrated call. + +What does not: first-frame, first+last, and reference-to-video. Those three were +only ever implemented against the pre-migration REST endpoints, and that +transport was removed when Flow stopped minting the bearer it needed. Their +migrated payloads have not been captured, so they validate their inputs and then +fail by name — see ``docs/CAPTURE.md`` for how to record one off the new UI. + +Duration-specific model keys live in ``agent/models.json`` so a rollout that +rotates a wire key does not need a code release. + +Polling is workflow-backed: a submit hands back ``name`` + ``primaryMediaId``, +not an operation handle, so Omni jobs must not be fed to ``check_video_status``. """ from __future__ import annotations import json -import time -import uuid from pathlib import Path -from urllib.parse import quote -from agent.config import USE_BATCH_RPC from agent.services import flow_batch as fb from agent.services.flow_client import get_flow_client -from agent.services.headers import random_headers _MODELS_FILE = Path(__file__).parent.parent / "models.json" -#: Every Omni surface here rides the pre-migration transports — the REST -#: endpoints on aisandbox-pa and the labs.google tRPC snapshot it polls -#: through. Flow moved to flow.google.com in September 2026 and stopped -#: minting the bearer both of those need, and no Omni payload has been -#: captured off the new frontend, so on the batch path these fail with a -#: name rather than dying on a 401 five retries deep. +#: Frame and reference generation had only a REST implementation, and that +#: transport is gone. Failing by name here beats dying on a 401 five retries +#: deep, and names the thing a capture would restore. _UNSUPPORTED_ON_BATCH = ( "UNSUPPORTED_ON_BATCH_API: Omni Flash frame/reference generation is not yet " "ported to flow.google.com batchexecute. Omni text-to-video is supported on " @@ -47,10 +37,6 @@ ) -def _batch_path_blocks_omni() -> dict | None: - """The error to return instead of reaching for auth that is gone.""" - return {"error": _UNSUPPORTED_ON_BATCH} if USE_BATCH_RPC else None - OMNI_FLASH_VALID_DURATIONS = (4, 6, 8, 10) OMNI_FLASH_VALID_ASPECTS = { "VIDEO_ASPECT_RATIO_PORTRAIT", @@ -61,42 +47,6 @@ def _batch_path_blocks_omni() -> dict | None: OMNI_FLASH_CREDIT_COST = {4: 15, 6: 20, 8: 25, 10: 30} -async def _fetch_project_initial_data(client, project_id: str) -> dict: - """Fetch the same authenticated project snapshot used by the Flow UI.""" - query = quote( - json.dumps({"json": {"projectId": project_id}}, separators=(",", ":")), - safe="", - ) - url = f"https://labs.google/fx/api/trpc/flow.projectInitialData?input={query}" - return await client._send( - "trpc_request", - { - "url": url, - "method": "GET", - "headers": {"content-type": "application/json"}, - }, - timeout=15, - ) - - -async def _fetch_media_url(client, media_id: str) -> dict: - """Resolve Flow's authenticated media redirect without buffering the file.""" - url = ( - "https://labs.google/fx/api/trpc/media.getMediaUrlRedirect" - f"?name={quote(media_id, safe='')}" - ) - return await client._send( - "trpc_request", - { - "url": url, - "method": "GET", - "headers": {"content-type": "application/json"}, - "responseMode": "url", - }, - timeout=15, - ) - - def _validate_duration(duration_s: int) -> None: if duration_s not in OMNI_FLASH_VALID_DURATIONS: raise ValueError( @@ -201,23 +151,6 @@ def extract_omni_workflows(result: dict) -> list[dict]: return normalized -def _annotate_polling(result: dict, project_id: str) -> dict: - """Add an explicit FlowKit polling descriptor to a successful submit.""" - workflows = extract_omni_workflows(result) - if not workflows: - return result - data = result.get("data") if isinstance(result.get("data"), dict) else result - if isinstance(data, dict): - for workflow in workflows: - workflow["project_id"] = project_id - data["flowkitPolling"] = { - "mode": "project_media", - "project_id": project_id, - "workflows": workflows, - } - return result - - async def generate_omni_flash_text_video( prompt: str, project_id: str, @@ -230,9 +163,6 @@ async def generate_omni_flash_text_video( """Submit Omni 1.1 Flash text-to-video on the migrated Flow batch API.""" _validate_duration(duration_s) _validate_aspect(aspect_ratio) - if not USE_BATCH_RPC: - return {"error": "Omni text-to-video is implemented on the flow.google.com batch path only"} - client = get_flow_client() try: pid = client._batch_project_id(project_id) @@ -279,61 +209,13 @@ async def _submit_omni_frame_video( seed: int | None = None, ) -> dict: """Submit Omni first-frame or First+Last generation.""" - blocked = _batch_path_blocks_omni() - if blocked: - return blocked _validate_frame_inputs( start_image_media_id, end_image_media_id, duration_s, aspect_ratio, ) - - mode = ( - "start_end_frame_to_video" - if end_image_media_id is not None - else "frame_to_video" - ) - endpoint = ( - "generate_video_start_end" - if end_image_media_id is not None - else "generate_video" - ) - model_key = _load_model_key(duration_s, mode=mode) - client = get_flow_client() - ts = int(time.time() * 1000) - - request_item = { - "aspectRatio": aspect_ratio, - "textInput": {"structuredPrompt": {"parts": [{"text": prompt}]}}, - "videoModelKey": model_key, - "seed": seed if seed is not None else ts % 1_000_000, - "metadata": {"sceneId": scene_id} if scene_id else {}, - "startImage": {"mediaId": start_image_media_id}, - } - if end_image_media_id is not None: - request_item["endImage"] = {"mediaId": end_image_media_id} - - context = client._client_context(project_id, user_paygate_tier) - body = { - "mediaGenerationContext": {"batchId": str(uuid.uuid4())}, - "clientContext": {**context, "sessionId": f";{ts}"}, - "requests": [request_item], - "useV2ModelConfig": True, - } - - result = await client._send( - "api_request", - { - "url": client._build_url(endpoint), - "method": "POST", - "headers": random_headers(), - "body": body, - "captchaAction": "VIDEO_GENERATION", - }, - timeout=60, - ) - return _annotate_polling(result, project_id) + return {"error": _UNSUPPORTED_ON_BATCH} async def generate_omni_flash_first_frame_video( @@ -401,50 +283,8 @@ async def generate_omni_flash_video( the workflow names and primary media IDs required by the Omni polling path. Do not feed Omni operation handles to ``check_video_status``. """ - blocked = _batch_path_blocks_omni() - if blocked: - return blocked - refs = _validate_reference_inputs(reference_media_ids, duration_s, aspect_ratio) - model_key = _load_model_key(duration_s, mode="reference_to_video") - client = get_flow_client() - - ts = int(time.time() * 1000) - request_item = { - "aspectRatio": aspect_ratio, - "textInput": {"structuredPrompt": {"parts": [{"text": prompt}]}}, - "videoModelKey": model_key, - "seed": seed if seed is not None else ts % 1_000_000, - "metadata": {"sceneId": scene_id} if scene_id else {}, - "referenceImages": [ - {"mediaId": mid, "imageUsageType": "IMAGE_USAGE_TYPE_ASSET"} - for mid in refs - ], - } - - context = client._client_context(project_id, user_paygate_tier) - body = { - "mediaGenerationContext": { - "batchId": str(uuid.uuid4()), - "audioFailurePreference": "BLOCK_SILENCED_VIDEOS", - }, - "clientContext": {**context, "sessionId": f";{ts}"}, - "requests": [request_item], - "useV2ModelConfig": True, - } - - url = client._build_url("generate_video_references") - result = await client._send( - "api_request", - { - "url": url, - "method": "POST", - "headers": random_headers(), - "body": body, - "captchaAction": "VIDEO_GENERATION", - }, - timeout=60, - ) - return _annotate_polling(result, project_id) + _validate_reference_inputs(reference_media_ids, duration_s, aspect_ratio) + return {"error": _UNSUPPORTED_ON_BATCH} async def _check_omni_batch_media( @@ -507,166 +347,4 @@ async def check_omni_flash_status( project_id: str = "", ) -> dict: """Perform one non-blocking poll pass for Omni workflow-backed jobs.""" - if USE_BATCH_RPC: - return await _check_omni_batch_media(workflows, include_encoded_video, project_id) - normalized = [] - for workflow in workflows or []: - item = _normalize_workflow(workflow) - if item: - normalized.append(item) - if not normalized: - raise ValueError( - "Omni polling requires workflow descriptors with name and primary_media_id " - "(or raw Flow metadata.primaryMediaId)" - ) - - resolved_project_id = project_id or next( - (item.get("project_id", "") for item in normalized if item.get("project_id")), - "", - ) - if not resolved_project_id: - raise ValueError( - "Omni project polling requires project_id. Use the project_id returned " - "inside flowkitPolling or pass project_id explicitly." - ) - if any( - item.get("project_id") and item["project_id"] != resolved_project_id - for item in normalized - ): - raise ValueError( - "All Omni workflows in one poll must belong to the same project_id" - ) - - client = get_flow_client() - response = await _fetch_project_initial_data(client, resolved_project_id) - http_status = response.get("status") if isinstance(response, dict) else None - if isinstance(http_status, int) and http_status >= 400: - data = response.get("data") if isinstance(response.get("data"), dict) else {} - error = data.get("error") if isinstance(data, dict) else None - if isinstance(error, dict): - error = error.get("message") or error.get("code") - raise RuntimeError( - error - or response.get("error") - or f"Flow project poll failed: API_{http_status}" - ) - - envelope = response.get("data") if isinstance(response, dict) else None - result = envelope.get("result") if isinstance(envelope, dict) else None - result_data = result.get("data") if isinstance(result, dict) else None - project_json = result_data.get("json") if isinstance(result_data, dict) else None - contents = project_json.get("projectContents") if isinstance(project_json, dict) else None - if not isinstance(contents, dict): - raise RuntimeError("Flow project poll returned an unexpected response shape") - - project_workflows = contents.get("workflows") - project_media = contents.get("media") - project_workflows = project_workflows if isinstance(project_workflows, list) else [] - project_media = project_media if isinstance(project_media, list) else [] - known_workflow_names = { - item.get("name") - for item in project_workflows - if isinstance(item, dict) and isinstance(item.get("name"), str) - } - media_by_id = { - item.get("name"): item - for item in project_media - if isinstance(item, dict) and isinstance(item.get("name"), str) - } - media_by_workflow = { - item.get("workflowId"): item - for item in project_media - if isinstance(item, dict) and isinstance(item.get("workflowId"), str) - } - - items = [] - - for workflow in normalized: - name = workflow["name"] - media_id = workflow["primary_media_id"] - payload = media_by_id.get(media_id) or media_by_workflow.get(name) - if not isinstance(payload, dict): - items.append({ - "name": name, - "primary_media_id": media_id, - "project_id": resolved_project_id, - "done": False, - "status": "PENDING", - "error": None, - "workflow_present": name in known_workflow_names, - }) - continue - - metadata = payload.get("mediaMetadata") - metadata = metadata if isinstance(metadata, dict) else {} - media_status = metadata.get("mediaStatus") - media_status = media_status if isinstance(media_status, dict) else {} - generation_status = media_status.get("mediaGenerationStatus") - - if isinstance(generation_status, str) and ( - generation_status.endswith("FAILED") or generation_status.endswith("CANCELLED") - ): - items.append({ - "name": name, - "primary_media_id": media_id, - "project_id": resolved_project_id, - "done": True, - "status": "FAILED", - "error": generation_status, - }) - continue - - if generation_status != "MEDIA_GENERATION_STATUS_SUCCESSFUL": - items.append({ - "name": name, - "primary_media_id": media_id, - "project_id": resolved_project_id, - "done": False, - "status": "PENDING", - "error": None, - }) - continue - - url = None - url_error = None - url_response = await _fetch_media_url(client, media_id) - if isinstance(url_response, dict) and url_response.get("status", 500) < 400: - url_data = url_response.get("data") - candidate = url_data.get("url") if isinstance(url_data, dict) else None - if isinstance(candidate, str) and candidate.startswith("https://flow-content.google/"): - url = candidate - else: - url_error = "Flow media redirect returned no allowed URL" - else: - url_error = ( - url_response.get("error") - if isinstance(url_response, dict) - else "Flow media redirect failed" - ) - item = { - "name": name, - "primary_media_id": media_id, - "project_id": resolved_project_id, - "done": True, - "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL", - "error": None, - "media": { - "media_id": media_id, - "url": url, - "encoded_video_available": False, - }, - } - if include_encoded_video: - item["media"]["encoded_video"] = None - if url_error: - item["media"]["url_error"] = url_error - items.append(item) - - all_done = bool(items) and all(item["done"] for item in items) - any_failed = any(item.get("status") == "FAILED" for item in items) - return { - "project_id": resolved_project_id, - "done": all_done, - "status": "FAILED" if any_failed else ("COMPLETED" if all_done else "PENDING"), - "workflows": items, - } + return await _check_omni_batch_media(workflows, include_encoded_video, project_id) diff --git a/docs/OMNI_FLASH.md b/docs/OMNI_FLASH.md index 64d3c040d..bf8a2e607 100644 --- a/docs/OMNI_FLASH.md +++ b/docs/OMNI_FLASH.md @@ -22,7 +22,7 @@ Use `http://127.0.0.1:8100` when the caller runs on the FlowKit host. For a remo ## Supported modes -On `flow.google.com`, Omni **text-to-video** is migrated and live-verified. The older frame/reference implementations still use the pre-migration REST transport and remain fail-fast while `USE_BATCH_RPC=1`. +On `flow.google.com`, Omni **text-to-video** is migrated and live-verified. Frame and reference generation had only a REST implementation; that transport has been removed, so they validate their inputs and then fail by name with `UNSUPPORTED_ON_BATCH_API` until their payloads are captured (see `docs/CAPTURE.md`). | Mode | Batch status | Endpoint | Internal model family | |---|---|---|---| diff --git a/extension/background.js b/extension/background.js index 79036f87b..6def15cfd 100644 --- a/extension/background.js +++ b/extension/background.js @@ -8,8 +8,10 @@ * `Bearer ya29.…` the old REST host needed. The current path is `batch_rpc`: * the agent builds an `f.req` envelope, this worker mints a captcha for it and * runs the POST in the page's MAIN world, where the `at` CSRF token lives. - * The bearer capture and `api_request` proxy below are the legacy path, kept - * for USE_BATCH_RPC=0 and for an old pinned labs.google tab. + * The bearer capture and the `api_request` / `trpc_request` proxies below are + * the pre-migration path. The agent no longer sends either — it speaks only + * `batch_rpc`. They stay so an extension updated ahead of its agent keeps + * serving an older one; remove them once no agent in the wild sends them. */ const AGENT_WS_URL = 'ws://127.0.0.1:9222'; @@ -643,8 +645,12 @@ async function handleTrpcRequest(msg) { } } -// Legacy REST proxy against aisandbox-pa. Reachable only with USE_BATCH_RPC=0 -// on a profile that still holds a `Bearer ya29.…`; Flow stopped minting those. +// Legacy REST proxy against aisandbox-pa. No current agent sends `api_request`; +// kept only so an extension updated ahead of its agent still serves an older +// one. It needs a `Bearer ya29.…` that Flow stopped minting, so it 401s on any +// post-migration profile — as does sendTelemetry below, which early-returns +// without a flowKey. Nothing here reaches aisandbox-pa any more; when the +// oldest agent in the wild speaks batch_rpc, this and the host permission go. async function handleApiRequest(msg) { const { id, params } = msg; const { url, method, headers, body, captchaAction } = params; diff --git a/skills/fk-doctor.md b/skills/fk-doctor.md index 6b92019c1..6c23f97bb 100644 --- a/skills/fk-doctor.md +++ b/skills/fk-doctor.md @@ -6,7 +6,7 @@ Diagnose any FlowKit error and prescribe a fix. Knows the full error taxonomy ac - Any `/api/requests/*` response has `status=FAILED` or `error_message` is set - A request has been `PROCESSING` for > 10 minutes with no progress - `GET /health` returns `extension_connected: false` -- User reports any error string containing: `UNSAFE_GENERATION`, `QUOTA`, `not found`, `CAPTCHA`, `UNUSUAL_ACTIVITY`, `NO_AT_TOKEN`, `NO_FLOW_PROJECT`, `UNSUPPORTED_ON_BATCH_API`, `NO_FLOW_KEY`, `NO_FLOW_TAB`, `FLOW_TAB_DISCARDED`, `extension_switched`, `Failed to fetch`, `MODEL_ACCESS_DENIED`, `PAYGATE_TIER_TWO`, `invalidTags`, `quotaExceeded`, `invalid_grant` +- User reports any error string containing: `UNSAFE_GENERATION`, `QUOTA`, `not found`, `CAPTCHA`, `UNUSUAL_ACTIVITY`, `NO_AT_TOKEN`, `NO_FLOW_PROJECT`, `UNSUPPORTED_ON_BATCH_API`, `NO_FLOW_TAB`, `FLOW_TAB_DISCARDED`, `extension_switched`, `Failed to fetch`, `MODEL_ACCESS_DENIED`, `PAYGATE_TIER_TWO`, `invalidTags`, `quotaExceeded`, `invalid_grant` - User asks "why did X fail", "what's wrong with the pipeline", "why is this stuck", "tại sao X lỗi", "lỗi gì vậy" - An HTTP 4xx/5xx reaches the main agent from any endpoint under `127.0.0.1:8100` - A YouTube upload returns `HttpError` from `googleapiclient` @@ -67,25 +67,23 @@ Cross-reference `error_message` against the taxonomy below. Print: **Diagnosis / Match against taxonomy — even partial matches (`"not found"`, `"captcha"`, `"quota"`). -## Which transport is running +## The transport -Since Flow moved to `flow.google.com` (September 2026) there are two paths, and -the taxonomy below splits on which one is live: +One path since Flow moved to `flow.google.com` (September 2026): ```bash -python3 -c "from agent.config import USE_BATCH_RPC, FLOW_PROJECT_ID; \ - print('batch' if USE_BATCH_RPC else 'legacy REST', '| project:', FLOW_PROJECT_ID or 'UNPINNED')" +python3 -c "from agent.config import FLOW_PROJECT_ID; \ + print('batch | project:', FLOW_PROJECT_ID or 'UNPINNED')" ``` -- **batch** (default) — the agent builds an `f.req` envelope, the extension runs - it inside a signed-in `flow.google.com` tab. No bearer token exists on this - path, so `flow_key_present: false` in `/api/flow/status` is **normal**, not a - fault. Requires a Flow tab open and `FLOW_PROJECT_ID` pinned. -- **legacy REST** (`USE_BATCH_RPC=0`) — the pre-migration `aisandbox-pa` path. - It needs a `Bearer ya29.…` Flow no longer mints, so it will 401 on any fresh - profile. Treat any report of it "suddenly breaking" as the migration, not a - regression: if `token_age_s` only climbs across tab reloads, the token is not - stale, it is gone. +The agent builds an `f.req` envelope and the extension runs it inside a +signed-in `flow.google.com` tab. **No bearer token exists on this path**, so +`flow_key_present: false` in `/api/flow/status` is normal, not a fault. +Requires a Flow tab open and `FLOW_PROJECT_ID` pinned. + +The `aisandbox-pa` REST path that preceded it has been removed — it needed a +`Bearer ya29.…` Flow no longer mints. If an old report mentions it, that is the +migration, not a regression. ## Error Taxonomy @@ -106,13 +104,13 @@ python3 -c "from agent.config import USE_BATCH_RPC, FLOW_PROJECT_ID; \ | Status | Origin | When you see it | |--------|--------|-----------------| | **400** | Flow API | Invalid payload / UNSAFE / entity-not-found — **route by `details.reason`** | -| **401** | Flow API (legacy path only) | Bearer expired — and on a post-migration profile it is not expired, it was never minted. Switch to the batch path | +| **401** | Flow API | Should not happen — batchexecute authenticates in the page, not with a bearer. Check the Flow tab is signed in; see `NO_AT_TOKEN` | | **403** | Extension (`background.js:432`) | `CAPTCHA_FAILED`, `NO_FLOW_TAB`, or `MODEL_ACCESS_DENIED` — read the suffix | | **404** | Flow API | `media_id` not found — same handler as "entity not found" | | **429** | Flow API | Rate-limit or quota — backoff; if message mentions QUOTA_REACHED, terminal | | **500** | Flow backend **or** extension fetch exception (`background.js:504`) | Transient — retry with backoff | | **502** | FastAPI (`agent/api/flow.py:80,92`) | Extension returned error without explicit status — treat as transient | -| **503** | FastAPI | "Extension not connected" or `NO_FLOW_KEY` — worker re-queues PENDING, waits | +| **503** | FastAPI | "Extension not connected" — worker re-queues PENDING, waits | | **504** | Agent | 60s WS timeout waiting for extension — transient, re-queue | Detection lives in `agent/worker/_parsing.py:_is_error`. A result is treated as an error if ANY of these hold: @@ -127,7 +125,6 @@ Detection lives in `agent/worker/_parsing.py:_is_error`. A result is treated as | `Extension not connected` | WS dropped or extension offline | Reload extension at `chrome://extensions`; worker auto-retries | | `extension reconnected` / `extension disconnected` | WS bounce mid-request | Auto re-queue, `retry_count` NOT incremented | | `extension_switched` | User switched active Flow tab | Auto re-queue | -| `NO_FLOW_KEY` | No bearer token captured — **legacy path only**; expected and harmless on the batch path | Only meaningful with `USE_BATCH_RPC=0`; otherwise ignore | | `NO_FLOW_TAB` | No Flow tab for CAPTCHA solve or RPC signing | Open `https://flow.google.com/` and sign in | | `Failed to fetch` | Network drop inside service worker | Auto-retry with backoff | | WS 60s timeout | Extension hung | Reload extension; worker re-queues | @@ -141,7 +138,7 @@ Detection lives in `agent/worker/_parsing.py:_is_error`. A result is treated as | `FLOW_TAB_DISCARDED` | Chrome discarded the backgrounded tab and the reload did not revive it | Retried with backoff | Pin the Flow tab, or keep its window visible | | `NO_FLOW_PROJECT` | No Flow project to scope the RPC to | **Terminal — not retried** | Create a project in the Flow UI, pin its uuid as `FLOW_PROJECT_ID` (or pass `flow_project_id` on `POST /api/projects`) | | `UNSUPPORTED_ON_BATCH_API` | A capability whose payload was never captured off the new UI: **video upscale**, **r2v**, **start+end-frame chaining** | **Terminal — not retried** | For chaining and r2v, `FLOW_ALLOW_DEGRADED=1` falls back to plain i2v off the start frame. Upscale has no fallback. Real fix: capture the payload — `docs/CAPTURE.md` | -| `UNSUPPORTED_ON_BATCH_API: Omni Flash` | Omni speaks the pre-migration REST + tRPC endpoints; no batchexecute payload captured | **Terminal — not retried** | Use `model_family=veo`, or `USE_BATCH_RPC=0` on a profile that still holds a bearer | +| `UNSUPPORTED_ON_BATCH_API: Omni Flash` | Omni frame/reference had only a REST implementation; no batchexecute payload captured | **Terminal — not retried** | Use `model_family=veo`, or Omni **text-to-video**, which is migrated | | `PUBLIC_ERROR_UNUSUAL_ACTIVITY` | A reCAPTCHA token was replayed — they are single-use | Retried as a captcha error | Usually self-clears; if it persists the extension is reusing a token, reload it | | `no ogiZ0b envelope in response` | The RPC answered but not with the payload we came for — usually a signed-out page returning an HTML redirect | Retried with backoff | Re-sign in on the Flow tab | | `Polling timeout after Ns: Media not found.` | The job never produced media inside the budget | Terminal after `MAX_RETRIES` | The quoted complaint is a **diagnostic, not the cause** — finished jobs report it too. Check the Flow UI: if the clip is there, raise `VIDEO_POLL_TIMEOUT` | @@ -191,7 +188,7 @@ When the user describes a symptom in plain language, map it here first. | Problem | Solution | |---------|----------| | Extension shows "Agent disconnected" | Start `python -m agent.main` | -| Extension shows "No token" | Expected on the batch path — there is no bearer any more. Only act on it with `USE_BATCH_RPC=0` | +| Extension shows "No token" | Expected — there is no bearer any more. Not a fault | | `CAPTCHA_FAILED: NO_FLOW_TAB` | Open `https://flow.google.com/` — and check the extension is v0.3.0+, older builds only matched the dead labs.google URL and could not see the tab that was right there | | 403 `MODEL_ACCESS_DENIED` | Tier mismatch — `GET /api/flow/credits`, downgrade model in `models.json` via `/fk-change-model` | | 403 `PUBLIC_ERROR_UNUSUAL_ACTIVITY` / `reCAPTCHA evaluation failed` | Google flagged the session as bot-like (rapid bursts, VPN/shared IP, stale cookies). **Pause submits**, then in Chrome: `chrome://settings/cookies` → remove cookies for `google.com` and `labs.google` → reload `flow.google.com` → sign in & solve any captcha → resubmit with ≥1s gap and ≤5 concurrent. Switch network or wait 1–6 h if still blocked | @@ -224,7 +221,6 @@ Always end with a prescription block: Symptom: <what the user observed> Root cause: <what actually went wrong> Layer: Flow | Extension | FastAPI | Worker | YouTube | Env -Transport: batch (flow.google.com) | legacy REST (aisandbox-pa) Auto-handler: <which branch of _handle_failure fires, or "none — terminal"> === FIX === diff --git a/skills/fk-refresh-urls.md b/skills/fk-refresh-urls.md index 5c364eb18..9689d56e0 100644 --- a/skills/fk-refresh-urls.md +++ b/skills/fk-refresh-urls.md @@ -116,7 +116,7 @@ curl -X PATCH "http://127.0.0.1:8100/api/scenes/<SID>" \ | Issue | Cause | Fix | |-------|-------|-----| -| `flow_key_present: false` | No bearer token — **expected on the batch path** | Ignore; only meaningful with `USE_BATCH_RPC=0` | +| `flow_key_present: false` | No bearer token — **expected**; batchexecute authenticates in the page | Ignore | | `Extension not connected` | Chrome extension WS disconnected | Check the extension is enabled, refresh the Flow tab | | `refreshed: 0`, `found: 0` | No media ids stored for this project | Nothing to refresh — check the project id | | `refreshed: 0`, `found: N` | Every re-sign failed | Read the agent log; usually `NO_FLOW_TAB` or a signed-out Flow tab | diff --git a/tests/unit/test_flow_client_batch.py b/tests/unit/test_flow_client_batch.py index c38c09ed1..f91d61da0 100644 --- a/tests/unit/test_flow_client_batch.py +++ b/tests/unit/test_flow_client_batch.py @@ -32,7 +32,6 @@ def client(monkeypatch): envelope as well as on what came back. """ import agent.services.flow_client as module - monkeypatch.setattr(module, "USE_BATCH_RPC", True) monkeypatch.setattr(module, "FLOW_PROJECT_ID", PROJECT) monkeypatch.setattr(module, "FLOW_ALLOW_DEGRADED", False) diff --git a/tests/unit/test_omni_flash.py b/tests/unit/test_omni_flash.py index cf3b2fb14..617054eb1 100644 --- a/tests/unit/test_omni_flash.py +++ b/tests/unit/test_omni_flash.py @@ -1,9 +1,20 @@ -"""Unit tests for Gemini Omni Flash Flow submissions and workflow polling. - -Omni speaks the pre-migration transports — the REST endpoints on aisandbox-pa -and the labs.google tRPC snapshot it polls through — so the wire contracts -asserted here are legacy-path contracts and the module is pinned to that path -for the file. What happens on the batch path is one test at the bottom. +"""Unit tests for Gemini Omni Flash submissions and workflow polling. + +Omni has one working surface — text-to-video on batchexecute — and three that +are not ported. So these cover three things: `_load_model_key`, the input +validation that runs before any transport is touched, and that the unported +modes say so instead of reaching for auth that is gone. + +Note on `_load_model_key`: it currently has **no production caller**. Frame and +reference generation used to call it and now return early, and text-to-video +hardcodes `abra_t2v_{n}s` instead of reading models.json. The cases below pin +the mapping for when that is fixed; they are not evidence that model keys are +configurable today. + +The REST and tRPC wire-contract tests that used to live here went with the +transport they asserted. They were pinned to the legacy path by a module-level +autouse fixture, which meant most of this file was testing code that no longer +runs. Git history has them if a capture ever needs a reference. """ from unittest.mock import AsyncMock, MagicMock, patch @@ -13,8 +24,6 @@ import agent.services.omni_flash as omni_flash from agent.services.omni_flash import ( OMNI_FLASH_MAX_REFERENCE_IMAGES, - _fetch_media_url, - _fetch_project_initial_data, _load_model_key, check_omni_flash_status, extract_omni_workflows, @@ -25,20 +34,11 @@ ) -@pytest.fixture(autouse=True) -def legacy_transport(monkeypatch): - """Omni is only reachable on the pre-migration path; assert it there.""" - monkeypatch.setattr(omni_flash, "USE_BATCH_RPC", False) - +# ─── model key policy (models.json, transport-independent) ────────────────── @pytest.mark.parametrize( ("duration", "expected"), - [ - (4, "abra_r2v_4s"), - (6, "abra_r2v_6s"), - (8, "abra_r2v_8s"), - (10, "abra_r2v_10s"), - ], + [(4, "abra_r2v_4s"), (6, "abra_r2v_6s"), (8, "abra_r2v_8s"), (10, "abra_r2v_10s")], ) def test_omni_reference_duration_model_keys(duration, expected): assert _load_model_key(duration) == expected @@ -46,12 +46,7 @@ def test_omni_reference_duration_model_keys(duration, expected): @pytest.mark.parametrize( ("duration", "expected"), - [ - (4, "abra_i2v_4s"), - (6, "abra_i2v_6s"), - (8, "abra_i2v_8s"), - (10, "abra_i2v_10s"), - ], + [(4, "abra_i2v_4s"), (6, "abra_i2v_6s"), (8, "abra_i2v_8s"), (10, "abra_i2v_10s")], ) def test_omni_first_frame_model_keys(duration, expected): assert _load_model_key(duration, mode="frame_to_video") == expected @@ -59,14 +54,11 @@ def test_omni_first_frame_model_keys(duration, expected): @pytest.mark.parametrize( ("duration", "expected"), - [ - (4, "abra_i2v_4s"), - (6, "abra_i2v_6s"), - (8, "abra_i2v_8s"), - (10, "abra_i2v_10s"), - ], + [(4, "abra_i2v_4s"), (6, "abra_i2v_6s"), (8, "abra_i2v_8s"), (10, "abra_i2v_10s")], ) def test_omni_first_last_model_keys_are_independently_configured(duration, expected): + """Same family as first-frame today, but its own key so a rollout that + splits them does not need a code release.""" assert _load_model_key(duration, mode="start_end_frame_to_video") == expected @@ -75,21 +67,20 @@ def test_invalid_duration_fails_before_submit(): _load_model_key(5) +# ─── polling descriptors ──────────────────────────────────────────────────── + def test_extract_omni_workflows_uses_primary_media_id(): + """A submit carries operation-looking handles that are NOT pollable as + operations. The workflow's primaryMediaId is the one that is.""" result = { "status": 200, "data": { "operations": [ - { - "operation": {"name": "operation-looking-handle"}, - "status": "MEDIA_GENERATION_STATUS_PENDING", - } + {"operation": {"name": "operation-looking-handle"}, + "status": "MEDIA_GENERATION_STATUS_PENDING"} ], "workflows": [ - { - "name": "workflow-1", - "metadata": {"primaryMediaId": "media-1"}, - } + {"name": "workflow-1", "metadata": {"primaryMediaId": "media-1"}} ], }, } @@ -98,44 +89,28 @@ def test_extract_omni_workflows_uses_primary_media_id(): ] -def _mock_submit_client(): +@pytest.mark.asyncio +async def test_batch_omni_poll_uses_as29s_media(): client = MagicMock() - client._client_context.return_value = { - "projectId": "project-1", - "tool": "PINHOLE", - "userPaygateTier": "PAYGATE_TIER_ONE", - "recaptchaContext": { - "applicationType": "RECAPTCHA_APPLICATION_TYPE_WEB", - "token": "", - }, - "sessionId": ";old", - } - client._build_url.side_effect = lambda name: f"https://example.test/{name}" - client._send = AsyncMock( - return_value={ - "status": 200, - "data": { - "operations": [ - { - "operation": {"name": "op-1"}, - "status": "MEDIA_GENERATION_STATUS_PENDING", - } - ], - "workflows": [ - { - "name": "workflow-1", - "metadata": {"primaryMediaId": "media-1"}, - } - ], - }, - } - ) - return client + client.get_media = AsyncMock(return_value={ + "status": 200, + "data": {"video": {"fifeUrl": "https://flow-content.google/video/media-1?Signature=test"}}, + }) + with patch("agent.services.omni_flash.get_flow_client", return_value=client): + result = await check_omni_flash_status([{ + "name": "workflow-1", "primary_media_id": "media-1", "project_id": "project-1", + }]) + assert result["done"] is True + assert result["workflows"][0]["media"]["resolved_via"] == "as29s" + client.get_media.assert_awaited_once_with("media-1") +# ─── text-to-video: the one Omni surface on the batch path ────────────────── + @pytest.mark.asyncio -async def test_batch_text_video_builds_4s_yhhmef_submit(monkeypatch): - monkeypatch.setattr(omni_flash, "USE_BATCH_RPC", True) +async def test_batch_text_video_builds_4s_yhhmef_submit(): + import json + client = MagicMock() client._batch_project_id.return_value = "11111111-2222-3333-4444-555555555555" client._batch_payload = AsyncMock(return_value=[ @@ -159,386 +134,69 @@ async def test_batch_text_video_builds_4s_yhhmef_submit(monkeypatch): rpcid, freq, captcha = client._batch_payload.await_args.args[:3] assert rpcid == omni_flash.fb.RPC_GEN_VIDEO_TEXT assert captcha == omni_flash.fb.CAPTCHA_VIDEO - payload = __import__("json").loads(__import__("json").loads(freq)[0][0][1]) + payload = json.loads(json.loads(freq)[0][0][1]) assert payload[0][0][1] == "abra_t2v_4s" -@pytest.mark.asyncio -async def test_submit_builds_flow_omni_first_frame_request_and_poll_descriptor(): - client = _mock_submit_client() - - with patch("agent.services.omni_flash.get_flow_client", return_value=client): - result = await generate_omni_flash_first_frame_video( - start_image_media_id="start-1", - prompt="Camera slowly pushes in", - project_id="project-1", - scene_id="scene-1", - duration_s=10, - aspect_ratio="VIDEO_ASPECT_RATIO_LANDSCAPE", - user_paygate_tier="PAYGATE_TIER_ONE", - seed=321, - ) - - client._build_url.assert_called_once_with("generate_video") - method, params = client._send.await_args.args[:2] - assert method == "api_request" - assert params["captchaAction"] == "VIDEO_GENERATION" - - body = params["body"] - assert body["useV2ModelConfig"] is True - assert set(body["mediaGenerationContext"]) == {"batchId"} - request = body["requests"][0] - assert request["videoModelKey"] == "abra_i2v_10s" - assert request["startImage"] == {"mediaId": "start-1"} - assert "endImage" not in request - assert request["seed"] == 321 - assert result["data"]["flowkitPolling"]["mode"] == "project_media" - assert result["data"]["flowkitPolling"]["project_id"] == "project-1" - - -@pytest.mark.asyncio -async def test_submit_builds_flow_omni_first_last_request(): - client = _mock_submit_client() - - with patch("agent.services.omni_flash.get_flow_client", return_value=client): - result = await generate_omni_flash_first_last_video( - start_image_media_id="start-1", - end_image_media_id="end-1", - prompt="Move naturally from the first composition to the final composition", - project_id="project-1", - scene_id="scene-1", - duration_s=8, - aspect_ratio="VIDEO_ASPECT_RATIO_PORTRAIT", - user_paygate_tier="PAYGATE_TIER_ONE", - seed=456, - ) - - client._build_url.assert_called_once_with("generate_video_start_end") - method, params = client._send.await_args.args[:2] - assert method == "api_request" - body = params["body"] - request = body["requests"][0] - assert request["videoModelKey"] == "abra_i2v_8s" - assert request["startImage"] == {"mediaId": "start-1"} - assert request["endImage"] == {"mediaId": "end-1"} - assert request["aspectRatio"] == "VIDEO_ASPECT_RATIO_PORTRAIT" - assert request["seed"] == 456 - assert result["data"]["flowkitPolling"]["workflows"] == [ - { - "name": "workflow-1", - "primary_media_id": "media-1", - "project_id": "project-1", - } - ] - +# ─── validation runs before the capability gap is reported ────────────────── +# +# Order matters: a caller with a bad duration AND an unported mode should hear +# about the duration, which it can fix, rather than the gap, which it cannot. @pytest.mark.asyncio async def test_first_frame_rejects_missing_start_before_submit(): with pytest.raises(ValueError, match="requires start_image_media_id"): await generate_omni_flash_first_frame_video( - start_image_media_id="", - prompt="test", - project_id="p", - ) + start_image_media_id="", prompt="test", project_id="p") @pytest.mark.asyncio async def test_first_last_rejects_missing_end_before_submit(): with pytest.raises(ValueError, match="non-empty end_image_media_id"): await generate_omni_flash_first_last_video( - start_image_media_id="start", - end_image_media_id="", - prompt="test", - project_id="p", - ) - - -@pytest.mark.asyncio -async def test_submit_builds_flow_omni_r2v_request_and_poll_descriptor(): - client = _mock_submit_client() - - with patch("agent.services.omni_flash.get_flow_client", return_value=client): - result = await generate_omni_flash_video( - reference_media_ids=["ref-1", "ref-2"], - prompt="Two friends talking in a cafe", - project_id="project-1", - scene_id="scene-1", - duration_s=10, - aspect_ratio="VIDEO_ASPECT_RATIO_LANDSCAPE", - user_paygate_tier="PAYGATE_TIER_ONE", - seed=123, - ) - - assert result["status"] == 200 - assert result["data"]["flowkitPolling"] == { - "mode": "project_media", - "project_id": "project-1", - "workflows": [ - { - "name": "workflow-1", - "primary_media_id": "media-1", - "project_id": "project-1", - } - ], - } - client._build_url.assert_called_once_with("generate_video_references") - client._send.assert_awaited_once() - - method, params = client._send.await_args.args[:2] - assert method == "api_request" - assert params["captchaAction"] == "VIDEO_GENERATION" - - body = params["body"] - assert body["useV2ModelConfig"] is True - assert body["mediaGenerationContext"]["audioFailurePreference"] == "BLOCK_SILENCED_VIDEOS" - assert body["clientContext"]["projectId"] == "project-1" - - request = body["requests"][0] - assert request["videoModelKey"] == "abra_r2v_10s" - assert request["aspectRatio"] == "VIDEO_ASPECT_RATIO_LANDSCAPE" - assert request["seed"] == 123 - assert request["metadata"] == {"sceneId": "scene-1"} - assert request["referenceImages"] == [ - {"mediaId": "ref-1", "imageUsageType": "IMAGE_USAGE_TYPE_ASSET"}, - {"mediaId": "ref-2", "imageUsageType": "IMAGE_USAGE_TYPE_ASSET"}, - ] - - -def _project_response(generation_status="MEDIA_GENERATION_STATUS_PENDING", include_media=True): - media = [] - if include_media: - media.append( - { - "name": "media-1", - "projectId": "project-1", - "workflowId": "workflow-1", - "mediaMetadata": { - "mediaStatus": {"mediaGenerationStatus": generation_status} - }, - "video": {"generatedVideo": {"model": "abra_r2v_4s"}}, - } - ) - return { - "status": 200, - "data": { - "result": { - "data": { - "json": { - "projectContents": { - "workflows": [ - { - "name": "workflow-1", - "projectId": "project-1", - "metadata": {"primaryMediaId": "media-1"}, - } - ], - "media": media, - } - } - } - } - }, - } - - -@pytest.mark.asyncio -async def test_project_poll_fetch_matches_live_flow_trpc_contract(): - client = MagicMock() - client._send = AsyncMock(return_value={"status": 200, "data": {}}) - - await _fetch_project_initial_data(client, "project-1") - - client._send.assert_awaited_once_with( - "trpc_request", - { - "url": ( - "https://labs.google/fx/api/trpc/flow.projectInitialData?input=" - "%7B%22json%22%3A%7B%22projectId%22%3A%22project-1%22%7D%7D" - ), - "method": "GET", - "headers": {"content-type": "application/json"}, - }, - timeout=15, - ) - - -@pytest.mark.asyncio -async def test_media_redirect_fetch_requests_url_only_mode(): - client = MagicMock() - client._send = AsyncMock(return_value={"status": 200, "data": {}}) - - await _fetch_media_url(client, "media-1") - - client._send.assert_awaited_once_with( - "trpc_request", - { - "url": ( - "https://labs.google/fx/api/trpc/media.getMediaUrlRedirect" - "?name=media-1" - ), - "method": "GET", - "headers": {"content-type": "application/json"}, - "responseMode": "url", - }, - timeout=15, - ) - - -@pytest.mark.asyncio -async def test_batch_omni_poll_uses_as29s_media(monkeypatch): - monkeypatch.setattr(omni_flash, "USE_BATCH_RPC", True) - client = MagicMock() - client.get_media = AsyncMock(return_value={ - "status": 200, - "data": {"video": {"fifeUrl": "https://flow-content.google/video/media-1?Signature=test"}}, - }) - with patch("agent.services.omni_flash.get_flow_client", return_value=client): - result = await check_omni_flash_status([{ - "name": "workflow-1", "primary_media_id": "media-1", "project_id": "project-1", - }]) - assert result["done"] is True - assert result["workflows"][0]["media"]["resolved_via"] == "as29s" - client.get_media.assert_awaited_once_with("media-1") - - -@pytest.mark.asyncio -async def test_omni_poll_pending_uses_project_snapshot_not_legacy_transports(): - client = MagicMock() - client._send = AsyncMock(return_value=_project_response()) - client.get_media = AsyncMock(side_effect=AssertionError("legacy get_media forbidden")) - client.check_video_status = AsyncMock(side_effect=AssertionError("operation poll forbidden")) - - with patch("agent.services.omni_flash.get_flow_client", return_value=client): - result = await check_omni_flash_status( - [ - { - "name": "workflow-1", - "primary_media_id": "media-1", - "project_id": "project-1", - } - ] - ) - - client.get_media.assert_not_awaited() - client.check_video_status.assert_not_awaited() - client._send.assert_awaited_once() - assert result["done"] is False - assert result["status"] == "PENDING" - assert result["workflows"][0]["status"] == "PENDING" - - -@pytest.mark.asyncio -async def test_omni_poll_completed_returns_signed_url_without_buffering_video(): - client = MagicMock() - client._send = AsyncMock( - side_effect=[ - _project_response("MEDIA_GENERATION_STATUS_SUCCESSFUL"), - { - "status": 200, - "data": { - "url": "https://flow-content.google/video/media-1?Signature=test" - }, - }, - ] - ) - - with patch("agent.services.omni_flash.get_flow_client", return_value=client): - result = await check_omni_flash_status( - [{"name": "workflow-1", "primary_media_id": "media-1"}], - project_id="project-1", - ) - - assert result["done"] is True - assert result["status"] == "COMPLETED" - item = result["workflows"][0] - assert item["status"] == "MEDIA_GENERATION_STATUS_SUCCESSFUL" - assert item["media"]["media_id"] == "media-1" - assert item["media"]["url"].startswith("https://flow-content.google/video/") - assert item["media"]["encoded_video_available"] is False - assert "encoded_video" not in item["media"] - - -@pytest.mark.asyncio -async def test_omni_poll_missing_media_is_pending(): - client = MagicMock() - client._send = AsyncMock(return_value=_project_response(include_media=False)) - - with patch("agent.services.omni_flash.get_flow_client", return_value=client): - result = await check_omni_flash_status( - [{"name": "workflow-1", "primary_media_id": "media-1"}], - project_id="project-1", - ) - - assert result["done"] is False - assert result["workflows"][0]["status"] == "PENDING" - - -@pytest.mark.asyncio -async def test_omni_poll_requires_project_id_for_legacy_descriptors(): - with pytest.raises(ValueError, match="requires project_id"): - await check_omni_flash_status( - [{"name": "workflow-1", "primary_media_id": "media-1"}] - ) - - -@pytest.mark.asyncio -async def test_submit_accepts_seven_references(): - client = MagicMock() - client._client_context.return_value = {"projectId": "p"} - client._build_url.return_value = "https://example.test/omni" - client._send = AsyncMock(return_value={"status": 200, "data": {}}) - refs = [f"ref-{i}" for i in range(OMNI_FLASH_MAX_REFERENCE_IMAGES)] - - with patch("agent.services.omni_flash.get_flow_client", return_value=client): - await generate_omni_flash_video( - reference_media_ids=refs, - prompt="test", - project_id="p", - duration_s=4, - ) - - request = client._send.await_args.args[1]["body"]["requests"][0] - assert len(request["referenceImages"]) == 7 + start_image_media_id="start", end_image_media_id="", + prompt="test", project_id="p") @pytest.mark.asyncio async def test_submit_rejects_more_than_seven_references(): refs = [f"ref-{i}" for i in range(OMNI_FLASH_MAX_REFERENCE_IMAGES + 1)] - with pytest.raises(ValueError, match="at most 7 reference images"): await generate_omni_flash_video( - reference_media_ids=refs, - prompt="test", - project_id="p", - duration_s=8, - ) + reference_media_ids=refs, prompt="test", project_id="p", duration_s=8) @pytest.mark.asyncio async def test_submit_rejects_empty_reference_set(): with pytest.raises(ValueError, match="requires at least one reference image"): await generate_omni_flash_video( - reference_media_ids=[], - prompt="test", - project_id="p", - duration_s=8, - ) + reference_media_ids=[], prompt="test", project_id="p", duration_s=8) + + +@pytest.mark.asyncio +async def test_seven_references_pass_validation_and_reach_the_capability_gap(): + """Seven is the limit, not one past it — so this must fail on the gap, not + on the count. Guards the boundary against an off-by-one in the validator.""" + refs = [f"ref-{i}" for i in range(OMNI_FLASH_MAX_REFERENCE_IMAGES)] + result = await generate_omni_flash_video( + reference_media_ids=refs, prompt="test", project_id="p", duration_s=4) + assert "UNSUPPORTED_ON_BATCH_API" in result["error"] -class TestUnportedOmniBatchModesAreRefusedRatherThanAttempted: - """Flow stopped minting the bearer these endpoints need, and no Omni - payload has been captured off the new frontend. Saying so beats a 401 - five retries deep.""" +# ─── unported modes ───────────────────────────────────────────────────────── - @pytest.fixture(autouse=True) - def batch_transport(self, monkeypatch): - monkeypatch.setattr(omni_flash, "USE_BATCH_RPC", True) +class TestUnportedOmniModesAreRefusedRatherThanAttempted: + """Frame and reference generation had only a REST implementation, and that + transport is gone. Naming the gap beats a 401 five retries deep — and beats + silently submitting with a Veo key, which is what a careless unification + of these paths would do.""" @pytest.fixture def client(self): with patch("agent.services.omni_flash.get_flow_client") as factory: stub = MagicMock() stub._send = AsyncMock() + stub.generate_video = AsyncMock() factory.return_value = stub yield stub @@ -547,6 +205,7 @@ async def test_first_frame_names_the_gap_and_sends_nothing(self, client): start_image_media_id="mid", prompt="go", project_id="pid") assert "UNSUPPORTED_ON_BATCH_API" in result["error"] client._send.assert_not_called() + client.generate_video.assert_not_called() async def test_first_last_names_the_gap_and_sends_nothing(self, client): result = await generate_omni_flash_first_last_video( @@ -554,14 +213,18 @@ async def test_first_last_names_the_gap_and_sends_nothing(self, client): prompt="go", project_id="pid") assert "UNSUPPORTED_ON_BATCH_API" in result["error"] client._send.assert_not_called() + client.generate_video.assert_not_called() async def test_reference_to_video_names_the_gap_and_sends_nothing(self, client): result = await generate_omni_flash_video( reference_media_ids=["a"], prompt="go", project_id="pid") assert "UNSUPPORTED_ON_BATCH_API" in result["error"] client._send.assert_not_called() + client.generate_video.assert_not_called() async def test_the_message_points_to_supported_text_to_video(self, client): + """The error is the only place a caller learns there IS a working Omni + surface, so it names both the gap and the way round it.""" result = await generate_omni_flash_video( reference_media_ids=["a"], prompt="go", project_id="pid") assert "text-to-video is supported" in result["error"] diff --git a/tests/unit/test_operations.py b/tests/unit/test_operations.py index 670435164..c0b85e2da 100644 --- a/tests/unit/test_operations.py +++ b/tests/unit/test_operations.py @@ -159,6 +159,60 @@ async def test_uses_landscape_for_horizontal_orientation(self, service, base_sce assert call_kwargs["aspect_ratio"] == "IMAGE_ASPECT_RATIO_LANDSCAPE" +# --------------------------------------------------------------------------- +# Test: generate_scene_video — the retry branch +# --------------------------------------------------------------------------- + +class TestGenerateSceneVideoRetry: + """A retry must re-poll a submitted render, never resubmit it. + + This is the one branch where a wrong answer costs money: resubmitting + abandons a render Flow is already paying for and starts a second one. It + was previously gated on the transport (`bare_uuid and not USE_BATCH_RPC`), + which made it dead on the only transport that exists, so it went untested. + """ + + @pytest.mark.asyncio + async def test_a_submitted_operation_is_repolled_not_resubmitted( + self, service, base_scene, mock_client): + mock_client.generate_video = AsyncMock() + polled = {"data": {"operations": [{"status": "MEDIA_GENERATION_STATUS_SUCCESSFUL"}]}} + + with patch("agent.sdk.services.operations.crud") as mock_crud, \ + patch("agent.sdk.services.operations._build_video_prompt", + new=AsyncMock(return_value="p")), \ + patch("agent.sdk.services.operations._poll_operations", + new=AsyncMock(return_value=polled)) as mock_poll: + mock_crud.get_project = AsyncMock(return_value={"user_paygate_tier": "PAYGATE_TIER_ONE"}) + mock_crud.get_request = AsyncMock(return_value={"request_id": SAMPLE_UUID_2}) + + result = await service.generate_scene_video( + base_scene, "VERTICAL", request_id="req-1") + + mock_client.generate_video.assert_not_called() + assert mock_poll.await_args.args[1][0]["operation"]["name"] == SAMPLE_UUID_2 + assert result is polled + + @pytest.mark.asyncio + async def test_no_prior_operation_still_submits(self, service, base_scene, mock_client): + """The complement — the guard must not swallow a first attempt.""" + mock_client.generate_video = AsyncMock( + return_value={"data": {"operations": [{"operation": {"name": "op-new"}}]}}) + + with patch("agent.sdk.services.operations.crud") as mock_crud, \ + patch("agent.sdk.services.operations._build_video_prompt", + new=AsyncMock(return_value="p")), \ + patch("agent.sdk.services.operations._poll_operations", + new=AsyncMock(return_value={"data": {}})): + mock_crud.get_project = AsyncMock(return_value={"user_paygate_tier": "PAYGATE_TIER_ONE"}) + mock_crud.get_request = AsyncMock(return_value=None) + mock_crud.update_request = AsyncMock() + + await service.generate_scene_video(base_scene, "VERTICAL", request_id="req-1") + + mock_client.generate_video.assert_called_once() + + # --------------------------------------------------------------------------- # Test: edit_scene_image # --------------------------------------------------------------------------- From d009dc2d396e14b7a043eb21058d6c91be434dc2 Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Thu, 17 Sep 2026 23:40:19 +0700 Subject: [PATCH 17/68] fix(tests): repair two mocks that drifted behind refactors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Six tests failed for reasons unrelated to the code under test, and one of them hung the interpreter. test_processor.py patched `agent.worker.processor._retry_state`, a module global that no longer exists: retry state became the instance attribute `self._retry_after` plus an explicit `retry_after` parameter on _handle_failure. mock.patch refuses a missing attribute without create=True, so all three tests raised AttributeError before their bodies ran. The assertions were always fine — _handle_failure(rid, req, result) still matches the signature — so the patch line just goes. test_result_handler.py mocked crud.update_scene but not crud.get_scene, which c071cb8 added at result_handler.py:61 for the chain cascade. Since April those three tests hit a real database with no schema, hence "no such table: scene". They now mock get_scene returning None — the no-parent case, which keeps update_scene's assert_awaited_once true. That accidental connection was also why `pytest tests/unit` never exited: aiosqlite services each connection on a non-daemon worker thread, and this one was never closed, so the thread outlived the session. Piping the run hid it, because the summary sat in the pipe buffer while the process refused to die. 266 passed, and the process exits. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5BJVhNgerhFTUgmfnKTSj --- tests/unit/test_processor.py | 9 +++------ tests/unit/test_result_handler.py | 12 ++++++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/unit/test_processor.py b/tests/unit/test_processor.py index 2340a209c..c2f7e9850 100644 --- a/tests/unit/test_processor.py +++ b/tests/unit/test_processor.py @@ -139,8 +139,7 @@ async def test_retries_when_under_max_retries(self): rid = req["id"] result = {"error": "timeout"} - with patch("agent.worker.processor.crud") as mock_crud, \ - patch("agent.worker.processor._retry_state", {}): + with patch("agent.worker.processor.crud") as mock_crud: mock_crud.update_request = AsyncMock() mock_crud.update_scene = AsyncMock() await _handle_failure(rid, req, result) @@ -158,8 +157,7 @@ async def test_marks_failed_when_at_max_retries(self): rid = req["id"] result = {"error": "permanent failure"} - with patch("agent.worker.processor.crud") as mock_crud, \ - patch("agent.worker.processor._retry_state", {}): + with patch("agent.worker.processor.crud") as mock_crud: mock_crud.update_request = AsyncMock() mock_crud.update_scene = AsyncMock() await _handle_failure(rid, req, result) @@ -185,8 +183,7 @@ async def test_extracts_error_message_from_nested_data(self): } } - with patch("agent.worker.processor.crud") as mock_crud, \ - patch("agent.worker.processor._retry_state", {}): + with patch("agent.worker.processor.crud") as mock_crud: mock_crud.update_request = AsyncMock() mock_crud.update_scene = AsyncMock() await _handle_failure(rid, req, result) diff --git a/tests/unit/test_result_handler.py b/tests/unit/test_result_handler.py index 2641f64c7..6b893b38c 100644 --- a/tests/unit/test_result_handler.py +++ b/tests/unit/test_result_handler.py @@ -60,6 +60,10 @@ def test_parse_result_raw_is_attached(sample_image_success): @pytest.mark.asyncio async def test_apply_scene_result_generate_image_sets_fields_and_cascades(sample_uuid, mocker): mock_update = mocker.patch("agent.sdk.services.result_handler.crud.update_scene", new_callable=AsyncMock) + # The chain cascade reads the scene back; unmocked this opens a real aiosqlite + # connection, whose worker thread then outlives the test session. + mocker.patch("agent.sdk.services.result_handler.crud.get_scene", + new_callable=AsyncMock, return_value=None) result = GenerationResult(success=True, media_id=sample_uuid, url="https://example.com/img.jpg") await apply_scene_result("scene-001", "GENERATE_IMAGE", "VERTICAL", result) @@ -78,6 +82,10 @@ async def test_apply_scene_result_generate_image_sets_fields_and_cascades(sample @pytest.mark.asyncio async def test_apply_scene_result_edit_image_same_cascade_as_generate(sample_uuid, mocker): mock_update = mocker.patch("agent.sdk.services.result_handler.crud.update_scene", new_callable=AsyncMock) + # The chain cascade reads the scene back; unmocked this opens a real aiosqlite + # connection, whose worker thread then outlives the test session. + mocker.patch("agent.sdk.services.result_handler.crud.get_scene", + new_callable=AsyncMock, return_value=None) result = GenerationResult(success=True, media_id=sample_uuid, url="https://example.com/img.jpg") await apply_scene_result("scene-001", "EDIT_IMAGE", "VERTICAL", result) @@ -146,6 +154,10 @@ async def test_apply_scene_result_skips_when_result_failed(mocker): @pytest.mark.asyncio async def test_apply_scene_result_horizontal_orientation_uses_correct_prefix(sample_uuid, mocker): mock_update = mocker.patch("agent.sdk.services.result_handler.crud.update_scene", new_callable=AsyncMock) + # The chain cascade reads the scene back; unmocked this opens a real aiosqlite + # connection, whose worker thread then outlives the test session. + mocker.patch("agent.sdk.services.result_handler.crud.get_scene", + new_callable=AsyncMock, return_value=None) result = GenerationResult(success=True, media_id=sample_uuid, url="https://example.com/img.jpg") await apply_scene_result("scene-001", "GENERATE_IMAGE", "HORIZONTAL", result) From f4e2265c8c9b605473af9c3e3f7d25ad3d7a5256 Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Thu, 17 Sep 2026 23:40:30 +0700 Subject: [PATCH 18/68] docs(doctor): teach /fk-doctor the NO_INJECTION_RESULT error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A live 2K export failed with `SPrCad: NO_INJECTION_RESULT` and the taxonomy had no entry for it, so diagnosing it meant reading background.js from scratch — the one thing this skill exists to prevent. The string comes from extension/background.js:540, where executeScript resolved with no frame result: the Flow tab was gone or still booting, so the envelope never ran. It landed on the first captcha-bearing RPC after an agent restart and cleared on retry. The row records what the evidence ruled out, because all three are easy to reach for and wrong: a failed captcha mint reports CAPTCHA_FAILED, an oversized payload is not it (MAX_RPC_TEXT is 32 MB), and a structured-clone failure surfaces as 500 rather than 502. Auto-handling is the generic branch in processor.py — retried with backoff, counted against MAX_RETRIES — not the captcha branch's ten free attempts. Also added to the auto-invoke trigger list, so the next one routes here instead of being guessed at. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5BJVhNgerhFTUgmfnKTSj --- skills/fk-doctor.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skills/fk-doctor.md b/skills/fk-doctor.md index 6c23f97bb..a13074b9c 100644 --- a/skills/fk-doctor.md +++ b/skills/fk-doctor.md @@ -6,7 +6,7 @@ Diagnose any FlowKit error and prescribe a fix. Knows the full error taxonomy ac - Any `/api/requests/*` response has `status=FAILED` or `error_message` is set - A request has been `PROCESSING` for > 10 minutes with no progress - `GET /health` returns `extension_connected: false` -- User reports any error string containing: `UNSAFE_GENERATION`, `QUOTA`, `not found`, `CAPTCHA`, `UNUSUAL_ACTIVITY`, `NO_AT_TOKEN`, `NO_FLOW_PROJECT`, `UNSUPPORTED_ON_BATCH_API`, `NO_FLOW_TAB`, `FLOW_TAB_DISCARDED`, `extension_switched`, `Failed to fetch`, `MODEL_ACCESS_DENIED`, `PAYGATE_TIER_TWO`, `invalidTags`, `quotaExceeded`, `invalid_grant` +- User reports any error string containing: `UNSAFE_GENERATION`, `QUOTA`, `not found`, `CAPTCHA`, `UNUSUAL_ACTIVITY`, `NO_AT_TOKEN`, `NO_FLOW_PROJECT`, `UNSUPPORTED_ON_BATCH_API`, `NO_FLOW_TAB`, `FLOW_TAB_DISCARDED`, `NO_INJECTION_RESULT`, `extension_switched`, `Failed to fetch`, `MODEL_ACCESS_DENIED`, `PAYGATE_TIER_TWO`, `invalidTags`, `quotaExceeded`, `invalid_grant` - User asks "why did X fail", "what's wrong with the pipeline", "why is this stuck", "tại sao X lỗi", "lỗi gì vậy" - An HTTP 4xx/5xx reaches the main agent from any endpoint under `127.0.0.1:8100` - A YouTube upload returns `HttpError` from `googleapiclient` @@ -136,6 +136,7 @@ Detection lives in `agent/worker/_parsing.py:_is_error`. A result is treated as | `NO_AT_TOKEN` | The Flow tab loaded but `WIZ_global_data.SNlM0e` is absent — the page is signed out, on an interstitial, or still booting | Retried with backoff | Open `https://flow.google.com/`, confirm you are signed in, let the app finish loading | | `NO_FLOW_TAB` | No Flow tab to sign the request | Extension opens one and retries once | Leave one signed-in Flow tab open; nothing here works headless | | `FLOW_TAB_DISCARDED` | Chrome discarded the backgrounded tab and the reload did not revive it | Retried with backoff | Pin the Flow tab, or keep its window visible | +| `NO_INJECTION_RESULT` | `chrome.scripting.executeScript` resolved with no frame result (`background.js:540`), so the envelope never ran — the Flow tab went away or was still booting at the moment of the call. Most likely on the first captcha-bearing RPC after an agent restart | Retried with backoff, counts against `MAX_RETRIES` | Usually transient — retry first. Rule out the lookalikes before digging: a failed mint reports `CAPTCHA_FAILED`, an oversized payload is not it (`MAX_RPC_TEXT` is 32 MB), and a structured-clone failure surfaces as 500, not 502. If it repeats, pin the Flow tab and reload the extension | | `NO_FLOW_PROJECT` | No Flow project to scope the RPC to | **Terminal — not retried** | Create a project in the Flow UI, pin its uuid as `FLOW_PROJECT_ID` (or pass `flow_project_id` on `POST /api/projects`) | | `UNSUPPORTED_ON_BATCH_API` | A capability whose payload was never captured off the new UI: **video upscale**, **r2v**, **start+end-frame chaining** | **Terminal — not retried** | For chaining and r2v, `FLOW_ALLOW_DEGRADED=1` falls back to plain i2v off the start frame. Upscale has no fallback. Real fix: capture the payload — `docs/CAPTURE.md` | | `UNSUPPORTED_ON_BATCH_API: Omni Flash` | Omni frame/reference had only a REST implementation; no batchexecute payload captured | **Terminal — not retried** | Use `model_family=veo`, or Omni **text-to-video**, which is migrated | From 0c45b397c9f49a8162454bc82e9e5caca775899d Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Thu, 17 Sep 2026 23:40:42 +0700 Subject: [PATCH 19/68] chore(extension): bump to 0.3.2 and note the new Flow API works MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 43b0406 changed background.js and injected.js without bumping the manifest, so /health reported 0.3.1 for both the pre- and post-merge build. There was no way to tell a stale extension from a current one — which is the first question you ask when an RPC misbehaves. background.js:229 reports getManifest().version, so the bump makes it answerable; reload the extension once and /health says 0.3.2. README gets the status at the top, where someone landing on the repo sees it before anything else: the batchexecute transport is verified end to end against the live API — image generation, 2K export and i2v — and the four unported capabilities fail loudly rather than guessing. That list is taken from the guards themselves, not from the docs, because the docs disagreed. flow_client.py blocks start+end chaining, r2v and video upscale; omni_flash.py:33 blocks Omni frame/reference. CLAUDE.md calls the third one "4K upscale", which reads as the image export — and that one in fact works, verified at 1536x2752 from a 768x1376 source. CAPTURE.md lists a fourth item the image API merge has since ported. The Architecture callout's v0.3.0+ was aligned to v0.3.2+ so the two do not contradict. Also ignore extension/_metadata/, which Chrome generates when it loads the unpacked extension. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5BJVhNgerhFTUgmfnKTSj --- .gitignore | 4 +++- README.md | 19 ++++++++++++++++++- extension/manifest.json | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 766c04bdc..636c99a04 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,6 @@ GEMINI.md ds-bundle/ .design-sync/.cache/ .design-sync/learnings/ -.design-sync/node_modules \ No newline at end of file +.design-sync/node_modules +# Chrome generates this when it loads the unpacked extension +extension/_metadata/ diff --git a/README.md b/README.md index 997f52246..04be57229 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,23 @@ --- +> **Working against the new Google Flow API.** Flow moved to `flow.google.com` +> in September 2026 and stopped minting the `Bearer ya29.…` that the old +> `aisandbox-pa.googleapis.com` REST API needed. The `batchexecute` transport +> that replaces it is in place and verified end to end against the live API — +> image generation, 2K image export, and image-to-video all run green. Upgrading +> from an older Flow Kit: reload the extension (v0.3.2+) and pin +> `FLOW_PROJECT_ID`; Flow Kit can no longer create the project for you. +> +> Four capabilities are still unported because their payloads were never +> captured off the new UI — **video upscale**, **reference-to-video (r2v)**, +> **start+end-frame chaining**, and **Omni Flash frame/reference**. They fail +> loudly with `UNSUPPORTED_ON_BATCH_API` instead of quietly producing the wrong +> thing. `FLOW_ALLOW_DEGRADED=1` drops chaining and r2v to plain i2v; video +> upscale has no fallback. To restore one properly see [`docs/CAPTURE.md`](docs/CAPTURE.md). + +--- + ### ☕ Sponsor this project <table align="center"> @@ -188,7 +205,7 @@ One signed-in Flow tab has to stay open; nothing here works headless. > **September 2026 — Flow moved.** It now lives at `flow.google.com` and the old > `aisandbox-pa.googleapis.com` REST API has no caller: the `Bearer ya29.…` it > needed stopped being minted. If you are upgrading from an older Flow Kit, -> reload the extension (v0.3.0+) and pin `FLOW_PROJECT_ID` — see +> reload the extension (v0.3.2+) and pin `FLOW_PROJECT_ID` — see > [Configuration](#configuration). The REST path has been removed; `git log` > has it if a payload is ever needed for reference. diff --git a/extension/manifest.json b/extension/manifest.json index a01b657e2..78eebc2d8 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Flow Kit", - "version": "0.3.1", + "version": "0.3.2", "description": "Local agent bridge for Google Flow \u2014 runs batchexecute RPCs inside a signed-in flow.google.com tab, mints reCAPTCHA, proxies API calls", "permissions": [ "storage", From c6076e8ac53c29deb6c7d31e15151924872dede1 Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Fri, 18 Sep 2026 00:15:42 +0700 Subject: [PATCH 20/68] docs(readme): drop the sponsor block, add a changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sponsor block sat between the badges and the project title, above everything that explains what Flow Kit is — including the note admitting it was put there because nobody scrolls past the badges. Removed, along with the two QR images it was the only referrer of; `git log` still has them if it comes back. `.github/FUNDING.yml` is left alone: `ko_fi: crisnguyen95` drives GitHub's own Sponsor button on the repo page, which is a separate surface from README copy and its own decision. The changelog goes before `## License` rather than at the top, so it does not push Quick Start down the page. Entries are taken from merge commits and tag dates, not written from memory, and the September rows are one arc: Flow moved to flow.google.com, so the transport was rebuilt, the REST path deleted, and the Omni modes ported back on top of it. Links are relative (`../../pull/N`) because the badges point at tuannguyenhoangit-droid/google-flow-agent while origin is crisng95/flowkit — a relative link resolves correctly on either. Also ignore `.omc/`, the oh-my-claudecode session state. It is tooling output, not project content, and without this a plain `git add -A` sweeps ~800 lines of it into the index. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5BJVhNgerhFTUgmfnKTSj --- .gitignore | 3 ++ README.md | 63 ++++++++++++++--------------- docs/images/sponsor-qr-binance.png | Bin 246652 -> 0 bytes docs/images/sponsor-qr-vn.jpg | Bin 127720 -> 0 bytes 4 files changed, 34 insertions(+), 32 deletions(-) delete mode 100644 docs/images/sponsor-qr-binance.png delete mode 100644 docs/images/sponsor-qr-vn.jpg diff --git a/.gitignore b/.gitignore index 636c99a04..f77240ba3 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ ds-bundle/ .design-sync/node_modules # Chrome generates this when it loads the unpacked extension extension/_metadata/ + +# oh-my-claudecode session state (plans, hud, logs) — tooling, not project content +.omc/ diff --git a/README.md b/README.md index 31b866c7e..e29ea754e 100644 --- a/README.md +++ b/README.md @@ -36,38 +36,6 @@ --- -### ☕ Sponsor this project - -<table align="center"> - <tr> - <td align="center" width="50%"> - <a href="docs/images/sponsor-qr-vn.jpg"> - <img src="docs/images/sponsor-qr-vn.jpg" alt="Vietnam QR — MoMo / VietQR / napas247" width="240" /> - </a><br/> - <sub>📱 <b>Vietnam</b><br/>MoMo · VietQR · napas247</sub> - </td> - <td align="center" width="50%"> - <a href="docs/images/sponsor-qr-binance.png"> - <img src="docs/images/sponsor-qr-binance.png" alt="Binance Pay QR — Cris Ng" width="240" /> - </a><br/> - <sub>💰 <b>Binance Pay</b><br/>Crypto / cross-border</sub> - </td> - </tr> -</table> - -<p align="center"> - 🌍 <b>International (card):</b> - <a href="https://ko-fi.com/crisnguyen95"> - <img src="https://img.shields.io/badge/Ko--fi-Buy%20me%20a%20coffee-FF5E5B?logo=kofi&logoColor=white" alt="Ko-fi" /> - </a> -</p> - -<p align="center"> - <sub><i>(yes — I moved this up here on purpose. Was afraid nobody scrolls past the badges 😅)</i></sub> -</p> - ---- - # FLOW KIT Standalone system to generate AI videos via Google Flow. Uses a Chrome extension as a browser bridge: it mints reCAPTCHA and runs Flow's batchexecute RPCs inside a signed-in `flow.google.com` tab, which is the only place they can be signed. @@ -889,6 +857,37 @@ From `youtube/upload.py` (HTTP errors from YouTube Data API v3): | YouTube upload `invalidTags` | Tag-char overflow; reduce tags (quote overhead bytes count) | | Python `cryptography` arch mismatch | Use `python3.10`, not `python3.13` (x86/arm64 binary mismatch) | +## Changelog + +Dates are merge dates. Older releases are tagged; `git log` is the full record. + +### Unreleased — the Flow migration + +Flow moved to `flow.google.com` in September 2026 and stopped minting the bearer +token the old REST API needed. Everything below is that migration. + +| Date | Change | +|---|---| +| 2026-09-18 | Omni 1.1 Flash first-frame, first+last and reference modes ported to `batchexecute` ([#48](../../pull/48), [#50](../../pull/50)). Unported capabilities drop from four to three, all on the Veo path | +| 2026-09-17 | REST transport removed — the ten `_legacy_*` methods, the `USE_BATCH_RPC` branches, the fingerprint pools and `agent/services/headers.py`; net −1043 lines ([#49](../../pull/49)) | +| 2026-09-17 | Migrated image API: variant submit, settled-wave retry, and 2K/4K image export via `SPrCad` ([#42](../../pull/42)) | +| 2026-09-15 | Video submit unified across the frame and reference paths ([#46](../../pull/46)) | +| 2026-09-15 | Omni Flash text-to-video on the batch path ([#41](../../pull/41)) | +| 2026-09-15 | Extension: idle-tab leak fixed ([#44](../../pull/44)) | +| 2026-09-07 | `batchexecute` transport added — the agent builds the envelope, the extension signs it inside a signed-in Flow tab ([#39](../../pull/39)) | + +### Earlier + +| Date | Change | +|---|---| +| 2026-08-18 | Omni Flash generation ([#30](../../pull/30)); MV3 flow-key bootstrap ([#24](../../pull/24)) | +| 2026-08-04 | Web dashboard rebuilt with the real pipeline UI, a guide page and i18n | +| 2026-08-04 | Video review: contact sheets split by duration rather than one giant tile; `agy` and `codex` added as review CLI providers | +| 2026-08-04 | Skill files standardised on `fk-<name>` | +| 2026-05-09 | `v1.1.0` | +| 2026-04-27 | `v1.0.2` | +| 2026-04-22 | `v1.0.1` | + ## License MIT diff --git a/docs/images/sponsor-qr-binance.png b/docs/images/sponsor-qr-binance.png deleted file mode 100644 index 6618ffffb4bfdf4452257ee5082fe62134730f8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 246652 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%0D%>F0N^ym4GWU!a=i;) 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�+=8)mFlk<Q?LWeZ5qDYnGd%XIuTmZ; zt4!{Y3HBPIq_BFvQs0%scul}J-+ZH4sUt43a&}umZbvtmMU0~kF1ciQ`22sL8h{%P z-B@)$Miz&q6srGiP0}Yy4&qTaWX=KhJMOfT1&ezAc}32>`4%G+v{ehagf#^rjT3vJ z6p91GUVH9s<cA<WSae5^{=hH-8{`CBaKB0lbd=wgMo2He;zB7DZA}r|UqP&}km6b> zI8DAKPQrv9Q1cbr!0yydWm1fm4=4Wl&qhdR&YEE>^2Z-{daZ<1MKx=`ayD!Jph0VD zKktsRL=TqS7O4+?Ah)k;?2JYfPVhE`URfW0#L>2AsY8eM3c~ezMnX!E9^B!ceO4Ay z?Roy>laD34(Mka^K>=^svc1VYZCNDzIJ0k?ZMPB8KF*>ePnq&v*kiZ74AU6A3+qc% zfWf<S=Ptr`O>-k=Um-`!l!$<SqkhN26A>^OFP2|!8RZ>}=pk!Ai&$|+BqW&rez26$ z59P93R!dN$^UfVEx45T`gxCTWgMlvULf>Lsz|EAlTC(d>;i5|}HTQJxAt2B_ci*Wz zxDO($#WpFIx8HG(S)P!gTNNDafd}qa(3Ht>kkNCg#Vzq_@3ENh9R!#5F(Rqg7Qq}B zToKaSZoerM_v~pT`D@|v-IOWnyIQ1^A`B@tELG>!&XkKE2nHAZn0>%YO4%opI9B)( zI&=7r+i#OBPcyHFxJZEPR+iMBo%dIf_BW^gfgE({+F8MjHrE(%gpH|ucjFDR0BWBt z<09ptPW+HI_#m^K4a~w1B;oWk&NS~AEbCuuzwsTn-)?aQW{DW+al?gjnEWb@L`b*Y zeoHNWv<)wed`XeAZ?Xk1tYNL&5NIm~=xN(d0jebX33u|Q%~)iCY@V$}zL-Y{ha7T1 z_(+}}yhomxFCZ5upL~j3N|({%&Q$GlJWGA%zhR~bDc%yui;ZO>Y>eslTIsXEkoFh% z=+RSNA}4AwaV3?#Tt{}@Ez8{vsy}^)qjw;0-~m~p?Wk>SS7t)WxCQo%eU!1C7OKuT z^K1pU+F0dm5r|@b*Il<;FfcH&GE|UhTM&`V1Q9RdC@86lx&)0i9TW+6h~}d64UZqb zo2H;_#~N<PFlpJ`t9GW%ZSH0A&u~%BUcLHQP$RbbfCHXSPe1*H$lEU_-^dzuB7NkV zJXmarauv(pv*(IhY&%?gWH*wm6xyEp3(r4a_iJyyWRd>CLNrm@x7unOx!G@~1;Ost zKkz1*Fkyl%;7Lm5YTZeFg$T~G<c;u#Jf1$#!ou1*T5Cg<p@l4@Z`nRi`X6&Xq(3f3 z6xlq<d`gsMJi%=7Q=S!Xzx}2WQY`JrA4GPqz4x_XkOWP`ntJa&cdOhFS=+_BWdP2< zas(O)0Vkx51gt09Gzj4Sf`Y+ZnkEXACO$|j#zakI?qijZNrlOhh`gI@`g<LFu!G1} zFHOu-E#l&}B3w@@*b$brl;*)AH~a3pzXtzSHhHk>I7R_@$d`$a34y(6nt!Djv!bgB zS^4mn%Uttx9}})rKq)Sqa~c&;NHT|o@44sRcE%y@Hy?d8PG|SMWoI;g_uY3=u(TgZ zgqK6-aiJ|Pmb;G#;*Sc1LD+WOd{LVA-+!Ml`h)lNnh9DED1Ro<?!`UBdD=tTt5+|< zP-amjpML5|n*{B~48I_x9I1dc3<7@bwb#fM=x)PM8Dw~}>MP2@PqLQbCJhEXRFA{t z#<|{lItNm9B-jsO?ZF9>K4i#HDGTSS{&VaM&W9d+zyceQ?MiZ2-e>PW*yR4jmtTax z{`IslcFbr^{sk61<OC^V>&Uu;%J9Iy?w57x4m%zO9i^$F>_U3DnEVN3LbT;ED&v(` zTxNs~*#Q^Yj@PCL=(UjreU6oi1KTgZVz>oOnLcA?*k7yK5YoA}UonzW^1zCa>9RJE z!UJ(dK2}&kg!Dua(!pzKReY)zVJ3x>PCQ$O+E1)G8D(LFSxOrF_|VfjcV65G>2AC4 zV*8!G`udyj!2OS#n=OPT5mFN6@bz7G+1)JPwYlu#jtz0enudjxU|n?Lv@Z}DP>;60 z#ePD*!$P|K4%<r!KUNmF>9Ul4A9mYi55w1#ZYggla9BMdbCA&;ciLIX-o}Ri#ED<Z z4f8o!pg*_h+3byk6nD|_6HAH!;mXVY(dlxp8@$e7<r&-e-~$g(U;RY+MAtzGKVQx3 zvOE03zZoHAA&84Qpd7}2fi)&tl#m0)rwfN)Yyr8DkE^b_LRS8}EAK~MI6mXfyGGce z4DUIk@!$Xcmyu}-V5L(g^ZQF4NDSZc*GQ!DVc`oxhZ6nJ!w=Y5sN|paCXyQE#!Z`h z3gvA;TGW9uFi!EBK8(!qo-v4pyPtG)3DLl>R$XWVC2MV?>}$Q^9#Rn~c|c%!9k6PD zS%dad@Tc``{6#K@UwEkz9rB{g)XfOD$_J^SKVsoWk>@<%oz(WYhA*K-2ac<G;_=57 zr0ag`U(}H_xMEtWx7sH~+3g@g`pV0%YN6{^DgNV>rs#s^7sg1lKx!O{(Ya&)1{3hW zD+fY~*NIu9RhGjKJJ^Va<wK{^g>0U9(n(>3ZcCeY%mo)-XlHAeC=zVMSmn~Qg%uW3 z+JN+FM?UB5&_qaAU%kJ|UZy?B_lUILAne&H&`Jq_5R0)TDhp$gWnIg!OoS9dtwi+0 zoQDjsz;V8g?Al0uOroxZ(8pDdJFGu5Z*oy)=4QhP`I2iYQFcj+`T;HxcGuN-e$KgP ztGqMA)L&+6;puprBjdap$IwU~NtL$CTp?t+xMwdTq<#AIv9XH9<|lPT5ep{Ba~i`T z*I*1mMecExH61~P?A^PEj)OZ~du2CKnOo>sq{kK8;R185E~)5ComBo|!*-Il)%IFI zT3%yri7k-6`syoM(D=wKlS*FSEvNKbm^=Ewf!Zb`aad-Vr9@_Rv`lG%0%*M{xAgzB z`4`++^g*9N*P)NDuQ_wSKj<_71z93OIbIWZbb%4&CvCO^9Dc-67O5Vj*vEY14cFP$ z1Q279sNz3g`{f8U83Im7n+$5ts4);=(qIBk76%61G|@3R@ty3Gn%J1=<3x#aiqhX# zmbu+zK^Zn|I}Q9ZZLiK_kHz!yxF;$I1$K_)KKmXZ<#aK*2z{nwN^X*({ItH0feui* zDF-XNX+q>#rbPRTa#S%%vr?V*%}`bjFt^Byd+uWaQwXfYIi#Fv#t|-&Tt_94G?=)1 zh+tw}Ty3@0&B7bc^PH(8E)JIE?LAFQxQ|7}hWvZ=?qh_sM~`Baqg;yH`L^FL9*dB< zRj|rlcKMY?fM?5v@fz*hx%ZwsZGwxFb+W|PoQ{eu93mFf0asQC0c8AWxxj6$Rpa&@ z+65x!UVr_y;cM-aC0|^<w$xrL_DucxgyXgU@?BfSCJn4xgskU`MBJHiw_}eTq4Ec= zIZ$V*9T$3vfKQw>Dcm<=gt=ow><Qx0R8e+u(L?Tb+ig#iq0XJVijaO_3i-QoJ;oA( zf`hUE8KGY32f$chA(+S2SN}~|wbdTElCb~&(L#y^LE<C%j&fEfLRz8h#{GB8nT2%l zI%}ESPnz_F&N#h5F5#1EY)Ir8r3Y8?Qn|?z42hNhp+h&2Tk@VdnxKz};B0vh{7-2g zZ|RtVth%7+?0?|FBBZ-nl-;@zQWjdUkaDyRRs{M&BI~igRaq)<A;&^GY{y~YSOw0Z ztvR56=N)&o@gOR1?2FR*n(Esu>};najds~(7ZJOTwpj5mk&%bx{{4$AqYxP^THKGK z+)9dEj~+e3?>FB<!G1Q>>tfYCy2T%`-+m$#BBZhwGA7hSNG}?GsXPFlG3yHoE*I@h z9`VBR8P8Z{kJ-8BU7&uqvSG*m>3_<)$c4O6A6(l1aqW$vSmOaoGDjl)^Pl(1;_<o3 zg%Y=CEe~E-yti>sb+XIyM~);<CXcaB)P01ajbhcI&FM$)zx%GaWz+8&S40<NNsU%P z%1wSeM?R(itB%pzK{76-8Q1FXwZQh`iz96@53HiwAteEany)e`<Ma`p!Cib)MIAlr zs3T;-UQC}yQuD&dS7e3##mYeWNSl5Xw?-g?jKgK-QSyrx1-f<XCb!?;+2R*tCJTXg zE0XQA&pt<0D(V>jf@C73+hHMHtexCWU$LM@<Hmg?{2;$dUuC2&qK1|Rn8vci_U_W9 zt1X0{aKfL>tA=e8M;>{oc>sW0n!7j}=KuchWR-ErFjeE*`8v0mvwK;b!}5k(vGoCy zo!FMlCn~KGD;73!%RK6+W5Ox}`s%qE=CXVHZMTOxN`rlxSe4sg)m2|9DoQd~a~s5O zY9^#$#{9>8i0e5r$^y`7r=Jlv+wAu?-oNzX3$``m-FM!xvQlR}9@uXhpQUWtS4veZ zJ>e%=?cAkP*iMU02OoT(6=U+(KZes!JJoQ5knya^AlU0U%8=&bSnm1!R+X7chhKC_ zpbyc{hY!C{bNf@aSWCN6KKcgZ0eGi6k{X^_)NjCmmBT>?$yIi}^@V<s2<c-Aw0Ds( z*E!(AfH`~B0sX^q$Dg2B48IfZvvmIVEAnRem+i@(F=M(BTo$z2wQnoJJ;MUOF|KaB z@lcxsI!Vse?RCW2TjBpsI>E|Hy`wIH{6|j|$mZ_5@2P#|yQ+j`(g#K>e#ALu1?66@ zEw<R&BER?T+gF}3-)dYLVUdODv&av1wCx~vxBqeknhpU;pE8Sc3HqTQ`_gpSdroym zAWfDCE3f&>pvh}oY2wNytAt!}VrFuTic^_Zf?1_E)x9DqCd*EpI@^ApLk>Au#~(xs z6|031HqvIICXFq(+*%6v{(-$S1Qq)C0}q7TZoNqv5CBB3x=dWk7iGkXq}Nelj&44T z@Vuv75C>lK3<~Xl0l$;m>YibP4K_5FOe|>UoPB0IFkAOnnU!8tj-%p5ox5s3EC<i; zEz4U+Dek!A9CP%Mwqk6PaYY`u$M)*oSNo+dGUbv<oBBQf{ByRaL`i47y2>(isUlJm zxtO%BCa94@<Hrdfe0jVA)EZKvuCeamg4IkB1T{%B$rJ2ipS|~0;Hhq5)Tmd&%{Seo zpd|m5g3v1-cCRSA6DNKp>)i>qe->pJ{7?keT~|um$)}h?`QCf)h7*oIR!TyN$lqRS zuRj=R9VKEv;@*3;=k^U#kZ3OkyxLrLKmPa=Tji&XtQBO1>)w6E@R!q155JRAA@K>< zU3b06(k)6aS|_L{^|QJfDzq^{jrNiSd@n1{m@#7%QTR%^w!Tv#w{kgGa2J#(tCv|- z!8I!LtF5+LxcZvEo1Ecl$FVP;efEW(RjH)38UB)~+S-6VWB*K0%WVaoD7)*dySC&` z(WbQ*>$FoZG^~|ajTb?=EMllE7o3+z-B({@HMu44BNzB}^u9>0t>1?OWUYtzMavN7 zED!tbf1t?uZo;9fT+Ru=Q}a2boGppl+0#$QJ)}g#hL9S8QTx*`RRTJ>^(kbkgBCS* z7`8+B<Db}{S8614r(ruA&M0iOJ^h}G{n{K-PXy4Pf1awnS+APqn&_-}Ii!9^xv3*0 zo*b9eo<pK0@2;RYSWmIm9Ij(uMjb*iVE_O?07*naRDUp5@<Kh)r1c|c=CzQXf9^$E z2zt)?Y8s>H*I1PxE_~KP{S(}}$-SPSUj#LxuDE&Q?#hLA27*VV+B42P$M&5=K(Ov& zO(xJ+Bzhu<!U~M22kDR(HKH!$hc(f#<a5R+?$-_AclAFmw|$z7tFOK`N<oe8w17#- zI7k052AIX!qU^F~UeD@E^@&&@BM}$MNFJ1(@*(eay&}1c>2%ZHdGOy&!Hj4p+_kNl zBoB}q^1=FN(bBD^kVVL^WOw#-xkWBv7AdwxurNj&fW`Ew(=52%Ew|n(x9aJJOKgAe zpg*?Mnasz?3a>q+vUt5X@<okTH=D~Y<)dE7otCOG)<Q_Y0laC4rL_Rb{`Uh9JV;e9 z2w!~uh3$F%QeGaE1Md;qXZ`hugp*G>Mf?6mNJXB{KI?3Ab0??~M3Oe4-Ds=?Bl#n{ z)D`l92hc$W9UOWTuc*H8on+%SEzbSZu!nHq;nSggM=Q4w%Gea-M0ViNL*(tRXPi|T znfB(JIgj}k?$A$MU}MoB?%S3H_=qFIHrs4ti;VBTKSt%aUHg%rkK>&YSoVd-BUY$C zi-urejjFK?{5am{u)`16g3#~nY}MCaf73jDzK}PA;af3&Qbrc(s(UDr)ch{mwpew+ z185m}0<rJ({PWJ!Lc<H;Cj~V^RwdLneo&TZ#YK)HIi0O>o2@$QtUE{^RC|j!t|9M< zSvp4Ok#Oxb*GPZB5>4PQ;t1>|FPXhHZ+9`*|2yuuJ>aFpyp7if3nKb&GK1V8tF2qN zv@I2T?zN{D7gkddio&SZ-mxtS)R{5OycE>t;Kp17j+<?^xnTun5YFqayEZ&1&k4%k zR`Pz_@qe~4gY5`xLAYIV!P)FAJkf`Z*sH$Q2J-{XKXU{c2>~ahjRdSGyYL7^Wq=8( zVyZ)N&;*YX#6%nw%&6ROhfPM@s~5JKu8D(*$yW6Bnm{EC{3s$!DmH0v@_Uh*Q%#A& z&FRS}pU{Eb=jnS~jtIrx%8rm>)o~p~iX?~*M<4wC?|(D5K=MMVp<H%ki^@UyC<{so zgFFK}lLhr5T_zFxQ1`62-UbTPaFASL`^shJE1mIqzbqa1TRA~6T6W_kOPbV+RsN!) zGFhbhDag>Z=K4kG{-ZSUkNxmNtDCasY0GoP6?-VS!R4k*qx1~F@VxNsbF$RbA*j(Z z%Pb+qSV4_M!f1!9uEat*LiLUHGsTkT$Z#=vqC_*<(H4*bltva3dh{p`$Nce6nji;> z?0+G$|8Ke2KB(2^A>quk&y`Y8pg=8m+WCjyP5GY2H6<HsOP{`dbfm<Qwt`Gxs)G+Y zFnq6lgJ+$6wp{s!s9ic(S?{{*E{jr(RlyV=;g^Y!-l^a*999o8;9z;I@2nno?_L~E zIps7Fur;g>*K4A`<BnSlZ{&b_C706Jz<`2<eIM;1-NzK+apT5W#MF1+eamDHOi(P6 z{E`kh^9#4;fjZ~z(#tNfJRkx4?6Xf8|H%Y>En!gmqUf^7AxYEw442Y`^gtF+ya;M^ z+;PVV_rcmXsURV$@9C!vSER?UYEDF1wro*qxIjj@u$B&9XI+a}y7t<GRhkwGKr~4a zpZAlp^^0)kxC>;ZH0*!i0b!5bcNZaDN(xXd$G&W}nOUKpdFELKV!6#Mq(;JJMX<#s zwIxDmq(<dJf#Vnuj$b(DkDS|DDA(0*%tFdNSWH=Qr5yCbp&M-)4mtQRDWtvC@4hvK z`k{yZW&M`#kyHALUaEbt21DGUvWC0(b=TdX1+B#`D(hi~9UR7u{aCU}vt=Np=Url? zak`XH+>FVGG--3Y?0wwR*+u)vE>cjVm9dbjELUH7h3)gAJhlaaKYEU_WADB9(cbcQ z@*o(k1*0p&+gi{eeZ~r0^pGuNGuA7TK=QS*P;yQBiImwm1-a7ar=E7Kl-teJUQ0?o zKGg!k4YJU@s`S7GLd!8lb0rU)JKMs>HR_-0#b3Q4d&`Ty$3<Dv=j6v_gwtNl|Ce-h z>nA+RIj{#Ga)=Qk<^Y1+K)h!upp4-&|0Kvon297v{#5`Y)bv-dvoh(^ciw(C+<4<H z0S^Yo{$zc#MKpOS9CGO4^32#GbXsEZ@aoGi+rHh86^M=RS%+W_fgF$ra%Z?JUD}HG z-Bw&d3o{3V?Y7%qMJQ5q@Yh9x&ar*V;Klv4&01>>HkaLHm+fi+pw88p_FuItuEoq< z7DZNnc_toR6iJx%2jxe<+-29@wHUU$$lP+_b1h=suD!cNDW~1if})LA$cCQDbRnXJ z8fSQxvvJQk?7d}FT+y;Fnh;2k1a}DTG;YDQ@!;-3g1fsD+}+*Xo#5{7?(P=gt(<fB z-TUmf|GqKq8{__==`nlF)oXTD&8k`TeRb|;`$I%Z^j_+;gJ!y^$5sLyJfpJ0=?dTf z9xeIPUlItah&a3@<cqe_354K>b;DaDLP-LLxlfWBklB5PPxxU;rFSPyf3Abb2dRxR zdu1Ds%a=!Q6JFM=rLxu;#;bp0XsUdFWmFWeJ5$vtO+<t>slAEbv$mQN^Nhc}QcS_w zzIOW2!_%D#b;r7&)Cxv!+?HB4>9kfp9X`ivpLrO>by(*;PrwCm0CvW_+oc_euIyU) z5xh@{G|}PsZ$X1!EY{}4U~40@ho4G|$GOI{R{&a_%-;PpNiE?p7wXhp?knpQ2*h3n zl2-!@(1b&Ld;PoS#k~}DtDO6tMXRpMe$_<pwKf-1-m4_FcUrRBuOM}=remow%@?t5 z%55z!sp3)%AQ=PWA2;X84)Nue7s^yX_msSe4x|}lf=@T(D8Z=yu)eSEAY@<g&O9ui z&;`;8tLzDu%ye&$iY`By-8(l<;4Xp96xtMwxV%;Vr5T=2(^Yr4lXQ#3j~Cr<^|P{l zdStqR(5~zCOD;Gme0`o*K@cYzBocn`+6h;E&OwsUvPDtiw4@<dvPywexxRK=CX^+Y zk!F;LPaenS^>N^RmG1#*xv_4hXDp3Bk=))Tdn+RQN8JpB%;&54vj@+xiMlEVs4qBO z@f`gA05M75q*fd08g50L0hSgmqC3UJfXyB*hkz3cB3>BGlDlGEH4}_$l7xehKCXOh z=>nvHSb6WqoD_Mwldh9II*W$mck8(7oT3FE-V=H=SI&YmAq#0`O?O2n=_rat$L6V_ z7k$-4LeeJ}u#|^TKdDYxNC>9Q!H}rvc{_l_ZcV$BfMqf`n|34xFy@pu=N-kA5{(wh zUwggbG*;LQ;ozyXW7i|m{1lM&hrXKgA)*p7<9n`D{aC%7ujkfBA#+2PdXq3mmqSI@ z*xZ7E>#T>C0^=_kuDkE>tVuAc6&e*}7)j51yOa%7RTmOfP=tLF<xxG=&Yq5zdt&^= zvQ+&Z`j9QAW0pPFMl+|v*er8g@0QP{e(@*gGQvXBa5QWvBfrJfyy^Ku4q3qsR;+ZT z!27&*ieI(l&#wy|FA=5{fXN*3iO0?Mk7UTnQLLtfF6vQn2Z(6(y(i!mnT^9;60^Ab zluHn}o(8&Y*#9iH7o5x)9xzZ$AN`7|?XeY!Qayrt%x+h4i*kk@R#Laj6<zRz9R@9b z&$Z0IOIj`6=D>@r=K1bNEsQiDsKL;#7zH#=QoA`{*w?R<cgFfONRCVth+z=24WZ|j z57h2we{iLDT(B0o_Bog_hM|6Ltim6(zecH3<rHf|F546c%HVViSn61T_$_p-FidY1 z=8gU(@zQy#M{F~_<!n|p`aZdpV0(lZk!{H7VN=9dV@Yki0gc_0eTDFNN(4U)+*A72 zfYM}8$`?>b=ZS&`QYf!~I@-MHcvXD%NPr0$RQv<5an<Np@KQB?u^EJNXk1Qr8ybW? zsSi!7avQt|83~qlz3j&9rcWFz`zUz@p^ZNE?bi*El$r3DWnpQsgSTvb)n1kmwKH8x zff9h=oa70>42!x%HtEW6Zd7kTi@Vb{m+%wEv1qwPKh0}XeKbv{HVet5%nQb++4+py z7yzn!Hl>DwbEZN2Cf>ih;*{od_nlSMuQ7`IR)qDkOQ)4js*sxhc~0FkFl~6L{Y957 z1>gxNLU&AOIj%yI8^k!p#we=8{D3D;H{DAltW9H*Zhyy~yscbmD9yh6rtj}Iy7FRt zPjnj9_XUG}H`{H1vH2rh0O%*K^A2G!xGJs<|9Vq}IH&Q{hk?=GY{g-J)Moyx&O!}~ zP7n9}fl~qu8BQ(fSsN4-nv36NX|H_Pbeh2^??&baGgJPoyMl1sM{!|+;;o`K_E(c* zs~%aAB+&OndO{7S&d1H^%Wd=Z8;|F=POehnh{uW2S>g=*A~M1L-;5#YT|V-kQIlYJ z-^PIct&pjatjyWzTHS=1QMmWSs3c?pM3}mlJ&NH>AEe)ov9LFWX|9fe8lFP_v^W<s zgxECEtwgINAv2=M8rel3ig^Fm>Zj8d1aAh`%I74Fh$)YB1YTUd`+l*)6|%2))X1@U z5(!Q}7hX6-PM?m;>tRri;cD=sC<i&IRAsS#RA;q{T?$U-gmV2BsyqDIp{$e9y^UqA zEd@KT>1pmH<PB}rzb)Xc50z?I*m9~~C05WDxEI{~);A$n&YkOe;Z4z(Q+A^A;c$h5 zG9)=Nzj=zRwi`s*M(G4Ai|M%JtlU&(j^lEx#vdPaZy!2L9E|A}2~iB9bR07N`AD)< zSr|JjLMORtG+XR1`pBn#X`tv{8tWZ3&P(p&nked`+|(N$?|M=v{8Kh_GDZf`gg6(# z+Le?>;;VDo@D3rLnNydwR%e%_>&}@0G)nn6G`ji<8fr$DdI2=?nHSbc!3Do+ItA1; z0TuC%#B*H9&|k&XpX;XU_#@fho|@u}P^52scTz+)KJX3GDt7Ai6D|eYoTk6B^TXvY zZGD3$8E-bJSf4&DU!u3_pT3hG9C!v1-1iFjYE-RvCg%H*tfBsP{a+oz&9fW=gX1-X z>jt{<%*OgPYzFhX*<uPr8Ct;a`CiS%IfAL&zvQ7{h{}g5etKej{;sT&CDM4AuO5qc zrI87}@=TQ(53xL8vasNX8oKE7?sccPiYkEuo31|rRIftb)Y4%*x5l>S^nHg>I3;Yz z9a|(wi5j`c(<xYnybqg;9g`PH&1&nJl%rvOYs?uovbwo1b58u(9Gu-IxU*-!ilM2? z{voCw+%6h&iT2oEhSR%BgoG1dtq$c(55M4)e?HB?7Al`q9#2EGdD<{U<>0V2ktI0F z<o`|~LEAwU^X2v6cl*T1p_gWDal>Rb**AJt%bL@Az$tWK9>&+g0a_f&Z9E{LbHJGO z66x5@gAzpg@at6SOMFi3KIiC*0T>*0>V^+8bW;jspJf7|b~kO8N=oi}&vUtl8_#Xa zZBkfIy8)8KY+^&<;0x)7qXMYe^%sjTO?nxWbctHQ7JoD!e$|U}T@84S%qHRx7lm$r z7D}*=<N6)<Xat884V)#-KpfP@#+_w-!mp<o{o6-ski}Sr+%~Grh?l425!qp>APmHi zk!n4sn(V90YDv)7iBr*`b$E2>qvU|#TP7s1{X+t*W<jmIPh96{4fkV`!;SIv`r^X3 zI-1AH^Wm`nyw0-P7s>c4+@ktsvN0oy@$PI@Bt-R-|97@k1p{dG-KR#qh$84vAy*}u z0I!UVe1f_GAC{=8v$9MHjDW4Jv-$^4foDn}cdBG-4<@z`>J?NoFM#H>?vmRY4^ zo`&Iiko9aDRoq|~cXg3E@D=atcE4xwA4U8ZdQXIo2d)rvK2@0X-uCZ%m{SHw-cUQy zNl`cBb9nOT)IZ0QC~X!QaP0;<moS=Jjusg!r8#2!Q7y4bbA9L3hIQ$0&Zd_|pSuyb z&9sCIQf-RSDL*a|J-yt&4L@B2-4)CKs2_`{W22^cxtKUZ#r4sNWQrkK2`uGWx&DL; z=98mO#Kj~dG(wE)Fkb)ko>E-==VJR<L52$z*X;~Sy>kY1=E?{F^tARN<D<&<K|EPu z2%I>B{pLIC8+0-K=3cA=>R<H0$;bPsf2F@$XE?t0lXO)hhH4H4RNdHa<JS9`5+%Nz z4C15hM~7IZSh`r@yQ|NOI)PA-Pimd~Q*DyzzVoX6;jx>I7^tFT)GOXFc6@1sLb6RE zLh<+3o?>uKb>#&*U|6~eRRq!}0Q**D%k^EApVBAxsKtyhcP^molU&#{^DQ_@({^Hs zDAV=8t-fyO=VRGQGufe8uf4u|at^Ee(wJQeWv|S4{nNo*i@o<{UH2!7W`;-rcyYKA zzeG{nhov?S{0FE%pCEC|(BFb{g-=kXE!9lYaA5!G_l|tWcT4nHFG}}(iG5##KwznV zN>6$nI1<!(_WF$lM(pxIMlO@J79am8fE`DjoAi_rqF^86f73{BbjmVA_j9R=jvUuh z_@O%9R<tUTNP8wBlcU>VMJ&Fy%-j-JU;k=ezKi$##j)`@eR=l`M6E}7mJu0Au+{8I zO8E6wZI3(m%MZd{g9Z-5JhxDo+UZPw-(6V8K&X!?toANWlI5Xn8lGWMW*`xjBuNH& z6q_^BYI+gF@484?6<T(e>nE;v>v+_=PA9)O?)=@`j?S^2A#I>L76q5y(Y8cIQo-p< zn*Vl!PU5&K%qcSi2?1bD;-8x-%+}dq{5MsN=ZKE2@jsz@mwoi&SZ5dfuB7!R@jd?V z8`rWZ3tE{h7Ehob!*g9AUc+yce!sg}BgJ@n8*E0o&**Ej9}v<o3kmVm=~n?~Y&I4l zta*-yhyCzIQr+Nu6$WQC6C`2L)+D0^Xyzr>6m~X6sdQRZaP7WHF>WnnlhQ_r*9L?z zR#grnK+@M;nsDguR(6L^+y&j9iV<<3n7{Z(jW0hyqR)I$zU0Mo^;t<|t17IBH0F}C zXxwyBUF=s)Hs7WBP}D0P+`6cesePipsy{t?@~t?$`a$*$f#*SH8K6%aeh`w#xSEtU zRvr?P$r;l`XM)?r4T}RhNS2SX;i7f9|Cw+Yz;$L2o@{Sp=K0~TsTG3ebnbTfC`6OG zO0)IsGejXxw3@I|8wEGTpjz?1VJKquW36q3E`&uI9ddp2P6gMBYeRSp(nrWxDjB}) zB(=nD0n>QtTTd&!^6b?)jhKTO8%4a^WUCgX@`r769#PjM<BnP{f5qk+bT76=C;3f> zN-pGuXHF)KEQ(!#a;b7OYDIdTIdxVF8trOqzg9gzWdA8JGCk|15|_9qaUebwfETDB z#cGFJ%*1=(vJpJ{A8G4=^|!Xt+h_^_Qnd0SOjPqO{U(HU_xm<<y=(>9iNlZqi1DxX zBU#mIeL1DyOjCGn0B(^b2;WgAjyZ`N%?IO~%F8$!zM2nu18Yke&AsR;C6*2{O=|<9 zqQ2-FnCpkjoM){yclBo_3_A6<ZLa5SA`IkPJahQ7^A&Ap9Jl+1Gg>tYQl-O7!{W|) z3Ev1uN!VXC^$0fr`oPFrI}GgiA72X>MA&K?T}F1+z~#jlNg+DRtfywkU8@d0vAJw( zn0aW&^I(&9`d+x*=@n%~Y*a+(ZkJ<oMAqk*a~5{^Xx(YW7=a)SPx4;?78n$Y`xyFV zC_mEJMjGQ;Xp!2n2T8;vnt~PV1-OTYZf8w~Lb>g8LfEV8iCzSOD(_`&biLBXII4GC z;d(B-;XjESX7Zf$FPh(TkHmfS$2dM=QP#F_eUeGGg43-Jqwce=?oD&73_t$%upwv$ zl`4kmeikT*P)AW7<!3spa?S7vG7%8RQb0~gbRJcw&z7PP)U5jrKysgrDkke$ozaa+ z8{L2P?mB#<Nwwco&9}=&R6~`|^V7(@K`{!rTQ->2)OUaOr8KC~2N$FfZYNN4T-c5y zw;Cr$`5Tdf3CAQwVJ0pI$?;X6GdD={5HQYx)~j6_y|N=(u|B^H0NBTU?9W=nAI4j{ z+Nda;C5MZGqOvo;za$-y-EX7RVpcZqIK;;eX6Vmy^@q1s!p>Ys%&cU`pkrWABhG(x z!2GjilLLu>uCwNHoMyEfH*b9FnYtwS!WUmAGzHIdg9vrEARpg47L2(BN!w!Mz3x8G zt=NGX2$Po<?sHqy*qDI2(<ZbRkOaXg1_uVVp?uKI(z1Hi#uECwL8M#+h+ng5RRCY_ zJ*%m+f~4WV?L7q)3%1^zzk>2%6*hVE@j*Ns2)W*kyH?q1^FC5Q^l)AQ@))TaCWz}X zw!<%sZK-FhdG|9I!j~H)9m0k-Vp@DxS{?WiMu125)%EtsJRRovvsVAoY14kjtcpWL zU#Hj}fNSof0<opVADHpa*RMJNRkU2_9&!Y+4LiLTm0)Otw|wv7^-#ls_q+gsZ2DFh z>zdFw4VsqIkK8=z9lgE{p@l{aXGyqUGiDyjs!1!)24TE^28hj5K5X|%iyyZ?pTRW@ z8^qQdyax&^romWYtuPIkqQwfksv6H$_jSE-W5wqRr|x@B$YZ&=ZlBp$^9yBRplhb3 zx@$K`@5PbuJo>`FmbjleLf##{{J9=y&6h1;{>3*mukPtv*(3@TqKYUo1QdzxFEtI< z5?1#ZvaT0}spfK?-b~lhS+f%_pE4uRd#)61muPuBlB)ZG%bOzEFNj4)i`8;he=N|S z@@uBhnZfIhzXiIAEL7oPV=B__Ry;?2xY}Vl8~v<V8_8%<gK4z}h2i)5;Ui{}+hJaU zndkK{wa=+J&7>jhTB4DJ7sBDtdqSRi9c1=@3nFQbZhSe$;3Sy!Xb$D^(ht{izL~u~ z)1VF**~SnKiPJYS?b43?k!tZ`x{o2RFsAF%yrU*}v+H)FOaB!KkMB|S^j$q>@x0@$ z^XB8gmR<x;vGc<=egBkx1Y-}4#Ty|eVTkoc>x`VlKr;t57mzdC#Dki6HcD+Z)gSED z^WhO;XI*wHte?R(Iz>3FQ9-(@CdzgLv2nnsD@1ziI9aF&mX9r;S86Wk3_Nv}mLP*- zKTVWi!BASv*3vz}GSEqJpEAQe{ffIYJ*1E*ISs^o1sdfIAdg&fE<KmqO>##PZsdL) z8eTDQY!}$ZXQcwFL2%Htq}_fX@-gT`Y%m%OY1MR;ghAa9ij#c`%-PVH+;RJjrS|^k z*2d@Zao*<){}ID(9#=Hk=*lDdEZXu72uKg3BH!MQ7l+_GES_S;;bkgR*inUea&+PE zj>%1lH$m{tyYcFa;+EFdRe>j<?^iJ+Y8SgbK~J1(ch7u6)<HdGn7tM14ZCH3B(wL^ zUF%Vs8bIzxzgW<EPx-)t8pe5w%nT#&`0iXwV*)@cWaSe{{*_`Gc<Trak4K9id~dJl zW`4wa&4H;BG}RpVMKu#VPH*nJy;QUozal%#2yz(^A>)G@byJlpbFSXCbDmfGiXOJx zC?1iRJ+xD}UGC;y^y`IJwbiXm%UOUW7aCU&%gDZ~mM+!ByG{`_X{J?(HQF1g3Pr{o z{+LqM9-eYbLMLCFfgGj(g+@R{Q-?Igxl`?5Erd7lb%+8M!Q6gsaUbS+ec5#B8jbST zd3(t_3b_a45a~Wov(sTFV}BkTXiEEn2+=ZT)xOndAuugo<K7X~KJMVS<Y~rqQbSEn zv?&C~IGqbPrG81Gz*7QL<>#+YP60DSZ2$G8^S~-1c3oM^S@2Y-Rz_*nIrxrFkuOmY zG%&P9lq)nif@;t}2+BPfTodf)m@JU-I>fj!99qf})JR;CS4wHOY4GKWP_$DEH*h{G zA|K7>yDh@;%X7U?SNp9dv0o1lKTOk-s_G~9>->J*((-G?Mb-`yDQbNozG4dlH0AER zT>R|&B+2dV-`>6>z8|32!K>*HyFxTmVF-T%8PL3TO7{2Id7ifCLNo5$>2526!dX$( z50;IuYEW;<g$%M53F0`UXpUNa97KNbi&h_O2~&CWiiw89X9Y$QFD}X7YP^1|OFgn~ zd~9)RuyF9Sww5N|8aA?|#zO+Ft=MgU5hhvqB>qOh$80BCutfXx<Z@hrare^QF5Dcs zZ>`7sIYINuk#jkre&h4N2nH4-EwW}qnQAsc9s!5l0oj!TyNq!K6$FDioNo>oa~wKD z3e$2Y;PMyuTYuVxAr#4yQhB>M^O~p0wrz*U%jab}yA^<JpdBUOh-Wj@sMM9(PMz@P zWObOHT!1N^19HpxxvZf(@9HXvXeCl2knt48`A4go>#4mt!Xe`@t+6`p#XH^fjWtU$ z>3R;&yGKKGv1Bma9uCCYhOk5nZN4)AbSdbkVWSQ%MkiCDH{fCtC^j_ufX?z8{xf5P zAW7~3r|smSVJa4Y#6Tgg)i#Fj2}^MfvlUd;|H^hoeCqs_6f4;jy)nL8>;ACDX2GCA zQ;43e-lKcvCI)1m(;o_-0VLC+!|2K~Xcz6VRPkLGeVE+Mt)UP;WWbn&aMq@6foUu% zGvD)nzmjfiEX)~2i~dnLVn^uN=5jZa>Xv>dMrZEQvwbB4!F#7~>o#@3pjRt;?_Y-k z2Qy69k@_{KUc5t5z!DvU1SOJ>NIe4cQhN50B`ohGO$k*m>XP-UFcbIdQo{@qm&jt3 ztfoG9dg)8e3BSkDAh|h`OTASxOU>`n%@Z8Wrgd=uxtLv5l;9&rV{9YniF>=WT!$=& zL+JONZE%h7*VlaRSM>!3R!}`X8H&Q`5Op~sr910KCb?@{TAJG&ZGO?=A+ADMvc=1D z>`#A-d3{R?miVCQof%~rk;tGz#gc-;ZNIVexov-Eoz<V8CnG|YCZi&Ie|K}4AQplq z$T=@s&SJe07Bde(T8qG=yWaxDV%lp5vGS@p-V3+rPyNgcfGjW95m#XeF)--7k|BaS zW=7h?BI?-@dqo6@<%Yxy?PGtrq77_3?q@_Hdk>@KGEnIuj)t)=sg&H{Do&|B#;R75 zg(p6~ww%*w4lwzBnx`A3g#G%K6q^ULS1ckVqSO*Gla$)nhxJpgRi?e#ClZ#kRMI-T zq}*M282YqkjKg$@#+0}25IZ?>U$ip?N6Y0g&Z_fqKc)H;mf0fX*>hL0*Dx)*95e#b zhjE1+zUAp$j%g)nqwEfVSftBOnruLvvLrB&Di}{WYh{43>155C6MZUz`Yg=CdH`R^ zKg~|^%cs<wKS=_ly)iX<>Lu=#ne7AyLBt%9g0^jPREvC~Q9oWu1%{AV$<yqzp$|=> z$>W(xu4zzZRnR*nF<{}~C}kI?eWIQ);*0O=5C!~>WOLRcyNG)mpsIg8W1w@Rrd?V6 z=KnO*TpQzqZ66nR+D1kQbgF4>se=+PZcZ5@Qq}(<ah{-Nf^`Z6-KRAr(0fx)g#>Qp zFA6uaNlb=Icmn9y=-O^DG&=TC23d7bEnUS{C)UAggS@x5g79nF;(2$G;vk%q$f<CZ zx5I5Sey<IJUryf<-NI~Le|^R>39+n2(VIf3exm1LphY4G$Z$C2NIc$?CZchQ1-4`2 z>Kk{Xv;A6L;O`0q4M*)4a95sTMY_$pCYu?BTyS)#DZ$*>c}Irv91Ssa^p~+P;-?GU zBRHM=Z3JFXGOaJt+%LJ{cm2rmv_oaNr@Eozc2x_t>#xr^SUq23U4U*p)0?oT_<3a% zmRV1YoAQDJb6P}YH9|dRplDo~kLjmbRc;k+ubDc^>ciA|qL6;>y==q9t`T{I-@-@U z4i~o3e*ZMJog_Irg(DUj3U2aI9aj04yY36O{nhrvHM|}NNoxC59QsF!`<w_aljqM^ zBgP2}6__m)^86|iJJ<S6C$w#n310W(Eb|(A?|U3p?b$Y$2d{oCLpw3DRzWYdyK|08 z538Maerk{hEuObtmruzMP(`uob3rY2e|TpzNJO|hu=4Rqt0!b1tHN<!U`&eh6xZeE z;D;?P`fU(OhYVK8h~fj#4g|(9&A$FfUI#J^ieJ>Y0WJOuj(KbQZ3`MW8&0T;a$Z^c zdo?4`+UXK)zI#DP(g}mK+}k~`llJ?%v*|{zu|Ax*KKhW|aLlPYoe?6zRMSG`QH&7W z)fUJ3y9^1%h_j_`RicXIZw}j9oP6jTSjpq6W<fh`ir{r)L)QpmhrCVusELAFo!_tK z=$)8?>Vr@TG?bxO11iRccAUO;02F|A99iS7<JlrOO0zV#!)W>UN|Sjlh8vbMS8Wtn z)sWbemo)V8!aZubz5cvL^y;PW`1~hH?v2C^$xd7%I*u7V$se$iTsXXd<3?h#;|`Qf z95iLTdthbH`jEuLZ%qI6s%4s77Kw1rX%*;igytZ9?p1$bufYgvWW+#7+8@cNw+IQM zWNx4gZUcW@dY#z`&$#z;px{xL?lwut#`DT0e6-T0<b$QbXpU7Sy>;h(^D?7$-Dgjk zR04+`e+hhX2xsFpraTmI%oShgKtsnBPIadYrLo|N83Wnx!WDY<Vn4YtnW^?!$lJ~X zgb@LHwV0y_*e%4k$DJ<mHanixso|lg>hi!vjvogB96W-~dBl*>Q{L4~9)FzFRo$;U zER(8j0n)6L=+Pb9oy}iK{;2+h_GUx12bvDn<}r1p5X7e4GxZxKKehOShwxm_bY*4t zsVckJ)(5yx%Ug2&Rw@kZe5mu_5=d{9av>PSw>OXhKOecC7s;S(M9CShYdx=!=kg&& zF3^*)i4xSqh*+mJIt%!+{q2a+86nlZP@hY8kR<L-s_;K!2)mP1Q&VSwPHRzePohKU zqPqr!@XMY7i$rPID#JA_iNyK16Eh+Z+`EA8n#(0@H{I6pDuJv3g8+%Dq47Ikv|U7^ zeckn*`>XRsp6Ci)a|w&1T8HnSZ69G~t?U!{Y4)r%f?P|MuY|o%A*2+vQs6vns3ZoT zHoa8hKo+0CTtw(I!Npo`>!bdoTO0Fdh4RPoB_D*L9W-UFJPzUeeqwlD1%1=hL1jG@ zIsFBV_p|uWrCoUZeXu-+BZLq~YNlld>QG9G6RhZc;zA1x=b~>P;Pk!S{kHqUm>ivm zDz?7+kS_L-1-*wgcV^dzqDG0|5D2SFtF!FzT(CNL8q)i6jY&y~gcWTN%Yd#6O%}O> z@9`k(O0v#Y{e0$X+0R`-#8Xu|pl)|=kh+^~Y0&&_>(Gj(@k_ivHUbRD1cB?K;^N%% zWf&SuPphz30G0;|O69?KC^)3B5A{d?g8=HCdHpJXh>t7PL!<^h>4(N&>DfF29r<)j z35YXBEvF5#Y3hS08*zMAE$2dgb8)UDm+t@~+G+hy?C-W4Bh~aFpSlrvYq=X!Umo&G zEh6h02e5-s77jXwFz#nFvTa2ZkO+4{VttSI>#oZEmSrZkJ;}av)iq3ua3=N`ZXh)Q z+76T?kDW;okQ!)v;l`L0O;3lUb!B`Ddwl9sA`VjU2u<cWSaiD;^FGR=qZ|I`rMepJ zqDtpwEd@m=l3Rx7Yo1lro$5F!XiflKHd6gAldfrJ%OQ0(l2EYg$VQ^~=)reS8(sWe zrWcS$YBq#+MAy^?!pgzJ;p)H$#V1*%EnFYRkGA#bXbP_+>TVeO+mgs&j$nQn4G^-6 ze-l#8Zzc^_mvxWh?=`d*)q`X|PVMLBvVY4dSx)u4zLN#>v@7|&$yP(u%sZ_tSgYM6 zS<nujkp7BXa<4WKUQ9PGuK}f60;CSY;#E3~_c3&xeyGo?a2Q|Be*8IgT$5?jj*PpL zZ<;%&aNPf@FfKrIre7afy)&?dkFiTbduA-VpAg@h@XqIe)$u4X{nOiv7wB{yx`E<@ z6Nb*Dd09?a={Pk<wRSk4JaOcWQr~+f0x|6ZPvRJmB%0m%Vnu6CS3rMfYo;y>b8}8s zYfewimJ&tY-@|i4BptrpU+=joLBdkhj6aA--@#CqHX@c+3OLqi*lSjoe77K*uo=~j z!v~u!)nX3#90Z}{ap^%l%gJIJ9&t|b@e|^wWU|ooaph$98%oks$f1vE+H|bgtlB{i zytB<AeGC7}nYa~(gJ6*ZDf%EDGbduR|EQsq(1`qXRXORi?8nAZJUPsy$RxgxpH+I5 zW)o(Fq&MI-Dm)%{F;Z&Tq1}AQjL9y>suL}!bb)@w+(hHX+5@O%&2lmvth>9q_8vfy z(4t=;(bZmxrIEoM(~s=7_&N>1?L<1%T89ve0xDSB3}fgjwh<m?q65Xd+rV->lycQF zi}Ftp)bi?0KESCtXKA&#r@KZb+P1OWD=&RR5y>a9L$Zz;R>=bua_bDD0W|Y&mZMwQ zU`)=*KteqX41*1UPakb#si!(ek*31Ccw{XaRf0XDcbPP6(Z+4)s7JV6ZyA-X?*fqW zP@r&!znv}X?ReaUqe@+c&V^r1NS|p^A99J^eW<y(EMIwQe{rZb3A!tCkW+OUq<d9B zl{YVbQLA40^0hf@_j|ImQ3f)4qLa0wOFsNIoqgqu9v@L4TrNO7&Jdjz>k3A{{=;A7 z7pcp@_wi67W>+9E4%O|%IISYkKk$yMP&W3QNIu{7uBRk34BaGup!li06mng0*t-CY zQ0{rZ`Cdh~vA&W(La(;siM(l*iGgswid)fW*Ra}<Zo8?A+ZBCz5*z4038b{}7<Q3# zy@;f~7MYsi=M}V1TVKMXXF|a}SKA<+WO{rid^zmTC<{N~f4vF`+KU(A)tBCx2xF}e z$W9;Uy)T{pfR!bA=RX9AwW2fdaqf-8n#j;H2@JWFurt3TeZOQdJ5TpwID%chDa=|f zD{@D^g^sxl9TC;|Da8Y!YQvToy9+nO0)QjX_)zqRAbzQh36Ik~5hx!$B5s%*7ZM<s z#I%gZCi}xY7wxIRMOE$ak#0zu9UX;L1+o(hH(u2NjMG5y4pO(<q<`U;q$DQqS|8S3 z8WG*307eOR&=>c}+G!P>j+FItg9P<Ckfc-4hE0ev#5S8n^<0GF8^z~qR}Ob!t;Rko z<T4<L&mEgd=r~dBd8v1Ig-V=s4fl7xODZTmkquBk3XIU}x?8riR06F;o;O}Q;H-Bh zHhFoOfTC^INOJw#uR`u_1ds_QK@gSw34bbcWr>cu!O}lLxjY}{HK<cvhO|d?KN7ax zoF^pq#(Y}%*!5W3D8h73unhWmA?VrlCDFazX`cQg;c?Y?k9EW)Xm5PKxV;hu5{qug znD0<(k723hT%39_X#`T*WWK%4iblpWNf-T*VM+Q4PzTdLU^e~qm{7HKnG^}-p6D@+ zdCNGD`aJ*o-_fC5<H;;Q330%v!2qJoTbPE%^fz7i-+hwM+(OE`^9TmHcr)yyWiIO5 zy)SL9_p)Bq5;H%sKiO;AO<G;+CX*hMZ9j`sSL8PR0Ed*1t4Q;hy?>Ir`gMFGg71z> zHrzFs4P|b4TiZnHGE*5SnN(}0qat6v+d^YmJ(bg_l8zA~5x=C0BbENgmj?EGvY*9O z6q5YY?zxis=$`Nq_v5jpV!L6SZmDf*_k_e&b_?tP8*BemUn>7_m5m_l%0%hG&G05h zY61HZje23Weymu;;zOs8YifpR3^ZCNVD7w;GBHd8l!_1R%f5GHk5ArXMWjWt(r=_| zbQ2+d+6jgc`#>MVqy!J)PCt<%GaMHL^AQX)&jNy@5T&qUjaoFrDOgDs@Aoo~havmA z>s#Ha-x*Bl3N&06tOCpG=S2bDNTA6;ZcnE4;(^MJ>a@SlZ<6IA`F(K%;%IfsXt{^V zxyQN#BqKVg&^8we%32IqnA}i)6sYmiQ<MGA-`ftTH%SZm-sy%IRMctg?xa%_4R(Do zhk1-ZujW8}E$u`xLAmD=M76rC<uLx7E!BAb^04iQ{lR`jA^<K;d&&DpcVhp7(9oTl zr@Bd}PSdV|^N-Zo#E`hqUMAu;Y&|UeCYw40A;$hzuPHnR?yW*zD*ADFqRp?Tjq&Pe zQ8-<GB@`h!1Bjje3l;qWn|3rlKJ0pIw(z-KR?N|umpx&rB}cZ<hnZGGl&~g3JIY9z z*L2_diKhDwjv3S#;Swb%@QLD?3cedK@bRj65{4<+43)K_-x1Lu>%VT1-z6wH=)>9K zhkPRtS|-*8NqWKP5%*8g?=u+s5NGr{gZg~EMq)mO(2qpf>ND&(qcaxL*;m;y-%pV- zq%|hC(BEdaIw_}lzFMj46XK5@yKVaKmyU|!y!bG*OC-?Nlj?=v6>g=EH1fTP^|asF z2<34c;Y>~iE8?wsJLGzRNH$nU&<T!2mv+Y2snQ5(p(|y~Lp+EsYCpk2%4QU)aqTYd z#vkWzw@J}U)1nh;xotu<d1@QGHks1ZtZzay(?D3y1aB*@=>96;pUIiX10=`X)yV=b z@Li0PIjl6Pu>oUUN)80Ja(Gf@l94G{P?e~Dt}Dxc?P3o|V7Obw$BMEyES5hbM5>3| zm<9XzU5pe_r-S^Ljwz-hH%e|E>D^o@4;l_gBRC<L-gilS#v8%D1?_^DH>_%QUlit3 z4+~5ro|2>B10hZW<M_=*UDbw_YArQmG-L0p9!Lk7C4R+aT#D%-Fb+L*OA}hS%j%ng zObirE&-ljdJ3RX5pP)lAuSHYv%M;s)bbV8z%8!O>SEFw`O4F%0-BYpU6P(b5;EJFr z(I<c-#>Km&@EB@Zb<xIzCp}H_FXayu-}3HT1J9!xjM9R&m3C2frka($?ap)zxGao9 z<B5cZP03OsvYd67K(HP9Jy%ROr0S(VLBMess4ol$QUoasKo}FrSCuOs3StvqmP-{f zI|f}aSn|uLmU_JdN|=8#N^D(n-v(V9-WUZkjvAs}sXOzI&%9C1t!={5whq+OPdMyn zI9gz`U#WJlnCRb@s6^5`=YQW`;Cp<xxVHr@u;+82^{h+?r-N~fw~w%<msVPvNX@IC zTYQ?m;)SGa?<}^R5En!qt3;i~D-jwt{pOP2+wQgTc50ar7|UabryL&$;DxH8fdeGf z8BDEMC=oCI#efr&T(9?>R56hOxtNPLgQA*IVs)Kqmu*+q$wOYc*@kiHn$5g<JtV&o zkUo~|MSN2&n4u5>Nw`qC%TKQ}ANHJ2_hi_F^)%-jzFg;n2?pg9Am!A1SuK~M0nrKI zGb<70Frs^E`0|NFPqVK4#lG{(e56HIN|h@I4>5uHE|MI!k|uKiifyiTFS_SaYQ3PU z93nzo=mdOwgJnA1*uVZw1G}8XFvfme=1kN}w<BDf#|WKDj>=WEA;RxwH=!E<VHiz% z5GtEJ{>JIMsE8#>2dq9xyWn2sAEd8J_XoUsE?uw!E=NTL#+(CJKOb8+d~9pAFVR## z@0x%F`iWpev_4*0UOn0Kkc1o2oq!jA2e6hO;Ku7m)2Y+@+XYkj;@|h4M@A*Ox@eJ> zQn>!%np0=H%t+afiQq1w%MNi-OlI(hdi#!58JX_*>R)e&%J@yApSkT}>snZ}L@xAH zpefr;zN3~PwY{X-^|j(1K^@$KwPJ0^)GoeXT5}%P=RN44)im@Gicfw#^&hmW5Ru0R zXC-VHJ}1l=Lwv%us=PZrH#)2_59FQ%fK0|u!K6nWxZWUv-!R7LECCn>ok*g-HmMU% z?Is&<w~p4C6(jt<F7{9atLl$0Ty!#wLTu&)Y$34S9#AkpU4mj1Q&r?tw~okT1pRm4 zVURW5ESYgiKh3UJ!={3YCB-Q?OV{MssDJTDIxBdNX|vHl3`ojJZVfq@5wDB^MLgI3 zzWL@cP@|)<Jhuj-pWLa03rhoqP0qY0!R_^zKlrcBXP#BR>D5+WiUrrKVHfEV6t^m9 z<4{xcKAgfqAw7?xy)Su4yt#ngr0GzJl>ZrzAL65uj?%Q9zS39<i+#S0iG#tW$E|iS zvZ!azx&xn;qv5b9=mPX4QN7VILI0p@{W-AoCsCMA*TSe1-gL07j2VVL?Ww(j1a!Mm z6q?(R>qKT}aQKrl+(UQ!uI(7Ryy1O2iQ|fD{TKfm<o1<u)4jlA<^gJC^0Tl<Hq_Uu zGBFz6JmLIF`zX&7YU}V|`~7x`h}am{tv?_8T!b?eGvs3w>1P=>MX*);2wSSkV{=|H z4sVZU$y43OoB;;jwWVz!W{=-}hN=;gZ_FhoVH8c7YKM^*gg`uUmi_1<n!x8YAYAR@ zJKOpo3s3LswKX;1ioR}MQQRK*LU-1I!{x;N^{ZX+PIXz+&02A9%=7tkLDMW-Dc4NR z)oUU#Jpz!&+JE1(zK0I+dCl5pVq<h?+^8&sfhUUX?u>q;pp#c>1`VZtHLxq**@l`* zArc}g^qaG=f!Dl)q9m0;uz;wLtgZ4CM(h`5tyqoV-koT&vxkj8p0@F7rNSUvIgsAt zZRpgH#?oWKaRw_cL@g=ohXj%$8w1WdI>sc_l7Qh^c@rZ@$+*%9@<ZDj<GUMD|FF&X zP>DQ=oXVh*Fv6$a4w8h=AhMLJy-bUwih}@k=Lk}jM=844a)_DSOXfYK{=S2(u7^Bn zaHtJntVYOTT0~LRDELOKIk10na_T|}xJ-YaSC=6^S`+5~M)2`6k$8o^#6+`=X3Guj z!=%@D5@Ty2!%)LD71L9DeM0Wl@bkyrgpBScAS>iYj`)?fGxt3u;p(?Bh4BzprQ?Hy zI{V%(<Jqsbu4v;Ae)QmM3Dv>=p>dVMC*+`S(T%}XviG^K9|91?(2u4ZKCZ=BRKwdy z*On{M>BW`G;p<aJ)gL*|?%R*2FA2JITES@usnSm1$!Vx9ei}wQF65$ggjx)c#6i-} zQn`L-P?Qo{!c9;!hp)FZ=ZJ{<Qeje33>A>e<OOGtHGcWofHV<rp#U7bLk0gHU~BgH zv3%+P4KRFHl^!vLM&j8`c)%`Uj062`0G&1y1a!K-E-=B+8&M~)e)!|@P5u$xdjCsW zDXXx-AZpRWM1|5#NqX`)btya=^_X#VHPd)vVABl?3S@7kSi{yea}@pio>^0Ig=>R# zDkL%@GCB>XEfX6Bc(I&fJeGp(b!J)!S@uA2NOmwOO}#9v6L>jAhuK1w>(-yo%OO;p zUYstN0G2W2i}fYNo%WJ5A*1n?2&rRGB!%VCZyrZlR268p{>vGMUM6D}A_fO*TPWzb zid(e7{PxIJ$lv9#%BY8lj^>XB)Ayk@q1zqhB2lM=U+cHS(L;akT#x@{(asdcH+h&( z=SG^kkt~)-j`yO?AAI;qlP|=am-P+rqa-1_@R}cnETHpCn)_ehF18Ui0Zv9lLU+aY z*FP5@qbXl**mm_!rIJBoR2iac*x6sQ(Za95bUsHUpy(d`LlS9y(os!o+#TY<D189$ z=Y5N^&$Kro+5-b?^dh~0V_dyVP&BzU<cMhP14Gs%fjP5pdA{b}P3rmF0?O+hYS1t& zNJmO{egaU;A@6b{&VFlO<(?A^$3|TVJ4=^WQyB$>?2G-{-%jj0zWMA_Wa*Q%D#!~p z9mwCqHAWNr9zxP3Dz=|_PSesIe0FMylpch-*5(>9Q755H&9q+#v@Z+1nDBj5Lftt( zZPGZ2!P>a3xPk=sWap{K(FSZuOQ4fP{<2V_k`bYun>V$h95fNbPSTNbGG?*o-SK=X z4LbR~5zP<2hCyaBGd5eL44!(i-(&_UF7k_V>2>=CjtY`WaWUvI>~9L>CDyz8cgHqQ zE&2QeR7zsrfw1zkBo(Z3#Dw^NZmCm{GRutmjl2s_EN@s$IkBsC%?9^O6zEb;@x!*m zsnFvz+#?uqFeJpmCMFF}=t`-_SU&>4DYm0igv!s(Yak;Lj*F@-;A4%L7}41rC=*2} zAw<z1eR24N>l8R9zSf(~(DBf94QpZ-@^#YtGe07Mq!1SiT|)39`4H-9=HWo!=>x|g zhTqIU%GD;>QjzDIVs{XE8t&84%Fwxe>l745D$3fQbDZkPF=hc23~J&@!yhx)f*k;; z)ikL$Leasr!T&e!sF?Aqq$f3}2zZr1+6}`tG=y7UBJFpqj{q$-Y-vZ4el!*gO1wNY zjxpcaHdFJc2{J}3F(q&S%XZsl1P999Pj&U!IKaLM2(dpImZ0Ot2U_a&`5S|sJL8L0 zH5Kre`%4fCZD$)9-li@>>%u(poQYiYDvb~^>ePeu3qFQC^wmxYfZZ_qsao5e(rNf| z9S5?0`2(PBxyf2i;~%)nT4~#ANQ+6fmUK-I5XZk7J&6m9qjX;LZl%9^gM9&54A{42 z|8FvHz?MPQYEd2M2J2xvp_J_EdvDq7NB8u?WJG7>>%0PU%XmC;&8vw~R%?Ynaa6KN zcb3yd>O3T2;8@1xp(d($vO@)Ysua0rbDmc*d4fo?o7_|a1h)Xm%)$*HVXKJG5R<6A zH(VzCUU%7(2ctKXODMyT7{O$7h<)+7%u5)muOU~$s~t;;1&qq!_@5a=73)HYq9T3Z zV8#SRZ`1Xmca+5V-pSx!Ig>nCyM>0>KGA-n^%dR?waK(CH|Q1e79kV=Ir153@nVU| zs4vK=bOI1!!oE2_WL?ZE$LOvrw-LgoDyD|pcuNX_bk)5KG!&RC{WNQPgjGXGLTV(Q zZ&WF99Uh__JV5=88lEq_UH$kGH8xS{P2<TMKAyEJisRJC*h`Y9lGijOcSYaz#0L<J zV~n08@TUyk<&Vpi>mcrS=}-GjTkOqSmQzTR+^Sy%?<R0{>inR)QuTO51JFcoi{Tg9 ze*ikPm@#ShmaPL^(2ljVA@;r^(<<6=%!QPSA(ixz>!D>UMryI10rXgm<m|mp0)5ao zp$gDlI$i+>pD6p5SR3QWM3wC}dFcG&&iE1ot9-tjo*(KkqY(PlX##PiIgk+<tw+DS z0wF@6U1xkp;ld>EeW3dCdQBB`%_E=id0PP~ZcckQ$C?}d^b6B(dDfw@DP;05Q)S5$ z@~ZAUVxpkr4zc>|E7WDJGJOcq<qPL#!^zkQ+cG!^#cgnFi+GcyJMG<{g)w_E28pwv z?mjMm2ADETl9+7Hahln+S8<Oh<7e7esRjnEQBL&5hh&S1b?1(XJH@%S&@xR~<)=!d zA<<^S_Y!n9p+qM(Qs&-iEH5wj9OH_Ra%rnaT^b)`#q7iJi6yFvFRuf+GZtMv4!?J$ zFn@bSo*xzs81C8`)Lz#54XF|>5}gO$%Rq3PUmIIdTsG*fC=~R6r^t0>>MVMg`&4jW z<YrGL?Xo~m=pSp{JwqB7)R8K`R<;a_?iZ{<CY@gDkX8)!1JrE&x!?q~h-0s+P1L)< zgig8CvpJ*Vu(*p(k<<P9xMOaJjMx~-_X?3OqBoSMI+w0)M$Q3`zPZ~@RfHWQ<>?Pa zf~7t(e<u|C*{`yp`}xNQP7$3+LPT?(8_K7jIO-3Aa#6;hR}c6i{_PIj_aeWMtRVmK z;+-$z1qFvLpi(L7J%2Ie9lJ$_m(!v*N|%u55wCij(;(u1AAa}<ihodw&bQ<qucC!k z_(r(IAx)GE$`#E`i=2bv>*)WN3I9%S1cI!r-r7bqPk9=JbBC5Kd-dH#B{E6>(M*2o z9fq#uT38i)aL54x=MSjAzt1?n!~gz1|NZT-@x4WP20z7+pLNZ87GG6J$vvVDQ_RWR zuGblsoZTvi^RW_a_%Y+Cbq;Spe}f43BL3emGl6_@{wN{FD~{MOl<4y9yNsq(@$!M> zt%}Md<!;KC{C^faIU!X48lF;PSh~P}Uin}1T&P19uUOn_lCqWAEWX^LFf7Qq<p<~5 zNRw1|v@fr-Lxf-hTUAIi6qo1!SjYDw1Sk-V`&U44PN&KVV;379Q1VJ46ziT_pP(>~ zsG1j)_YW?Buml3pNx5XRqS=g#`S9P_;NLKZ*}dzwj{mj@M_zm+F=%cI_abs89?fX_ zEKR#)0<bXtq3DNZC!(Uqkzwmw(98^fDSt4n#>f8cHz=frus+`ZbLXj~A{i&cwMVL; zBDnq76gefNMVP12dOwUbzzU##eyWE!IsZc#{+DQY!$R(ffFFy=EQ}$Qw3Xh{nTtCr zM3>&aL8yB3HGwy#vV;8Q#|X{mX=82AER2m4S<Ou-4%TY4o%?$^kDmozQ2nB#qk}&< z)*WTzgs2@5Xsv3f$i$<eT?zcp-|Bz8+xZA_O`f|;lxy2vTO=iFn}gOC`>#LgKR!kP zJgRNwWb43x8vFnZUT2}T!T+bh|9j;I^v?fhD^!O(wY3KDLZ3GZQBY9KNb^%rQo__2 zj>8)m7-VVif@y*URE>=(KorBBN3Ky{|EB@^?|0~E5Wp;2?w?{C%-0783IVTRRx-Wf z-<0#Ol0W`M(*7}(uZa2&gY4eGV5$)rUG9Gv{6FwYzB0es#(S#WQ%>3}TT!@E&=jCJ z^saX&GD=G5L$~rX*%YyH@c~^v)v1M*7*qeI;{RpE2{;i8<02jYCIPp%($XS-ins!} z@&ET458wdWzV}_;1^k}|Y5oo>xjGyFhhOLaUI|$Gf&T+n2q3M_qDMtV^_weO_NzBv z_P@Hil2PMelT2Y{LH)0^Fdz~3f~`flxg;a$+?=s-asD<hsC5*u26=f|m6;$*zRTeM zXpxzDAPk6d`Tb(4k*Df`e|QakJlz;eiGIO)+x@rw_P?&5*nl3%h>XXfv=>;~uyXbJ z4>tH4#9tOp7?`)?|2RSJ-!dAxMsB8m+g1O|SMl}()Y{MQ&HmqZ$p4aLBe}oeRmzq0 zr2nAv;e3Bj2?e^|IR1x|@V_3Kney-EiE1%!CQI;}T^P4kU8PXaaXU+x!!3c>X?wpF zez)~{_+PZndqs$EDOA&lxmEan6IY}hV%lYE|IYirPnB!0U`I9fBkSSKmydAe;t<;0 z12P1Y!8E(zA~uLTTb9qJG8U`NiizqRB3<0d#&J-W(=wS%PQ$}9P(vX{Y3;lR|FSZ_ zvxPD>T%@o<&g4$u;DT?OL8xeG0qnLv#XeEN`ah8y^vC`It4fV8BPHTP#5oWi?g6wg z3<ANG;$Q@(pOOertFCv{=Z#K=Ft%Bgx1^+`KkiNzvr0=PgIoRD{QcT%6}s@1b@md1 zJolhMRFDMOG{H-LNlX%ERu+rZ;6zSGrGtg6HorFeL~g@;{RDf#FEbwO|FVXWzR<O1 zvt*JP3`~+4JjAuet4eSewqc<H;_8Pj>@~FnbOJ{}ED-iL7U)yDWMlzBRC`n}F`C{< z=Bek;({#W8bb<lTd9yK5rN?=#O<8dQ^ChLOVDDd+fKQK@-t=z8>g5aDFM!a9Ofrpw zr8Z_*?}x12Vy^&)BW)kCMmKf~NqReR<p#7u@umf#rq#utpcTH%(o*nmMz#FeuBqxp z>_~vm2|oe`U{8?UYgf<bZ&oasYm&vH%llV(xhC*3-Cn2bAk*+z+^xr`&}?xa%Ca5F zsVXcKJ!_%SX9&X!zveo!1Y*{3Kp4SmkXl}SLhlk*eY#kG+?6I_hpJMhnl9%@u<scm zP352+1is`f$!}_b!WKWL*Z=cQ%w!P$;LR)Qau{U|kGxY98Wceq#g))_8g<ojvpQ-j zef**nQJfkquG6Q#U?Y#lM|pNXz9tQaVew%BoV(EAL;>-tzYt=EV*fjykTCSecWHt& zN8o>|hW8P4EcM**`m2Xx<Izw_EuywQ-0ALaUL4$+ir8Y#4&248?DhPj5AYOb#xQgu zIfODw;<1{nw+*#lUIDG|$F-IGcDImo%TA6T6e%G2V)HLrNAL+L@`XvmWl?eSsH8mV zJ^|vJ2_YVYTJfp)0Ur&jU+geUQRhZS_2<7imN^2g)BuspR>{pVG=p$&)vPQub4QDB zM+Z4wlTWgdHxtchofC#EZhZjW_J8~D-yptw@u@mXEDO5aD!$PRaJWjXWDC`5t~jt` z<#-Wb<INVrsCCz<$N*YTOQGxGIYua>rB(Qn1FjbzxP#G9A^7_Qu}CxVG`H>>W^(@{ z;2GeC91;kzTHIA0Hn=yjmU?tw3<r`Pu^1{L@#rgsza!iS+XBqVNcV78YgMM2zjOUU zHRW;5D3DIs13=a&>;uOp@d<~qlc-M`{GmS3hm#`sGzqJ`#cQpG2t|Oh&kJnC+5Tg> zt}x%@+5sHkLsq+J%7ZASd~laEr-cblV=n&H+A_s0x%Usd(E3;qunfh>y_xE`vkOYH z*{YJAyKc$h3{?N{r&He8kt8I<#k)=x8O)gX-iRJ^6XI;@qs}{rtLtyK6o5Er2Hg2i z8+C;REdAq3^P@H!@VeeN+8zMdxHjl-@BU$w`Lu|E*r_6g?VNhwkNG@hf%?F2#^7Iq z!v8zP|F4%*nVOL1Y_+4+y<aLTGgF2aD(gS*|6b)AfQ5GdYoXg&FOmOg-TAuznx4(d zo7iMLZ#5X>ah{jqWqXybzixTHCBeA$CV<FpzQA;W{f9_-5k~?NMmV}we;Gad*FG*W zTyfgq0+PtS=B4HK&pmx05Eu--ct}wF`zeqm0o_^`AdPmL3^%C%^h*g`fg2>ZnQxPp zd<EvH1DYuAeES>xwZ3nA_?LSk0fShZmvl9M@1(lMr`75&0tC}tdIyyMbZhwThyZbS zUG9@m;soX}?H@QFu>R}rI(=}t{HME1Knx5rb!}_^WC#AKY4vV(f{OsYqksQ|{J$KR zoB+|f@m+mbLa76!33)EZuiCT>K{d{350SaQw=qrWg9A2H8_1zymM=%4rypB};-=i9 zYup}mdDdA}*3u&ZOUJDK*JD}E9}fwh7Z+{0KT%$@z8p)ggfpL_{m+q8CiP!afe+Cn zDq2E4c*8;)`|~yKSlgFsVsTzSOpAz~1_Y{g^9W-x%Wl1Dk%Zc0r(N=yryRXW?{MqW z_Gm2LS1h)!DJ&e|sW_c)9got=>eJWvrq0t==SXUoc9x+nKYGZWPf8!}JvYKXl6cvh zN7w06#Ay#md-|#Btm==8dYH7Z2GhcByQjjj^Z&5-p3!jq(fjBOBf1eadMBbKq9p2w zU=Sq;(R;7aq8kJeZFC`845IhmqZ3{98bogsz2zSH|9)@oy5F_#+q>5FYR+1inSJ)z zpS_>`>}Nl1Jtn!W4>67P?$>VyioBVbq!hd*&+>;!c8vH{zLzDJ=WUjHTi%NtGktF@ z#5H}D;pi`8#zV`kh9}Yp_iu|7P0Ba5B9kYI&BhtdFJ{X;ylj-h0bA#G&AI48aMq}q z(%#3e-ZYW^x{lwF0of0k<3{DUC`LZ3vKswPCLyt^L)=9uGnO9X{FzL0Hf-u)Ow(_L zenn=c1kZNOZKrqsYUgnz0`K?rykmXTya<_~`9+*cXqE$wQjJg%GEqy1tda@7pT%Aa z`JGJ%wgnH)m?VEv;+#j+V91SeFw7QtHO8b@7rrFsA9!Ey{JM1_>C-2jZ&7d1$&tSK zobQx;*{eBjJ~GVCUcSlihEj09oW&2;ZQx57HDhk>J4_NnoKsSCyVfTJL&rKk0+k$_ z3svk<sSPaC`C8pH#~s6^q@m_Dp}cT^4=|sHrKwUCMhqw%yo7lRg%btnv7lZB%1f;X zk{YF4k6i(Y0j~(mMQr1P@$0OjxQD^H6L0SS_~4ssqp79fcO&-U>wNqR9KO9oKX`Q0 z#Y$xZ5<d2uBLP<?iK{P&v!&o=cp}g4pWq7_3DkfguR)vy>eKZfwci>)w<p=Q6>dnS za*FG0Y`Hp=_f*r6Xgg+XqojSQ-{(Yj?FkGmtG*@1z@89MH+V(d<5lsDDfc6>DaQ=Q z=@t#$=hSHL$C(n>um|N)&N(8?mh$YsyLeZ$wRXpDNLo}MVdz{KT*N>tbW^W&R<5TU zi9w2fb!y&+i`@%&7r9E6>&`Dycz9OUzuk3rcY;zR<J9kNym^Hp-pd@5APU{AUVf(B z1D67(3RD@c`lmRumlCVkIV_wXKYto%)|*d_rx@d3e|b4DKW0Uxm@%`_kg;K9Sn~4i zo)TdzJk?Uo`;SOYA4|?#9aLEEfi2u3K!RO`7cIZOF1S9p5$=^&16JAAqYH1CXuiB@ z3L$oS!;#`cRC29^zW4c?a>P!ome73MT1*9N(|JUOhOor2>pMOz)3cmc=2n{rn@N2( z@}hq*iEvrgA};yAVX9n;8TVYV27T^N9E-B<I$~Ro!+CTte)f3`ec%@k`%Xzve?DND zZ#XVH^P!k@Y^f&8KUVZEVy4xgV<$=P?z+6^3ZGUAWZXOc!Gu=pb|}aL9W?e)k)||G zEvBWAXMKWV-tfjvt>og1;`2BATx$|&`K27Oo!F_S3#4X$ZOz8crTBglmh;V30yFoM zj)eGdepJPj;GkYTl$*4>?`y(rtb0LmG2;WVzg)W-7xA*+htM&vU=p5#XV*#>e|&iL z^9}09fG2rwBAsBoO7PiHgO}k~Zl5Ru)(d&(M5p5Frk`UR!|@hwpA|BuQWBRQGeCX? zf(=KMuSaC-q{lPe9P%zu^A8xFGuabph!5u8RbJ{$dl%gN5a%!?|B5fL^<brk!JnY@ z8XeC0=oP}6-wb1|nTzU#lA{b$E*|Ez2Z+6F&Q{xQPUNctT099cpJs~!#&ebMm;C?w zo&%Ftm;sA*YAGmaIov*emWWGxV<?TM)O~Mu<|$D9)U*oTd|!|Ai4{XyxOsl;e@)I= z!kO0Kvsi8_$Hnlh%6dE(eSce~h4Y}F550+H4@uNh&r`0JfX|uW%I_uRH|)*TLhlAL zZ>sF)lq-l2(kUBRNqr<-e!sGv0{HmtW*-lbeR>TKU1G274iuHbxNZ{MZ`L;qxp7d% zOa&k#h(!cn*oWMAAD?6abhSxrDoSL}cH+rJf`4}eRpKzPG=nTxCBvZ>b;_8ry*hH8 zem2a{f?P{&&2N6dkYwOxohsaxBBWp{_j`i+uP!j<7G1tE;sJPxy_lW&I=2*K5)LQC z?09o@<>qV&y4n*hER)b2RaBAv!^wPLEs1Tgv8@Xv_xKA}IAg%uM1cNYcDY>`>UVQV zm9^YBi?fB2kNXZNLK90|A9g(UM4Q>BqReuSIp0<w(bO^)>j_#!wngQ#Z;gY=&wFvo zn!l}3D*Of%d>^ed?cs*wk?c1TazMMfx<bIuU?Z<<3b?8#xTd&01lukPqw`G*XcRW` zGW@6)JvZof{E_Msg?rnR#ky?n1KgDneOlk6Eaijze$Y#<g&*X;`fTExb}AE67dq^+ zrBI<flTYbuUHwxNzp$vHALA^i+_Wd8wDq=O$QRh|tciz-O;qG!XrrJfd9g;iQ_0|a z9K$1m6h21@<uVM0)3I8%A;8AK=1W3ANCLHBIQQ%W!4o1TX}|#MKIPdAS8pUC1!r=z z;lT|C&0fLPQwE}s4PMAvv&;(7@N%GLM(_+mE`h_ls-^eB<#`Z{_r6+@{jk`dS03m- zj*e8v7VF8Bml&!Rb$ab@Jw_G#nJ7kEe6K=)7ALbEFe#8b&))QOJrLs@*eVtb>}`MY zD*16c+2Bif9Er5(8xFUJUjPkOhiQk#y$H}$u3fBTVj^ItSwBFkp!l)vWRXH4HXezV zbRQ<lXLBUWI6G1ZuS@*Xpl?#c+vi<zjOuRf-FOMot>0Mo`ynCUZ7zV-kRJfean|dz z*1v*da8?by&rkJ{=S<QefX=|;GzDE-*lh~8URc?izXO4!zBlz7=}$?1ytAqQc;I+B z_Iq0~l^1S!sfxbQ@K_0^^!u5FJlN)!Xl<zi#3MrlH4U?+0=>*_mauO26SRPReb<1! zD!cBP5q$YJ+_Z|B!NfsK+nou_fQcRNFElDwwEe<e9qEl>!TgYpr8Jg8*@(r{x?~s( zJ2@ifBcULB5A3vh>~Xk^uzY!PP?)YGPzsc7)brv~AyPni=vdy&H+zCn{}NvQaRDIm zuVjVN<CV5t7Tg~bSTUwkL<xki3|)Q=;9$iUdl$E}1dPl0UF~(08Fyf4Qo^OaH|6$6 zPzyeq_y2n%OI99|iNpRvp+SCY?WsXFE3oskBG+lZX3jzO^1P_Vrv+GM`PiiM<6*|% zYYrp_K1F=AKumB*JT?xnZ_l3GecBkiBcLK{T9ZS*I-!=msp7)rG@>FY+3Ur*HmL5P z<tl>FIN;Y)r(Rb=YJrD#_3Mctbe$40(X5JVOwV}e9-|h@?8MKPgI0i|knrsoV+Y|( z`se;R)uq=-+rGF1R@;gmn5aw3{)3Y#!_r+v2LJ1KX;&m`87-Yl4afg;tds(iJcvHk zipyMgOCLDpG?VVzMaC>$$L8u7Iw1Pk>^ORiGZw0d9evQAi+NK9H<h+`PVHaux0Pk= zd+h5~-bGO<(*+3PbO4&5KIuG3|5M`o0{Mjw!^HLHFE1FUa5(Y0fngrI!o}S;FYBGU zzP@`&l;b!kI3>Vb^Jhpj6nul7?Com*iBVI4Oqon--ks^=Px3)e#c;JC-3^OWdy7uW z0ixlF#Nl|yybo9Vt;5{zZ;@qRneZc-pfq-60Wk%@9+s}6?g=TGwc3QrnhIyj5`!w4 z2F5UM9OLFr!A4$6{tpRsRNo^7a*}4B87E0_3<8R_Q)Zh-Jq*ydtu8kOj)vb!(k@BT zv5hpQS~`E>(qrRp*tH*)_s|2LNFj`5y0p#hy4Q_O(fxJ;K3Ur^f!ov;b-n0!Wk0|{ z>OK>w!kY-J6pUPx3jDDL=v>rfe!g@Un&`u|7ODzN%4z{3YB8Vlt=`aG579EEpbuZi zkZl&%I!^daw#D1DhaybH3==1NipucS=e0m`!tq||Bp%34U(EioF1ZWGB|J+J+j}3X zs02?jG^<+_sz}GMAR+^f?}4g_P-CfO?ZX66g(w=X<^fUV=*cN<iZGDmq`tor4xbfe zvZol-D^-}(3Uhy<!&g^%%EW=fUlREDerZVFrei@rJRmP*FdfeF1WKbS&szV=Z_T7* z7Nb8-3e0>HtT<37fugny&cK@~ssDfe&3s$#tFg=aJ^LH+XXjaJZ0i@7o~+G>Q$CZl zd`_?@_wa86yS_YkA;4={RXFg}H)Lxl`5=%G&^o}|Xg6&Zr-ZTL<Iu2`oAqWulZj0A zQ%b30%LRMHgD1>lmz&vu7XE9X_(fF|=dWIGYq;2aZe5`rE3RFf9g+tQ`_ewjb0*uZ z{@kZ$YM=RU)?dk%VHavdW56=7-*5LpPgeEhhM0VT&8wK_T1iPMXlel~WExXneKK%N zhU9e2#03Y-c<G;zWssARZ8!Cf9o}9Y%xNclVS4VqJAD`0BP`#<;<;rGUMSYjR#}_+ ziub*+$(V3x+K@<Jah$8M-*eO-Dp>pcK|gl&gG_AW2R?t!0R$NHyZf92Wysz$?&F=Q z;q=min`^_-r2W>vw})$SDk0Glm%T%bN++pHq-$wI$Mz8}@b)M!V|Zhg&Ch}tA#E)> zK|`g8%ZS@gwBl#;E-L_ZS|BD|$3CC0Zc2CcVzyT*_U{BGQf6D`#$#c=q~Vy&jIo;P zjIU<e#F#}gw5mSr(^PF3@k1_42ic{EBR*pyRrXWLt4=uPIp)UO6NWFO&eCuCMR^xz z*k9ihB>U?6%)9<x`Bw^=2JJXssXsI$Dc>T+QiESI8sc)2vO?l-r<LiFrT}vbud{Hf z<KyZNiA$Jv6R0zu4|re^J=AMbR&aHzi2B<6JH<AnxMudzZquJ3W7uD?)I{h0u*O9L z$ygPvZK*`RF{C{Rn`SGh3Pxn34)MR-$~y!^pRmwDRjPd3?Jg6MUO8SCj~w+|Xr4J` z-v2!)G{=3+y`S&7@^?lQD#!WBE|OAS!$?Y1l|YY}@-^$X<aVxms$^I)!cB+5%?oFg zySfQj8sAgMpMK*?CVhbW>nj3spS0;VZ6#GVLVQ8o#q#%%p0d=^e#yQ_zOqtAX<@^o z@}-z;Hq{t04v5#M5t~qN<Qb4IJgF~dacAxl>Ij)uo3c^|L>?;w{6VYf;@(k>21=#j zybTZMojM4?bMIc!wKMz;tbrj;A@#a7c29^;kH=L)fjn_y_Q`c6u+qvBv2uHJH5mGg zgCYG<wDOk$El@ZD>c@a8buH;Gh3f|LweXaQT92_-f@_kWz5BWq9a%Znc+f(V?zPQX zd6i`7XI)iB<CO)a;jfGt$)7<8BzjJj=y%gFyhvb19CuL~3Zz-po@d%crHx?EnToQx z+E6fdC9+;H_n<>pIzm&M*+{39<26t`E7)GRL6Nk;ZuP|#uhU>G5b8J<ef1Ut)e$Qk zBqkaCAqblec`B3kZ1|pTW-C~Yx=<+a6@7|nPgFId{r3;J=BoXe$AEMhpd)euw_9ov zr<L%Tw##mVrpAD<6d=}v7^vxt$jbm|JAsr)Gkhc6#o>V%itM36VwHFRHy;?vaQg&z z1e#=c?}gT-Y80ZTb_>uPf{y2@K$G;G!!F`BrD^DpIrn|MxGYD}O&%UQ#kJpoo>;%Q zqx`_iy6y8U%3Fj%L17R!G$oCb0XuvB1t&J3nwI{P>lBk)3f~)-;6XI1_IL_q37k2% zm$q>SK#n7j(WO$Km_S7Pj2L8p++e@Z@Ds+)kGEOC?UhA(Ju?I(iE)L%Pf_8vmiePI znOR`VDb<W;yK^^{<p+GerpK>7^Rq?Ji#H%!cc;r)d=A^O@AaQxfM?1jD_kP{Y<j*3 z<0JcrNAa)P&VZa=SoaSG7+GTLuDU+_doXnmYYfOI@1O3?S?<XlBN<Y&7_Q-Kg80bq z_!3Re5YS-)S=%q(`}JV|W$LrF3u*E<qC$;u-A^}Qn&*sr)7$RtqHP#NaM8?Iz0O7L zySqXkVTb2|%Z~#pt^Z9uhXWMU)(1sX+BsVbzf!9JT~C&g?5q#PWw=t5JqnN};GRGb ztmm)gq(g}akKte3XRU(`sZ~QV?<0F3>#SiRV9`oaB2pHPq#z8KlnU?i3-BZF3sNyr zHt<@8$1mKSz4<cZAh5S<)?Oww%rq8V&a)hApd9jr1X0jD6Zz&gg7*0sOsr=7A=aq5 zBSN5@t_8#=w3dBFNPK$Je$Ww<E!PjK!=s^j(d2jI_2-~=$*-{}bUV};SR6#@)~ARB z;HVEkc$;05rk}~A=Bv($q!A7Q#?}%Y)pcX_J8AqaQTJ-v9L{;qGHo?~VS$dpIKXDT zX{Pe~>&W~5Q%^Qn@BBSDbT)o=>d&wwgMsHd`IUZHyLqDWW=HcTMbKM2EPcDc(tM&` zTj2MEaMNkkg`1wmNE)p&-y(AyISjJ*n$i82W$#vLPEFu$O#X?={XI}RWdEa<_xJ*f zfbnS@)$^t;C^n-J@ymgXfuXDc3>`d_JUV2+2AC)qA7?w$lycSaau75GsEp@Z7MMqR zl<gq(tWo4n&Wo>L3eChnI>Cf)Um0m`A<N}rYhAdAr~bFsZMDumOSpAq>Df~9!>`fx zAH1|7eybJL^eot5E*f{WSfYv?^qepB!THtFUxyA8Lyr|KnqQwBY$(U%Kp(xNrnpM# zzR%tl!u}Gg5&F|Lm*)jvZmDxTIUgOzYAgZbdt=q8;?Ji=P1G5~l7Hu0YA1-bwqH3b zLXTwFuYnx;{=Jt}u~AU)1J0mV+SW4_<^cz~7eo~mJXxXF52#QK-spAdUYNKU8(3?< zD}yb`LsirL*MnKWp?+aGUPFL&Xe`mw-6Iz_SEr#Fez$#VYl}8vOy#Vufg!FYe1F5| z#6<*2kzb)gYhC1g>7Z=IMD8d4ZMOxbHkZde*Ua{~jjuylw+F%2{>PB1e0}a^M3uhH z_jRijtV<fkNJ1He^x;$QQ@g8sYEo4gndgh7E6IJYCyTU6&v~PTm){-c!9F{V$M@Q5 zLOBBrzTi0gGPu9}v8hPF;z#mh05(j;3F|}RJj68{<>KWNue2g>X8)Y2LaYeuep0iI zdO18H4F&YX$;5$O3zMeg1AP84Ik4#Il!14#(k=wCx~|N_Swq(|Vw&tECYI{sQIWT3 zlP?;w!>>Ig`S)VD?fs__Y}bPH33Z|}mMj)20nl2s|F!AcI;WL);&s{$#-g(%%fiJx zeGJQy{>VdeGiFW|q4FQ`lJguevr~nk@~|kb0bx=k9_)MEX*j`kF1KOJe9JrYiC~bz zr$_7D)s&k~t=q|_B{^FY+%O%AN6*`|Jo<hvEYRH^hDs(&GNx`nYN>5yDCBtpCg&^q zwo_E|A&nM!`o7fZ=5h@1*{iY3p++`}%>zVy=tG3-(XXz_xb9jhyc%7TWg!!E8zyv` zAPGcl0e>^{s*EYM3J<Bq#~LV(l?6fJDc}}8FCkDib-{ptj!B{<JhmccE$oqzYVzn@ z-+nGj)W@098@h+njZzV>y80Rc;>`SHAi)k+TPFPY-ET8k68_$`X}h4%t_pm*zrFn^ zsc%eb{Y}zg0Ct;`Dtd1d8K+Qb7%u5fj+7?qk4dsLZQ0Q)Hwh+`v3STC#y|4ahYfg4 z#Zd@55RN#CfF_S8(_6FOR&fNuN8<yJWf_tNhNJ0(VhyGlQ)i1jKHh6eS&%MhfYF0E zpX!fG_p@rrkhp#Il7X^qYd3HL63aChNE1shH~>amIsx*NpC#L9Jl9jp^=>Yb>D3Gb z9v8L3b-ykG#<PreTDY9OGhV~JFaF~^BTFDoDJ-ZQmOmux7`@;&rB4ATeMxHMG#r+A zds^G7jmR<%f#^bXAj#J4j5T(EC!U6K@PFeq0d)5VzrD`>-ei{lAjDL?m0*UgO@_m& zVoLLa!K8RE9?vOj)X@{L+6;fVtf;=}GXa>%-fT666IzKuB$L6b&tX@7Ixdo_@h)06 zFK;Q#s@-oMbeC6o_*5XyOs-k1ZTOq_(Xt;`+~H*N7Z-7^Cp3H_qqcqTBPR&?IFEH1 zFGmmzRf1+`z$CFCC{Tqd`naU~;P36h-zb_}UeQho0>ic6)TwI-cY5EW;&^SLRT1YG z3=MXy=K?fH6D>dKnQ@juMG#FzYSY9=^Ctmnx0&j8P&?V!l1+#`+rB*oqYRY9S)HS4 z?Q4(E)>zJ@^rydVtyaE(;NcSBktrbuIpeb=CuCD;m}APNZb_|aJiybPX4_+K`w{Ds zg^>-hEG3U@N9x1Ko2`7LMc(~-iJwbt(nQ4aT{!4S81)YH4W<*oQvk$|e%A?dXC#gn z&b2H3z}Kr)aZ*MwoN}r98FzzAj1skU8~wPQ2BZ8T7LVDlxBQP<U;CKcq<9iAV!_LD zABr=+N|E-BLuE(haEV~RJ;7~A{n^+O?e<6hKV)$k%}u^eyB}tWxnflnVEwIdA*V=G zB33F@rhWP61>WVQII*t};UZ-87`f<sCXUP4{FD9Xuk<F3VxHGTv%Oq@yGjm!(LP5# zJu5S3GfR>T&$YvP%iJCv+1WgJ548zGUR~s6baX_E*)^jGVkVIb%p%65uB!%{Op=}> zUCNiYx*|XtP%uSHRhA}!IU?KzC@I^h8RjJMTP%~VL9+=x>f?SUe&hIAJ*)QqeXY3V zmazp1-*%loNvYlK2A@A6pcV3$y;Y`)%b<XjFBfB&VeM57xQVvUA+C=w9neOqMPQC4 zrp{B<%wpUSBGE<~hdmv!h#=#T<87;CrYU^3bj6<Zyb+UCa3QQ90jev0-lblVi5(EI z)<32wZbC2vfGv*EjpWpJ@0ekLbLXFTwhKw+Z%6My!p3yZdb|VWFj0L@b}$mKDlQTO zq(IK$-L>xJ!tL4b%EGWkxUkyKF0iG<{gdmKfcPFH$@M!gtKFMK7G~lr*?8Z1CTaJr z1rs&uwh!!6F$~}6HLwq}N|G5P+)*|0-G86S_9&YP>&HdJZ#=umK&79WpV3v?Z+Q(X zf=0j1+cHzI)0osOOlM@Z*V}1U?13;*1fy%g<cz>{n~ZBg4o{a@Opr^?TiNw4@1H^F zhoudSDmBI`U!#)czqpqlr{@^o243_WRi^Uaew3)~l{NQ{zlk+iN|%pJUJj$T2IaR5 z4;mRKo!h?-gwixHx0;QlU*q%EG0wa1*stt+?-K!OxhGTF+t_;yJq$wjvu0wD`7WC0 z%b5Nie+W5uI{ANL_#@tH`;!+`BsJ-U&_kisGv_)9zX%6~{O*-S#T1wG_{MPeb>MRu z7^&5=`6^VI@trD6_j$w336~nNs2#yNbFY65n@Jw8W%Ye5Q};Auw}1K>gdS;sZ1f$K zFDDm4n|5uK;8&Ggkj`L6eel|EIrcMsG;4cD8@LDCE0XdjX9L!DCCncaRZdP;r~iJz zO^7zy_-)EZHoo3vV_WD64ua$h7wk2N^pEZ26QebFg)9qycxxaS&1y;SfASFwe}AxO z->QxwYz@fbz;Pk+7?PXt*eLf{bSS+VRx}8Ya3-h8$|$3$L78dcy>=hwy~he_&CHSk z0^Y}JPQ6b&E8>pV8jeeIKZfj%Nh`GBG6oZw&wTT?YSVId8p6kGdkFR(Jt*hoqmHeu z;E^}nVy)jhN)-!uV{l>Z9cTsIUNsi5+J(mK&7q0r!v4NmDN%=e`04h<Y~t8CWuLSx zn_XT5n`8}F4=Wmss=_~Bp|M3zkUrFDogtlO6`wvtGHlfboOd^&A3zhjgv*4NVoV$p zU1Bn})4k4mBT88P7y$OZUF!;>Q@hea+kn7k{G1GodiUI;qKZ^#6^pXjN9LM{x;Mq4 zaZHhQKfsTRq@q_vBk8a>kLO8#49MC**BLhZY1WONqW~*b`9@9QR5~=>?kEa8wpM#J zl663bO#c=&nsMw7OEE~zG5U5Kl9~xo^$@_FCetAHc+$k}x16WG?duTc&-pA!QY@jT z+^m09!<KmA6%5bb73MA!h3oMP_Nl1|#nkwox8W(bK}DU|9}c1Wz3a)vrfOgL5oDi7 z4J!&a@;Pv#eJgu}M@U7#w)W?45i#ai+MX2rG`<NrS(lI0fW}*n<7-;Ar!I0D?1JD_ z)cxX~w^}G3DeT2^NvDz~Zhe%YKLjOyqK_fKrkf~`oBlJZ*K+l`sB(y3wd<wQaeTqP zSzeX6`)^?f;!I9!-Vx^Lm!4^bB`Zq&3?ip$*)a&R*<WGGMNfY`r1WtF`Xs+O&R=QT zurYSgPv6r`u+z4QE8jbAwn_XESr@V}O+A`Oixm1Q`z1s-^Nhj?HtS6z5-fBVt&Z`2 z1t>qhkNrS=!>9JdMG?#?6?M+?WMh&h=4Et5=dzB04F`<+Y`V95lckaL73XGgE+r5} za82%+dnsq;(^F#=PRmQV3X1Hdl#0knAeh8yxnoGC1W&&!ugP0tWgqz_h}b0Rd)01& zjT7~ESz9q6PQ2bP;>0Y9ayOL3Q3<Z&LvQj5Hdcof?Qv&W_rngxn;X()4Lxt}BMZ`c zi7M`IOo+N?4aJwyA&vnp8zO*@mO+5r)|sTIwzJ`Cz3o3R%$InG%~vwevqpKg^cTke zWRf~{0*(*}SBbIR1Tma$_B}zw8z_Rdetdo!j>Ij#hpHgtk3(j3KCj{W)uEZ0<PW%* z<ti=J^fNx@(AikbF$2vIN}v$wy(>h_;2h&EfXPw}gpVnRRW<{L^pBoEJ%@DDei=#k z;4PxftT|x)AGmuBKjVBPCu0EW^T2QY-mWE%aKR5`DUklJS&R*E5POPmGv80nW@EOc z*yt>L+=ckO%Y$+j^NGSPUrp8%D3Es5n#}=qpOOv4-pW|ouDhOnBml<~I0@rkfjU{$ z2xiuSgAi~b>Ak`=ik>UkqW1ve`SofXsee)cW-kla<w3GES`WL0>@K>FD+#T|Qwm`y z{M@y;2&<>6;JQ2y*bdqem(cvm-0A_;)AlCZ7AEE<+}H88&GLs`Q=J*6ElfF~@sui0 zEq=Um?LTYO#8CSQ^-A5_v{1fv;hxJ<;ZhH)m3O7p-F~J*QO$;p>iImRGLPYF0mer8 zT6kH`Kf-^;s8lPk!-w&4x=<J)8qF$>O_0yp8y@uC^-*LWn}@0sJF@F6mRmc^xI-o| z!W{#3eEsmPv~Zv@I+<L%`Nc8bqh!TO)FjgEE%OpCCY%$KXFIelS%jonfO;>nr{T-y zyX`V{`%<qd`Z9{1>a}c^Ka?Q;BP}$V<gBuL*=1Oq5=a~Lxx%5wjy@5lLSU$siB=1f zdGnC2Lwy&>`hJ-@il;q^e%Ub2F=qw3VB8ThBb;`~wtl2WypRFn-1{Ol6hil_A#yHc zhA*GR?j>|<zTSnfZIt(zCT5)!&E)sT@A8NPQ+*z)U(!zLznpxz@*WvO^~$S5c+0W* zB=Lf=H9^l&BalM`3<uAgF9N+&KhtmlzhVHT`FM)j2yP}7xhHEby4&-Pi$us)<6k(V zcA<9&@BwT$SR1o6y7JG}0_JKRq1-IxZabQ(;<1e$Bcyis5o=gITN*n9k(gBHm}TdF z2VcW^@hsCkH6J7&Q-Dm+X265`sR&|S!4}u|xP#5>$o}CJE~=8`1Z+hm?C^!hYPcEF z8UIGVoh4eCB3jds=DD**^0RU-S2s6p70L$Hzq|4TIjA#%ckP{ic9`4`x>bZ77iryZ zypsY%5Ue%DiJ9`zlS65u_H`u&4a<ghBMEd_?a$|cp0j<fK7#W^#=u|}Xc?aaU@QL| z2^xmK$jVNW0-$S37Eis7tqN5PG|h5uap0fLu>V?Q>n~5Cv1iho?QscKBw4V}htTK& zUMQtXW8JQ(b`7TLYq{&+zSXORhXbWK?hwA8gkr8ywAVzwSA(_2Q^JiHJJYd;&wm<I zv^Lo$G>p;=o5`N*YiT9TFh$E2f;jCh2NHQKM19hdOs3^(V3b3;31yPk8qj8IMIyNF z8{45C9;7|sw=<_lg*SI#&p6jn5L5z(uj%lG$6oam#&SF?f*y|^P5Y;<mhmyJP)gdP z04zmyfU~>cg^x1^%9c?R1*@%LJ^V`Jj^$c5$!PmR`7?i)Yd_7U+%N!9&wby>@TbRt z;1(ok2+wl0E}Y##ddB6`VAUsPI7?lpKBe4FZHpsvV{{!P5_he;6Aj<vQMpOQPfC@6 zMs2@mEHmtzzx*)5o6hE~lFBfxGz@e;cPC$Bko5C`$@UX52sN?3h<a_U$juWJ;c1WC z(tD2~(e~?^H+l`9L?1n;4ID3bI9;_{%R){P@!SaSF$SLZ);i|YH$H>?Z|T!<NlE7+ z$ysy59JXU)bMlT15-&;0?)#>>5N19DkkQoUFN^cCY)7zr*T^O85a#i#fp_=Qbg<yy z%=1%V6||ivl||9yA0`Jm?Y;8X?m<zr_AGayQ+6_9+!=qu5ist_+>oOCM=V-ouGYlU zVKLJID&kDA*TkQ03FyNd^<91504k{mQg=n0o%83rN~s2sCcF#@_sm}aaf)+8R5oSH zW`OcLnTqVO?69T5<>gLk2LSguN~>sFBIzYD+_po#)L?{8d-1M7w;>dm$D4Li+zpU` zG$Gz^r!&TN()+jhopVTYB=H&218uH7GrV)@+}3@i@wAm8gm?&yUz>nYJ%HP%jDhC5 zj|18Ub?Rz4r}0FIIl**)>AnfUwyb7zeQDtVa!pPS#f?9AAb*ZN_ZfvI`5KdT7WZAI z0y$nD*wrpda>V^v)D7qgwAR~kmM>XdE;a`gmt2S9ceIQSU~1o30z$ZL&;q;ph&{Eu zly?5mt@AAHI9d2nyOv)Mv59N|vR9hu)KjDy4>`6-@39QNN=&2#p6f#UUiZif#n&Q{ zHh|}b>&zdx;0sIv4x4Ign74TEU$DT13`dKh;U0ieNfCAwV>BcD>R4@X;LV{-X7<UV zz>Znvq%!NK*~fXHgJTmH_Nvh%#aEI`yTJMiFz8(1u}?Pq;DI~K<HA>)-v!$U#T|TD zx+CfltZMWOftv|jnjzJH^=vDB@H`5lG}8Yl%Y)Pq4|WQMG9;HeyJcCAW0d<@G8T<N z3`@#mg?y^tt8H*$c*$*(MYX+(M6sKnqE8#TpPzMJXg*$58LeSWImdKg7JYLKelFkO zz`^N%$;H?OP5$XI^yPW3o1R?0P`iGt@~F=C7SIyFZ7Rb+wg5XSCI^%+Jc1}wH_@@n zz=sxo+`n5(z^9zRkyB#RN7Aa(@8rk@=B&}Jv`|{cV(05VreVGM`N-SxKudfiakE`h z*CduJwnS?+yJihhl@ctr#51CU|9Id9dgVc+u%}dNk#tJLhvzAsLShF{da>mlWKE68 z7u}}-KqjzI02wXREXGrjxG*~hbmO_(MjlrjlN9%1b&j$qApLsi-akk-`le@q2yoq- zlztR`U*Kr(AtJslbup1yYE!r|meFhd6F+hG#z$CL9O#=}rY`|}i?fS}bw>K6$fu+W z5x>~WoR7muUdnu2vCjnGSXTzj1QYq22>Hm<GT`N$<4?hWHF{&M#^MFXf`9%7KjHNj zD2M`~xWN#{^&D9Ppr0W=0~!m)r_|xIt^`?YrdjImD8h8sa#Ry{BO7vo|JMHv=R%nR zdUtGVYocu(0w%Q?>5%BbTfP+|G>Ki?2YL1As0V##1UUzN55`ao&PcAx5jy#ioi=dV zpO6-}-)_o#M!++@RSlpDRX^mO0#%bIHmc%fS-R8-QiRbBwvDLDv!Cz+>?`opO>DLe zyk*#7_!r&UM<VxXR*03VKJL}BY-!wy1e>@jX0k@{rI}OpW#-ZWg;hKdB82*5mGkTY z$U>mmh8FmLN@o$je|tf#RfzY*QSBCEr}Sf&vtKaB(reblQGM^v!f0-W4QY{+Qz?K* zjBXp)+HeZ-$Fboq*rZN_^D)O<hpik+fZu1Fy}Meh62eA_+xPvS*KB-q|B~P{w`CH6 znY-vuxQmzoTQ^t=2v33U-t+FtQ784^`~7=88=JJ}4V=+?S0YZhDRy_3xaSUhXMu&M zDXBY%DvpnLS5?Br0Jy3G9P4+l?fV8!n}JVs>PuG#QK|uwZC6ZDz)~suRD*+VuvyZV zcUQBilfMDe@jU<cx@OJ%>JI<DY9Z1KWWW1j4FPn>Nhn;K_I4$dp~hT7;&PKkmjj=x zN3r5@Wl3V05hu+glexQgv9ykvHHL1efObLP$zNbM#QN%_@@{yJ;Yd)Y#P8DUs_M7J zuw#yUC`b%<DU+ym7<4^B^TTtSftIqOPrHWzj;~9V5Z;>v)jkat#ML%E1%NEVyfk;6 z&(NpJ>~{D(Y#Qvz?_jzGdgDoRrvA&cqD+78R75+&NC#{=Dyncq6#e&=6m<%i9cL(i zVjsU9r@Z7At}^S3ee837s3&oF+aq~vd@5TD$Q38;4LUQ7kVCh>m<k;y5EZ0OtBkph zaW{q^=+Ks=x}*WP&B!l?zuu`8lT4B3FQMnmk^@Tm-h0(G7W)hDm*{{E8oHCE2A-K* zG(Q!k*Y6xAfv@aLKGMYY{9T?lV70uT$pgBT|J>mR*!lpx1sqx5IWl}q5M&?)qr&CH zHchGL;LW;st9Eo_GU59KF0pNma8(83n-OW~%xoBqumb^iV@{i48)BAx_&CMk6)&2I zUTk{Jf&ufst0fl(9N222hiOu~;I5l2dUk0B-i@>4EN7Aiy0SD*uP9I1mV*du9hV%I zGu&90fTPFh{BWhhzR+6ObyF1+RlDG&TW7ywA0WsYeVy{b4!4d<%*v_aPzueL6)EnW z3V~}!y8>y1xqoKV8s?#DnyKV&TSL{^yst{#afM=sJV%;Fi-A)5R|HubKA#YXQ<3Io zOU0kxNCc3bej&nV*diu&)JeKx`1djitkzfRmBfpd{waAGo9B}lHlP6T_XPco>=*C4 z8D`l8r^r&pByJJUsZTX*9u-+V`F-DapIQ!8RU;jnj=G&DwJkqqY#e>{$uEW#LJE$A zN!(X-SYk2Nuu<g<&lw|&S9;R!ihwjtQ(nixyCcbgA2|In$ABJ)Sdn3?gxz!*6Nm(d z9}M0FheAdmX|$x%kLu_o{hChVF_g)VbElL!&tMe~j&qe#F^tHTuU4Zabzs~L2$0pd z>2&|g;rl+JgftYOX8-}rD^o634DnL)Ytk0b#U|9!cY9N}7OVKf0r4e{1cvwaS`Zw` zW~88^R$*d5(sQtQQw+{_+eyby752AtC*CaR#($m(%>Xts^51pQ*22NqXy?VbV}L`W z3q9Q_ZFN|tYMAifg`Pv2zKNcmV}K$S6}=*{4lB$!@!*O^-yrb(Z236$;GL4xIPP+O zL9liQ!7hubCPv#4vk}0n1WU#ns>=!mL6=`6-VLXVugp2N3W5d(NIjM-wYR>w4B-OA z%%>S`MCSsxKk%`lR=E6!zs9}iaZt?gyUcH%Aog8bOMaP_#o&4Fsimb=2Xyyeb-&J* z)s{e;vAO;V#sp1zp-6jxwpz(<l1z55AU28!ZYuc>My=ZsEjkE<4$<Ony~UKfP`Y47 z1mD3%5#(USla%=bG*Szrz*h)za9-OtF9NU}<hQ8%E{>t^$(!j~#|&_J(;|x(#@0Jb z+TDf5+IcQcCm1ndt0qVdhJB4Q{nOj+_h(D$&1~$bwzPN-{I)}YZcvG!bNaL}l7~$k z56Zu<c-uxPYE(NcarMJ4U}*X&{sUF)Lu1TquoE0ZWyHu9@(d=_#(dJ~|JQF-eG58G zxY$cz2)h1&OZvkBM7NI(GH3G`F-;dVqZIv)O}~40;9{;KSPbZmDBFC}7e_XK2>h=W z0EiPozW&W|jpH>1-J!jeI&`f)dSwSF!8FegJD`N|YV3tknLPspUZp(|RHS7=09Nb- z^|Wi2w^0OHAfBR4G1r1>&gBh`+buVZyYKae(v@ZG7qbt?bE@x}WAf2H<Vve!NH0jW zSr7kx7o@4LK4FecQ~S+Z1MWR*E%+Nf`R@#1cY*0hGO~@_dqpzwNR?xAE!jvNT!`_$ z#P?!-5&|zGoK9;?YXS^wL*#YHlo=wi4u{l;{PwCOZ5mPJC;l>?E$Fz|)OI+xHJ+Cg zV3W=bIYCgJeA@PNEq-;_6*WymgLBw@sg)Qu4E6-!??=aZ^o1N%>qM7JI+s(mJ)dOh ze&QqW@<9VSObQb_IEw=+C<+(aD?H-Efag;l8LOm$AM{ZY4`Tj_Pkm|`<@@K=4f>aq zpYlS!#DlR%uuuCw8`qoJ(IG&)eAG+RoOJVz;zT5j{;E!5Sz1m1P4;U61`%z0c?mZC zayouvQ6V#F4*k;ZBzn&leT(c!7^VKh;U~_WUYgl)Ne6ew<Sq-~i~r9d_y(Z?=9e;` zed1{c$$+%Y*P0I`w!Qa^mb|SyVSbmkthqjJ6NZL##ZNVV32!;K9EE4=I;LaT_G3Qu z|9iDW^T52~i}q8?;D8`6n6n^#*sT0EZtrNoOJp?tSd!Ql=Z!1h)GyPaague{j8hP% zkgKunOOk1X9Cu+<G_6z={pW<?^hoDkW~#zI4Kkzx(OwK+4VOe;VnQ;p0x8oICQ1S1 zn_D?wu+xzujArUwNxR%c#slzpyJL_Tx{XEvKF>iFL*rLb7*)A8*cjp~)2gHUOC<GN zp=4SM8Hd)!g*8}>GN%%REvofPlZp!R-<{{wS8@OAHt_ThVZD7%pI_WCh#apuDWJdq zu|n@&1Ej|9?Q4}WU{ZD^aS@ZX%{8wr<G%MyP5HljPOK^jslQx%a7d0|V#hC<xu<~j z7H{t=t1Y)(M3o<m8j}Fy9ab3z8KejgL5}=G_>KM3O5+G~bM{v$WYMw#xYCAv(KlxE z2?ml^ukP_<%&iEjr`*YME%T6vO6lSlrt_sM10b^8fO1Rq*l53L;<-=m1O^XvdBR#w z=R@hTaCv~tx5dg&?{C6w+jB82*^wZnv!gaT<SQTbmx;`XiQS|Tjy{HU(Y1EDrst)J zn^agDM->5CjniM8<CCs;kK8<*_kco{@Rb-FtU#o=JILqy;|Ic{_nRMEcG(%qXm+jv zK;~VvnUTtigSThQHKyP80r4MeM7j_Lk1G;7k^kNC(?2_k2LG=e|L>3AEDcNtBLGha zSBPBI)E?t)ppC&Aow!az61`fWn-}~u=P5vruV;i%gFxq<nJ?Nv2EPX1JteImRt;xh zTnohK#ra{<=+XBJ;GJ<}ve&mg0%yNEWFBcxhj_%ajA1sLg4!Nyjq&x-sDoJ+Qfs2y zBhQWGTr+)2imYF%qk+SyDOURytU_1G@X_#)4{XS47Uz@rdR^r{>`_`KHs9$v3xBW0 zFWuls^Y`!Hhl=jkb->6G8X{r$gr#&5@#2X1b;o4il!L<XCf6`2>SL1`r0!+sg|@R+ z<2?WdjI*)FrJtAkWFJZ^vZ0gC4X8s1!TL#5s_rL*S--X5`}^$9%NmjYWu3d=#E7Lx z-1z8YRL~>|jHzr7OpAfCohl(bXg)JI2bgyQ?e1QL309<?ByfD3@1dr?<K0h;GG}m~ zFXQ?Hcz6vZ_gf>|LJar?y(-xEjb{{Ctz>-MZoq^!1j4FHAu+;%d;LK5+os@pOA{+1 z>vE(5P;z;}5{*5Tl^4GbZTf=9196(0@%6EaSYI(CG}f0{uJVT<w<ex${_8DQ4;XXu zqNz+dJMJl|<;){gykxaX4d~MSZ#@BC_n*|HM>`<;*fcLLW?On_$w2L=Dz-wFZO)l8 zI%oI+GkQe2-^miRwbmD>)D#O%^lA9mB(wkSE-gPL1(FlN>$>qfj>EXkkM-hzdA<^m zYWu-bEM8+M2O0<kYM$b~z_kNfEz`g%2|8VMfk<U@dUI38EKofaf=nWofo@rbaj5&b zcK}TrN5_3I3bKTON<eFgh8hsS&7bb~IEcvo?e9FPy6(S<ki{^IrrpU&bl9Dt{=7^M zJQ#m8416-^IAmg;sBnNdn|EK)c0yjTZZR3g(E=?%5jRcGQuOYNeul{fGkaCSnaHi~ zDvfyheIUybDblX&2E3Q90S?V~O}y?6&xnDlpl6;XN*uoQ+b^B~wB`1)6o(~nQ_A_I zQ(cai-_r1TFBc0v^c>sdip~kKA|)`lRAY&CC8k@LOKtv_s{zjPAGum27Rp*P%KPR# zB%VzaXIh&&2$sZHtxp233pB@C=vASok*aSa3=l;;yN4>`d4!zTO<V4geZd=h?h@hC zztN;aLKr|X`7CEj$J|(|)Y>tw&z<1hnfo$U{n~o~8`h7K;=V!y=^7Qo&qyD6_ZRn$ z*rFrJri>HCgcn@n21x)4``PSl{XEV1N9%ARgzL|OH!Hw8VZ5S~nN8MAJbfP|+1xCD z!L^jZenK-uww%UqKrjj@`0YW>D@vd2wSyCiy$f-(Xpx$gYNqIXN;{tcp4zw3$4zT< zmfP@K?Z|LhnnUM}J7RuA569YS!ulaJ5wtBK<h%^<oE0aJ#RZd8*wQT0MH%gL-O}7E z?|SDm6z-S44tLS^4RCdVARCc4dN~4N%z2Lw>la2rTJZ|TZNF95L-cw%>se_o>>xI~ z^+U2o!$|$a8Y3%aaTMefZ{C|lyzQtrCOs^oEDHhZ@odla$j0O^6az>>qtelf>{e`Q zGw-uTNF;wsihb(;!ZrZlhJJcb&P!aQESiQ#TW`Gz44&oDo>>9|aHz51=BQDyzH538 z{#03OzdA*xeBiyBm4@qVw84I!-Ka=JE7MP;exFW!2yW7!9&dPasDS(Z|9lea5%Hk- z%p_PM;{BiBgOiN_!=Q5aH#qQE$JT&Xnkt609;YpV49<nnk~phGVc8=2i(G#H_^jFT z8U$^D9N;apQEte1s>&jQO-ElX%YU`R9kIg6J1(%~YuJ_V#gPPYUemN=HUI-9=D?c! z(BjZ|13IriCa^~m6Ab)}P-my;l6T7b%(|KYa{Xv#RNgBq`?%BbdE(9Z@mKmX%(Jhe zX9G)F@+QN+BQZ-Kp`P=6skuk0>50B8GKASUnT1{>;*rz;Cq0Y#uLwA+2U8dskR|@n zEqvEuQDX_&#lXW+n`65#z`_9*uDI_LM|P~JToPAB#JNO;E~Z6jNHy&jzlTC=_*I_? z(Q0Oz9xgNCmR@JoV9@mj6lZay{2G1ud4*}NEojxyUmoGh%<gXg5(CM<o66KU%t4CX zB^1~alI|SQf}!5aqAIr#n~^k&i$pgAQoA(b@B)?Ngqu}ww;#R})gaC@HNN;bM<)YZ zHLUrrQ0MuKgiR*%KH88ygJ<h6bTg9pBhi>gcgTW9OWPvY+Ky0iU*HafsG@f9wEc%D z#64%U=Vk2L#&dms4>=}!Ih`FHEWG434g>FqY+%*K+slZo$E!yW2Kdo_;6f%5U<8BI zLRjv=yTm#Wl1SY8Td`8H_s#+)?Q*#Nau0o`sv`{g@f(EfOSoLKa{;Z8>2JNs^%6)O zhWxKm{*&DcUKfD3CgeE+5D0C=Q7JPIBn~Z9Zu-v3Xgo2pXe-xq+%ZwT+-VT*BkY;0 z<@O+RWJ)d#;tL`5F?TqHYx(^XOrF!}Pt9nEM*YxBCGMH{gx^DHwu-+GD?*I-bZ+I3 zm;2s1#{COe(Elth2eD9iUgT^0)8!o&vc5OfQytz1t(NVTB{@^7wl1v~zf;RBhtr*w z+rX*dw^EfD?q+PNmMmo)A0+|qS%-O&K1E5(rA_MF4~)9vTFo)^>8z)R*&B`k*|g@m z*E%oFVhYsRtHJX+>azhrVcIG4K68k}zsTf#{KE67KsFD4yE&TO@!2xnnm_8nlkaW! z9(|*v)GpI<9M>}RP55DSrFTBnY5)a51OaDs)>{r<C*`ja03Vg|n;|T<t)OI1iPInO ziESB(TQFU|_paC-fzIdL=?`W=KiM1Z@Y6crggyk2j^LZCvs5~bzvsc**z~i9qMIF| zxb|yj+J4xTcYJ6)0DoSYwJjwqT6xsEs`Df6&m!x;dhqXm)`O||a4t;0HhNMT`=yqJ z7A)3HHdXs1p!2{G3`~;<`<%{LQdB8Q1aM+l2T*yb*Go9B^*(l(e}<Wh;7`=gNh+(A zZ<>h%VFD$?yX2>q%5{g|@dq7(?y>vu|G)+rTM3AVLH3UtN+$@bM)U8xJvRRS;W0p4 zPn`}E6a@<(5+nI(e)sBjT6mxB69U75#>?yXP9Qf5x>9nNSv1Xux<Zb)G{W{(&P9ZH z@C5t9BYO^*g1E7|nXKh?z~?tx2|cHvp8iwKd`ctQzulBI4huHoX$2gcc*qxWAQH)q z9DGvuBc6whb?_JLve3KM7ERc|@|f4_`x{d(|3JQ7;s2~rT)_DletT5g?+@FgbRA>q zsRK9N6?P_z@uS60lflot#>tW~UtrBc7B@LD%)ms?ET$j!ti5w&AwAyAGO_Q;QB2Yq zCasC%{^{|gDE7cjdvXOx?`zWy``FuLXT(H)ZuVRt%qREE&iQ)~G&9(jKd8m5R1fw7 zp`$^B_7@|gEPbY8m+2J#q|buR-g~zKMCkJu9&0gj-|u#{G@}qFO%uupGVP<MuBQF~ zQ#x7lFzxqxlA*(ZBYeZgYZO?k1x)(IoqokIijq`~Qu1p{_wgt%>H)ftc5smnr>z{y z$0gmNJ_v5}pS-c{t?N|DD{P0U|1UrUz-h`wr0mg>xbBKQc(T<hrJq~+%)ipY1}cXo zXx#VbweJa12P$Tkz;qCbA|!1t%{U{R1^PemVY5L0X1{)eK9xJf7K8Zb<|s>p&jq^7 z>%@lU5g{Tw0z{Kp@;c0Tpq95zaK8Gy1U2QLS>Lk4@x1zga5#4N_;*5xiYYewk#*8_ z)Z#kW_+U}o0+U@@r`4|+toGA7k$dkR{3lJs5HQsVEfVfC(*Z;}E1L=OtE6%qn#|f6 z-n!$8g5dI1GD2)V+6XeEJ||a;m=<7O%U%F9^(l90LP?EHF6#8hwO+h(_0=7a80p*b zpMh2a=x_UY{~n9$MJWQ4juC`=tZ+wGt3oYX5J=qQ7&gYz9eCV|d#wHu6JEW~)iQ)s zIu2`>Qz&n!0EqulKpED2tQH4-5&IO%{j*D;P!+=`R*T6Ud+C)4wpVzDipB4o&}z7i zFznH1Fv=$>%m>j4R1Dd6mJ4w;*vNjOyY{4~Nw&=`EbXXx8*nZL3SPYj`#>iDrz3I7 zJcYjp{qHL*{O4Byss-<myR)*IPLz>nW@jreqb7-3Mf^m=NOsu*2p-~^|DgOHn%Kp& zwKe}+^wi;0>$T$;>F~!yroOXZeG#Jp2EGz?DmCB;0?y_l1tPI}tl4e=cbdz6q=&S) z1791=>Fx|Ee)lONXQSwliM#8FDxub`y#*pT9kN?u4Ixky!tg!?z-QfcBI}z3{{h{7 z|33Tw|5yKGjdb7BnL_}L4tCp_3<l=3*~dHn#=atz?47i^24=d)@dckyE*2g2+`ezU z(ys%^zu$ogO-tRSm_N+;W2JA)nTrgXMKb4rX;b^bzM^UYY$!b~h_rUmtFV~q`Q9(< z8b8xTouKJY-qUY;h(&hUSawumr`c+!1<`d;V$vZ5oK@~7q=Pp!W57ffE>!Z`$>XSt zvI8Ih3|wY%>2k&GVyf5)0dTX^pF!bJV4R|7GVMnpLw`BZ7J7X^Deq)wDrss7MUR5E z-1FUh9U2N{s1bK_9h2wyOz3xgB-d-63v5dj<9=J#HYuMbXq$NP`1Y~YGUFc(D_Asy z?}D|b7t`_7(@QF@Vm_K^I)CioC8n2L6fNP^sW0X2QMCUD|Jy$qV9_%A!sB7J?L=LN za`$$f44~(2pe?kErQ*jDLPTeS&fFMoy{0wr+gdO4>2kL9zk@tOiRk)GUQY>b7p1$w z-|x+m18NZ#JLSOm$_~(D@hkI+mFz8<9^U3%!7Sb1cet`|Bf3ML_4)J21Nmr9I}>;1 z*T_#oH8IA3vG5T;U17Uv;?sjA!&B^C&CZN5yOC6}85{;NV2TX$wgDhMuJm)25=bjk zt0k6FNAtCue^2*s`sfV|ju#D$VqN92ZHI2CzW)U+@*VK%%}e*P;mr`x8SHm~&2kR_ zYYyK6PZU?tuGr<oU8idBFF=CQS?=xd0NMkmjO-wm2Y}v}x>KrhmS;VSYy=ME6cTVJ zA_-7i6_~W|8upEitqXK5ih;g?Pj_>d)xd;8Vkw}&fFOl{-+dezcHlkhY-RksjCWp4 zzA2U~OKN_=K50yGz1_dSn%txtDJdPU8>vjW8rH*95jPuPuwC}<%vWspCJ|<5x^X0b zo`{Kaw?v%4h_nu~GZSCQ_3IFPg7g9*im?OCLWKe>o8TB0IqJvD^a}&;bVPs*OsOP1 zj*@!gi%ZRD<)!dZ6gwg)NgVgkT&B$|nxG?;5NfK-Kng6;6u_L9nWbh-O~Ts5Xd|(T z8YpNP3G;!S0+YSuchmTX0Js#)45Fdqt6Rnx--=b_eL~eI?O<QQ<PA3SI1CJ5qL{_W zEFBGN_=b)20|4-V*G&H=)Lq6?R}P~?2Tnc#ZP<tg7UNb<_1q5t2pbBdRlVC0Ike?c zj_Q4q3d?b(Z9~bUrr$T8WDlPG0x+z?HwdzfcK2%uyZO5E>(o%aF-*_!UOlBG9dx;* z8<yim2S8f4%#2?OYdXc_!$wuVoj-8H7gz#rUaF(%#z@b<o;~=kC<3OQq2B@D`wno< zZH12*IUa5V7_McdE7zaSKWk&@1vR<3xdkioH4EI$#$y<OFs0y{Hsp*qz_?q7=s}aI zltl9Yo*8a0Qj%!Mm2g=~RS}_rOwChFOdqT}1@7$!fDgy$bGgM4u&ghFvs^XCFai~Q zwEU7H(4;K^gj_4I!1qc!w7;fB5Izeek_Yo_V6berL-a7Zzp=pb_iKY5`6EeZ{D6@` zexudNI-aoFYhxfsUilTyM|7tz5y!6dXbrmL^G9jA%3A&Wd^Ngw?-NDU`g<EiG#~o; zy@~M>S6<J8Z)Rs;#DKf<<LSH6q-Nvupk3@6mR5S)zl$dao&FMpz|okJk9jW0-(E`( zQ*h)#P!VH4kP@;o=9?k%{lB<-%eN@IFx-0>I!6KNP7#oljv<7hOGFx^1q2k3W(Yw< zx&#DC5m7p%yE`SML55IjXvDqddG|iv_ua>_|AGDK`QkCdv+jG=x~}Uyf9H}=b?}5b z4(@-}IPwg3^Lo2W*m9nA9l|8<vsw5UOW%ca0mGX1p4=}9itfuS(iz`9vfd$F5DE=F zRX3#r&Zo^{S)=@Ip!?flbboQo1Yg|yRVjZpMv=9l5d5=HHyR;Kj!2@kBImpPj%OB8 zG<I%=8`ftni)Yi59Qlw{$6{>q9$a0Z-9SgyPS!nB+)Yf0h5m(&2yO#PiD?T*-7k97 z-4?xS(#YZGcZiQgXsZ--0g*y|za!iUx+-MIYFj(@Dk#;+NNT!(+J9iAMP-Yxi={mG z-SX64z%ns*tUw!ryVzeYBL)v0c(kr0*M`h}x8HL7eD-9xH1Q|4hLTY3Xt`pD0XjD= z*}DAY)<{imAJFJXl<;6`bXHVpR!Y0HPZ6U6wJhC1+*!$^l2W%n18HYEB)3~hhmH=9 zWN3d_ky#Ac7lMudjyiY@I}=U~zjcKpmO3o?m@$=Dd<E(E1wWomT)^buWx$7UrbMCI ze7J-_`+@WvmixeiS{2UoO08@eNl$LMSCd-ebJ4tenQ35qsnBzg9;wKhC+n3OO{&-X zvC91qJ0O<s!GPF2-H*?WU%^>FC>1o!KjsG-SJ&p@ESu>6w5b&wiUNuFF^_G!agY7T zPqaxN<PQwlW<%tC2jb$qEazJc!E_>JpC79bXRl8)=iP@sZ9z52*S45raOX4cPoMP| zYk)ye`6P1xo$z$>%61`J*8j_E)r&uCvIXlyy5g*%RyVHX+h$vDP6Y1Lw{7^<D97vM zyuJTZ^*}va-^Cxy9$;+Clp>D;#`7L-E?t~kq{N+(7;O5xL_By7dZQgi3p8Ila|4q0 zIwW9+2`&|U6S~nj+xXkx=|V@d?&v*h-T66%j*Rtkb1rp=_)$AP9Y<{cI>QoV8K9&K zo=+u&e;ku9XUQG)v7at(1CI3_lidmr;}rHi`K<<*hZgK1^wnypM=+McuX}8N?dr}y zT*Wgkjva^KGZ6$>4i}L^jM4ZmXI#b4b68C$cw609JIZbQ$>}rXd~~4*{~#)ZIbav+ zkQwzZhKlhR$VF&Q-HDRfw3%!IYd)$Nw1_defHnWtoMp<4IYk=A?<gPL+G;OFDsACd ze1mEU1sBBFt$bjqM#PWbgA?6ldlI}?(Tiy}jPU4);zdOhUy@%!5b5u?Fr?M@)d>25 z_N2uzyx=dFO5}HrzkO=c;Z;uI+pAdpVHs?WSD-l*#%DIDK5N!4*LD}L;7i(jytBzh zMFF-It)vThn6oixK`e=QAD5O>Q<B`K5`dEuHb5N?!nu^j-5P(3Wiq^GI+kG?3lS4g zoGCSTZZ4P&sSS~Hq5DK2Fp}FZUID(PS&N{?=kV#39F>VL;lEF^&EPEBWc{0bTPKLV zi#iB}D}OW|_wuN|HKEu7*dhCreaU-S<P7<@eunLFY^X3}>2qD>rIp{l?9<-kq(CO8 zu{4!uNZN4aZGHlV*PSDug_NKlxAbcZ|ClDIdl{|8k#>I!7)eM9eEb5QVaM3|i^>t> z>8M@$H3DKIFj}{}Y|}cv)T<o@Z9y$$$uY+2%8yHlGgioi{W($f7EZAJAs=}Tcv8Y< ziO9cEy&nnogAZEz)oyX5SI}2hC8*|5VNduT|4Lt_ycX+u+nk@c2}8kI$jYBR)NdoS zjKwNI&mKZoFnJ<NDy4Ru$C(A%pQ(2gAYm`eY?4McD#jNGSa84dn|L}v=|-y>3|K5; zK7!ftBJCJ~z(9HAeeZnP?whgcX*-eQn^jnF`D*pp$Z_NV3ta{@0>uW0SdQC-3i=_o zeH%gI3UmvVomMWslD68esap_E))y6ozO0OMjUq8qb^G(%)h+M*8LZXM4`J9_DRj!F zQwx8L2PL61gMO`Kts0zA8W=N&@Q4}F_CMNZqD7o9?gs-KNAonqNjN-{!}vGHrj9cf zk5voKjGeTy{-VublXWG}y{Qz=n_2vuFQ(HD*^5>tbE!GSr|DdjqJgQ4qJuu!ra3~G zO`AqqDn$%4^g<8l33g$d!@QXK7>*A%zxS0_c<$6}vJofcL8R`ikekKF7de7+(vE9B zlG#r}=5T`o;8M-Aly_MLwuq7?<c^0#u;FN6aH)~?8&8_QuXcm{%2AS3U=e#9Np*s} z&N%NFw}mot+NYY=zbM2C1Bh>D3*n|ow%dxv7wT(ctRi@lBZ{sqA*vek9Q{~pFM|e; z+sfMNXxQ%Y(_fF<=#h^!?zU44_Q(Y(U@;z{SPOd@ART8}8=F``T*>Xdv<;eZjF<Tu zd#^US>17K78cF(qpl_7@8}bxb&F*3A*Qg@tWGcQvc+eZW6<Hff9u{tK{@92F?iuqN zT`*9zl9h{;`x&<^#E_YN0m$79*ydd6=h!jsT#DuR2^;NwnPtkPBBuRkXcJ<Dh5%cE zzl-!nr$yh-w>WOooL<!2{nT59paayZdb?GRdpQD%ldF-_k@|;JC^uv>{{2j-a%iV> zS@TRN?Tpjj&W`XPm9L-@d#*iP7wbJ#tTFY#$uLnaQTmq-gsr}E!+KH8Ph`yt@i479 z_96DdbQKv7n0^;y#9b{%C6*q%K-+I$*=^&nc;E$w?U|nZm8wB=A0O}$j@g}^o7^^O zZdUbrEhF8k4%t@XC1nuIO}1YcURN*<kwIa7`pgUsoTk1Ya`#n$!+5NcYw*(lQZe^y zpxM@7e9;Oy#Ioc-t3fkF;R`1iSx5_E75p$4=kAx5E7x8pbcK*RzwJnBP>}Py^?h9E z2LhrW#C-0WlUD5r<6(zD=72|~=_LMbDOl=p*bS<yN7lvT-h|SZqvU8OM5F|4VR};O zUV09$Jh@kg5QP?J;x1JZ))MM1DP#+x?}vy+VYBv+RBXhZbUmM<^+nkt(K8DjvKspp z%LU(ML?`rt4k*>vCgfav^z<F;b`t}8Ka-QpTGOoek@z;HW%Quv?vq-Pxuh@oHxepj zrPh;QlkpIR6r!_h;lG<AMQh(M12V}OD{p)wEs42cqdxG31ZO&JcHwc*-;*?V!Sp9? z|I@lBDOGRbm;Yss$mzSP6T1H(mAyaivJFetjf$Q(&)_97dIUqHk@uC~<{Kw7&Zp2d zB+8@aRPdZANivhaJ-Phv<`s4nNv<sqJ(Lnk5lS4AFnfO%Y@zBo0~^A8S=fOgw_^Db zZ)t81-F@>ZZ3kd#b;2oU4<E)#zjI0rLxpo)s5A7o7dfu8Gwhn375%o6n+8i7yZ-Vg zF{z*0QOKPp8w(VUmhB@se{x>{G=qZvmcTXELC=P8P18@TYOIy)fFm{2T?#)GM?<CT z7DN6nXmZ_lxh7r`!p9yMGz<U_Bt#!VepD3&>t3@tFZa{}h#nRoRtH-V+4o%dq+P2+ ze2SZFKgF~YXVr6;Y5*)ifZ(puS`caUCN7qYW1|a)Pcc8%7atE6$-RgV@`ud_m6wiC zmd%F*)vNf-8@;VQk_t@CgNe9VPspFOhvJ@2tbopq&vH<|h=AoGSwG~TQ2)?o#>QKw zxjbhXhyL-X9{`@Cey^$78*X^c5QNBD?VO_a=e(Z8D*n3aUk6{u=tzfRUT<CPLxA(0 z(2C&2tj`<h7tx{el9IttCR`ua$BbHcw%mfRGDDOhJkDZIxp8TTlJCs2A=t5;H0$*H zCEk?c#*-t|pQBmywl)k}_i8*y<p#FQ>?B4sh*~zpKU67%Q75X#CL>?_?8=Sv4`>{v zqEbCCH@9q|>9$Y!L|6M|J=EzdO~XI#VQJM+I~we--T6U(5d$e$qu#y6%ubE;yx~9Y zG>_ijxx<no--Y&i7aN09aG<U+OPW>i%B;@mtk<`%Peq?m0iO=)wvnV7ssm(ezev2M z4e3fo-y;p1#Ou`$yXb%)Qnu876|!BCGGdPFuRxDn@l#g>!ZV6bF3dvh>^+h$(i`#i zcn!C0{)>)?X1v%%r(b;l_wZ-D7FdtmED>`;8Gvvr0KY0$EJK}dX#y&i)~}C^?$u(D zIvE<m&y?`n)j~t@t3K$&$`9etu30kfjzf$goMKtf_7w=|ph8*mhRWlHp*8PX7pa`Y z_q3^?Ya;7HQ6^YCCz@GF1j!O{*w2n~btVFTDj~ZAkEk12*J0K5A7hS)20UYfpaglw zz8}vW%6YE7EoOGDw{pR$rS1_k$IkUR^o@*^y%MtngdA@FF7i<-!Rfc1o#~P|`kUD1 z<j>64+Fp?#S41j{canCE)qW@XfA+s%_52JQ8HUA<M=j{{%NFFZ)+<xjt9>$MdnQw? zH$m5d4NFZ8#Hv0Z<q`h!?vCaKd)7+--@WPB6_}eC=N~sJmXwx02s4DI>i(puHjGE? zllj&*hw;^*g>1pQXDj|LJJ|5I%<f;8rTnzjX2${5UmW-&pAqxUF*<kKJ^TD0)gPmD ztDXMOT$Mvw+Lx6DQKoEe6J&@vjeVbZfu=Avi=m*3E@I^&e8veREfCbJF_c&krrHP^ zjmYEO#U;7RD@~JdFIbsgifBo4MpBHgU%{gIEamEMQKeZLgW+tlQ>G>!V!LK%)uxSw zhlC&1kzY61!XjO5i{C#er%i_N|C%6XYvk2wJ{1Sa-y86{$O<T$=#gbmS4~b?*45!S zk^t=w-=g_iNt$#GRNpp)T1~Fa!_Jfq?8R-B0+5$2bJGPXW~1r{R)9Kd|GQ@FM1g^! zV>WSYg>37jX*-7ZM$qw3ZE7h1-5C(4H7YLhs;c^SP;}sD`q=5JuWk_)KpUhO)-YRs zjCrGYzx{5y?D~J`Tn^o}-2d1xxlj>MFf}JZwv<VPZz}efSI2vqYAhHd_U_&7dCXu# z(R|oLOZa)AK9Z7_@L58ZtXl73y*c9MmS#o2s;9i&QR2D#N5*4U$HZ8MOy5VM1WWw} zx{O!G0WPl%Zn|C=F{O=YAk*@2jyIg<sO{72NS~00u>C0Ev}OHVAahpSj0)OTY5|5y zW46{vO4Ew|pvs~)nk_SF;1z|9C$sOoY3TU)*<hf;gN&cN_vp^i4pzZf2wwF=4e)22 zA4-RqK??$^{0~+XCV7I2yZ@#{E!#Tgx1!u(0aGfr;z#4f#>hw4<*c=zB9q+^7b+P{ z6G;&qr#dZHDoYeRLN*VO$-WTO-(TX;;7_p|{tUa~c+yfVvI#O>UamEmVt0ORq-^uQ zFpkK4rVJV7^jl%pPZs+#_Yc>5nW;T%ey#-e9e`1?8kfH>XE`5nGp#z2BVmKY;|}lN zBnZL?kfBe3iDPLmhnjd=DKU#3so~T!P)G=6a*2E;-^(k48f;tCN8(q#VM5qfQ3&4B zIvu;MbM8JAei!F^KoR2Bh)ZEuq^-{9?k=C@-+%A#Ewq-AJdW3@)X+}F%EN#E64@3( zN)Od&aha>^J|aLDzAC)`fqnUGIoM4G@~}dCRx{w9rS7?S0jD$7HfxHGF6^8}PS9mm zZ~-mMQWCq;^{#&k7Nij9(R!^A6zx`?uwo2j;h#@EpcmW7=_O$qn6CrriFy~D1V5@0 zugS8;1hi2-R96BRnq1M8(0}5w@jMCy42oKP$u0Ih;h_6#H~MOO=t0{)k;p59qN(Ve zkIMv!I~mTP%+mPX$n@J0*b06>;k|F5#6QN2Rm_x1bU7k-<zgy^?4I^@%>Epea~N%V zmx|)?tqpQpp7=ZN2FQ>Yg0Xqp_&jV8r^>@&3I#slUWFv|)3{QzeNdk@KdB8*SMQI; zo)rBDLA5&^|KcZv+>AVDB?$Wjhx&6#Jf-t4jbW6YfjWgcML-i(k(nu|`iN05?xX>! zTh?eEY-V&QUX;xtCv0)<{ohya!i|j^z%2`@1g!~Nhd}l#5*r0K@T{PP8xl%OvhW+T z!{VPx@AXG~I~1|d*8CtL<jHx1f6%`5U4U0ly!wahLhalj^-ju*Bd^&0F#M=vKY(RL z(N-*j?($u2crdzYubnx5z38LQh2D`?0QU{4+9c`6{N}agrWMxWKsI@?&i$N+Y-K>T zvEcZNr>iq0;@*x+9S#O{vo#clFoBix;r!AA`Mt1@6?#T49_BWx_yyc~Mc+rhRe~M? zJdq1@Ixe6~HnG%LbaGU5Xa*$@+Bm+iT7Q8TjFK$lzatceFyVwiMR#bEWC;XQ2o%Bc zP9&Z0H8}jvoYl${Gj<~u=GA>#wh|>PHR&uFc<D*s5(onSXawW`Oh~)x=-d*~o@gXN zu;`Ixxb#Gp{Z8DMmFzuhAYT#MkMLdX$$YMEACqO<lBOa(!VcM>w`^H}Ca<*$0f~uP zj>B(}VAf&egOmS;z992tY}|JG(@OGlh$70)P%>0IcGYkjMuyOMJcM2F^EK(A>dvj! z^_N)o?%fecrl9CYksga(Ao=Fn!$;0oEV3pLSj{c)@<^iZ_=Mqksj!uSG1|U-Qr4>f z^n79fH0T`9X=kd~8brDLdUZWQrH1~z_6j7ved3od^nRPQ(jKwgABou|DCaqL)S8@h zWCT=V=<K|DWhd(11pQrQ$|jcK_OTGmz{}BQ^5XE<mH&`b4i4%Y-Q!ZFM$ER_IP-3B zT96nm4j<@DjAX~c>BV`DLyzNveowBs8Mr<rxL!-kx)(x9z=rb^2T`xGW)|fSmRne8 zveIs_13*&zRz+#}>34E^6{K$3RC4+`jKH||qm~H>*zrtTa`NX2d+KTkb%OB79Ei9S z=e&CXjf2GZCvh*lavVC40Sa>xzd$)AD%bUhr)4p(h|<z9D;E~9nrp@Ahi+L4I37M- zq~F#4bqLpv(5f6^*$t~4$?^NL#*%ck7VZipDn5N)7S5clNvswd2d-_Py^ie&)w<0K z!6_|<yw&6Gz)6E+7M#ptolhY8^W=j8W2umLklT*ku2Gl0b$#n}rmv1@yMScxx{UfL z_si2BKA`oLV(=^qZ~`A{IIrm%4hQ4j69i=7A_|kTX)6VU^&FbMkMAS+41(o*0JOcZ z?tGnnXxin*=xerBr|8vF57zh3ol;9s2!ZYy8ZGLH>R(OfNX;c>QVS~a$(8wkQwiRu zLal<joSLq!m^W3WX{EY{vGHw#4aU>drS>TnFo#|CY|Y%0--HOT=0R1vndMJ6-@=i^ zx>Ifft*uT`IcaTg)ij>B{`EF>K6ocGau;Xiy&y;uHk=9T(pAFUaSG^Tcgz%XHF+-| z+`=#E38ahpPIed{RFQB7^AheBhw6~{@Lt>|$irT4!t#d9%M=`)Ll8!#W=>W2u}MT( zwH_=0VAdUO@+E`~DOy_Mw?Lls=#WiW;BKV_O&hGW1V3K*5koK}p2}4NBGxkOAZC)P z#xtM#zCNY4>rGgmD|k6YOWEa1F?00Yx~w!$V#<m(z2-fQQ#?e{6D|(R2MlVpN|7zE z;3i#ff^_^bilYAy9ZPj1H;^w98|v7iQNsDA)Q%BQ3x&Baz)$O2_<lataZ`@fn;Hwc zm0+hRmJBz^#v}_lzf>$kbk0_YucIUjqm}F%pt{KHb`8FS`>jpaJOBLu&(xS{nw6eN zvHUK+yU%*UG{NNN4kvOvW15&{*WR-M8<O|m#?xU8X#Z<rRuWwSPSaBl+-f0zptPo} zV?5Jw;{SO#{ll1nlZn~=f1~^6@lwV<u>r?VF%8Dp;osDbL6~OguL0zAg*45n#|%cy zuB1-H%E5PteGV79(+&uvZp>%Suao{Kw=S*pk|7rHe?o_AFn`DVkK(!z%&D%xSzSy3 zKJ#7=<})#WImS4NClCBaaw}AhrQqL){b<o{CdGItN$=%qJp|unAcXnMQ=hQ^96I9X z71;V`SatB1n5wh>)N9ApDnuK*fN!bA?_}rTXiy*$q!7=Nlk)B6a5Bxe6)^HcL%5u2 zpIM)S(BZC`J+n$5weRjbuWMPP&TI?w23sIL#nPt^SzeFdi@RBT-^%vy&=Oy?_4N$^ zan*K%Zon7G)pRt#Tk9_ULP5l0h$&Dx+6z(EuyYSwfI1?*PqN+<Ba&5#UY*~Wc20CP z^a0WUMzb7V&gq{o8slaOE2D}nA_2gX%6cNFMn_?qg-L3N^Yp~kezTi%NhR4f;5A&) zIi%(&Bd*fv#yw(J!iDivpzi(4tmSANua$`ShtYR-v+^c=x3Y{7+%uAPlBo{aL0kcc zo79^P#kDQ>nm}IFwcx+hi`CNZSLv2*re05+u(N`}pYjXVBxChgdk1fM!YvGqBtw@k z9;|kDl8XPd^6E-ddYBgI3)uW&Zy*vroo)87QzihPR5kuutQVy}mr5mI!SG2t>)F}n zHX68o(tm@v!r}vfuB81X&Tu&*oE`;0R;;rI#skqG-&-VKs&om4TyyhZstbX+=j{7s z8}+Qr$q4jZvZWg%8)tnpX!6|FH&t;0*<`89(qu8bTCV>_EpO;<F4O*L%{<?b6z6c# zX^l|6+#njQwxvICuKf3V-z9OopMR`~O5&M^5zi@I##byYJ|#rk{_Gh(>{6;A&_sHq ziIob)0rx|Vv6|Y%zn;dD#divyL1@J2<LPCO1X>P3iJlYQKTnX}E=cMC&;`k(;g9n2 z7`qPgqw2T2ESx?O-2U)8@Ix?X5I?{Z>?5YZg5qR?h{x)Xy3R<LDMVRP42^7oa>eEn z>*BnFmaa%UT0v`Hgx-P(w2{W2gRx_yCbKRi&{Zn(2MF+f*NY+ft?nES@|)Ja*M?Ze z1_KSc3bqna(2(FNQHCFX1Hh5q8qVgQA(4(6+#`}IMd>0Acr)2er}NG+Znv{6{7-5Q z&MD#+=5v6CEXeZuCra5jmbcwd7KtIXK2h8p%$T~RVDY>#nsfq*)T?iKO9_sjzo#y3 zxV&dNfJ47g=<qRc#v&AOGt$<84BA|<<3+DMIk{6;2;vDiK?PNzYpMu?h~?ZQ>BtF5 zV^vn9`LvszKw1GjJ$X&GA`PP1j+xB`h)p~|(YOtg4u_dP^Uf&sET4ai3goXff30>c z+6%4by}08KL19d8e;W7Yt^&c3+6LabNA<ZKs^+ZmN82Ks!_^fvh7-?KF*MHJ6!4Fe zq2Q(c|BARV6KLjKV;wa$W};M0avfVySVbJI&`7i`cTHQpYOQ&Vd9LaU&|729a3mJI z&;h9&ufWDKsWc&ctz%7m%c|U3$*+tcfLrsu71kB_xpn}>c#rN!6_|t(k)G_dMb_;? zz5}I|UI(fgq*^rrigacaZac=xW%B1+_42YZ>>>jC%G2g|7cdtsAg6JY1PD4+NyLL! zO&(vaj=@$}&hW8iuv%vE<tJ5qZ6B90UmWD&$Hvs9Z)|QWmw{9+`cq(yF})QNm=irb zo5L#i;RiOt*-7J>X`ehm(JHl(lKR=&XtTUYpz1$ciMdKJm3=csarp+ebpn}a_CJl# za(hk$&^HyxJGem*2kqv|!}^^!vbCS?A75k1k44C{NS`VQkZ(%bE5&~2$Jzm}CHlyV zS9cS}LLUhE#K10Iy}~W6Pq~zs?k(jy&$*i6Tv{vE{h;RcJr_m5<u^&pfA_G#NTzN0 zHULqdBCWMPe$<G&;g;M*?K{^?tZC6^4pPQX6%E8nv;5XId|*!Nt~->b4xnxLR#o$I zhn?7yoQ3mEPULHNmIWb{gvm#SW*sRQq<flRES<_<%MS0XWrzb2-|v{^<=%m^A3_zv z-z;kkFk{ZoT<zEyNcyGEaZIxF5ZFlu^$_F>LBSd5&y=)ng5QL>`#36j!|w#B#4<Rw zH~ZLahu`3swgNZ6FxNS~D3%NdoDlK|jvv@^xx<S+2%<@i&%ukP$$aAZc>Q6Sylg8; zZs8AdzghgCy@V7QPfiaD7>l7Pn`5M<OXGKbkFPJ`58!ds5TJk;Zoeb_o}F^~XOVt( zEGi9=oEua??`KUt7mMi@sw*UOn1T)xnsbJQ2z|SO%l!iUMms?xDM{MO)p;JvFdRgy zn8|`_Sqa@J1onG7Y%G(2<BbjeQ)GyqDP4MXVU@G92CDs*$2G$;i?#H5E_1CS^<0uo zKwK`W$!GN;jBt4)`&qF(RDVA18f!VJ8NCqk8?oX4Wf5Ajc%V8@Enq@35DcQ&=OkO} zDqsF)pfl~ja<cioJ!RsIc@#BuFL$vqk0NHcvr`v~s+VYh@_qN&rH2RcT_2XVTL@M+ zD`BE8m3NdZhB)!$qP-_7g4oQifQF<#P`A-IfU$&=LEv(2lAZ^+s7h7l(}Dc2e{%V( zxOlx@y;^X8+CrEm<NLzc`_RFY1a4Fb|H#@BAYK1_QEIn+ldk!hu^JXbgP>Vj_)zj| zt|(_04m2pEOjd1zb4X$2y_M|MUa@>rw3lB^Y6d*9`K*mRN7bQ9Kcl~?t*J7`f5#Ib z_XV{qZ@`|;SBgvb`<5#-t)bi}6`+SM_x^2iMFO!J;#%kxU0(-wi|Ll6PG(5Z7@MBz zLB7lle9ffUwV#0DDyfj7uFc51D}v-<-6O`x)Kc!?D|Qxs-ZX|sRg4!d+0W{bK^hgz zLA?>nq)f^0gb_EzF+a5HB{@ND(Oarr^8i!7&`C?D$yLLPu=Hiog6U8P*>g&>TRwhY zMxm8Fg%!MFoH`dc43)1QkUhk5GGmg1@_Ga<33-tcK$PK1NQkc*M8!7sdZRtk-&xJb z!naWCS7(6+`mJ8JRts0qL8#n|CXgV2w{rd|VPD~Jku9onmL_XfDXG#)xU<y)p7A5K zfI?;r@LNy2i2!s0^0J@tOXW5qX+=w#UEs^$MLbooA4rmT{1^4Xf1|Z;L<7ck7aD(* zB?vL}qX*Nm^Vn3i_=CuoBa++|*f-uy@@=Y3vl?=!m$4rjEM99FQ=xNYOur`WSzfw) zR>sXZ7<+JG@PKLKOcn0OanbUnQaiSe@n+mW)%f(#xwQs)ttU5>Ei?bX|N4IInHx{F zSTB~7^Y7n3fee6O5K~iR;H*UKNyicsrimNk$MPZuKQ}_JHn)Dkf&-V9h(jXHyx$-w zmF*#<7>tb!Sd<{cJ-$=~6mEaU@qF_6w)%KKTEz{aSm(MUW&Wha=4IA8kTYiriKn}s zhc2f<iqE6CH&<?BPk_OIgbdKhPXF3kl+kYzuH{7j#PMFsm2IftX)m*Y6J;@F0)2ju zOAaa`#A27aOKsuP9?=7|DYQOBn)k`;GS8=@4>-|f)bWZ%sznpTkT$wD;GB)r{)ul1 z*~W&+SW)1Avus@gCiu-lkdQGBCUCAG9deF%ZWR{j(|zPV6gZId!MN#r8iz?TcNBh5 znbaDSSmMSiL;8_E*hOc_j<KZd{P$QE^hRety$L+pd&OoUFh~7wL%h}@{PjGocZz&% zSRg2LmH5AtoM5`t=G5aCj5e486(<3Q(r=9Cy<vR2QX*v7;5Sv9cO`eba-0_78w~}I z+g~1n{YP!ji*HG4bp18#vy2^K_*h7R6#|ljK`p*s-;JY|Er96TZ*5BJlUH}EZjG^j zl!f%BN~=M5lD<F?$Da8Nq5y(e$srNN@<#Ov(MLI-Kqu7c-N^zS-@=Z{JxJ?mO0Phm zD^9BPs;O4LL&u{FY*{gKFC2byPp1+T+tNm75m;w_9|d~G9A3unDok4(u@|-On*%AI zsFMn@bnA7_W@C7QQLN4DvC`zh-+4i(v7`#IpOD+g+*suGgs-bBp)q0ti*AB2gXpGz z>)PigDmcekZIP1SukuoWg@0Q7G}^VdJ^(k<7wmYmIxTPF276|WZ%m}8f2DxmrOblV z<}XYmb?mywa5)Rj!bAAZCitu*Oli>J-)XQHKmVA)hYY;)nWqhjjIC!{kc#oS4gd0j zXhxFzJ8M)+sK?;fqsSwVIBL<my$AZXzusHOI6k9rFXSW4+AuPl{V#;Lh4l`LVfsKC za~}3SDZN<u=3pBBO#C&l7`c$M995D3u%mEfmCuRms(a6|;lQ42&<xVJ@0c90>6{9f zt1jsa5afwer<`bD6(DI`OqIF!x&p@vV&j=*FYKvWK9t<_gW4`nsZe_?yv%mW>knrf zVTF$qT(-iS2l?oQyG~8ld|@;dzk0279Cks<4f6S{L4%S`Zy%ef(R$c6#eVhRy~u!M zn=rWx5*;mXJHIimj~ujn1p^;}o}*`Y!f(3b;1L*K=4`0BK4-{>bhWd*@F-laNeX0) ze_V_h{X>AkHQqdX!Rr6tdzaF%6EeG(qX@H<wOYq_E7Tm8D4P=bRhCozhIH)(LzPnp zn|U<$lg(U;3l3anko;Ff1^=>gOE_gk;adMma@AdCY>k2PZU{o*?pY<)!I;L1g57|! z0U4wKsTbi0xVepuSn?-bzt(hwu)c8&k<wc%S}mK&0bBU%$UQ}DzdkiZF)R+!ms~n0 z(BRYyR7;CAU%h`+;N)HA2T<BzW%k;}qYaG@FBwfeu1AA!Cfn$No(z&D`tGxJov>zj zEPB8$IM5FDxgecIlCRmp>AlD+?KviICDLGJgG=2<r(v)vW|6NMZZ^IlZQ=z}))r6u z?gPV|1Tgzi%xSnPd6UbZ?@D}1=Q0YA-Ia*>1S$6EKGO}Zi2F1y2DV_kCsp1tq`k5J zEfv&+^A$gvG;_?yxMtr+nOsl$+>P@p*tXkRcxJCv^v*H5Wj^6tIR7vdm$(BncNx?z z4t!%j-aPmE{yO<%0TaG6xw%a0f+(reOuAM?AE)jX>A@YhxpD;KRR16GZuM(lu4IyX z#@}zZ=4YGmjJn~x6K054={e|(tpaUwY>6=S_s7JZQY_yLm-Ehc6*Sy)@dK}soQOf< zqqj!`jWA<ydjXaXlUn5+UzAeVl_#(ku=G*Dj_|ldJa-mK-p9qx8EMo&CZ37XWeFUF zWlym;^qg?}KVJ9mzGF1YA;t;!Ygy#-@AiZ^LM_Xl`#ks>;ArQw7R3$KXmyuwqEC1f zw`cq`gtY)?H=0^Ntobd@-WUH3a@p7v7-=jPH?$L?-?o6sJj2}3QpxXMLea#5-^<5n zjr81}u$3KlcIlaISE3W4v^>#~9akb^DNIXdof)DTI*|!R{rMv&W(ycuh!Y`AAGPi1 z(tIJpcaLg;Z0T`iFEWjh+t)ZMjd+Szb_E?I(qy(`(x8yW;RhyP-OXo9&MP0X{RTEJ znB+kI%)+zO`F8uU*gzc_Th)kuY=l!Vu%F%s3B<)IKRC*Ea`ivTWKyQoJfgn-b9Q~Y zUN%Opb77^Iak3Q2htePqK0@@dWj;}%zxIHGVaE#F6egF;D|3X{`z;tieERX|I)@(@ zt1z+*O1!i}QE<HC>aCxX?V8Z=zp?=EKAyLit*8ob_TR?8?;)7G60(aUVrCG3cQJQ3 z@F5xiByU}9ndiu4d0i76q@iwpo$rlPjJ?%nRYVQt@Cwl1Z*O2DE+UdI6D_xImiCH? z&#OK?dj*Xrm`R9hNE$IlCs=xw`E{2i+@?EvO%o4&LbId}<3Uy@NGTAfLmr^xp>T*a zx`UPZA_g%f+mutp+PK4NCu`iF&`s<Ql1Wd2i)7=IS@Ggnqq&vDbE+`9()Kj1mN(zj zrIP(hAJrKHA~Xhz$2%U@U2P{_D#Um5rKFT7_`H*uB!0rcvg?cqNDo)`;9-6HdoMj9 z!7l_B72pU(7(a`oz7H}{FNCDU|JD5nzk5)GFue!oI-}YN4gb5!(`sN|b6St{kIDBl zZ+|C9x-|Uq5X_of6LPb(3@{@d9(%96-?m`2w`<zNK1M#<RC>JiE#QFnAYKNc$s`<a zL=<`)CK8cEst%=<(xxm=bxa-U52I3RqO@Yzq^~L1%Td5tm@CeL@U(vm6~{$D%~268 z6G9ri{8vy2t3(9V>01SI1<yTd^mnW!NCC*VaFXmBSu@z6lSxP?m4rY6bjW)auRbbc zl3bKsvlTRl*9gbYnnjUnm?%AIwyy~UFRk4iwaeHW4rUc9V1$C)Y9m8d>k(d}`m(9j zK@QdI(I#&P@Tojoj(@=~VC@#McSN33y{A!Z^k636QFh~SpfR?|<yqBFon~FPjcz%U z7%F6P_SysInc2Yzb<mJHDkR~^w>aU&-&~9a-^ZSKhF-tMB+5g0mLFpyI2%u=h`qWZ zNLQu3cBb4HT<g-~uo3;vMI3WAs<q$wSE<1x=WVEJFF9h!{^qAg6uez>xxzpzVPxtU zz7&(Qimbl<*pn{M4lHt@o$uCyFgOjg#Jx7dvKuLJ+`r-r^@5xS!?pL{P+`njlpN98 z;GBv*mY`-P7Ea7<g3Nyfz)$iDNtR8Z9X{Hcy>H}-DzVLUnS==+k@Rq-0v}D-m19Um zfX}teQCdf9M%YAKIrzYj-aiu($$`6@uM$I~S=pKK9`bA8vZP1Hdqv6)v5^}+a_3Q+ z4;doDvs5Sxa4GRGvcA=+DTp>5I-JDc*NWJ)@S2`hv$%<lXA{=N?~4vX@}0yB+n!Au zS=O*Nnr*dw#bKEi@8-M8yGk%`L27@~KHy66?ha;dnLE*X((<&PKUirIia2S^lWMm| z@hrdbN4SB}a;BNak4m(C-+c}IZrOrM^Sloh-&dk5xm~r9=*q$SRcY)|-o`E_e*9(p z-It(II=8YBoAwIOv`COb#gI7JaT5QKu%C2bb~-zIn2kNrQr>Xv^1nw%LCBDlwGsr; z*rV)faW=f6c@mHid6<7_J20UeAAH*N4Ix;5oeOK=DG#CQ<-iRd)6><~4Fthybn;j^ zGIGBO5bJ(Q+<U!DSz{^uyyHshag3b^ZmkU4O<N_$y9DfUa6ZDpj#i6*Mn32Y)lLv9 zG$31$$R2I9^k6y+(zzdWCcXQxX*1Qdqlx|(r|g`h8%eAXlFUm(hq~7zQEtOy$jj3v zlq<pv6KW<_3|xr8Yey$co%qe*0GEsCo?uro-@Guton6t|8LburL7?Y_x-#4lhq!+R z)xT=^1LN)MKY#uJAn&^{%R_A!MN?@&cUB@q_cC^3^}r2*CeVcgdxQPYe~Np6)Vn>r zwXg!Vh&dNzGfyPHt-q&%90)7V!&_db*WbA>FisrJT#@=4%tvFgQ3h1m&rB18*Sexk zvqYEgSbB~>wDUdkso9Yd1~GUWZ@j)5mEN42efdFElL}%_O1iIayfI3f_ZQN%LZ1Ju zkdN(yHyT?p%Ad*WpAW|r;3~++90%$}X8xtnAlyluW(=k^B%>zyjt}xxCY?s?tu{&p z_6AxY(YHY(i#tXjY#bUEWf}ovevVb@hx+0)0eCm_S;Q<%ItHZm?7ad`^ab5VSd-5# z<K^uJC^I!*6B=S}6RBcEBgPz3C&3;wK4J*NXcDtv#Nu=HyRH-5rpMnm^PsU}ME<~z z_mKa@@0gKCu3fWe%9;tOL<VQ3SJJK^Cj4j>CMO5sPxSk?1iZxufU<}HtPJnoQu9J- ze~Y*N7V||O7)(EqGxOW#tCFmB!+|L)af_W>VW;|9|JB=hLkcGn=-1O?w7|>qnlYZa zafIdZNPCpp`F$C8eAHs^jT_IT*0QZ6#`QV_H1%!0YRE~xEELZ#PK=eG;<F8w;suSJ z<YU>sAaFZNomAeBMDLVtrOTF^`CaSvPchcOa9`_r%kGhO&~WoWZz@tYAhTBdX&1q< zPCyf*enKtf?lgURE11d9ySD2(?7UOX8q;1Kf3uvHcXT3?Mq{jZIb6I||0vngZ6BZ| zro?_1Ef@!UOEqwrM`4cI%!~Xuxk^ZkmEp4FZI`2!xUd@Z#PA>|iiHJeKN%;p!|#Ri zNw|)_SB|iC9zxUr!dZh9AhVZveCw_*HjN#gQOi2Tt-<w445UanF-E#@d)6BO48T=- z-|R&{CzZ0u(f$vPoB?&Dn3xN^?PK`Z=F(xcRZ<h?(!!?Sb5*^4Ny`h$NbN)m<Y$3I zFYRsDwMOlbd_Fnk-8P&PbpdKC=o}u&-9YXkA$o6vwGY&E5WV@XT&2i8@{4AzY97>Q zRTAG3reJRg=Kw-9VL3Wg$L^vtGFa2|a>!2|+@Cop3>lpyls-<xLY4>ryE$@$qV1~e z`^}26w+=cY4t{ZxLk@wCukJ@tG+$FK?7`%90WgZ$eW>56=`38zeW+(2>idP;;?bf0 zyTEZK>xi;R_UPX$CAEa+b6HIGw()T<|IK_`NIb2cM7{?<8B~c4(xaH)JgK^n7h4IX zQCqT<x|5Q!MJ_u_BH&iHMJ~X1VwNHK(tdSIzq$5v4M?~%;s143mjs?it%2)zKCKGy zh&-!=hZ5D~Anxcya>#9l3Zt=Pi%Q9QB9b`~<)rL}f0t$dD&6oURco87UFL+ZyrcWQ zapH5h1#^ywNVXs3Q>VIZ(nzVrX;_TXi_QZRpbRexH-04J!64V5^*J-dpuGmIvtUEv zSYF2uEjY&!Js=j_QwxMp)~9vJ`pOPE1xy}o1h3)W+N4KBC`>dOZb%#Mr0#1|FVzb2 zH3jB|(AX+lT#%zB)3i}O0J)x2%Bg$vd&2YcP!jB^4M?8uyJviFaN5tJlD2uX(0V7i zC@ndS1j)WbKzlR+Qdeo7=ulW1=?K*(?v1r&e^dX$y@UPn7v}^}a~(8(jTsD{d=39g z`#|B!K914$<@m2AZc;=9Cvz>e3`&#H!;*=4K*{oCNb-cl^(b~r@A4CE#<l(7B2Q~? z6Qxt3Yl0B3b%}5P!HX7;=0NKs{@=4A(2p-U<Zt)Z6tV@SbVoYNq&*Ri%$@#yZuZpY zZ}81laE7c;ae>%}A|u{X5D4))B}=u6FP<3DIMRwj9V}<1UK6B2??7+0j8{hTD)g@? z^ur8<ah}6RJIjnaq|EE!vj1&{517tn&eP)~AaBI9o|dhn6Nmc^%X_o&{{kh#6-v)l ziDi3-5a&YWT~2IH1WU$>j_Fs55Q;4v6Qnql-=3oRd@Wk5Ud93du6EMlMbwc?dR%v( zE^0?${n}14%AXbdl>743<L!Rb@vf9Mg1g4yA#G^$i_L+fa8aDylqO!^vB9ORfPaX^ z%4#C#^d7sXnR<_<R;jU*wz7Q09~Idss*{~4iih<IP0~6FX2pi&<~2>Fo@eFo7yl)g zQYuQxQL`e050tC5xY<P|g9#x2;jljJSt0CEc1dhaS(Alt=~XrO&u_D{1*WOTxV$gT zw=ww|%QhAbV;ZyS3+fTi{QdBJ>kX>;4f72+nBk@1tsg#;K9#z!SfqEhvNi7`L?@r- z!a+FlgR39QDf3Zyv|bu`?`Q191g6w5OK4$=lL7qDl@{Ex=L@U^YzH{;P%czW0X4_| zm7r7K5fx+tNGi1q$`0Gg?t^3UT*p{VS|HsNE1@Z;c@a{KR(<aBaIEWV&d|!hL61z} zqn4~wk8+UJ9+}+lo9+86UGZrTl9Ku9dsa2iJGNA8-q58-&Zf^&qEHD>9VL;E*y%~m zYi<kPeMWr2c2*W_7wBU<&0ZT0w8B=)WMz#%6fD!i4~JbeAo{Xt?<pX+GEV51$gw#z zeePo+*0=P>sSCd)0$W}Q-|v77Yfu6Xmw%ab;l-4IWn@5wj&cE;?v<+LR!@5a_QcE& zz~%m0kU90hFW~f-X8E?f57xp>T43(~kX2c&`kdh_cs~QPKvCZ^Y{Lws@5(ytiOatu zSWbUyj}rqiQBi@G`1ci({v&SMFv{&Ge-;0Y|M`Vc|2KW%7%(uhyyoPo9u<lEGby(p zWR4&ItXce<5)rA`x3eB{VyPJ^WU{K<Q4RI*(q67kDA(j})q(7wRJo_x`1Z-<jCQiz znBAo0_3V4Qw3Cx3r<)*O``(}xzTpi<0$jzUZ*sm|dw?B$u}QtoYTEB@*he{#`hhR7 zP58kWr8%0ld+X%>Rj9cw^Y}2iV9Up=x5@o^M!uw%9H$Wdz2Qm$jHuf-GEraoVPxIT zvYM<IRUx<`G|9;Q>Z?KiNrG8cW!%C91_eAp2F@P2EITqzXMd&;<G<>VDj=r5FPbh@ z(NfMC^%q#(_RheZHk$y{ITaT^*^G9uxyWUL*#5X(M8FZsu(8z6(xisWX{k~Gg-{$- zU;N&)uauwYG9(vtze29IOlcnYIvMNWN79bOV%)CMPR`&O1qN-knUC^*8;+HGlLD(N zA=uXcA7}Yx!WH=c?*KxVt-QBtQk&!03WwFEsyk%g9)o|6LbGrXzTYQ$0CG!*fqSu8 zo;-p*lntoaTJ=AV>|EV2(5{U<0O~X!i(dNId8=>Qp#jKk5R?5?ODQf#1&swa!H#v_ z;2m4dg;_luQQ@#n%a%C@5gv>;>+(09RJP2rexAl<d=@}04E6zx5)|oi_GfX^G~v$0 zT>M9^%b|=1ynH6reYL<6lu5D~YDhLyrZYnlu#o`xAOV~i_rJhRj(uc9?Adm|g0Uo? z=Yy6kgOq0<lqD#5HS+o(SG$kBz0m^hhl%O@IhGJOo3uf(S077qu=Sqwuh%dUdJX1T z&g?0<)Dr0LbA8y0-RzBNYT%DAtRIL~=h8p_&iWt9Y-=a`xIa?+9A^P!blP(CmDKSY zCgmm_r(qCdg|%J((>)=>&v7c3UV2x3)b-4?Ju&puzeYbYr}7z-H#9c#m)-s5-2gMq zqj%jN{^zjYlD8){B0Ww`mtckS9-e`f!-1zplJ}nDEhXZuB=7wCgBF2oTK{jp>D2x+ zbj!xaKKtvlXLd|IgCeJIo~GU%CnCw?xTlw_Ec8}VjfDm)5ki6dW7;ZpPDlSOsbO?` za#8nAx&OX_|NdpmrP1Y$VNFTU-`&a|f6iLYn$h5@z#^cRqaPVI=lqlu`C04GspTX1 z_K0;9wv${4B4g#vgXT83k9hCvL^8ZU)LvB%r(JbUVKGSB!gelcSz~J1=8NLB<N~K6 z1!*Fp-NU~nX*8m#gAb{3VOMsl*O9EwV}d&b+c^X?XItbU>WD4!zxVt(2>3V@2Lye= zC~N|V+{9`mHf(g=KVK*JaGTJ-KAvO|k-6E>xhbG=QXxB?^Z)qtE*g3UF1h8+*XpAW z`}oyyC9M2Hi#t|Eg*>kg++L2ZWh&W=gu^-$IAtQU9X1Yrz8uwJzMAbFaFY^hXs9O@ zaJ}2};r4?|+~O$rEZSRd2)H$Sra>Y~R;<*{=dQK`k`Imb!)~<`_zB{EQ=-U@yS%H( zOs&sZy;{%O@%M{>=ET_yB4;*-ZY4319kM7jL~(DOX%g~0{kv0A_6gijUL0?Ec*}bw zp|?l)`G#gep@#6q&_6PngSKk>;S5g@jg+?g_(SwP?0-((QF@Ykf-T_M<V0;s_K7#a zgLi+sKm;sgQpu$E%7rt$hlF|y?(jZNK2HuvUVo5%JfVDF!_)iCWb7fM$UO~gRc|Id zh}*_WTI;nPYrzrrhm|eIzklBS6U^t}-^9Nd&kd3QIHE><%305g$ogy4KSg)Xlz-@J z-rfUcMeEYehmup<6NANNp4Fc_<2hH|^}N?Vu+sPOn>TP|1swHnPky}dl-m7THGzfC zpgW-uloMP)>>Jh)M8H$ekhf<t7x6k)qoLh;u5vT%OXBh}qXc_5^S|@nN#L`|(3adx zW_v}T7(u1XS)deFi6@Fr@JLY#KgTE`|DhG@ZGDwDJW(*&bKQo2X=ggI-ydRsU3Gv6 zwz)IjkQr!c$$AOuu3bDwu)87%^j{yilMva)FyJI8)pm>>jDRxoJ(!b?SA$0XDF+_y zJ=o}hPJD?^R!9ZrdRH<sDO64#aiC(H&-0zRDGMAzJe8I%T&g9zg1x@*XWNyUGTyN* z31Mb#0P4QwsyuqE@T4e$x%GA6$`1Bqt}|JdD9&qI*)zf8q1h+SXqKhSKfb#&{N3<r z-vc1wXwq%2vBh+BKUj27M|f${6kbf11sM|Llrwxdu-@-$aT<Rz$ebX5GG#Cc!i7=+ z+qfVSsJI+7GAyx;9&<VZSD@c{djCeye(KeWzE1(ao5jUj(`#MbyuSL>r3*yprAlp= z$N#l<y(fSDjzKj;)z|HI!g!aiNrai5<~*jY;S@mm5VejwiZJjD`>9x@8BG_j)qvcH zL{;{YERHW*vGO<P`gmR|JRgs|r&1;mLHm!jrCu+hEfXC&cy<TA$3m3jqoqP`^i)Nc zGyA>d!$o&qI(SS8d3O+UQzo7##03<fYFrmqCcQTsAIqyc+s6ld!Vc&AO)^*Ro((G{ zpSXx8GK@@T(<R*2Oeopsr@^5jXSI9t{@yF#$Sh+1i&C{KP|qJ78(WFQx)nhb93#xO zV|s6LmWJf7X#6`VcCC>PirStZcW)baZ2shqv<{<8mvYM32R<0%cg$z_UJ4t1D}BF; zDpdDS5qv#=wU5v%mcR|Xd1a7~7h>=(X#9@Trhv>U##_8;s+&)t!qta*h=}=~PPQ{< zL&j`P99R13$3){tPZTBfjf!RKVT>DxN=9+g1n-fem4Zdr<cTKXwrkzuWA`!Er^%0= z*m@j=eaE@~M~%H_`8Bmg^6`=#E`HD-($0i_LLD=&nYKG4*M9xJXIZZ%>z@C6Olug3 z%8h)Rz&slj>FkjRlW5&$UZ%|4S#UGHhqY%Nyh7@Xf4$1D#kSneTk0Ua!zw+Y#hu}Y zuz2uPo7&DMx4zid%;H^slvk0@w_%*aYnhapx-17!p>hbN#cjHN|4gr_UF3dwNS&SF zl;zXm+Cb21l<v|pxou+pW0zk4Fj{7Neu$;YX~jzYcV%Jy@a&w^jGDIm%^HPo*~)wA zwg4t<{NEJ#(bip!%z=Kg282!m;X8jX-oZHwjwQXmJXcb%%Dp`S(vMsCmO|0ZCo`sv z4}8YYofz_Srv&M8EBiv-SZT)%NF%)ADq&2kKA(Jt`)+B|g#5|W_6F%6Y5StIq3?=V zc>at|;ck<3sz|WPuPJKBM{2*Iarj~OQmb+{%4tYpipHRW0uNh7hIYQZ>J1`5!#Ny! z|Bu&8l>)7WBhpMB7c*X$<%8M|GReh`ZLd*Jb017__UmLe!rRmy#I(6(KEuiJLC2ZP znuu-2S3mVsx=~cKja(WG>~ZITpe9J&7vU$cQ@1?!-6z>8FlOi=nk)71SF~^g7hQ*b z#I<=>;9HaqyG|`)`<b4~dAaALElKdsx(8Rg^x{I6h`Mq^{tsXnw5iM$)tP-(Lh_<L z3yu}t-3_;*j98_l4>y@<&c5t+8T7u7r8voYxRTtDs6%8T8WlXE++R~zA4gY5H3@(I z0JcKo4Jl73U2`)kFIt`cyjUmjS)~QTqqJXF{Jv{T16M&M(b&<ys$P1T6K<QaT5ghI zgOe{Z<SD6*1$+4z0S`2khKBPYBENm|Ttq^&$NIe!<;C`$+Qhq^%5EO=+CClL1P(iH z!ZfIn@dM!-nhPp2;TX>+`Q#hQGV7Xu9x1BzJ||;+IB>gwr9i7Q_oQV%+k`!1L--lL zE{@wIMc7ZTB%1*$rFaIsThtQmU!v^l-2E1n5d0h1Zj6)!PBdBN)>AKXMfU8~5vx|V z9eMZMk)|7@4o_YuFuZ4a_0wY;!^HW*ShGm+H9QKjT_l67n_eYG#oyC7+69>SdjAMx zgGPyUYN56ipY1<J-|>v@`qD!uc*)N_ZRPWRihOrlwSS*sn%pV~FRt{ba$o%%DLq)( z2a=pG^qMxd`jS?uH|K%ZM)BEW&0G50tBdY>+TpUFDegC~^T}+!A=wlj_?7eGlC?mK zb_X6#NhW1C-P<{#YR2BOHgdtg6qH19qm}h*2i$*Muh=rchzCuHC&TWh>uFK}FS$Mr z4y$WyJoLMhSvYHs5Q*X!Au*{p@z3u1)3SEhxYCVBM~K_TtKwnz8vFdY=n<@yRzTb? zu>Nk}$)p^XKvmhD6x;lPr`pKOqkDs(_!VlAsCBv|TkGvp<?0TLM8eruuVTT4O?A{x zw<j!ABKB)(;0N}Qaav>cUWHOYzt@wzaxL7Ae;RfN9+~i7c9>?oG3e5uQK0P4<Y9e4 z6df<7ig>L`#{E%^qP2U}Egb!Junb{&JweT_is%m3r50YLbGkd!H;HyEblSSz@c!n$ zwhAKurK-<iiy+P4ji?fdbXTjA-0kE-g>`A><w(8cZhN{mo}jq5@e_sV)VK9d3bZM! z#60Cl*q3938N1Yih-LbzBJH#HA0p(@xv-R2p)B{U?5nw-3e#)_6OqKUooy=bb4x^u z$PB&1<w<Be_9El)4$0;Sw!yCWM2aA=c2&*=->apWe>ve7@>41<jdGyq=MUD+mW1HM z`no!V3s!#wcgOG-;`S5A@Tp|;@JF348P=j`l2Ab+2+fZ_rcZj%dMee^Pp^b-nXGPq zb32*6S`<}$aB9uq6p+Bg`#flUcNy{Or>`n4E8`4NV*+bmzO=6=Vc5Mj`cW^bGRxMM zceA+Zj@=axYVIwqQpbJ()6}YWd9<uGjuh<i!Qzo`XjwUXlg*_%xk)_t&xrC(&pk$; zY7i9bX)F(R6BL(QQyeBeX84y*uJ0c}#}g5GTi<E*mYC#i?pE{0EqZ-}G_Qy!UgTt* zf;inV>|tLKB0tPFhL7?)nZu{<(kbp-ncDFjyba(CQ1R-DyAk2hV0`psY$;(xYY3Y= z=uf9JW$f2J><!t!Q<K}DGTqcarT3n-=TF!@IZVNyrVeov39>!sck_NpC9DstA=s`@ znnbc^<$dVe3Tv=`?-?s2$YZmm=pQz)9SL$2HJ)329#%rsgb);8b-opmG;3_QD@ZFk z(&^VqK4Hyj+?h^{bB{HPc&cP5femaW#o56s)e-4>!((rITIV1UtYe~i5BmI~JNveA zs}Ceb8)F66UmXug2+NW=DZ~dTJ+poKUOS&TLYc<K+A$(%al?4*jfXdg1KLVhV}JR< zqz5OlTH3oM&NV^GG^*|A8&Spi(a&Yy9B)-Pm$q<adHkY%9X>AZ_lNrs-wpry!c>vL zhj;NiIf4(y37q(z;p7YU^}RU%?J}M)8t_X57yqJtO*_PiTk@Lrj7pbCk?7U_|KRJb zqoVA>ui?iBC8R~^8U{tAOB$pGloAjS$&nI4x>IEcWq_d@M1~S+lm?|638fht2FaoO zJM(<MZ+&aM>wVw<TuZq<oO9pjTxain?L8DX&*jj($e2gA(97S*8*oXQC7|qBXZ376 zy)4Z;ng2Csn#@sN-Abk2cDs|$$g8IFkA0m@QO+Oz`OjCjZH$D;T|w^7o8>U1<7%M$ z#$jNoUq;#AgIV`2@x_0*w0t!*OR)&a5nE`}0PQmomiotPwv3MTM;uWDIBBj@=cO?I zcFVW&J?cxlp7R}jVOkt75zhju<-9rygVv_V^qA`;UHxPiFTDACg7#R(vYY>|G&)vH z&FBrPFafR9U_6d{1I2Wp8*fbCL0ovMHA9yrTtymG7g+55_=+~_U9fZNb8YeI3Gb#` z!xN9bg-SjE%f)hMSbrcLf?qD3jORuP)Wz5S{IGwU76~`e7W*tV07tnK%$&`)d}6oM z*~0!g{$Aq6mH}4GXHPTdLN^jc@zNi04$sh>m{C!SP8N-Qf8ScKkgDwm#fhkj7!2J@ zOBbM_BnQ$UdOt>4odk-vL_2F9yq+I!sj=%LG+SnBJm<3)KU(K0&0}(^E9Z4>e;R?! z9lpm5eRhn54iIC3&1HfrX$jv*(q=ouX}k310P;}|dY6w+R%v^UnK(F!H-`$QW{Do} z;!qM?7}J97_M)ufnoMA<q!$^`NU0{wDtU$^?sa@_@|#EUuF&G^bYqo9iU0P>{oX#N zH?0*64PiP_nD$-32rbPxA<~Hj1S7m_*v9IcC8e7c*?fjp|CQQoI-A)}<gOp~P1b5y zV2^h233g+tBhy>aXnBz)t--runHO58eKKliO*xQ$=bq^r6L#54#I!XC7s6oD#TLUw zP-G*Rt<?2q*50gW)twVd4-Csz@BJ0?$Z~Eke>@sOhZq&V_$wj=B&x-*^R#*G)zpD( zFALE-(m20%J1JozpYOMZ6@C?M4~XG+G>@ClPAa2*C_>Rf)`qPPPEwI&u&2SL^CN<% z#k)sS0cf@DvP{>a4G#83H8uM3a>^VGgn)adJm;G;0mHnL4irj5_7m{T4OGLP9i3mf zUK3qIQe#kB85N|Jf{f`5DLe2bL4W#cm>TtPAgx;Y?}(V6Jf(FN7K3WB_bB+uM8>Sb z&TH7}YB2o=N^0#&$5uDlAhL@{ksi?(&&LIvx?}&WH_uoJ{hNjmb&qn+b?b^@>x$&A zhtbIIe$c+HI4L5(!HE|9<YYmum#d^DZhBU0n73gTq*S+=R*c=gNW6<d2|I+DCeGb) z*;KvK8oX}fa%e)o*4m<#922Ir+C_x>htB8IdGfOS!V@{uF8!mmM<4V(!w#@-cNVDz zySDYplb6>HSsDtz5EnN1{yd>WxBE0d^~p}5w4gf>587Q^4X<l<dS}W?CMjs28&_AR z-(=iuyqWaZQ7ZuSYE>^qmDdjgfWdtIwQod{mxr&4*?w9BJ9-^5)hxP*(KIOabB^%0 z)yA&)l3E>oR4?5L3&8Jz&=;*tcfkrp-P(L$uSEsU98rS_6%_ptqlwlcJvrYnTFB}; zyAm<hunCv&&T!&xn9Mu}am$~nhBs&57r??4B{J&!13T2S)Y%7pI<?6ay@KUE{C%l4 zALyprBH@df-1Q4fNL1ZeZ+pCHC_7F(0Yx}Zo^zKh=~t(d-9#@~jx@NMw4P_c*z4cc z2oO<Ep{1VqUCn-PqHqj$OY@x-mGJf8M<MTcqHru^lFb3?_S^Cq5QB+>sGOp|kJO;r zM@pIXq0M_XUn`h+3<f=ngg-N%d}6zhmZkBL7|4u}Aw4S)kZQz~Ha9TBYbksdeyFXA z_Z7x8?oT%Hd7+k5n3lxzH`Y1-+NK7S?#xi0w}~zAmngiAH#%wykdpxKBzj%igUun{ zur7ksw6%71ZjDX3$kr$FpHm4{*4<YOMgt-$C@WVbvr^x|{0Ebd-XMLu{AQ_H8xx=| zOM|s^MdU?c1Cm6LH{Vj0-(9;5*CthJs}9M)xKndg5R6=FBisB9%2`5d@>dj81qgSF zN2MI95kC|;(OvHf<A8Nmro)aXB7}Vf_Oz8bQYM(=d%y>sj6kX=K?DuC6Fq!3nlLMi zaGU`mMm{W##`_NLZma$&$SkMJ8qz63cYGJHQf+8Uq5k>l-CeISQ?FHt8Nu2*2l}IB zn=twQ0JS%20vhxWBWWsXcHCCzYMxZrj45cO@`G$kYF(Zya2Vwte+s5p=MMAF(Zpp8 zZ383Q@&=`5EyV5J$N;tG<B*1)E$$IaSk(t3Aq$bvi@9Nv(!3xlU6<hr!HkOAMH{Rs z%}QIg>*n&-cF#wMp;4P<ahEY;i?u14%X;u{xZ;LJ9)UO(YrDL8?IYRKUm;rH1$@!x zKz|RC@uGQH=Q6rN#x%qB?BtvMSYo?B?*kj1EE}H?nnq|=P3O1aN`1;&@vju0Y)nF! z4$@^9D$)ks>zY8SxH?g`@BO@uj}a6+wuom9pEWt`XX-qxf4eRJA;y-am$76wS7Q3> zK5Ff?>nlo`>waDrqQMsfB(D!LZiM_$<UltuT&x0mOYtUe+smSlc`=0w?)22oHVq=5 zHAF_$9hLh;OYTPO-PiBET+1+sq~@UvqoyIO!m#;UFpfVLx^%1)ibk#Idq(QMN)NlZ zFmMWymWO9U&R*iPrs}D6CB7}}DnK06xTfjTe3vv0BUK`gCF>;hJi8wqTL}1XOQ@IT zL6ckviwf-~{7Ys4$Pll<DS(2UCs**u|0)-=u0HBYiD_GjH$5fx5|&>oYlkenN2OLU zVaklG$HFH@kF_HW5ky5Z$l8n(!6mH#r@H2Z+@O=BAa3jK{UdDr-3&(DP+3o`_s648 zTJ%w#CmNH^wV`Xx8%No{tZF0$Y8)?FVd<w&vzOx7C6<c(+(o-eDdmnWxcz!CpH2&C z(07b*O|9EMrkp%F%jn$x5(Rq>#;dgB$Zj0`l3Y#K+aG<%{$}4((`y%JT0bZ_w`vxz z=fapr6G$Rr+qv6Nz|5PgemEd(Jo2f&TSQ4I;Om8mWqZAQ<i7s4@&&J>)rrR4^=#17 zQs3tEtKpF<y!A<XTdP9SL`w-1|HX6>qKYkkU1aYL9tO4VdDa*j`ro3342zuaWnIZ! zY}m@DnTV>j7U(RcM#4ptxiZ{!h15hlh{Iu3Ngx|*EcT6xS<vRe{y=^4Z`Y9gp}Xpq zY>{PUs7PQ+EhY<KzjpS0Inz@HosHbyvMr`NV!n1uj-Y*m`;^q!r0oNw^;5QpJd8B> zk6Z$+!!7wnOe2y3!yAB$%i=XAL)~!N4pAUY5==!bTX4SEJp`>7+CW}m{sCvkbGZJ5 z6<o+-*f=uXCFT({u?-gMTVM2xKAxMoROAi{1nx#ud>aIzOS=2OmA)*Z;hr{1p+we+ z+SQnkJwNlEl6W<E!|9kQWS4%q|M)`CBi#}$qn_!^99$#GtzNoXQRTL5cPic+D<MVb zg4@atV|}q>+~|9NE|+oGSgQe;pH%|zcTWGlOu;>3jb%GgJMBDRcUfOGef~f@hHEV^ zFy1^e5thPo+uY^7H9A2`J5WC~e&RkRTUEYpa7E;7tKKQ4<V(X}ne3#x$k_$>Go5tg z`xh=Iz8_kD60w;`ZBR(ez5Q%PH4a~U0$Wn8yoLS^B<ni+v09DmM1#gvPwE^es|wec zu>z)Tkz|2O_bmZO7-Y1|M6u2}ScoC==s#Dc@Ucl}|53J=CMWoRhRigQ-`ku~7mdHZ zUMu+a^E>yIe29A^zqS#Mg<SWOOVn!p-Qf{!`HZdRt4qZ$Dm^W4t56+yyu06){wkty z7r0ef3k|2Yvfrod3zqMC#EcYj$rhKDd@j^A*EiURN22%JL=ea?J{=d1Q3{>+6*Q;` zwk0@Z>6PH#yQ?y`9%h_6FJfkTQQ*39lWXC=V@V8cTT&oAosckN!8(<nY^jm{fI^o~ zgMXp>?J~W!!EQ)9u&aB1?%Uq&21|}C;Mj8yO%Sm?fMe`K`W7UE<%geg1?$j4U&pXg zJE9{*n$_w7_JYW4(6au3M9BuP#T%kHFaoU<p@MOpSbm4)#J>rDma|!d+HTB`T(fqU z+~*>&(FyduE)qXwrQVEE&+00b(w<J5rM^nJc}L6QaU#V(%WEKVwi~gkR2yfHi4~to zqtrS<o@x<kj2g#0+`rA$tYqtRU+Swr!GKCSQ6vq+@FVZ0lYsLNo$8&}-hW81!|*tL zG48|tqMqv`(UXflKITgg&#x(}L=v~M_p}Kv(7;iJ{d%@3v}DrDPS3|f(iH{(r10J> zz^jBB9B?IipL()9{sTOb&6%pKUdZk7HwsX8A>Nu-`=<6}Vn4#)h59!KxCvZVn5Gr` z<;96SzzdW9gGKT8=wwmO&+|u_J7R6~$VaDgL;Hfz8241J??yViXPD-Cq$lISXgvjw z7ITZBo6U5`w%|*uadr#%ctX<DIf><mpSS5r2B|Aryj>5GG4_5-DHN}t#Rx5)IF_&} zKG+Z(Fo_^&eSAFdPC>wEfs)Q!nc2jR*t4yFn_Y2$SfEw*+?OF8Cith++`P#rE~&xk zIzR4B*H*58Y@OtM!{K^gZ|o3P-9e73ymeugb6tC<Y>r4%++pLVH*)blSiXQcIo^#f zUGeeR$J0n>mlz@rC%QrE^O({cvs>C@I2$VAqXeT}w$U4j3kBx|s~Vt4^iYlgWnBYk z?ftIt=688PunvO(#XLtbbBw`&`xs=Y-V2kFI`PYib(_fWSe;3V{R1v)+dtAKEnvZ{ z)O9C@GKe!Humc-c$&Y@sWbc9+h=IA^${c#8=kM`J2AIpn9r(#h9qnnXA^WCgdyY<Q zJ|%|`jGQchvrvFr=OCE`U%+4gb~^B05l=e&;JCqP66q!CImBL9szcF<*&BN0*L30_ zGq&Y0gdX4KGZ5J?=`c^8eijRddSdK42$v?7x@i^af30?G*ZnQw@%t#Or6ESv`6yU( zuDjr!(cHaRXOHW7yN>mh&S;&vJ9h2zNCo)GCYdUf4<GI!bY0%-=juJfEC;&4V^A)3 zJO65zBzq_&^e_WE+Ut{)IgAmb+dkQJjt)+9mfYP-^Cxr>;G#U4jflCb9kgcl487|Q zcXrvjV^DhbrdJm_I4sMY0xndF1MIdeid}1W3{6t1Piwx&dPW|TbMzkSbs@H$(ySlX zsZLVfx^$mSh+dWrJ8x<CK&QBg$mY`o?oD*{p1W7AiE<miHudn3a_`TMv(7mgFfo<i z|D_a1`cJLFVFKLtc|p$H?V4~V#V>lT|2}GpGfN+13cq7T6iFnx#NE3N)@W7QdbiLI z=XIJFwCC2Gw#SWVjN}8IC?x7NI$X*rhte&t9aU}08w1y~9i>FKRT@Dd&GGqNh8EA| z|DkAsqI3Qo<B%iM!hFS>_T{>4+q@FC;r&cKMMj@($9OYmxIT@U=bz3mUy!c|)vF~u zNbQr4ENrc)u8AnV-YpC)`x}O$&>Pf2grGR|$+SYbm}`DO$p&@Sgn1dr9M4`J8YkL3 zpo1iYEwMpOG&lCi$RnQra%xJ<O?fFkbF`#{xb0IZk^Ckei5kd1x0Cv&r2?I3KK)(# zBp|HJ!?i0;qV4cG?DX@rhp%njWeitiKELO9OMCu57ZQkl(80o=@lOe~;g`q`We}VL z?Odi?Q@B?-{~lE`SSd~AGtQtu8DOKd;@<id;a(U1dv%ot|7zxs7S#3K1b_M-_U+d2 zVNGAC(_M7^(_(}>9qmZt7yLi%KR<b*W*cf6ci%u!N`%bz)Zi{!M5UxjoDE-b%b^v2 z!wtaJR3+O0p3-Uk(4Pk~6Y?57r7U?%|1Nq&#bIU85d7o@_$C+}TfK|G&FRzg)?^-h z!N{{zG#vwZN@C|%zyo;`-Rp2{pjbx=YI-lY&`i-2wfu<jzN}J&yUjSLGexFDcfo(& z`lviq$Pmxw8Fm@gLX|#&fj>1=oMcU!*uf9{O9E=E<z<~=0!oXnJVhR$gTMg|Jfent zvG{+m?-KmbOHie*s-b|E*vu{g!{@J@HzvXIKf@2d-MthHj{l`d5CBh7;D+E4&P*M~ z{{!xtfC2vprbm&1`e{nZ6b#?QrnUOkuxSB)_z_q$Fj~_#n@fK%Rjq)rN|}F%tOn={ z;YTrKts)rke`qnofAbEo<Nxct;~(*c-U&RB?6y6<TL>7iTZn&xv@re@_?<i@GY#7* zpZEKx{n0`yxm@!&*-T*C;S(m~c=2^dS;o@uvKZhYU_F8ZKC#kx1JgJhLMhDop&^&s z32qr%kQ4Rb3^hrx3lJsVw6ZX>-E))7Qh*v)RIh{Xi?j_TMy>R^%|W_B@;!%O-<lh8 zpjpp*!fTJz{8({9UHH7dyDFtYV#0O@A8xeWu&4FY#H5X6C}HK$IP$!uG=-}xTebAq zFM1%oETlU+j;(86zCcNBQ{<IEGwDDxJD*XVm9CeM7snMTozF}P1@2P~H`~P=-LbZ8 z1QVCmRy(8#A09@65wW^Xn5|b|IgpX&SjRmB{1C7}Wg#HpQ*9JA*(h$>e4?xdryDPT zwu#|VG0eQH5u^dwLy$R^-*`A#wD#4chRz2vtYKnPM_DLnL35(@+$8<PZD7fFR?=i| zX2;%(^|u^)A8jeWIedJq9Ch}bJ0I{5wsrHNe@7?-cY@LUf4St5ui13HTO}vOeOknV z4$>v0(J8@KfHz7S06g`+(`A1%x5o+iKbwu~zNzQvoPtGrQdRU74i(h-@;Hb#cbO+K zNlJ?Dr)bRIc;K?1r=rT{*3#B=RyuIQ_3P~(;G0nWOqB6231M$+yPXW(Y`ID?Vc_`9 zKRXZp4dy6A5pyqg5iayhfH<5NJ?Y0`ki{2J2EuQIzoj2aW55rOC=jtcLl&&;&DyOx zpf4M@0|YLPJLR?TVjvPjZw1(Ai08eLMrf1-M+U&8LY}5Ow~*vsbD}#mIe|<pAR2)6 z7}E{$)1=ea`7S~aX6OasqY|YrzCFkQtwLCutYc-V!*R<9NNaQ2RE4$rX}?oo9IOA% z&wV_ntjIX;t37?bf;L7^fQBt2+%Mp6VY;woMnAbc|1fB+^T#9*&|UsW4rP;!*`92e zt)_b!2ohlO4}5}8K%Lo0U+b<E3N21gi-Ir_7VpKj*T$h0OwtBBzMX%O0r>)T^sx%D z6+S5)q+5K#?DX)*q^{<^*xdJ(6y!@@4<1MDq^%OMdb7`fHYF@r18tCq!)te~l$}vW zi>Td6j#~Hm2fDC=E=#r9o&+9s)7vb<yBaj5wKaJdpg7d;DyUOf4c&M7C4@`Iq+>+x zqM6JmlV@jfo`u0rSbKaRxTG>u)eKJaVe$#dxwiyQWap*!cm27<A1FR)#$0T9VH>?L z>ZMJG>u4!W7N}O{9WIFnbnBJ}V<2dD<qj|coBuix=Y-{x>p%4n{wys}RgQPfuLE)~ z^{}sksq`8Ffuqel5Eiio{aHckSJcDIFC8yIn7mF;?xEz~(DXg9iE4bcf9{6BU)6l= zf_5X!Z{vQBTlBr!`8+gbJ-TBbx%2h_iocMosmiCy9hOJm3BH%PO?U!kB#AZfczz$4 zrst2D`4!VYCKDkSvF!Hf+Dn53%_$JwQ@&mP0tA}dHCR3?PW!4e;|E}=5hY65c;J-T zjp!5WW@I_vB1(f}N!95?e-`ciPzd`md0|G;;eJ$7<-GaJt>)ENYvo!x_{S@-mZq?# z7|Cq_7&2VI;^oihDe0hm`?v0Oc5U2&RqrgazW1JX>C6SmyK=>*_1_Upu&=hB8(kS0 zG*PBGG{l}LS372U<>bu)!H9<SzP0rAF7`AgrZ`NedJ4X0ZP+qeHu0g;tjX3vkBF4} z+@{9ZFM;9fp(RQNB<_SkD@>3CqIMFOMGD#dUsaAXb-HXUfMRVgrSn|Qral*{e^kf# zGtq!~Cijl2_DS}MUmoHa*D$cfoQe&j5`q&^#FR$-PFQBtTtXN7e_<WlC7LpGe1>=? zjgF&qoJ0<6>XPc!wd$;XIkavKCAUT>F%bJpx4(G?MR#2RA&;yP<xrSo&zGtP2lhFE z&f0+zE6J8mR8#BJS#r!axQeCPy^=4%NkY@l_@@A0(~pK5`ao6x)1-_5SwNzOq?oH6 zx=J)EvJg4+^xt7w@&cV|QvMot5LfAgEo-IV32c1(@WqekA9aESlRplnOX{XvpqSv7 z@EQjFNB0d%Ut}0;eEU3|ri~cw3X@=9usZ+MXlK>(B}rkFv>H3j#e-x<U#-et`3MWY z`B>#{H9k}tH$rd)VlEo!AA#IzSE08rmATZSye#8Gva}-EE_cGZMRlRK!+qqf)Q+<N zIM7Qh5uBV;Ulu~DK2Ns31j)Gtvx@A1HAT2ttT?#enh#uFHXP3InlZ||#Fk~Nichbp z4dlyTV1;FU16U)i-}(|wTS{u+x=__85jmAHTH_b{`SN^~w>zk<W~xlnU0**Ls^4x% zn+2i=oE1XA#7@%|N9eNm0rgR@jfc!FgF)!D-`OkZmjvZ|!#&f3_k%Qnhm~1(Tyr;u zv{S`BkoH({Jw@M67O!}JG==y}eqN%nKKsDEBvlP-!%Mtjj-p0F{eO#k*|f=2YkKNZ zWIC)hR4?iGi6v30b+mmpOx%G0qvgVM2O_(KQW|EkP1o6ZNKQAqZcr)E;mY++)NZ{f zv#T)qa4M*IX$G8>^-FBqAI|)pK~WX<tU#*oHYg2jKbizM{ba{)+_)W}(h&<do5JvS zh*uPpM-U2-F_GJvh!AQ^Z&vMthA=r(k7a#qS56dfq+RLtm-KcP7he4&B4mVP?E><G znW|B#mo5VP4=4wM<?m|k4-6@AtaX<%G}mMXcrauaZwp}IJ)6MW2i3Hfu^m4ohqK(T zh~v*oHv`@tSl|ir7|_Tn49k||LW#^%)z&W)uY^9*Yn&raBAxtm{Mo)*wuZ9^k49(& zu83qk#wT5$e5WbDKfX-;yu%3Xw)9Tx^l(vt%<j<`@t9weY~1S@n@qRO6!K;a%CYt! z@s<EoY~eGRdqf=8<F5!c`Gy69oj_k6bA`p)Wp&d*u{+2}ysel`^Nu;$%dM+)2dz-) za8qD`es_yjtJDuHENn7dB&-1|6QjKh%?a4+ejWsTzlI~lXP@_EX%Q_ev&O@Q@8J;p zi)~Keb3GX;5C11^y(i|*fX5QI>%5g`3$UOu$O}%TU1yMTcgx{GOBsJQeQ#Rt`B)}i z)w_r0T|UO-*efF15BycnunL{&vz?~n&k-ZT*6I<L`xG-+n$uorzyCt!J~jcC$&>&J z#%F4Vl9lg3xmEe@HMyG^1T14=C_WK|KUCZj*2<>U+T{!{c(o&jU{niiYCppzHJc!} z>1RG3No6!Lk$)*;>Bk@=1V5)<4hio4?R>S)8T9ZxEtE>O_LuB_=-7ReIVM6sD%}in z*yC3A&AbS^XqYB1!U|Got-kltQ2GV58JQ=Th)~F^AvpqWKYYN%LH<-H#gh@{DQ*O# zq5c5MfI5xZ+kqo7V!um$g6@sQtTr%7eGINS*36`!)4N2GC=U@E(l^amF$Ub>s`-$# z{ngm+<$lf`aZc~E!#BAyHwu;Sxibqk#3ZXVJ65bccG~^0dQzKs)x{DDHV^mL{wQ(1 zlVvu{cuFEU!EP4ifcOb*W*z7NCe=|^gO)z#!u)jA;m6AADSkl)UHml{z-XtE|0EH> z)yvHEF|F$$MitG?PluCYCvINMJ$#_}TDfY1AG>suOUoJgoulXNu}ZD80b#uH<;-*e zaiP<M{88;-LX-*1HT9$=l{H+m^8z*hFvsvy83`BK>i_+v8mKH_akCyHgw(o`pOk`2 zcHIP1TWa8B$-bkU=v}R9#A}At;<AuCuu3mUgvDb=bmWVeZj9Tm!<sH|rwvMVan&^B z-&v#!U3Dm8u0vc~sUM)v7E1Ud`jFn!El)MArL#-?U)Ca%kJ^<Yk7T-I=;$ZInFxl7 z3%A*WH$3935u<CgIpgBpEz$djvxl2acT8sa!Y{X$IpN1DfvzhWVxD{y&Lq=oaKt|F zXykPfPDl)P61RPlfz2WFcTwCjwyTIh`I<9FiZVgwss58iQR#B#eNgcE)XyeGXr_<| z4O~!k6bP8Qenw=5-vP5~eyUC{X@b+HS;r0#3GaLTooQQ7C&!u+|06D|^e@*`ukK4P zh&m`TLeVWzGLQHr`!Nb?&F8rS`ElBI)VkZ?3*kifdy+tMjoTi}IV*GB%4pY|RQ2Is z=B26qQLWbiQ&CH}Td6%-oCKPwtm>(jGcFhCP7Kd$x&*d%-7*F6D!kZR`q3%ucop8$ zqHW&$*J&9c)}jGGGQ|s{QDh8t6pbGu7XJMC=V&;T7oftLQUDeHnB7jbw$eg>E7bC} z5)<OBe992JYVuwogd*cb@~>~!oZ&f8ce*4&!G(+osgaO|VQl7aA@FO6(wYgc|5B&J z$a0|JOUB7W^B-h>X%JMLKimYTeb{@{q42+Oi-RSQ^3;IRMTpX#kodQC-e34pLIAPu z8<xktpprfrCoYs=I5}V`5zT0;4puCa0zLsZAt6~#2Jj`~^M(h!6*)OA@un<9M@!VY zfJ)fa5T}#!>)6Yd4mypS(3Y67su9lu6eEx0!t&cJmEZ2K+0l6$xZt1u&cuaw`33<8 zksegKbwlzdCcP0NED-%eBx;hdOVKa}vy^i`|D40T)?fuWnnF&k=Lyvgb<`UKt1x+& zCHK3tf?ED}b$9zj^WEF>fhOmkTPv`~YL;h(5duw|V{ZVN9wXQ9FDPcVAMNcC(Oa+$ zE*7ubiW=Z}5v1VIS9rhrf74GUVng4SxAXc~EKt*u@K>OS)ihoRN(xbVQp`N=WXaI+ zZnf2dc#)fNMexA_L&f5xEN(T9v=OT;AJvpyxmS?Ro!u6L-;G}s-hyl{BiAA5yhj}R zw33RMw8q|+Tv*2r)oG8H^ekdxL!TeO)FR~$UGoS#!N;oxH6<97IJ%j?dXa$`bwkRX z^i!Wm&Qb=WSPlM?DZWNjN!HyS)RsL96(#0Aci8<wLTA%|3_%IKphb+5-QXmgy{KU~ zcfOTmAjQXzMrL8C^8;J#kNW&M&|L)to(s7IKZpyp$bEjlE^j2(ua_7|%&Mx&cjA?} z4JLE@gOW(VQVfvQoDuexT6Nds7$tGn7)olp_5yj_02FP9eWcK{kmBf#j77m_a!rS^ zceMm>5$%3FMl}1KFPh0r70E=#q8J$>sdbmLa-7!8WImerV9O((*AJ?^=-6J63=0B? zfYJ^#!|4C#1+Y`J_6}daSrFU*v&Zr-L{05L+5Wir>A1sa{=-B@MZ&kB74Cf=7p-EQ zTlr@*yAe@ZldyNU$#MR6ul(9AM~?`q@7a)b{SesyuzLP|xvgIu6MK1J?j(Rwco>QC z4qTs5lp)4~AfK4ajloNI*Q(+J=Gexfd^szKJyJDCv`OhZPO#CpHju<lB+AN$ui_S; z(!h2g8P=?>hV8fu<97>khmHQ{%@jA5<dd2H8xU({Xuz!HT-pmZLbvLpe7C_@qPn@P z6<kH`lo`}I70cg#nVPzQ%(MjGuKR4Rj7N3dckZn+`}F#`Y?{s8vI;XF@u@a66?+Xp zIU!=Zw#b2!cFJq9oh&x2^bi#kk{@b)f$}kiVEu*H&w9--D-d^0o-2<#lc|<C6&82# zU->Wdm~)@*w`i@VNZpmYYd6LpLI#gn{G`-27BF^RCz(+cF3F6%O{#j@+Iptvkw6p> z=k!Ik;mz2nwyk;m-I0^#ofCohL1IN!;m>A&^ZxqR17OBqJ?6`xJC%jzQVAPOvxH_( z4qZzS$T4QVj^s0*)ryFcTS0sXI5N-Ju3qT@>d`}s2}TZineVR*bH!P1tXJN7HvzMN z(CEqz-LxDjc(sr_Z-qX&9CR;bM`xx?I*Vi6Sm22r;$bu$?=f(V=l?d3QtO#tLa)e+ z@`4%UL*xDmrl$=8F;#yG>e8N})}aZ5^`(O}%FqnU^B_hm0TE$3La9KqxLZ=c^}y=0 z-m&J@pZFOb+<okF5HMqxT)1aul{PTN`KS`!5Ti<q6IqKlz3w>nT>$xlu(G36pTdIn zIy;bNl&5G-L<$!%Lx_7`9RK|FbJu=;0#jvh=1-VH#Wnxq1G8P5*q-uk@;qD42epKd za;o7jx24B%C>CMtTU5uB^1N-|d;9BX7=r0Yb}*WGtmSRo-*DRo8hGniqod<`{0u$h zAnFLJQ6T}R6jq$%M8{m-ojVUJ>Gz+XB*xxNGD)>n0(5@kf>pC#);0E*#N3k9CH6od z^TIp$mhSSukjQfrgy^Mms!Cl<zrgU9-B(lUKE#lO=3rFp?>_aGkIu_+=2xd<aS>_| z^v0+eKdqRe8lOKc79-VbUyK{&Nk4H1qKcDvM*So#$FEG(dfQ~?_a&+PTf<n67g<?e z0PvfXd;D2ptVTRCQINSsEgG|_bh5ZlzIeARqH@-E4B4_nidd0`{4V?{A@XMI6*<9E z8E6SvGkvbbIP5%i>f65XCxVE;0p!yPQpikgK@2rePMn0r%y9EYFb1q_459@B3%~Vj zt^X!kIeG!Bs|leoSn>!g?<wJ~2fyt*g$9uW-i9AMWCuUOg6KzE>|W9hhMJd3Ojy!G ztiMV(aGBPax-dowy@7Li6G0*+Mp8_0OI}(g7clm|Q9+f-_!(2F_NgFm3I~Ex3BWJf z9!py+Icri<5cZgehoK(QiQQCu;NTKFh?qc*I8f`lTG04JI7Bc)Udq*%m5R!%iqk>S zw681V1y(b<3>CDX(Le0J6Biy6vt`C?EvV9IrPr!$<8u1he26J<DEpF>RSto08p%Lo zPA#)<bwY{{-uTr%QS*a5+cvxoivV?PPJ8{6Gy(v_zM=G`_aM6w=_|UwYaBdSL!$IK z;QnuMXE&I`+?|?TQgIB4UG*DtWrCE5hPe$Y`ID}n^d4;@)Y~cP44-gWW%R!*zipCU z6qniauq*|WD!%3{z`QZ1?|?IhU85i!Tlj}<M7W#O|G0L$PayMeC>?b2_SW+sefOhe zY}<TY5^b9;qBay}imRtz7(DzQPX3aWKm4uCR;vFPGlzcOqZRIYTCtBc9rcX^@1plc zD{gPMIJ8txNN&BWUG;0PbvSdioISj&og$tfOKgW$LZYJIqhKZryiV-sE`Q$Fq8_x0 zGE*|0;^^??3!ix^>@A-GhD2thO#~{I2}_OTFMi@HHXJ55!+eV|Lb_Xffs+ibn&Qg0 zeWFSGl9jYW_H->LAV9<%Ou@5)qX+-yr~>?U$kOa?6g?jOB`C>W6<yOSUGzE=FLI*S zC(99R`qaYa3BNDqlD>@?1(jkC)lDc`(srq)injQp1k693Ao$NJbFmC$w$-`C1`$hY zIn^}n-`l^;^ss27E=)qg%av9PXZkgUHm501KJ2o8pPJAoy!5Q8G17^PS}4>B6|Yr+ zVyL^x6&{aiA=P+U_0fC|J8Q+-)9%vyhc83<b`Yk~h+%ZCK!=m_$9sK<ycMb2Q(FN8 ziSs2cd2S3OY(U}q`(xDNiv}$zp&+HyeE-&S01XN3E@Apr<Wk$<tF7k*%_tVQq&Vdf z!Kzk;S-|pd#j+Uj402-blokjNP8lT*A6Oyg_MujFU0~83Zzr}Zm5@E(f%+_Cje86p z;#=pqDTg_5?&t{7MT9tzhFPil#*i%jNHlBA8#xW66*?j>#MVzoH7t+D<`xg=U<pgR z!iERGEaScmLIS}(IZ>D%`~2Tmdtd{2_~}{c#~;l2Vu$&?xk@x4e&QE5&Ytm9NQu<! z(UVi?A{ioO7CDgZhmiB#Q^ui3-iMf=tBSf;>_4eUm1^zcYvnN{h3(3C>M<%OO6rU9 z<I`RuvL{5)rw#Op6rtIh&%RnPp}Y2i>jVqBU6UQL(vl;uBCiiYowqpE86gvNrtUfn z`VN6gjD!`(G3`R>7Y}_`ri_*Qh`Hq}>Lk&q?EdGThcb;BX@s?9%;$5~)-UuT2<q7> zGOT{SkiwfZSWD$NcilF`#ap^41rm7}ym}}*8Lqbx#w!;?)a9&c_S3P``-N9uT?H2o zs348L7wF{EcW<mD3iMjrHDC6|dUG%}SysJwr(&)F3f`mGur_tpSQ~e`{FQna%>jp7 zy2;&s13k$0wIxI7T%Pn^j<LAyvg3(<`qybqFBezOZ~{6PSEq+0c3pYm7t87=Q|ohq zVP-Q6?)WY*JpQ@_O(rJQ>Io-Y2M$-<^D47$<}){mrc7i38Fts)K=F%+HbXy)AMMAX z8fn_X?Yh;X^G6<c-o-${vUEX8|5c5|b1Bq8^C5H}%Yg})b|N(uxgUTUiN=0^Q=LO8 zQE=;RAYZT9QMNu5w0yK{Uw5LV#t;Pi76o#LXAU=RbA=YWQL%!UhZ<`czd`ZT2s+9z zGNFgdKZPQ&){2!rBP;tqoLJRB(v!Eari)A*+a=st+$G8$@xc*~S{dyo==623?q>dF ze;yM``%$PzaR6YiJ(auu2-$=4ddvmCETC+yUkl+3+y}7&4mFY%9WmV!stb|cB>;v* z&UU!zwK`trg?Y7ylnZDGzkdsBqWSYl>$y}B{oz9E4YQJNVqQ31MT~>$n&3BP?`j|e zTJDPf?P$$y<wHlU?*!=;0GZ1%nyQ2Dt_EfaCBu)6me!bEB90cszuLy3T0*|AX_U3c zg+#{R#oTn8Sy*hM_IL3CJ|iP|^`T&N1&xmZJvBv2rHWd}CVLV^8BIRut6FX>kLGQA zmbnA2BQ@LKUY3d`{-v=~4%&u|cX2ZWO1nQVWSX0s+)F?iC{FTa{r20V1mDN1dFr#s zP<+?T=CyBB%E;>z4H+(N<K$32M!(f{Pt|{X_WE<Vv%gmpPv_kVUNPRwK$Vy^`np!> z`O|yE5G|1t!ci2qE~aVSqo*=oUT3p}+M-Z44YvLnwJHyDd;h|IK6IQ0jms*Jx=5h) zddHdN5BLbC*9s(DCJ=n{zVgULo9Ew?725pWUfm`q>_6LFN)ZM&Q<r59@;})r(&^jx z*~6}}__jtl=5h5Xb<w{B)%g}Efq6N}%6)-ewrA~?2t|z9Ov~C4t1H^A<#jF0Mp8mz zDQxXFdzOi<5A$PDSGp<k+Od8Wql%tA(4jp3K;7q=Ew<v%eJ6{@d1dJy|NJ-uF5SGs zxpDiO_tb$^`-2%2V_*zy_D;1LL9=ZdSP<5wSZh%o)f<WenL1hSE!wreuDxu2Z42Ms zbDW!J3{4kJ<x_m%e=>DVDdQdtC^DccIO&sp><X2=k6KtT!_8r?S+_*~ff%h40-|MF z+Dsw0PiaMZp7q&!+xpjG(fC8Qv*8J|5T5BHN*7wKXVS|+Ccd6yph42X9(iO?KT_Oe zSo7=E4p`S~KMpn@A-1|NB-+~VrTFAX@a^)o(46xhH4!m7E>`<>gKuFkcptrtVX<mC zTaYavonCv?gmGsdNufCRlic>vl7JagPakj2s6hvP2nmtK^GRN=CKkVXxs_=3hkoYp z{_ON~zvCHS^kZP6U<lt*@jYEoMF{3x-!1&F)q!!*m-VMF-$Dg+Z05CD-#;vfYYxZ< z4F_oIgfW$0A0wQs<?nN*GCz08Yn!Co%RG;~_ma)`hvaZX;Ja$K_`9xDbZ!1qL{m2* zkyWm=s`C=ihNgpW-#!+88AdkmNJ(xFv%tD;HUy*UR_D+Rsw-f>@`-e#a8(JC8dgd7 zl^pz_Jx3tz5**?@<Ha(6Ci_J3wdZ@4RP^TLw2#V|nHFmWQHji`L(<%}v>%%3bIaA0 zO6SLZ{KMsO4NughA$k`)|GEW(>2?eDOOR6hucrCFy-V+oG{(#bK41{|eE|DW5aUF{ z_sDfXa#e$|1<BEo9lR$!?azfqs`#+Gd)aJAhPiObWs>Gll2|)PQAG%%paVg?wwRq6 z!0>f{tU|tu(qV>G{{2B4>MUkDwnn`{zeTKTfguqWVW2AC4%qgy7B%ouaqOm+I}gG1 zd1bV$FGurc1zq02HthXL;znm1tA}Dsinmp<?Al$>rhesn{=Ib2_9gF52$^q(f_4UD zQ<`Yc*4cRDq2g`%WX>0}M`j{gJ-WOvmHs$L2-`-W211)I5ZvT8aj1tLsLnyTvyDHO z<L2kOFX|oN)RK=mQcy>FJ|;po2s3T!-bK&oX3rK8BU!<2pc?IyAo23QY4HX-f(y3O zOPdp|sT3pB4Uy^!g~BLKY6r_yUR<6JUN!JOdjC|&`|7zV^7~I}vjL<X@Uooit?@i2 zSG8@XmdeR!Oc#{>%VITp$iBE(Jk$z6=K1})?KE|$qe5PHLQ^0#Y-vP3?^)d{!%5pj zy|c4sX&2LMLRiD<SCPJg*-4rAD}K6zH{`y1O?(fS8t~rg0nGa0lg7g%xG{+xX&N}( zS7X+VssFbU0d@H%KMsf(BSMCqVL(j*g<RPN4r}p+Jy(aA%c%<belRI|T|}SfeLC6F z&gL!}o_Ls9k$5uy`^SA}ae)jvh_r37w$EU9(8Jh=&c8@yckRXXR4Ho&$ib-dPqoSO zvoI~Gj1(979q@IL?BGg*cNy!5cStFVYt@B5T(gu5Q)D@}hVL<6n77v48m2V^BhPYL zkGu0u2M>kae_A5Ef`|U6T0z0+XL7nbqesHMC{K*AZ@V`Ch#u)VQFSSQk$)8r5~r(# zQ`-fI)lgppccw-%Nyvn+9$a^OeU4IthR(~_J`<S@mOS^Z^`3Q8AWPd;6PZ_Le7LQ7 zG<pAP73EB-3y)o+o6G&dU!=8%k#-TEaP~3I+w~Y6CijLZw7FemtHW(qYmeE<P?1qh zW1DvdRQYfN66`)sE1-@;a0)M<m?9qAS!Ko#mP_IPe<|{UT!|l1rLvR3v;$U;s)Np| zu?QNi<n$f}&YO}rUb^{swjj=+_o5$4{uWZmz0;3#Zg<=5c^)k*Ez4Fh*-g@nx-&nx z#4C$sRPDOgDw~s*M;``q)Vz+xFp+1}6dKH#B*RRDJ5I7=99u#-<|7^mIcJ_%2@r08 zx!h{`Y^HyGg#fQj`Hx0<@SjEkNGlF&_8059Zt0>w*&Rb~hTj;54`tw&-1xN5R!)yt znd<jF1BJTxeGj)UgiJbbKTE#x^F17;G}Vt>)lrhTQ;`%TU{-O~Rj>;7N+y>`QL4bM z4@ZmBJYOA;+PPY&xyD?sLrg0qf(X(cyRWg!3=(ELoQhlf+{^Tca$cNSadL@ta_v<= z(Y}j**S0?}oD+rmE(k~hU!QzAQ|jb5crnWxg#EEw6#m4G!)sFhXTZBKwU|P7c9`_$ z-DB~fJ#lLlI3ZufJNBB)_4jHT2UnKIkv|~Xf^Ty~n1erwKc-hqvaQZ5Z!dOoyzr#| zu(h0u5FJ(+SGY6@`)UUFXpVlnb%~I0(PW5OnOBt$%pTl=Y^26c?NbJ1%+JmIAkXWM zx&`3DN#)Wj`x;OXv;e)$<(_6h1&82GFi4ggJ^CH#ppv%pJH{(+{@>5Z`s>5T*A*>9 z{LY9kXD}D0lR;M(y*IyfUE@H!^|_~ZbDHWS`>l()ntYjH#Ert6!nCBcKdXEOFTCZ- zlv<9(nnm7(MLNsSQT*YP2kU5rJPS@&(pviP+5X;;P>;GJmD7^cc{dqZI&@3Zlw<Zh z@1+n!X9glbXI9=|I&~gg?3F98?Cp%e$6xwH?QBr|p!?&G`*@Ac?fZrdZXfYeI^PV0 zv%O}4fCII~*9Z4h@4c+*Fb-FxN5ao>wog0M2ww^pkiLYPgb6Ze4<OwEW9ZSs*;^1{ zPw3GW{PQpI$&3{Q4HWn;3}WYiZfs;?on2jEj%XD84AO~K_Dg}a6<#-xH9b|CmL5zY zRj@JWeX^XCFA#uLzY!tW7s58SaO<>n{q%3CcJ+*>@dTY4ut~eo?C3fjOe(|C_-4^{ zCB-)H>eT$o9&cN4?;<ia_5wUH$*apz^0ex^<OFtC)$Mg`b+|iP6Ro#IbOeA$d#Tc^ z#`L4E_dW<ZcnCARt<h}Wquw0mSE<|2U27%znfD7@%`ZrcJy-LI#$Mo3b$HzB68sW} z4$i_TXl4213QfFb(gDThlu)5;coa6TNGZiwemR;immqg_GMH~)QfuRCoNDG8@8V}S z>(a@BJ!-xR7~&KBd$8rcHF8I8V1ZJ+8Ow^BCfzu}w<2TRvd&Bj>)jvLj%h@D;@(`_ z|MnM93n#@+iLy2r-@nB;iWHron@Z0EN8VLZV)YG8^>?Jf9oesEcR<#MP4|FvBQxM| zqTBsWwKH{RxR*%aR$-d2<k>&1^Y~_7J0|!C)j8@_GdQsCc=99Y>MTg@YUk+6e2X3T z=6h7@IiI(#YLUgL$mG!Ul%A=IMJ8TtC8Lh|GO+WX%q;I=yzQ@xoiKR~frcGLyW<?4 zC_=NvSy2c28%TLuKO*0ztd8bJ!g_y8w2F5&0ml=$m&&t(NCG&q{KD;yh@IjG>wUFb zD^b#iHC2}l2Uy^|^CauIjq78k^C!18HhP$ZAnY;-2+`4)%fsrpiiN=XJ)mteR?Bu0 z9|PCNvR4c%e20qWu5)x+)BiCp?iUB8K^gSXdLAEa^E2n?jXFVAW5m#@`DJeqHwz7$ ze;Hqp_N3nv?5N=1?T<e`5f`{^H~~AyKe|`vTVBoTHs0rRMDqXLYq$q{RGLp3(&YMm zJB~&S5-;(jVow$Yhc!A0aM8JJ!^|GJ6>J{NG7`;cH5<Ud=P?(fFf9gg^pSGoH}@ox zh|OOR?+=ojN#i)Gy54xq;_<0&_x+xL+G^n8wD8pD4{x|q028mRp3h=5Y?O{Llv4Bj zgQ1S{jn+8wh>`%2Z<$!mPPN@rll=AP4Rh~Fd;F}3MfT}nrOr|z@^nDC@L!8<8UE{h zuJ*@yg%7_&Yp3RC`aZZgUzOLUl-YR%WI0JsS_j5oT1bfY1lpq|$$|Z9+6XWc8U_|L zaWUe7;n+|7i~)o<QYZ*p;bAO^Q4$N`99(LD*(<tS*wYtQPXX@D@8W8+^U+U0@r&0* z&0>@~-r6B9GYAd|gHf7_#Bz|iK*Ds0DuHRtZAthmkBDdqXf8#EGlIoVnPOE#YdQ$@ zDGcL9NJ|J-_q7!cUbwSRZvT4S{DRqe$tr$_c}i612I3^>u(hk1d>Ix}!26v=0cSm` z7rdUse4nQ$8Rrjr{qqKax&Yf2ot12`)mYKBuAd0#F~i~)`aRefRaT>QA}LkVf5PsU zuBYC|tUn*wW+7sBepD#lFxFpNDyMVRYML=fN#Wvc&Vpto^G9J&G#J$|){G_my*gxH z4&0QnAVMU|Ap%{xqeOVp#bpGXCA=6K4Q%biyPkS^y6sDWhRTt`{LEA>DJ(knk9)M| zJwXz(`VcYmEkFeQukAPg9YBA9KN`1k9|QHG=oY*|Ihb{+|6&z4Itw;Y0R|tDh5T#L zp;H$rQZPc*CVSbduFTAHkpYRE^Sm)ZtC-es>tvE`V8X=Tb`JU<o|J<0jipx+t5T9V zVMs|BzQhu-dn;ttGIuLUqKleqDdAo3+a=X7$EZv}@y}mI-s->zr{}K~2_|<f97Fq- z{MVG&9)ud~)oS4yIzzOG%LM5Ywz?_F_SYZ$>-O#~HtlLJ=yGs>k?pD`zSi;&OI(!H zX@PFy8qJ9()l9r;SjFwOCz4McGjhn3XT~4@DImtCirM$v9M8K`B#_|dah-RRG%z9z zs+M}DEpw^tyU@+`Bx7OXjn84Q(_3lDd1l|PY;4V9G*3i&Aray+A@3+91-x)<F2BhS z+`W5=4*|>eTxxA?uF-J|C=Tu`-`@Srui{Ib#7Z%y!!<OIM=qcf?+D~~H&)j2TWLc3 z2jsS0t(IuHJIno4&3wEw&kGUmnVib{mN0x>1sz{kCnW)ORegRUVHOYKp1H8bvE8vG zdA%Rw8s>aOe0l2rNHvP{=;iei8JSjj2oI7G`hIuw4_?C%&eqC>3}N`lT}l!>(2{c{ zdy<w5^l9HTuI)F{1s58o-!zaEg-b{TI@1u1xgchd_w-szfW*;iREVqy=Ncvt3js_+ zop4CM+V>ce`NyQbuyM`Br|16l9{s<^&^#p#pON&$a>KR31&@`=3k^rQC<)3&&VDy@ z2&NI!OP&p0oyg~dkEW4|%DVd~=s)i4evCYkN6%Lr&GPeFUDkM!qf-yO!Xmxx3V04_ z0TxvYg3zfRl6I$M^T?=7VQ&)3&vBZN%`tOnj?-g1lY#6UvOI8TAY~e(;MAVEoh2~s z+RK;QD0uO($y!_wohB0dzyv$-HSFYro`fqi>~S=(Lei~19Wbo_8ErO`?$!OYQ>^ts zYc!#jw(~I^5|mv(Ira6c$niVRwOrp#qyM-8S+OogpD;p+D@?KYbIamvn^(w4h7ZQi zh_N8m>sgbmiW&p!kau;GaDX}CdmTxP_{Bulg;B+)Xl|o@=0r<>KGRrLE;p3djE7+z z&_VWcFg6+8Yz1mKdhUH*f<FrK&u_3UP>;0?GvOhwJba@OHddV<OMAW~tLGGBoqYEF zqfqCs*oRg_!4A#2`Sx}l65psIT5o^H*8DO$CR3dMKso^nE&^9F#%n&evQMI~cI9b> ztwXQ9N4u#S#a{VQqXOOUby9nfE5-&qIX+LgVf_`q>zh_Pnw}62FDU;VD;1!Bu3Rkn zCEsjrZJQBt0a$;7@WvsVK#C)2$z?MxI!W{M7P^ryzl(0(%M4RRkc&6}W?H`&L1Q%C zebi*LfcUEA${`~`TKW61YTa-whCh=uAZGBJYN;ljxvPuOasSuUz~O?z;4%&epKd3( zhIqP7vYQLuJLHp@H3cbnr^7<5$Zcow1>_kT&io3&!f4SfB-(+*bQx&$zhrlYVPEEs zce46@r5bj%3=is3RAYD)bebQO3gq`_H642L;BXpo!V#QxZ||$JkWebQw%d?5hdo}g zG<C#9g>e`%uA}+x8ka0MO_7xFI{gUf*=IO62l%u5qNX@)&X%qGnGqyJ(=w8oUrkh! zOw=l~d`nPxYP7uJ*NS#qy><BGZBs&srMW+C>bpPpQh(dO<M?E9Q6F@)JuH7QBA;Ma zN4q>U@7lg>7%yCHWp_kf-t@WAEi~K~TFNuhBb2{!poibyH>n+TSfRmxMIicYzs7zJ z8Oy8{pX0>;{tL;?ky6QjS+pfkT6GbOI*t0H#@h!DgN#;3%|>z!#e4pr1NFU(Hm7)R z17oA)?~0zjU+kG%;#LM0*!is_!+1->E4hC=|C;dnW0cjiT@CwI-|eC;u^%bY{40hc zhUi$}I$$*w)pEaBa)Ek%6QOZ{u>^;0Re)|N^{vPf3<Y_WQY&a4$>}&TY(CXzC_kG$ zY61<_hpB<T&2Vg|u}U^;2-G_Ed!4mgPl+v|2a+<BA_Yl_5cS=q)+Kx)Kvemwz1EKX zCpWT+xYG&q0Q44vcEDgRm`Kw}zf<D2$vhvgL`*9^6eFf85ZEQN7?b^4U?{ICdt_9E z7jgGIJQ`!wPJA-zwGN7z`&8j6#8>n3=VAMUSLcJ)-+!L?OrCukGfCrbUce1Qa-cR( zZQWh`WqNe&4Z<ttp3*X3)ac;l6_Hd^FP4Ej8Xrq|wt(z!(thDhR>jw_@H>BsiKrrm zJtEQyYlsWE>!oTnCf@v!oF%U<nbC{(Uu44EH;w?6fcyh!WlYqJ;4?!>i39hxpW6j# z(}n_)#}Kql*4oC1<C@wsrdOq|V`9&Jse#S+cJz%MKqcHjsp+>z;r9#bR9{PN1^h*g zyO5fKjxdC9_Tc#}a<&>>(rQ-_bkb{1iwkW_sjv^KgG&%zHzK2gJ)+X}bK*dkGcE~Q zO}u|2(>bFiXxSI&H53tz3VruS(}4Z~yh}pFf?051dW%GLT4TamStOM{CiBh0lvbun zB63!ELt}!xqE8J<bh0#ekC#Xuqa(x|X#;#>=mJLs_G!hJ;xBm;OYiH^F4mfzcDNmw zP}AT0S4ZIdEa+-`<m%M?s^}|k5iizRp<~H(+3qRb@*g8f6h>Y0VYU1f7gvvwxDnWy z@rq3@67ClI1BD^UzpSSZJ-$h#8u2%6?~@mv4(!dO7gqzX3DqQ(x9{&ibfMGg3XO}Z z0<MDD4hnam=*D%b8r7Nmysl_@`Q3<}6X`0JCWwmKZ=bBo{RtnQ^grwMGYd;*Bs^Rj zQPU&}0u@lR3$$D5jw-$>UI%KnOiqK}CqCGa+naHe<x}gDS1Pr3&y^7)5?)ybZ-Z9k z!#C-6D3)}>8jlI#4i2I2p{H@y9;O)4z*T9?WAG+RD>6!v>PfV4iia22Us6<1>B?S` zX~9BO#C#cqvrEesCTymsoo4saE{VBYyE8+H?c`l<v1!TF2!1|Rl}S&7X;SHq^zbU* zg2(?Obq;S6TBEOlF;MANNX)w}+_qa1*U+4>mWchm9X~@HF+lcc;J#x`;dn@ptkREy zx+r2630&wvsDacnTe~Kj@1$?=+3xupPpzhO_mDN-fl{Nsk=i<WWp>=6`NePZ1Zv$% z@;>3?^KV(&NhZGCRz6p);#a@&Q=;<|hrH`fG>#?rRzC-F%TJyU{mj)Ga>>`4|2+Mm zNXMzl$K!<=OifcC*e6x|;@KZGeRek}WcJ_cH*|_$;(Eo=Qj9tLSkCGAnS;M$`8*{x zpGUb37@QhMPTN}jAXE3<N)$f^Uo*moEiMt;{nc7+c6L?v&h|T2neOr`j=HJ%rAb7Z zGu+3PTY7tGsgKWsB&^}FQP0+Z1j1Y|t7a=c$hRjWmk0nCcP;G8p!iQA=7&j0-`#)x z82=x_&N3*jEsD}WaDoR31PBm<y9IY>+=6R>4h{(#91`5!Eog9eOM<(*G!P_chi+Ww z_N$qinX0LpKeyhGR~7o6d(Yix?X|v5JC8)q8%=>*P-d40G!1c(KcrUzEfT(=X&aB< z-F(Mw^Ns>TxwtNW{1ogn=d0ynG69Ce3!_j)MrL-I5N<*%_UAk>%S@^sE@3fyk(7&N zB<cDdSV~RuJf%;67`iqtYLBw0=Kw?XpXg0o9%+g?Qd8bof7hVzy!5yCIrK%*po1k= zH2{V{MfkDs<ymg4+<mr8?twe78%<+2$i;XMGjlFVJbP_k5(r(7pH|r>+ie^#dM^-9 zrsPk#nmvpB%Pc{`Dz(^AXt@3)cd0vS5QYgUa4;t05ecO5`CD=Ldgrj_u^rgw1#MG< zCRk*nj~L@v8FQno=S8yXDZvXD`D&#(%yr@9(n_X7m>Hj`WmBC&gsvCeYSrN~!_F~Z zLM03+{d;KF-QcQVP5KKZ2|QXcApR2h9CDFW_gk)2Ri$^*uV_&!mSpVivo=6eYyK86 z=NVM|&lrPN2SQtPKbN$g{fSC-y-8}k(QZI4{WQeP7~=r?*8cs~|KzkdAQVN1e8b*s zJ<Ma<;Kt>5_W2j+c^)ga{qHQ(uX985&>OQ@W6sp14~1|mH%?BXdqj<i`v%X)<84>T zAT%%Qc%@mQO+!h<wx>2*Fr7w`UT`o{<4rUG;Rd%ee{vkckMNc+)5!7@yOc9VJ-Mfk z{-a-_ZR_MR@B;n<vD@FV3I_ydEadz9f2{yyNm0r4fM5}!e5c68F{RdO_tHm3Oy;g< zSK$?3KK%x2GL}gCYq5k<u@V(0(p}%6cv6cp(cR9jLjK#HFN)DlMzsuaMf=lp5h~JT zF^V0&oIMh$hM|v`e5M+7&Ca8;w2Q#2|EO&`hlw14XmbO%6jj!b0Q`0&p65?^dx74& z2PA-;B5ixQ`DXUJ(`&)Q*Nfj;#S-EL&eAx75*qllS_YaL_ANE(?eVUSfB75^J56-N zf&vz282yvxJ0W9&RhpY7g}v)L(J)h>FC*JALLmTDka(2S6dRo~=IZoCs)78uB{sSK zw+A7Ajs5255pL}4H}T`vPn((S$wDdeX~e1W?=TC|*PREb>CHcH-0m*o-?yvKHj!-t zIQx~PXzZ5GEXZO$j#1%cIDtUMP6yt88{kUYx_;E@G#13g?xFhdoWrP{E$Qo7eS0;O z&(fO;Wn=VLHY=>Yn|83x_Ei)squMyYJ&1=L?Ph9wK!;g%1_0jWZ#*$+>o0(uhcmwg zp`j53leNi$iYr7D-~!T_QH!#VNzS``_{-B7w2+=Gh_6Uq3<~v2{5jWW$X+I1H={lG zqvvr?*KxK0un255m#QJWHOHz+N>Ov-QRX0Au+}uP$Du_CZc+^Qz%i$gP|<PMzdr$5 zL`?4a^@{2j-`jNt$^6hi1HyZZTd-;){)FbfTnB0kNc~1?FnHPsC?EFMzd+zKd9N@^ zsXf_y_#V25uZqB;W~P~cBml+WGs^q3X9yif^51+K846;9i5cJ?inpx+EQFmmPE&uS z$W7K~6nZIQY*j?I7x~7>HC9`U#+#Z@y9u>+#xcv}VnmNJoYV@bV!R0${jEY=sd~gj zo&%Yq2uouT`pVU2XV$(s=h?%|;N&_&@?d}M$?3b(HZG;1GZ8Cp2NMNv1LL7{X^7BE zTE|0v{`+gHD2iXJrv8|=<_e@Qe`6V&06O{Km{U>lt*lku4Hhdtv;D2f<3%1PMt<A- zv2TUT+_WuwmaY@5UMYX-@Xsopuu(=5dRaQ2V4P1pLJ#YyoQuXj<I$M5b9u6I*VQTC zrE*}0B3cOl2N%^yWrIt_SfWVyD$ootrt`~OLNlGty{;1HleX(yLzG{T%gMVlhoL0u zdl}N3Ej<nx&7{jl%vIFjt0&-S8B3fWNrMS|R58BRbaxUEEX`ut@_mh_T=Y&>2RNrQ zGL>n71?k`UtOlJfX4QTc2Zg2ov<BP<;6%P9JK_Sj(7@h4hk7r3m8#~4O-St-N8u|# zGl1?z(1xiM|86icp;at5(?o6$0{xNg5436DvTDGN<mx}XWm7OG`%IUHBg3-&*JuJ5 zJ6Kvt;V?~m7HvI><M`N_ctwjKIAYtD0R8PqZF1$H90=l2<`Qh0*ppH{{jyH`I=1si z0-u=`%LnQYlauTgQXC_YJdP3iqA0iHS9S0$Z#z09b^6GFJHdb~r`EGjm`S6K8E4zh zj2j@nsxD}bdzP5u6dFjh)^su{oXUB{v|AkB&ECYs5AfYxd+=CcndRh*znVLV2<BTU z{9*P1Rm65@b9)Tpidi;E8=Y#jsot??D#%DxB=u^Vd36k5n6qJyPMzu~_fnTinS+ei zrG1!Uz6)rPg}9~gQX<apls^`@_DN8DSZL?p*?l3TtYG)wCeCAuqBKZ^biHQIA?iJ> zP@wj*%20|#l7B`myKwjXT};ow;sXK@e{5piv<`@2<wKa#3yKrKK#<Yj)WFOM?-gJK zD>qW7%pe!j5GK((Oj<ucE&dNXbh#q4L8rF;dz0K~jV>tKXeq(IXz{Te^AZ>~q<daq zB#2=d_Hd2T@w4oP`UVd+EOI`@{}N6=GSZUZ|J@Sa)e7_{TV{bNhZ@2tZs@^;N9#Z1 z);|3%59XU9KWihHUU;#d{k+xM1Ey)J!yh+P>PbDCm%ewxluDC4iLnFtnGK8hh^OT& zOCo$cAinPx@sN#F9uSAq5fmX^FMig(+$2npgqmNzKUc^?%km!)*!iO|4d1BNoZmz6 z;z<T@FW!h<Z+_d=DE%~ITNY*&o6|Gej}&kzD_w39+0L)4muJ|bRQki{mvsUw&fPE$ z0HeBpV{nXqlG@TzWS#3*5^bIpK}Tb=Uqt9-^-kp7Rg)2EsR$4?R4xtQuX3T;Y0T=> z1fV7VwF4Ru3D|}Z2VBpM*FbeSgQQFUL(t$^JAmHp1I?zxXVWj~B99iTSmoCNA5Dg_ z!n0RUEI|r?9{w>3rwaM*&a>Udv)!2QN{hU7c28P;hk*9SN>AmT@y$3QtTs#vbW&km zMEpVC|0VnO6d%tJJ?nFdTW$&}?ysx%9|{rKNx%C)G@SIa!q4c&NH4c}O}DYgVe1MU zF{#%a=Lr4i%(DiNH0<YejVoJO9XI6zK14n{?u&zW5Y0G+PfUo}Zu(49?S9iN6cCmm zZ&-!>xHPgoT4<R`)a%YlJ!uLs^!TYTv)#407gwPN#?B-Y9C7tzbP<^PkT~f6QQ;RF zb@@FzL_s0lkJ~TFZ--E!L}u}o;fQn%6H7qPbw8)lLm(T=pOK_S8G+Ux#NHwEN8-OL zqANHHEyoPJ;&^B-%xY@e*CE7MWzC@V@^AAFG`4gPO)n2cZJSQMt!ZXH$x;2#*2p=Q zB=4FXExQVMgy*Hb<Pj#AE1OnSG~EfoR2HvW`8NpU3+v}60Py&Gx5&G$otSNZ;G-(p zHj>Vc=!LOc*|);cgT!Lu?SfzOQ%K`7^(t9X_4NKcoY%+&LVU#^x{m8d69;r!DJ<kO zJ^Ak^`j;kR>g?;uwLZrLf;;jnd`@rnN8TPIMEKEg<QX!+L5BG{TKaR=L9z)e((1=e zAW&w@jVV)yx$1lt{jRU+9Sle2P4{s0RcWp|0EU5y{ixDmW0JFmhNm6HlU;i~0l-xb zNXpH}3xu)>D+v|3@Fe!3mwo=(g<O4S3c~xH(+kLq%YEkS@!TP7q4JVjSCO0DX1H<A zjqC8c6FG=crJOApuPGtn^yfe6f=Jos@t2l>E7Vn@bSo8C$#!EijQu@!%7TOrW;VJ` z{!Yt&%vIF1{*kuhv-`f=lj#|()4Mh;3R>qlSnvm1DjJZ}n)JvYHpr;E3bMU9h1;Z^ zds5b=)^b50KYxp9K^$G%LX^QWch=*gfE|pRUT6B$Q?Ht=Ss^<d-jl=$En5c1qV+kq zh}z@0s_rMa#1p(8Hx{yy@&62GT=Gemf1dm2GW}Y_Ubgq=4Cu<G<Xyk1zjt8>C2pPl z)BS!yP|KPa`ighz{b@|Mrz*V3hCoImj&Fvs(*w6>zaLx@d>%^a1VVUtXT`ka4C!+T zY3g77cCy&Z?799#s4nc`I<4$K&cFBu^38=%EqMO7P1>)UK4SG3ugE0<GP4<XVEgbV zb#lA|7S)#<Zdoj>=NAqPMO_*>r+%}xa1_2jZN58%sy-3Tm&EHN6PH)8ud+9grI|G; z^OXIF&coAYvf1m^9u*^jjZ}f2YloGq2hW*n*!}6_U~x)VUY71FZzUxksvN9?a+t}% z_C57Cp12@ur7SYx%pq;R!L&UyFUSm=tHMNq*Cu~ev~-*DJ#_%djTjwEo~vf}AI~*s zPkGQh{^9p)YLQ&xZcBZR!<V;hdj)EjS>0zo1Q|f_GtWU=M0y|sBr04fl=pS1a9cih zpmq#B3$m2(`qhA0<}n<3CULhsspS1d5GEZ=d9d$*T_=`%5}+(WU-B@5^Y9UF3{><5 zM!mWJN5lAMt~@9V&8A|j=Z)VMPTSU#tkbn8p1WPRa&OP<U&{B?(&dbXy-!Jb_eFfy zQc9~KRa<$?v_Med?kOX&zZJ87L2W_hfk2COmq&%|{fmLo_s75UUIDOLQqdbA(<!Pw zZ30PhN{ROfu|XGfJg|^^-$%#!7!v={VudH!y>bVZ2sb!A9BOe<m|D8C^<CXNe=Jd$ z>EL{N?dWsDXlrpqX?xQwYSGRYm&q>ihFyGfu5s~uX-Nu3UV7?rlK}BF*mkfFrXsFw z*v<qkGtk`_?-_uf!x}{$M{#I(KmWR)WU`Bj-W@$G36cZ?F|qx*-5*I%Z_?$t;D^&< zIq`Od1wi_z1uv6;8~9#m(I^-Z0xxHc2@hSn|HG{tkOM5K0ipxo0VRea?S%3kRuo<Y z^C4qP7h)*+pYmG=m>UqCY`}~0ZH5}AvJuM=u$3KQLro<I;yrUC*N~BCk8LPYnU-UO zC=#!lDX(sL3wO0`2_BrJQL9)&AH+|(_|zxY9(6M%L9>sxtJ{_{GY@g<cU3|RC$2+- zGfSowGZ<b8g^qtlXJ+a;^$p$@d-3Lp-dm2*J8LKJ?s2ZcbWCN7VbjsW=OzqA>|+A= z{xa<cdkaIG06cn{EM6XE5<tZccZuTzY$up$e9K3SkJny5_lfabESk1VQL^ZZfInW^ z{_4&>*v(V)uqFiYmBV4}DsSeML}*m`Kue!G%^!ekoM04-{mF>v9Q<K9O)ec7ow?!^ z*?I7_iXK0Ar!2#0rms21_HIvMCN(V}cVp!m<o#47I5TsW;`O~Q#j9$)basgd)uX1- z?|!orK1yhNQ*H?tET$Q!FIFh2OTj3;V#HI;SS4NQVB!o<?hzf^uFuHWb<7(otiPF< zsoQ`kpS~Qz7bFFWynmI!jUh5rv{X(v<==Hs(dB@@Q;M(>I_U#^037pVf&XQ&m<9qg z^rdVkzYJX2d$IAUTS64&Rh=eHs~}bH)S`RRB#3+&9DVNU&L;+FimN!E*c?}3b`)7d zW}T|{iqz}IIi#FET-wW>-utnlBf{OzrY4^5nfl#t*-e@RPCTzy8lk^vl>V?98l{t? zn(TB46&8W%IJGj#jOy^9OB?LpFQAPG@f1xDSd~}6cS-lG3||lRBNb3gTT^Ybm?Nl4 zjegjG9{9iSE;QrX>HV1Rh=KV2nC$2K2kY58XYpJGc^Wlnr;8Z{<krnFRpDLQj-P@= zx_;8edYzeJ_xAJ{GvSQrL}uyUp6Z*K*t*Uqs3}HCmu{8f9d#qeiThHM*B8DTqV{)C z%}fOucq~^&awc|m!~vc57r0(g)FoqgyDdUh$Ej5U8NCCl&~cRaG&PuGJirlkg6Ajy zbsNHWerbzvZUDBTDg?ppGTYk1?lc%Jng?gR!LwmhmM>}IWEIx9G7gz2EVwEirxe`L zoWZqSUdpnSGbIw_<W3PEn!I~-UEbE?rFCTgnjEG8zw^q9RM98fwR9MUjmhAvREVDk z?3Q(e71edc4MDP~^>c^E_>-otMr_LZlVSDpH$R-(5pSJzC2)Yi13s87sPp@*C=G~2 zK|_=?t{*iZTiD*o0{2yn;{o8gtl%s84Dn_V#9GS>=U$PI`|_|)&_r`IH)~S2`CjFW z+m0@b+a4D`37&j;s5?Jh^`hy;*WH0C!n=P)!Fw%@W|!(0;ZV`>s~q1Q+Q~CfI2nzc zqT|JO7BDmLX{O)y;1^kO7oMm%yU5OYqfH+EKH=Q`3A1$OFm(Ig$#hVVrUXw<&;;>J z(&_^DHw>W47=1ki*mui_Cw95NB~%=rK>u&>oXfc`N3^9r(5JYhZOY5^1GVYX*0tGf z=ff;k$?l&1%czeYDHw07$g|}^j7^__*{Mp1eCw^LDMb96u6rlYU1e<X!+JSE$eBLi zek~GaZyII>7X`BDK>j)T#5wb>PN3J(Q&l~Esr&6^MoxLa-=pRB6J?PX9XBURSEQ=h zFo$kO{&gxZeiPii#Qw|rai3qOOPK<W-n3n3x5~E1ZBL9<_nW(&E2kr!=F{H~)=%#C z<idF(jA8OC_WjDXpK~4W9v8Crc@n5bM|WcPr)Padh^ITpmGL~ix|_>JS1s*lHo|h! zFNI*g8?S$=mr#x3jj%%Z_8agFj(5H)u;U(_)Jm{;cZ{Aq+NV89cSZ6Dhd;t&;#n%P zU6Uc#Cza7xF5`}7bGybB6stOmP4_!VsX&j4q;%D(qiSyOKYI?){eOG(I90sfHm})k zPop)7Dqf4dw$dd+)dSr8Z@PZXbX<3sjljs|sa=<D-<!zB#gP=S?sP2G>TGHY<o^n7 z3Ap+L#RKCNG;@e#Z=0b_;T@%tr7lWkH60f|p*|?sZ8Vkr0D;Dec{c+CV$vi$D7uto z_?EmEpn_R75q1-gWiVL137GEC7N0}4>RH5~3~#Y-lQt)ymHyUVn&&TU67X;Vei}zK zW)A?wf+DMKB@?Q$uSMPzgR-H^a3lT!kp542+~$0wGeOLO5ad}H^}DDrQ$>_Qqunl- zw7Y#F(ZIeX=w~o6Q>>ii%~pLN`L=Ly%gg75hb!=9{*YiaWHoRxT$-x_x~Xc}$fWi; zu4@DgATAQoRUWWT)(zlCunGg9n+-X^&k;Tw_<jebShgZ>L~aa*J?tlrg!0m$yzm7U zFv+S(veTW<>Wu8$7-c=S@wgq|#GYrWtEMV{oY&JfR==2dAB9-Y#GbVIvGta8Y}jkc zxp<oHx@G>R^whRv<DK&p|H9eT!A7}$7r=MoI_GthHKRS#S8oaA(U67A_B8dpgnF9Z zbfpa{wpcCHixDrVe4QO>baYT$Nm$(?fk_HVbtsyUOC;;<>fX0~9E|oJ=`wW!*eYk3 zIrB1_HLRoCB@PvgK5h7Ze`O93R4VuD+lzfLy^}#1PB44)-&VU&-mKtcQFrQ_!xn%+ z!{~QnZ>9|B4$fbn0NaD!so+J1ca=#yFtSuR8!^P?D~4|{R?CMbWkhM-{aB4ThA^B= zus`bDViExBfBtX<;VcZ7zxD@~gaMU5JUul1*Y7FJUI&6}a$aDr#YbTTr|pQ#{I`aM ze(<r>PA6=HHRSb5^y7a9hj_q6B4fP$I_wEB`D7ss7Sic48`VQy;D@CpdGns92WTk( z^pS`&b!6F!BohkCdFOa%Ze&{3$lwW>T6PVr(UbOzWCR!SX)pZy)K?srYQJy(1o;4S zUf<#lI@w0p@a$|%bbXunBqRS#Hj2`(H=hK6SgmV09g5+gcV)#z7s>_0K2-9^w8MSW zS=ZaMo<7#M*eJdY64_9MI(mzCb#3J~o?PUW^h3K6XN4%AcGvI!Jzp<~pt9Y)yqaky zu{`+3;6<7Kpgvq!%vkD&Hz9u$+3R{e3j1-yb9BDvrz9~n^Ec;$X3~oevYHxZ)?&S$ zwkv9`SR^()3>ldLgv(3>BqDJTAHhpO3<;W&!nn{;A7=z2W635?04A#VdCgcMGJ?Qq z*yZg$b5>-06n?m89{97YH$iZ+f+lmv(e8l<Sl5XetYO_S@qa&`f$?V$?+17w@(vig zu|k)VuzkLTAMox^GKQE7<CN2h)+H-igOQ{dU}0H#mhas`$A$1GQ*m$Vto=p2*vZ^y zK!$|$H|!4bAl~)#>#qOPbUZyjKvb|omrLYs0l+Se9w#dns3BWKTfA(cQlJ=E<Sg%` zD6f#Ca_jaVOf8Z#+O!YueS`{c`k(+ol+*j)QL(!D74TH16848DakYKPtLx+X%Ib1G zC4)~w1p!8}7HEso2&;-+DTC<8J8N8n2xSNV<K;L3>^C?b(bFpAu{pXN{o{linS?dQ zz9+Dd1UW98Nk7jbI?bmFfTHZCaraJzUb)J)z2tBkSDAEF!Ygn3Bx@$NB@dJp@RZef z&>uFlbjMlhm+CZ1p9J0iWa#A(8T=TqM>xYk3@wox<)vN!tl=FnJ#E`x{%00BEPw~9 z?d@RLXrW_T=UJlyO55uK!GD;)WNm^urDj=kIc5z7yII)gE@bt{IpV&#<n+mvU=E;U zcz`_J1(f=@giRpkCyDdEdpMsR6&mqsu^D5ORx)$foO3_?DT62UCI>-*qCZ8Tz%&nZ z@G}$(@H}66EPY^5ahI8MEy;-6jcqB(a+GGNDo|U*x&n@LMF`*#xKB`+H1k%aOTJ!J zP8@Im&LZfXhkTRA3mkwgiKH2}D%$__c=Z(jxCMRcF{T-|RCcv4=3vXAfk}z`GHQHu z+|dRCL|(x_<p5{mE@x@@hCmxpxN0{=&-L3-{Rs((r|dDoKP0G6@u^Z_y)qSAF6_4V z_z<-dOvn|^CXZ>U<!iCSy-hHn91IntA6pI&O3;#>gS&k`-9u=sK{;3CcK(!JF9O<M z>O4$%c5BOX3IeH>dvC&ie=KH$S6%&4{w4MOFIHU|MrmeaRpI>YD(crEb!1+zfypqy zkqOytgxx1PR^2yVLP!c^r2U(*o;FR7X5^*_+&t`JY3a4&dl%Yh38z0e>74v)#3`08 zz66su?6iC`_P8AP{nwN|<i$CIY|OFMcHNZ*x0zsFg{N};!Pwnu=$(b>&?x%Q088sN zlwf-{LJza~`^)Rq95A*$!=2OU_l_qVSnYm#&$SmWIbD|orLW2)9#5f<P&Z%<PBAcq z>Ky{&h43%3XzQkg0E4sv+}ydqE#l2MU!L@D?%M~JD*F}Tacb}(FMTDj4XO)O;FyzG zdwsD>5dz-UYFbFstx{>`t;8Yg<9fEY0oBLkck<rWg(l_n|Bv(lz?(x;oo!`_@i|zw zdIc3H5@3qn;WFMPp!WLk?py}xZdxim)`E+aJ|OMa3!a<<!XB|nU;^I6;`5qTGwQ>C z)+`>>a8qTBo_cEeB-l`qGg$2Dp`$0yX+*v{M9}}~4wB~6CI9x8p-66f;<{zK&pPc0 zESq)e3rwO;fjY-L=N|d?em3E304<1g5kLfPt==hZIHWwgQEg6AtLjW0mB%x;5T%@5 zHC0?~7ERb#zD{Zc|G}TVPSu+s%FBtZ87@r4*d?6n{4}i(b$)C=_!fUU)aOZfv+Bw? z*4OQ|<E}$t1{^KS{NArXYYS&LF#Onxy9{ySvFr)gdF9x(Jyjv&g~h~CFtVbXrKHbm zIuZYi1(40Bsf!qmEBufLc-cnYufr!qI86XnH3GfEoCD%6ZqV-BCkD(T^^o$kw<CfV zG&e&EBaGO<?&A3JLTAEf9{<c=l+4{~&g{PM5y$vrRy<wYO1X`KbTzMu^dJDaT=6+G z7NtCZwuNiMb25wp8W{21p$JgLA`ZjLz0IMb>IejVGWRd?tpd%s&}HWsSAv8Ol5C=} z&$VB)I8Q?K_Kr-^O?&D~DO9%^@55)`|6#uGvPMlJhWvxRZ82|g6<(yV7zEiRyhC+b zo&kHgInb@UFXn`t0}zPR3tn#_Dq!2t-XHp?5^@IW0qv`OmIgU@o()KY{3xU1fB){- zwmVP9$@%ae%a)O^<Bk;_W*l1ED(96&V&%U5KsJNnES|pMEyO9?boPty?9_P{b}p4G zkoBZisRoUKrloTDv&Sjn0Szr>9||*zHv+8n^pluFkSMhsF@-@gXxi0V6M$^xX}+?b zA6H6Z&!HBTx;KxJcARuE);HhNNn>Xpyb#XJ(_Y{ALH&llXLJ?8>&|#Qqj{=R+3y6< zhd8udw}%zVVJgWXYM*nRgB!~j*W<)4mx%H>eYbFSeWrkZ5O1{Zh9lVYBFL8zXReLR zNf(Qm+W-wVr#`Vwdm<h7<4HPCZU2k-hK_XywQdLEr|wh)$eBAK{IE`+YP6mLE+>vA ztG8F+N5QAF2J1>y!SSf*vINp^5*%owpAB@Q_qwOwjLr7{6Rm+`jE#=<u8F|k<<-T+ za0@j55)c@UFqf2NK*bD7(7?;-jey@RoX!h3woeLa<vF>-ml;krtV<0m7B+O6{F`*E zGUc$w6eJG|f4YtA{)~iVS16RKh%>QAe@yy&Je(IxbKCUwr(F$^utRmY<Tv)nH7c}6 zTKpdIy5oPli{;ZWA?@lu$*}kSDs4>kJgEOrWFvf)Uo#_>b&%*4=-|AL8DYZ0Xp`Rz z742eUa`>mkOeN&<M%D!AkCuL0<p_MyZ4!!S!;Ft*$o;zN%`|V#!R*}C%kh_T{%keU zNQD;MtoafS#oaxImwy`;e0Ex6&d=@qKgNM6&c#^WG{no0w6%Ul#Am%pvSm2z1ASU! zi07>CRg{|mE8B38|1zOiUC_TP_hFlFo=K!SLRCupaVbCIuLalNZLEk1Z^*Fy%(F;c zk_&S}G^|$Q{LkqvV;M%XeE|YZV@J1t+HMn@WK%m|8WJ-&$gF1Y9zCAOWFc*9+qj8m z+HKZ9$;@W5iSY)BWO8=n)A+0kvKEZfd4Cj{d9hRM{4&lpsaPYH_qI53#i4CsvCb?K z`M_!>ZnB@~T>w!y^1)4#pNd!N8!iY^ndchQ%QwOvi8SyI!_o<{c`YD$<exVEjg)W1 zR(I67{AlOo#>c<fT)MaBPE0M$l4$a}sm$j3CZhh&^?Ab%@i_k<Q8%PKAkF2V&xxO= zkHnl`V_1$BpPKf$^SM^zwYm#+LE-QdPiYD`5E#?;^6n1uB<@6evCm9N>6MUA{A}iR zWaiWBp0AaO;am)Sk*?Cr2`vfVO^+5ur++8V7#uFSrc$aI_&1sy_OQk0FZ9J1^MsMe zf`SrYkrXDCqOBS!w0>D{k)G$Wp;Mm+OWGPjlnr&Hl=E0doTG|KH$ILlSJw}Kv)Grt z>t1;@twm9*V#+dJJc8q}X;sQ+vJ?bc-H!pAFm_OkZng1CB<9m9eI><>W)+>vHdK(U zkFR;eWe%kE7^R*W$V+5>y?S<~qhcAD?9-VegO}7KmOH6}qBVjt>F`emcExkHbd%AF zzf1nC$n@<gtuu_ydD3;e!P@oJvzdkjU0-Lmpo}!h=OAm-0qzhuThI+Uh)~Z<!5B~A zZ}?!%G$bx4Ycl*xIXtiJfDaeOs1E%*2+#ZU<c2>A4|xm5itJC<>USsdjW6kxFwVJE zzj3|)Xt}{u53}zcOhkGOKACAiE=n`=_tKz-cI}&X>@FBdcYl&?GmaIH-y9?s@}Pd3 z%PBD+Jwj29YC>0=fWc3vZqt?+`by|6GRV2>LicW=r5g-syAo+`^f@qK{`5}{8~XM> zb25M~4NCAM9LoMaeKsYuzJB0`===p<@iDfIg)Q5z+LGiXwTPE*4GG@EG|x95G>RQ* zR<d<Xv{xeskFqZMK~|`s3*YXgH~Ho6MBmnasJrOB!RDx+Q%qPGq@5~%ra6c8pjBjC zc5>hMnpLvGw;raZ5xyoX57nLw)I=_@<zD)6hY3zr=BzI%PBVl@id20V1`_DTZ2q61 zB<Z@cI@u4)1tiK_Qbq2eM-1F3ex$8I#W#u96JB~qGl1=@^aCFAk+X&BJtB@Uf05&Y z0s>liXI$6kh=I4Pbnc-so$ISeT!OO^w?~05Zi$f(nifq(PGikt$ZBeKWO8Cw&{yEI z&Pz~QPC7{HXb=qMP%JxD1X%Z%fUvnEfD7nxcXvn2I8*Tw**ZxWtru0_|9<}nJ9^Bz zyB3bRy}nWP0`2xZY?NKn#%UaswD+>17io{a?Iu#*^aTZGs`q`-l2?A<XRT#$Z~JkX zw`miBvslI1#Hs&7o{=Jj&X7XM*rsnjym-d2J4ln;d+uF7QTjKcbmzciY!EDVH3dz= zgV1$D<PnCK4qp>F^AB+1IQ{mUxmX10D>qtE_9P6Jk|&V{`5yFbA^mq~1xJ3Im{bgs z-@KJ4Aa;b_m?9b+`n>q!LuoGg#tW=eBHm;EHx*{F3M&`Qi#=F>CGm@KSKc5U05OPf z^=eaOso#Da-j?ng5A2LXUF1G>`>9J2eEsmzj|FFeLW)l=SM?22%;CTH{Xf8R>=7ET zQex^9UAe)b&wskP^^kbCEdQNmboe{PVIa@2_<lD<3|_3ZTV*pZ9XE_hD0hdZwR<{R z{+%vu&uFwoU&<G?HEE&@`objDc{(CFwTnICx^^#AR|&U28;os0IX*<O`njp8X2U{t zT~EJk%OYr8AcdV6*#Ml_Oq=pPDD_<2wf|$4_6i-Dr61#Vx$21wY96a*meJxhM}~}& z27T(+m3DXg+P4<87ofG2cj)ntw~IY^-_)t=GVhSBe4(ZaYY$yorWfsd?$Ng)qa37K zD=$(T&YJyJ8p-3$tz@u-!|<rE1Cz~dfoekjU;96COBO>}QAQLl<RbFF7AK1lo5Tde z<``Z=(2bIK&i(#hUphoc*eBqxu>5bv8-^k+_vhi4J|ocm%uxX=zTrIbcs07@>-TIy za3<s!ECt0oBvA3_4@Im8*wmEybI|0UjtIp?MHD!0{LHk^eiY`rOS}aUYcgCai7S^4 zVybgrWu}*=0}<Hh;Li+J?ci^rtXdq_d+`?BpKyS^Ig{rb><cgq25oAP?sN?*s_S#< zu%XHxIJY06Nv)-=t&KFy)U3~^?@T&nsOmBFvEZ1Q7+VCqZB&suxSZ^`2Q5~6Zqthw zp-PZuco>;%d@z8Pf=ePyau_v|dpaLhvKyh+?d*qP)_8p8m`W}7!v_Z?aUT7pa7s(T zDtfC>kuipQWe_e>c`X-TB1$&e^n?^;!;e5aEfH0P`2nQF<@i9$;$))Nj&oX^UdS^J zb~y~f)%BMol$DkTP4(p*L`!2shS)VI*%6h;1+95e`D+obD1Qu(L02|yjMJGV-##-4 z9QnsU<NIFCAXv|$Bfx^C`hUlJm!BPZJx#B0vLE-j=6}@zSq1=v6sdGu9hU;Xj=~oU z%V1?!UWYGyxrRdK$<o%3syjI5TD%(>lEZismw0iJxNd<1{R%MolX^#^%9M8q?KOCU zBR}~<>LKT6VGE_dlkh|0{+22GtA@60o49Q1M#hmJh6eW!{eg1~giuSYF<h*^KsTq( zu=J>x$v=Ic6}fe947a=N<W#bfF{v|=`RB3fgnxcS4&znm(-a0(Te%!7skL&&NN|`1 zGP(dw`zP|R6omcF3;FVCfGqe0DG`{f!Tk>_ZbxtOJ<e<P(!ndF*ZtCw_Edq%{FGax zJt?re(EvDZTfv~0KfG(#Wk}qGo2@6{^l4yTfmE7Sdf}zcc>a5obbW&Xq_RMRXW>)c zB<mhikq;e}`#+65?4F!h@u(UW<mpV~?EEH2;E~#jd#NmT4PTFv^(o(vwiIdUOTIMz zT3H=ipg&5-m}#)C%4PC4s{W&mrILME<m7kh7uiaBZ&hVyRo}X)%Z${wF$icGI<iM` zHic9;HKsC<88FY<8U(E*!W;-z(EJVcE0UQy4NpPl{G3-C@(&9xrEnHP<oh6u0;Uc! z<4-~BK>qJnX80%v#ExClgU08W+Xvw39s^k+EXinr{#7++dpj&UUFTn#61LjD@i>x( zRox3C&vxmjPtPbNfg^rgs0Y3>_euU0ulDW%M~A+`OVpp>#XGv4y^~OAj%OPC4N>xF zmsUwZuNOvMF4^E4*be3E)`TAWQ|2Cg?^kfsiemD3-6RcPvDBZ(O0Ut28d#y}D_-&c zt>*d0_f*e`@QD;`Xt>ZmRXr=F+Zt2LOxHfRAX;vGRGEvW8ohtp0XyQi^y7{QVZ8X$ zJ-j*K>Cv39GPTr*SHA%HUzoHI84~mE@66A@nQ_^(=WgA68YvzYGnW}p7-1bx0wL)! z`B1~32M?fG_&1$D^cLlH{{y~|jW%JSmX?}<u~OJ>Nk{K3o~X577^Hb^lX-mIK~K!E z60_xDq_EWDb0SKhR>rR3n^L)Ci@h)u`ERSWZ11&-C>7A~<l33?f9RN4eeZXFS9rJ5 z7;9T`4Z<;}E(a-a>2kEy`(kU5x;oaka_Ew-FD%`l*&BVXYx1l~jkve?H8p|ML(j$* zU@o=!qpyAoJH9lrQpeE5wq|II&Gg&@3J5FY_;$hIWan4rksVA=ti^u@<HCX%E59Le zm(XaM4P~_-y|xxWVs_+nL_hsC(R+JwG+2s^1UgD#qWO)bOn$KHCV3ksasSH{h~{Z{ z)WEf;QR6p&6pp-4*nY?}ty9l`SX3)m&h|@5&R#uzUH*P7hPyZaM6+f$UvB7liK~U} z7u3r?%b5QQyn*F{1bJ}`pZwntJez^jU!@<iDVcX8YYCe}tq7Bz_Bv_qgoMq7eTDx< z<hZqZ<vuWTcBGAu#%$}V4*$?K&h=dW{-q$8h$|dy_Gy_RoB$?kP?cN_sIunc=D4zZ zKFA9rkZ);)TGUO(75&nOP^w!zP~FP*?cl4K)6>)Zd)*|eNa{)TWM1$Y?EPqAD$n?y z7$HO>I@vPzhRP4)t4+Tq>qmS8C-Xd9YVUq@JPGIGUxmNgK}dxTwi%}<Nm4K?xn|@@ zq;5>|vm9(}bY-?@uk+2?&{;9HeyU8!U=gsIr_bHby-B@D4m^yAbc?Kyt;dQOLDScr z*9tTKOs3!ceKnJ;rg>tQ%r2mdA(N9t@TX>qE^_Ku*3XKfFoz}2zn+buj&fgJcM2wt z06aRz2@n&+;^;7HcEEzX1NN4X2y0E|x)M&p3S<i)d;Bq-b)rR0L|Z(a?_GGu#n{_J zHb;EOcl>h#a2jxrBD(f6?WKKAk?e)nB%_kkN}stZ+Wx71K_9l*(xv8(S^w#!x_m`f zml$f?Z)v5hucI71-=5w_HgnR%zI<+3R2rD&Lv_pG?74|$@agy@C+{0x1l)ANaHWhq z9=)zVzyfRRC1PKl=!{HH$VmL@i&ErP9c@k=_-C$6`@6P68`v!iFC#WpZIOiJv^44T z`1pB{IC-1=wAAotIqQ-gL#Qu(?dt~+xX3s;59w7`SJ(H>)>yi*gSS@uO3zQLe6CKL zPF7pO`~m_3;u%MDixH}=Ik&kfiSkeL1bHm@m3B2qXQXtc$q<QIsflqzD3z=LiP-iE zAni7X;E;v#+z9@;Qd@(cn5#0FW4U}TjuqS8x^Xci&dVDe^c6skBw81c4iQfMD&oBa z6ML%7rH2|oN_~nlpv`+l#%*W|u!Rrw{T}NQZvt1$>b`_*haWP)613Qqtu<W*aJ(GZ z&<ZV$NwllR6O^Gp)&k)5E|F#Lm7<G_I-|(;((EoEk#0!I3~eZ6XIK53ELTR#jfcir z#hD^ibxpG?sp}T1%1)#k4r%tzVIyUpWyYVc_|c3bD~nNzT)1;Nhkp@idLXCx&H^<0 zMxaGD9u6AyG^?7x!^K?&CNfYS-U8?%BGEV3xn8lCfe?rJLq#$0-U-@ynNRD<OfErV z#QV70J@>^U&S#$idwJ~1TH9>=v-)16zE#NZ2nLP)LS-E;r2r~5axNaoi~4byC&T8! z$UlkZfk<lpi&@j9GNXDfA3FXLe4@Z3T%6V}>4EAqwQw?ye=3Iw1v<pg=uAN4OAWW_ zTUPvi3rXP=t8I84>O>r>g`~It4z+d;ATTgWMq1SR-Qmee_yU-wWnwmW@x!A?tvM;> zmRCpdnwSgNuRoB;WE|K)(|HU}*diY)6;smiS<y!5UArz%R>|n3yxS&)|0q&RCeYFv zy<iZKB=`CIjx$M=LJg4T9n&`DQE?;Dv0fd^s?UFe08fG2(k3$3i1QbV+;s}(1g4M1 z6$6t1ve^p2Qm1@)kZXhAX(E}FRfT;OO;NGl?sT&_<2Z_Bi<FZ8QqM}~`#rts_;3F1 z9fVH=R(nBx)byRWFcU8H#y+c(tF`YfSd8Rad1xl%XIHZ{OKPaje&fF=B<5P4JdD3K z%;Z7+10~G_++1xAg<ypjd<S!cta#MT?;l%@-7(IykrIB|n)-JR%kJjOm*^-EyYztd zKaTw?_sm)d97=Zw5r$;7SJ$VWim-K==P-!8@DuEMvo>jt2Ujm1h>{8HJqU`%mdhee zE4WRs#h|(Wpnn<iqoz{M8^{x`03*z#{i-e<wJ?6*G^XJhGG%|G@OQ;uRbf0N4y?|m zKB9R>Duj=;pX>eaw`bh_(zWW1?S4F(WA3vNC2%O&bz#6)h0EML_>frVGaHRiK)Q&H z{j?6vi=;kz00N|75szcc1>?y@DW@-{?wQO~6VJ@4YsWTGfxXt1g(CY20Kmy`iFlg4 z<t*i1cAYxWc-cI}qyC9;t^Wq^JHH;$$?vDztEbwh>#L`#OXMSdZN-1_n^}0hS}W66 zih-Xa8Mp=!9|WOGX$y}-&Y&Aq&}R}qpbPeu@}Svq^?6i|=cZe_+r$QP{r)Q@wAUz} z<v_|*EHJ@t#NeS=^x+lN8?9<$Mm2JKw0f0i3(5=mbY9DoDHM|pQaEjN5`he^9D<P6 zW!*|+O=4X69ZfY22daNJ9cP`TqpaXcwD@)+ke3FECc0)aU~Zq(=JywHT(L50al&<l zEmWD1y%66MPh@O=zMJU`A%PaX=3@Ed{sjW#ct5iG7nFB#nNvG$IjO(5`84lt(AtoL zQcmTPl>$p8uL~WMQnv5@sJIyE5?7V(7NE7Dmg@PvYj_tGgfpJ%^tZlwf?;8<`=^$D z5BS?d*FwNQ8M%Lcki=ztc6z<dMx?UZ0-Fl)(U2A`7Q%DTf)3i)ycXvgr>>@`&ICGD zt*LF@hwls>)h!F)MMIgZkIIdeB+(?GfpI-(LX#3<@0w;IYs!~nirWVA0q_;0#Es&Y zv_>BX-y@_}JIGsiWIcW3<1(nI^23$4R2MDx58l}bXnnST=<!CE$e5!a(6Z}=X>U-g zrID?m{jE#*)PvT#C8cTq?~NqW$r<1;CcQpBI-*RY-2EqxO_3bp+8DL_K$JRT2gQ60 z4^+t)`upJ*181%bwJEwy?PrxcRLpg{d=P=4jZ5rNiq>-wt0H4Jsj~Sc1F-VTX<jOy zQyIAOkeE}Y=w1^g<^>Y(Qb_=H95WM=gWEzN{fp;&)ZC@OS8uW0eW>A{qCByXt$GRx zWRM$#^hRGXA<781{NwvA^qsH3L{O&ODH&$VzAT}%*0G$FwW2?Y^OSnAUs7EpOQ{bW zkeD04M_r(VL_4EtjO4;}m0KllUkR}F?1cG_jJoL7m&tz$tts@!2&a9m`!oB8xiqdz zm0C1)!}lbLop+C!yK3DZ7vSH!(JDizQc1$cD)dx_64TYLhC+XMd7>2dYentkvsszE z&sNW&SL5JV`K@@%TmDm)*?=XB55h<LGkx4{ihkXW9VHYe)v+Fk(t*iLYi`PAQbp<@ zp%Uv(%Sq0L!aeGQ9$*F?q@u4@CIs>9D0a#&z3jukS#Gh8$TsJ0o4>bkWPH8YMq}IQ zYr#MwHGBRlKl>>6>-CTzOFiuCQ6>0>y*|}xs=$d=#tQOP`W|H@1e{`>LZ)GmR|ET$ z!x=Zvo9c%guQhmoS46Fs1;-U^E#QSD3&o@Ee_!9Zdz(P!m1u{ox-}sD5b^iz+(r*M z`X&O+!R3cUpda@FJ$ZnqAiH(4-h*}8<$(9R38U65g0#9}Z2jQ@8sN;?bMKNaFV%qr zMe?$e-?-lsb;Nsy_T0s*2hk(`6m!SIu<-5U>%`Ztf$}hzsNYoJJ~P?5?VrDJOqYHi zaHjNgkR^_7u`^q@fFOegwxi6PxD}r{dDHat{h8ED1|qU*BQra*T8$XhqRp9q9UbzD zF~~uvk$mJX-y*fyg4&o6+8!c?i7pAq36K2x=m+s82AND|!k)><@*M^|fyLr~vlZus zA0xbSuKsWr6N`I$dp{S-N2+@jWdu4Jr;h}x@7JL`uDc|9O2ZP4A=QFi4dXSWlHSc; zYVHz{sm1QgCIUHPNu|j13lKH@#0SOhc?A+yP_1kxy}@)n#nQX(^-z3q`(kZQeICz| zP}F;tV!F*K(xKak(W7vynHo@&p&EKEQ+#B9orG5gTNzGOS)=m1Iz9KAUs^c2tgw>@ zln_X*v}G9X;hy|Ol4_ecr4Xzd_tnzJ<y^sjh&c0F*Gl><%cy~2etoOP>o0YOUB(W? z7?qkxtr0?n<wwtOQ*OX&cHQZOwcS$`9ScVL<rP(qXCIZDJ(g^$g(MH<zfapd%$F&P zFK&3=)N>-exP~Jqx#aWcL}2#)2|NdcVt*v|H6uJF>y9xsN^w*F1MuCra{zItB~XL) zm$ftQg!-_${47Lo(f;y7*9pnit0#D0t=J!Hz}6^YjPkbl?zDy9e(_T~3;S&s!ijx( zKC8Y8r~>4-;x?)&f1lEw0MS(Ab49199kaFrZH`jG*^NHRz5<F}gsgr}`O2k=eBk?U zhF@&C1AHYN)d1~f(kG&9K@$b&7!-0@^Hh+>=hChtE{U1yNK(CD8GGp$==jn`u14ha zj-pQkmgQql=FUo8(x_6SoJh#VgZCnay;=I0<<c%dBq2IS(Qo<4l+hP!bFC-Z9ljK4 zrv5b@Z7g#5^;@~p{fvE~cE=9+m%Y`)*pNjz8(;XU#;fF%%kW+Aji$%mn$^v-mT`GJ z16QS>*vL%va?vKth!<ya1z{=YKcYKiQWvy9(p9PIdLBpY<)Ua}dQ+K&#cl&URIH94 zu5|59+;dQ<sx<T82B8HuqKN7!%}Xj3TU&1%J_nU@&I3Ow^}}<J`Y7EaiLyBd2srAx zZn5`?j{N{CE8)WJDziQA*J3iMh|3#mca)wSW6jZ48{4$s!(@*CHa&uVUa<?hDQ$>h zqX#!>!ev>Dt?20gF^?8h@)g%wDJ>-0w#hY2*dV#rm*LppF~d$kb+ehI4$b{!8|LiF z0tN-PZ7}DCO5ZSp<>GwMbXngI<KVES+mR2HLTA+lcirG+OP{I_JL&wzu?A`vlH3WX zAQFZ}!=}NHkP655aJk*`Ji6D@bIe8#B;<}SoEiI}@mvlgD<Z(Lhab{>KBKBT#zyv2 z_h0oHmPpb*$+MZ^U9HK6x{z}f+X2!UUa;2D%ax9IKQyamBB5FKh>nS|4?VYpJ3_lZ z;+V-8=0Y#B9^wZs;XB7_s1*eZFU8K2b5@?7R5X9Hg&0+eBDvQ4rq0w$ld{x2yez4} z{JqsZ_I@sSuYgC60h{?vJhr)2tdsmGJNuf=_-IdwSJt9_`2k80DAo970uBd92}-lo z?-_QKVyxM0a=Df9oF(gryyLp>y&YBj#TVT0%(T)~B{nik$9A({p0%~4RttRWQnLhT z*O^KL2527>bLJ_O2icQmO*#4_@X(rVfwW);v>_ENXvEW?f5YSKaroldOc_|ah80*s z?L@@oZBuRpvTao&@Qb7V`^CPj-0JQrh+oVykumz5!T1Su_G$(+#{D{G=MzUjo#7sa z8ursk?bbuw@)To@eqq6!03Vhy_9|{lCOF2Ju3@(>a@mq328A4JX?W#Ftv<?k?7wsx z%C$v-+>{EHj$4LD`k&*9)7Dv@w`q9^5-KRVs-PK?q=U{>(WFW4<;?3erV@GT#{}M> zsWo(^iq%8B!CmZ^;^q6dO`_4%b8C8gTg5N9m_Ov86l4FUm&{br-4d(=O?!eP#;KY; zxJy%L&K-WomKIkF_{|FIIoDm12<o?&RamrHN*Zd4y0?)(o8j$8T!8h?Adg>QDZB0l zHg59xiT)NM_<KFzT-jK?o!vGDoF+mYEP)HiPW%@U^S8l`7HtgE=JPTMBUh)my$^dN z{}dK9Ut+iplOm6B1a&2mz}ZsMBSzXIWt&OK=dGrEP2qe7*rA(p!i)Jrg(ssmjeGrB zY|9>Pbh{&tx^9g~(Z)V#!u-%ijl&n|^DZxf`{#Y<0(JTE`875AHrB#-G4Kr_-GdIY z_Q@ab@G<{UFVyoID#=U5zSx$k?w}e`@OsM^)?{&*h$dKUjeo?<PDrnnYz}hOclBs0 zURlt;B6;f1>?ruDqYVZg_OdtHJ#fU5Bi`Tt-?{^x3hN;O#FJjMN6a8sLM7BT9_#zB zfbOsx%zhwNA778EHe4@jqdJn){3cER>kA#w*gBtq5GCsKy0|_5U%YABQ?v%6yyH|0 zb88l=WNY>>gQjKW2@hu3>;19O(CwM3+cG6tDy)C;<-MPL29h(SoOT0`CYR}?>t5L? zrWbN9|BdJs@V#eejqa>$Qc~!Jv0=5X*LV8Wy?JlIfT<mEp`PSI<D?<Gx&0$%M;<M- z-={>?)r_P~Z`ZVQs|Q=u%<TIdVE~D9`fk)`jlu&QQ9L_0!%*NqXY0cQfJO?=e^2`t z9BzDG7R2KJ_;Qry1?=_lVBkWac*3Y;z>3%9)Rot1E0))7*%l<WkU;UG_Qh+GR(c{w zt*FKqQN1bfWP3**W*l23Cas?wY4e6PZP7?(rA_YcM)0p3_WBQbV=L8!NbjwTc2i%F z_X*oYj<8}@h_PmJB#b&YzK?i3Y+v(tZxD5Dlev#J^f^n9c@+Q&75DoE>zXvO)3^VQ z-H2kIp_fVgU{UXqyiOFTm%3!-5+v!Ggv-mQBPqHb-_pF7+{8y#1%3!<a9eaF8Kp7; zu|}41kXhm!WLQMA7g>)KE%4TbH0mn$UyaKlG!u^Ql=RYerA;^{$iOFN+KDcp{>wl9 zMPp)8VQWXB1zPawvabr0jl&r2LqDfK;R3B6&@FQK^ofhDU3{H~me(pxn}CA!y|v#W zLM*Qw9;EO<0C#GQRnzb$(^#{nw#aYq_Z~hOs~$*rpWDRuLjA8qe1Jqmw0r(mp0(Fi z%EG?LD$kn7s^bT-1%%z<W!ke&X~gm8q5A-;fVOM}eu4CCj4+UqTakcz=coKvL4nw< z4yKl+f<32H^rnTsbuEtnrXXxWwKAjC=YPdb^rl`HOcTwM;;$qxoT_NoAXRwRztJ;V z;G|M)#ChJVZ@-<MD+XTPO58nvG$i#KCaqkvz{Ppd)T|0o_5O}z`yLj|R{k}8gq$lP zsv4;bws=HVxH9l%FOUvKo;s8L2*x%XJfFi@=y`$)c%M^^qlp!H=DURFWjmn~FjAtv z({|i8TUaW{uNuiw!49+}1Xq`#2sFLHXgWP$9*rXf6YBa*bq=hgZJ6V<FS1-G?zIVc zMA;Ri=7$=vH4LSA{`&lmWF(<Lv?2bUN&*NaUIMcJyH2wwQc4PnXm_59;{GVIunR#b z;P$LF1xGEk7Cy$~U(6)!9}Vu;TblrXzB3Fi>IdB)&T>wX6}dVxds+dCW`orZ&zhLn zZ5y$NU|(bZDYMp3-w{J7Kdgff+u`pch)$sNaiT;ke*%C$!@}Ys*$4)-vAB_N=g;n* zC~Up;^B?P5hMpRts%4ZS8o%=dz;$AI35-o#{;wSpQ@NSra_#du*DH^Tipm3_U0-!y zb=7vW4DLeIie1JB_`8eVjhs4wgiE-I5pSCch=0OWO>q;B4LV>tcz1B!^Dl&RDXr%o z+yT(v90AX!l+-^wceSo)=JX&vy%`M$BvSz6Ro(?mZ$eDPTphwZl2~B;F4;<ltxBrX z1B@Yb1iJIh4$Jko1ezSCZ}-TFDzT8(=I6mDCnr+ORv*og7)h9Nh22L04?;$MQ8$1{ zlETCLI0|uQR|2E)Y!Qw8N$Wmm=m7o!$CJ#aKMS2)t+Z3R1m@dWSvkS;TEBwB#oyTH zP36j>5nznUz2?)pE`*}zzLUo@RuGUo!9j`bgE8ZQeo0(<Qi`7!?D}lzEj*yOwO8LM zSmmOAEG8Ll)>JM>I>j!|CP_r;r^{32AR{ogJ-82RulCAOL|%-YUufT^T<APM(zP>u zyRz;4yyDlWmEw}ZRm8%QpFWQw@?Yd0o#qeg@d+KymY2yfua+I3VVE^IOd4VPo+s>; z6Pb`9y*A}#sbI_ZYTM^w6sU4$D|T1G2_dB9U?YHxFC+>xNwU1II4T}c8+TnN`r>5R zsJUI~0LG2}uqDSsgaVa1wuMr5roA}xZ0-&VFGO%y5VPyUpz$7YRaI5&fdzKoKFx{z z>;q!Ky@C@Bjn8~%r(4`^J0gGN+(GCSVuPjl&==|r*p3M|FT6(t4>xgHj7xJ0W1%Ze zqj*#^JaU%iH*0O-xon)2oOMlA^VQwAb{&tmN4*<f<+5QsNGluON9=%)`szhx=4%tp z0=8YRe_6L_!&b+Utkt#706pis$-$}VTLT4`f7XnvlccZZ1{$j-#jdiu;IX1i@9WB& zs*p5j?$<lL8k(A${Y#FMQmh3gHCZhsg|mp_Z0EHRm3t}QpU%A^RB@ntjz`1r4Y#<s ztZX=y&48%V5YQvB3R{g?^@#R%qL?jNkT7pJ-x~Z6#?C4#sz2QOLx&QQ(ui~_B1pG% z_mI*d-CdGOcXxLTNFz#j4c#$xcb?6Ez3=5&>)bGxv(}!?-p}v(#wS-~i;12}R>0R| zGs6K|CrckVb~<jWxi*_H?@+DLv#s?gru06Bjl=-&)d5g~Mu3b>uK@XBVh9__5dPL> z89T|7xO-vois2R-tMHjeN593T;>BF&a(g#ueHz>CZ#LlfYxaGd7DB#*GX{Y&a~??9 zU#T-jQ?WWLG|36!jMw@d%d@~L*LNv$dP{Wks72T7xsx{)qIbIs@b1S9GaIqG%U|nX zzqb0J+@M<hFP6nmorGS=Dq*|+V&EhcN^U)*sc}sMt=aqut=>VG;iw`ko?eu#Q9g7g zxRj&o(c?a5S=aRyho74uBD}Qusr>5`n%0AZ1dFR><0aX$sc5e&*kLo&5B4EiwKY~L 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 ZmtP4!eeyno`W*15B(E-)C-d0v{{f|7eq;au diff --git a/docs/images/sponsor-qr-vn.jpg b/docs/images/sponsor-qr-vn.jpg deleted file mode 100644 index 9ed51e8c8d37f3f0948397ca58733265d339346b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 127720 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%0D&!9gLuNw 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 From cd3ede2134e138f96823eb32704419fe8c67921a Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Fri, 18 Sep 2026 00:27:35 +0700 Subject: [PATCH 21/68] ci: run the unit suite on every PR and push to main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was no CI at all — `.github/` held only FUNDING.yml — so nothing ran the tests until someone ran them by hand. PR #48 reached review carrying an ImportError against `agent.config.USE_BATCH_RPC` and `agent/services/headers.py`, both deleted by a PR that merged while #48 was open. The code could not import on main, and the only reason that surfaced is that someone happened to try. This job is what catches that class of thing. Matrix is 3.10 and 3.13: the floor the README badge advertises and the version development runs on. 3.10 was verified rather than assumed — the full suite runs there, 259 of 259 non-ffmpeg tests pass. Two things the run needs that are easy to get wrong: `fonts-dejavu-core` is installed alongside ffmpeg. The drawtext call in video_reviewer.py passes no `fontfile=`, so it asks fontconfig for a default family; with --no-install-recommends a runner can end up holding an ffmpeg that has drawtext and no font for it to use. The ffmpeg check renders a frame instead of grepping `ffmpeg -filters`. Grep proves the filter is compiled in, not that a font exists, and a stock Homebrew ffmpeg already demonstrates the first failure mode: it ships without --enable-libfreetype, and 13 tests then fail with "Filter not found", which reads like a test bug rather than a missing codec. Rendering one frame through the same filter the tests use catches both modes in the step whose name says what is wrong. Verified in both directions against a good and a drawtext-less ffmpeg, running the script as PyYAML parses it so the escaping is checked too. timeout-minutes is 10 against a ~7s suite. That ceiling only trips on a hang, which this suite has had: an aiosqlite connection left open by a missing mock keeps a non-daemon worker thread alive and the interpreter never exits. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5BJVhNgerhFTUgmfnKTSj --- .github/workflows/tests.yml | 74 +++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 000000000..229aa5278 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,74 @@ +# Nothing ran the tests on push or PR before this, so a broken main was only +# ever caught by hand. PR #48 reached `main` carrying an ImportError against a +# module a merged PR had deleted; this job is what catches that class of thing. +name: tests + +on: + pull_request: + push: + branches: [main] + +# A new push supersedes the run in flight for the same ref. +concurrency: + group: tests-${{ github.ref }} + cancel-in-progress: true + +jobs: + unit: + runs-on: ubuntu-latest + # The suite takes ~7s. A ceiling this generous only ever trips on a hang, + # which this suite has had before: an aiosqlite connection left open keeps a + # non-daemon worker thread alive and the interpreter never exits. + timeout-minutes: 10 + + strategy: + fail-fast: false + matrix: + # The floor the README advertises, and the version development runs on. + python-version: ["3.10", "3.13"] + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: pip + cache-dependency-path: | + requirements.txt + requirements-dev.txt + + - name: Install ffmpeg + # fonts-dejavu-core is not optional. The drawtext call in + # video_reviewer.py passes no fontfile=, so it asks fontconfig for a + # default family; with --no-install-recommends the runner can end up + # with an ffmpeg that has drawtext and no font for it to use. + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends ffmpeg fonts-dejavu-core + + - name: Assert drawtext actually renders + # 13 of these tests burn a timestamp into extracted frames. Checking + # `ffmpeg -filters` only proves the filter is compiled in, not that a + # font exists, so render one frame through the same filter the tests + # use. Both failure modes surface here with a message that says what is + # wrong, instead of as 13 tests failing on "Filter not found". + run: | + ffmpeg -hide_banner -loglevel error \ + -f lavfi -i "testsrc=duration=1:size=320x240:rate=5" \ + -vf "drawtext=text='%{pts\:hms}':x=5:y=5:fontsize=14:fontcolor=white:borderw=1:bordercolor=black" \ + -frames:v 1 -y /tmp/drawtext-smoke.jpg || { + echo "::error::ffmpeg cannot render drawtext — missing --enable-libfreetype, or no font installed." + ffmpeg -hide_banner -version | head -3 + exit 1 + } + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt -r requirements-dev.txt + + - name: Run unit tests + env: + PYTHONUNBUFFERED: "1" + run: python -m pytest tests/unit -q From 5cc9dbd815a31671157d756e6f41b9a60f889eaa Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Fri, 18 Sep 2026 00:20:16 +0700 Subject: [PATCH 22/68] chore(release): v1.2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First release since v1.1.0 (2026-05-09), and it is one arc: Flow moved to flow.google.com in September 2026 and stopped minting the bearer the old REST API needed, so the transport was rebuilt on batchexecute (#39), the dead REST path deleted (#49), the image API migrated (#42), and the Omni image-conditioned modes ported back on top of it (#48/#50). Also fixes a version drift this release would otherwise have deepened. ccf89c6 put "0.2.0" in two places in agent/main.py; 939b956 bumped only the FastAPI line, so /health has reported 0.2.0 ever since while the app said 1.1.0 — three releases stale, on the endpoint CLAUDE.md tells you to curl before anything else. /health now reads app.version, so there is one string to bump instead of two literals that agree only by luck. extension/manifest.json is deliberately not bumped. It tracks the extension's own lifecycle, it is at 0.3.2, and a bump there forces a user-visible reload. Verified: 272 passed; /health and app.version both report 1.2.0, checked by calling the handler rather than reading the source. Not verified: the Omni envelopes from #48. They are live-verified per that PR and the tests lock their shape, but nothing has submitted through a signed-in Flow tab since the merge resolution. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E5BJVhNgerhFTUgmfnKTSj --- README.md | 3 ++- agent/main.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e29ea754e..ea66235c6 100644 --- a/README.md +++ b/README.md @@ -861,13 +861,14 @@ From `youtube/upload.py` (HTTP errors from YouTube Data API v3): Dates are merge dates. Older releases are tagged; `git log` is the full record. -### Unreleased — the Flow migration +### v1.2.0 — 2026-09-18 — the Flow migration Flow moved to `flow.google.com` in September 2026 and stopped minting the bearer token the old REST API needed. Everything below is that migration. | Date | Change | |---|---| +| 2026-09-18 | `/health` reports the app's real version again — it had been pinned at `0.2.0` since v0.2.0 while the app said `1.1.0`, because only one of the two literals was ever bumped ([#52](../../pull/52)) | | 2026-09-18 | Omni 1.1 Flash first-frame, first+last and reference modes ported to `batchexecute` ([#48](../../pull/48), [#50](../../pull/50)). Unported capabilities drop from four to three, all on the Veo path | | 2026-09-17 | REST transport removed — the ten `_legacy_*` methods, the `USE_BATCH_RPC` branches, the fingerprint pools and `agent/services/headers.py`; net −1043 lines ([#49](../../pull/49)) | | 2026-09-17 | Migrated image API: variant submit, settled-wave retry, and 2K/4K image export via `SPrCad` ([#42](../../pull/42)) | diff --git a/agent/main.py b/agent/main.py index 9649c8075..46f3a2ba8 100644 --- a/agent/main.py +++ b/agent/main.py @@ -113,7 +113,7 @@ async def lifespan(app: FastAPI): logger.info("Flow Kit stopped") -app = FastAPI(title="Flow Kit", version="1.1.0", lifespan=lifespan) +app = FastAPI(title="Flow Kit", version="1.2.0", lifespan=lifespan) app.add_middleware( CORSMiddleware, @@ -171,7 +171,7 @@ async def health(): client = get_flow_client() return { "status": "ok", - "version": "0.2.0", + "version": app.version, "extension_connected": client.connected, "ws": client.ws_stats, } From 4fc02835bc5b9764fc951df801ee338e6ebb70b3 Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Sun, 20 Sep 2026 00:51:56 +0700 Subject: [PATCH 23/68] fix(review): repair every provider path, add per-role AI config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Video review was failing on four independent paths at once, which is why none of them looked fixable from the symptoms. All four verified live against the installed binaries, not inferred. ffmpeg without drawtext. Homebrew's ffmpeg 8.x is built without libfreetype, so `drawtext` does not exist, and naming an absent filter aborts the whole chain ("No such filter: 'drawtext'"). Frame extraction died before any provider ran — the repo's own 13 contact-sheet tests fail on main for this reason. Probed once and cached; without it the sheets lose their burned-in timestamps and the prompt hands the model the frame interval instead, so it can still answer in time ranges. agy was auto-denied. Given a bare file path agy shells out to look at the file; headless mode cannot prompt for that permission, so the tool is denied and the run returns an empty response with exit code 0 and status SUCCESS. Steering it at its own file-reading tool gets the read done unprivileged, so --dangerously-skip-permissions — which auto-approves every tool including arbitrary shell commands, for a job that reads three JPEGs — is gone. Output now comes from --output-format json, and a denied tool is an error whether or not agy still answered: the prompt carries the rubric, both scene prompts and the character names, which is enough to write a plausible review without looking at a frame. codex no longer bypasses its sandbox. -i hands it the image bytes directly, so the run needs neither a shell nor a writable filesystem; --sandbox read-only already implies approval:never. An empty output file is an error instead of a JSON decode failure three frames away. stdin is closed for all three. Each appends piped stdin to the prompt when stdin is not a terminal — codex documents it as a `<stdin>` block. Two silent-wrong-answer paths in the scoring, same class, both pre-existing: - Every dimension defaults to 5.0, so an answer carrying no `dimensions` became a complete, plausible review — 5.0 across the board, verdict "poor", zero errors — of a video nothing had looked at. Now refused; a partial dimensions object still defaults the unscored axes. - The error parser required the exact keys severity/time_range/description and silently dropped anything else. What it dropped was usually CRITICAL, the one severity that caps character_consistency at 3.0 and forces the verdict below acceptable, so `timeRange` turned an unusable video into a clean pass. The three fields are now handled by what they can cost: near-miss names are normalised, a missing time range or description is repaired and logged, and only a severity outside {CRITICAL, HIGH, MINOR} fails the scene. VideoError.severity is a Literal now, so the three code paths that branch on it cannot be handed anything else. Per-role provider, model and effort. agent/services/cli_providers.py holds everything the three CLIs disagree about; providers.json gains a `roles` map and the dashboard gains a Settings page. Efforts are validated against each CLI's real ladder; models only for agy, whose catalog is closed, so a slug newer than claude's or codex's cache still goes through. agy's model and effort are mutually exclusive — its slugs name their own effort and it rejects the pair. The legacy {"active": ...} switch still works, keeps a model when the CLI did not change, and does not undo a role the same request configured by name. Tests 259 passing / 13 failing on main -> 338 passing, 0 failing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ka5BxVaWiQeWNDJakpCJJP --- CLAUDE.md | 2 +- README.md | 77 +++- agent/api/providers.py | 169 ++++++- agent/main.py | 2 +- agent/models/review.py | 9 +- agent/providers.json | 9 +- agent/services/cli_providers.py | 289 ++++++++++++ agent/services/video_reviewer.py | 400 +++++++++++++--- dashboard/src/App.tsx | 6 +- dashboard/src/i18n/translations.ts | 267 +++++++++++ dashboard/src/pages/SettingsPage.tsx | 359 +++++++++++++++ dashboard/src/types/index.ts | 47 ++ skills/fk-change-provider.md | 127 +++-- skills/fk-doctor.md | 20 + tests/unit/test_cli_providers.py | 666 +++++++++++++++++++++++++-- tests/unit/test_video_reviewer.py | 170 +++++++ 16 files changed, 2448 insertions(+), 171 deletions(-) create mode 100644 agent/services/cli_providers.py create mode 100644 dashboard/src/pages/SettingsPage.tsx diff --git a/CLAUDE.md b/CLAUDE.md index 4c4ca2052..599bb43dc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -67,7 +67,7 @@ that change how you work: | `/fk-doctor` | Diagnose errors + prescribe fixes (Flow/extension/worker/YT) | | `/fk-add-material` | Set image material style | | `/fk-change-model` | Change video/image model | -| `/fk-change-provider` | View & switch AI CLI provider used for video review (claude/agy/codex) | +| `/fk-change-provider` | View & switch the AI CLI, model and effort per role (claude/agy/codex) | | `/fk-insert-scene` | Insert scenes into chain | | `/fk-upload-image` | Upload local image to get media_id | | `/fk-thumbnail` | Generate YouTube thumbnails | diff --git a/README.md b/README.md index ea66235c6..5c3411477 100644 --- a/README.md +++ b/README.md @@ -499,7 +499,7 @@ Ready-to-use workflow recipes in `skills/` (also available as `/slash-commands` |-------|-------------| | `/fk-review-video` | AI vision scoring of generated scene videos (quality, consistency, usability) — see [AI Vision Providers](#ai-vision-providers-video-review) below | | `/fk-review-board` | Visual scene-by-scene review board for feedback before locking a cut | -| `/fk-change-provider` | View/switch which AI CLI (claude/agy/codex) powers `/fk-review-video` | +| `/fk-change-provider` | View/switch the AI CLI, model and effort behind `/fk-review-video` | ### Reference @@ -556,22 +556,62 @@ Skills are `.md` recipes any AI coding-assistant CLI can read and follow — thi Separate from the table above — this is about **which CLI backend does the vision analysis** for `/fk-review-video`. Three providers are supported and swappable at runtime, no restart required: -| Provider | Binary | Setup | -|----------|--------|-------| -| `claude` | Claude Code CLI | Default — works out of the box | -| `agy` | Google Antigravity CLI | Install separately, sign in once | -| `codex` | OpenAI Codex CLI | `npm install -g @openai/codex`, then `codex login` once | +| Provider | Binary | Reasoning efforts | Model catalog | Setup | +|----------|--------|-------------------|---------------|-------| +| `claude` | Claude Code CLI | `low` `medium` `high` `xhigh` `max` | aliases (`sonnet`, `opus`, `haiku`, `fable`) or any full model name | Default — works out of the box | +| `agy` | Google Antigravity CLI | `low` `medium` `high` | closed — `agy models` is the whole list and agy rejects anything else | Install separately, sign in once | +| `codex` | OpenAI Codex CLI | `low` `medium` `high` `xhigh` `max` (varies per model) | codex's own on-disk cache, plus slugs newer than it | `npm install -g @openai/codex`, then `codex login` once | + +Provider, model and effort are set **per role** — a role being a job an AI CLI +does for Flow Kit. There is one today, `video_review`; the config is a map so +the next one is an entry rather than a schema change. Model and effort may both +be `null`, meaning "whatever that CLI defaults to". + +**For `agy`, model and effort are mutually exclusive.** Its slugs name their own +effort — `gemini-3.8-flash-low`, `gemini-3.1-pro-high` — so setting both is +rejected (`--model gpt-oss-120b-medium conflicts with --effort=low`), and a slug +with no effort in its name refuses `--effort` outright +(`--effort is not supported for model "claude-sonnet-4-6"`). Pick a model, or +pick an effort and let agy choose the model. The API answers 400 for the pair. ```bash -# View provider status (installed / version-tested / currently active) +# View provider status + the current per-role config +# live=true additionally runs `<binary> --version` on each (a few seconds) curl -s "http://127.0.0.1:8100/api/providers?live=true" | python3 -m json.tool -# Switch provider — hot-reloaded immediately, no server restart +# List a provider's models (refresh=true bypasses the 5-minute cache) +curl -s "http://127.0.0.1:8100/api/providers/models?provider=agy" | python3 -m json.tool + +# Point a role at a provider/model/effort — hot-reloaded, no server restart +curl -X PATCH http://127.0.0.1:8100/api/providers \ + -H "Content-Type: application/json" \ + -d '{"roles": {"video_review": {"provider": "claude", "model": "sonnet", "effort": "high"}}}' + +# agy takes a model OR an effort, never both — its slugs name their own effort +curl -X PATCH http://127.0.0.1:8100/api/providers \ + -H "Content-Type: application/json" \ + -d '{"roles": {"video_review": {"provider": "agy", "model": "gemini-3.8-flash-low"}}}' + +# The older whole-agent switch still works. It also clears each role's model +# (a slug means nothing to a different CLI) and drops an effort the new +# provider does not have. curl -X PATCH http://127.0.0.1:8100/api/providers \ -H "Content-Type: application/json" -d '{"active": "agy"}' ``` -Or just run `/fk-change-provider` for an interactive picker. Full details in `skills/fk-change-provider.md`. +Or edit it in the dashboard under **Settings**, or run `/fk-change-provider` for +an interactive picker. Full details in `skills/fk-change-provider.md`. + +**`codex` needs credits on its OpenAI workspace.** `installed: true` only means +the binary is on PATH; a workspace with no balance fails every review with +`ERROR: Your workspace is out of credits`. + +**Contact sheets lose their timestamps on an ffmpeg without `libfreetype`.** +Homebrew's ffmpeg 8.x is one such build: `drawtext` is simply absent, and +naming a filter that does not exist aborts the whole chain. Flow Kit probes for +it once and falls back to untimestamped frames, telling the model the frame +interval instead so it can still answer in time ranges. `ffmpeg -filters | grep +drawtext` shows whether yours has it. ## Video Generation Techniques @@ -668,7 +708,7 @@ agent/ ├── main.py # FastAPI app + WebSocket server ├── config.py # Configuration (loads models.json, providers.json) ├── models.json # Video/upscale/image model mappings -├── providers.json # Active AI CLI provider for video review (claude/agy/codex) +├── providers.json # Per-role AI CLI provider/model/effort (claude/agy/codex) ├── db/ │ ├── schema.py # SQLite schema (aiosqlite) │ └── crud.py # Async CRUD with column whitelisting @@ -679,6 +719,7 @@ agent/ │ ├── flow_client.py # WS bridge to extension │ ├── tts.py # OmniVoice TTS (subprocess-based) │ ├── scene_chain.py # Continuation scene logic +│ ├── cli_providers.py # What each AI CLI accepts; role → provider/model/effort │ ├── video_reviewer.py # AI vision review — contact sheet + claude/agy/codex CLI dispatch │ └── post_process.py # ffmpeg trim/merge/music └── worker/ @@ -861,6 +902,22 @@ From `youtube/upload.py` (HTTP errors from YouTube Data API v3): Dates are merge dates. Older releases are tagged; `git log` is the full record. +### v1.3.0 — 2026-09-20 — video review works again + +Video review had been failing on every path at once, which is why nothing about +it looked fixable from the symptoms. + +| Date | Change | +|---|---| +| 2026-09-20 | **ffmpeg without `drawtext`**: Homebrew's ffmpeg 8.x is built without `libfreetype`, so the timestamp filter does not exist and naming it aborted the whole chain — frame extraction died before any provider was reached. Probed once, with a fallback to untimestamped frames and a prompt that hands the model the frame interval instead | +| 2026-09-20 | **`agy` was auto-denied**: handed a bare file path, agy reaches for a shell command to look at the file, headless mode cannot prompt for that permission, and the run returns an empty response on a **zero** exit code. Fixed by steering it at its own file-reading tool and naming the sheet directory with `--add-dir`, which gets the read done unprivileged — so `--dangerously-skip-permissions`, which auto-approves every tool including arbitrary shell commands, is gone. Output is parsed from `--output-format json`, and a denied tool is an error whether or not agy still answered — the prompt carries the rubric and both scene prompts, so a denied run can write a plausible review from the text alone | +| 2026-09-20 | **`codex` no longer bypasses its sandbox**: `-i` hands codex the image bytes directly, so the run needs neither a shell nor a writable filesystem. `--dangerously-bypass-approvals-and-sandbox` bought nothing and cost the sandbox; `--sandbox read-only` already implies `approval: never`. An empty output file is now an error instead of a JSON decode failure three frames away | +| 2026-09-20 | **A malformed error entry no longer vanishes.** The parser required the exact keys `severity`/`time_range`/`description` and silently dropped anything else — and what it dropped was usually CRITICAL, the one severity that caps `character_consistency` at 3.0 and forces the verdict below acceptable, so `timeRange` instead of `time_range` turned an unusable video into a clean pass. The three fields are now handled by what they can cost: near-miss names are normalised, a missing time range or description is repaired and logged, and only a severity outside `{CRITICAL, HIGH, MINOR}` fails the scene — that is the one field with no safe default, because without it we do not know whether the video passed. `VideoError.severity` is a `Literal` now, so the three code paths that branch on it cannot be handed anything else | +| 2026-09-20 | **A review with no scores in it is now a failure, not a score.** Every dimension defaults to 5.0, so a CLI answer carrying no `dimensions` became a complete, plausible review — 5.0 across the board, verdict "poor", zero errors — of a video nothing had actually looked at | +| 2026-09-20 | **stdin closed for all three CLIs.** Each appends piped stdin to the prompt when stdin is not a terminal — codex documents it as a `<stdin>` block. Under uvicorn that is whatever the launching shell handed down | +| 2026-09-20 | **Per-role provider, model and effort**, editable in the dashboard under Settings or via `PATCH /api/providers`. Efforts are validated against each CLI's real ladder (agy stops at `high`); models are validated only for agy, whose catalog is closed, so a slug newer than claude's or codex's cache still goes through. A whole-agent `{"active": …}` switch clears each role's model and clamps its effort, because neither survives a change of CLI | +| 2026-09-20 | **agy's model and effort are mutually exclusive** and the config now says so. Its slugs name their own effort (`gemini-3.8-flash-low`), so the pair is rejected — a mismatch conflicts, and a slug with no effort in its name refuses `--effort` at all | + ### v1.2.0 — 2026-09-18 — the Flow migration Flow moved to `flow.google.com` in September 2026 and stopped minting the bearer diff --git a/agent/api/providers.py b/agent/api/providers.py index 697c4f6d4..a16f1430d 100644 --- a/agent/api/providers.py +++ b/agent/api/providers.py @@ -1,14 +1,29 @@ -"""CLI provider config API — view/switch which AI CLI backend runs video review.""" +"""CLI provider config API — which AI CLI, model and effort each role runs on. + +`active` is the legacy single-provider switch that `/fk-change-provider` and the +statusline still use; `roles` is the per-role configuration the dashboard edits. +The two are kept consistent by every write here, so neither reader ever sees a +stale answer. +""" import asyncio import json import logging import shutil from pathlib import Path -from fastapi import APIRouter, HTTPException +from fastapi import APIRouter, HTTPException, Query from agent import config -from agent.services.video_reviewer import PROVIDER_BINARIES +from agent.services.cli_providers import ( + PROVIDER_BINARIES, + PROVIDER_CATALOG_IS_AUTHORITATIVE, + PROVIDER_EFFORTS, + PROVIDER_MODEL_ENCODES_EFFORT, + ROLES, + current_roles, + list_models, + validate_role_entry, +) router = APIRouter(prefix="/api/providers", tags=["providers"]) logger = logging.getLogger(__name__) @@ -16,8 +31,20 @@ def _read() -> dict: + """Read providers.json and hot-reload it into `config.CLI_PROVIDERS`. + + The file is the source of truth, and it is editable by hand (the skills + do), so re-reading it here is what makes a hand edit take effect without a + restart — and what stops a GET describing a state the worker is not in. + """ with open(_PROVIDERS_FILE) as f: - return json.load(f) + data = json.load(f) + data.setdefault("active", "claude") + data.setdefault("roles", {}) + # Same no-await-in-the-gap rule as _apply. + config.CLI_PROVIDERS.clear() + config.CLI_PROVIDERS.update(data) + return data def _write(data: dict): @@ -26,10 +53,26 @@ def _write(data: dict): f.write("\n") +def _apply(data: dict): + """Persist and hot-reload. config.CLI_PROVIDERS is mutated, never rebound, + because callers hold a reference to that same dict. + + The clear/update pair leaves a momentarily empty dict. That is safe only + because no `await` separates the two lines: this runs on the event loop, so + a concurrent `resolve_role` cannot be scheduled into the gap. Do not put an + await between them — a review landing in that window would silently fall + back to the default provider. + """ + _write(data) + config.CLI_PROVIDERS.clear() + config.CLI_PROVIDERS.update(data) + + async def _probe_version(binary: str) -> tuple: try: proc = await asyncio.create_subprocess_exec( binary, "--version", + stdin=asyncio.subprocess.DEVNULL, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) _, stderr = await asyncio.wait_for(proc.communicate(), timeout=10) @@ -40,27 +83,117 @@ async def _probe_version(binary: str) -> tuple: @router.get("") async def get_providers(live: bool = False): - """Return provider status: installed (on PATH) and, if live=true, version-tested.""" + """Provider status plus the per-role configuration. + + `live=true` runs a real `<binary> --version` per provider, which costs a + few seconds — it is opt-in for that reason, not the default. + """ data = _read() statuses = {} for name, binary in PROVIDER_BINARIES.items(): installed = shutil.which(binary) is not None tested, error = (await _probe_version(binary)) if (live and installed) else (None, None) - statuses[name] = {"binary": binary, "installed": installed, "tested": tested, "error": error} - return {"active": data["active"], "providers": statuses} + statuses[name] = { + "binary": binary, + "installed": installed, + "tested": tested, + "error": error, + "efforts": list(PROVIDER_EFFORTS[name]), + "default_model": None, + "catalog_is_authoritative": PROVIDER_CATALOG_IS_AUTHORITATIVE[name], + "model_encodes_effort": PROVIDER_MODEL_ENCODES_EFFORT[name], + } + return { + "active": data["active"], + "roles": current_roles(), + "role_meta": ROLES, + "providers": statuses, + } + + +@router.get("/models") +async def get_provider_models( + provider: str = Query(..., description="claude | agy | codex"), + refresh: bool = Query(False, description="Bypass the 5-minute catalog cache"), +): + """List a provider's models. + + An empty list is a normal answer, not an error: it means the binary is + absent or the catalog call failed, and the caller should fall back to the + provider's own default. + """ + if provider not in PROVIDER_BINARIES: + raise HTTPException(400, f"Unknown provider '{provider}'. Known: {sorted(PROVIDER_BINARIES)}") + models = await list_models(provider, force=refresh) + return { + "provider": provider, + "models": models, + "authoritative": PROVIDER_CATALOG_IS_AUTHORITATIVE[provider], + } @router.patch("") async def patch_providers(body: dict): - """Switch the active CLI provider. Body: {"active": "claude"|"agy"|"codex"}.""" - provider = body.get("active") - if provider not in PROVIDER_BINARIES: - raise HTTPException(400, f"Unknown provider '{provider}'. Known: {list(PROVIDER_BINARIES)}") - if not shutil.which(PROVIDER_BINARIES[provider]): - raise HTTPException(400, f"'{PROVIDER_BINARIES[provider]}' binary not found on PATH — install it first") + """Update the active provider, the per-role config, or both. + + Body is either the legacy `{"active": "claude"}` or + `{"roles": {"video_review": {"provider": ..., "model": ..., "effort": ...}}}`. + """ + if not isinstance(body, dict) or ("active" not in body and "roles" not in body): + raise HTTPException(400, "Body must contain 'active', 'roles', or both") + data = _read() - data["active"] = provider - _write(data) - config.CLI_PROVIDERS.clear() - config.CLI_PROVIDERS.update(data) - return {"status": "updated", "active": provider} + roles = dict(data.get("roles") or {}) + + explicit = set() + if "roles" in body: + incoming = body["roles"] + if not isinstance(incoming, dict): + raise HTTPException(400, "'roles' must be an object keyed by role name") + for role, entry in incoming.items(): + try: + roles[role] = validate_role_entry(role, entry) + except ValueError as e: + raise HTTPException(400, str(e)) + explicit = set(incoming) + + if "active" in body: + provider = body["active"] + if provider not in PROVIDER_BINARIES: + raise HTTPException(400, f"Unknown provider '{provider}'. Known: {list(PROVIDER_BINARIES)}") + if not shutil.which(PROVIDER_BINARIES[provider]): + raise HTTPException(400, f"'{PROVIDER_BINARIES[provider]}' binary not found on PATH — install it first") + data["active"] = provider + # Switching the whole agent over has to carry the roles with it. + for role in list(roles) + [r for r in ROLES if r not in roles]: + if role in explicit: + # The same request configured this role by name. That is the + # more specific instruction and it already passed validation — + # the sweep must not undo it. + continue + prev = roles.get(role) or {} + # A model slug only survives if the CLI did not change: agy would + # reject "sonnet" outright. Re-asserting the provider a role is + # already on must not cost the user their model. + model = prev.get("model") if prev.get("provider") == provider else None + effort = prev.get("effort") + if effort not in PROVIDER_EFFORTS[provider]: + effort = None # agy has no xhigh or max + if model and effort and PROVIDER_MODEL_ENCODES_EFFORT[provider]: + # Only reachable from a hand-edited file — the API refuses to + # store the pair — but persisting it would fail the next review. + effort = None + roles[role] = {"provider": provider, "model": model, "effort": effort} + + data["roles"] = roles + + if "active" not in body and roles: + # Keep the legacy field meaningful for /fk-change-provider and the + # statusline: it reports whatever the primary role runs on. + primary = next(iter(ROLES)) + if primary in roles: + data["active"] = roles[primary]["provider"] + + _apply(data) + logger.info("Providers updated: active=%s roles=%s", data["active"], data["roles"]) + return {"status": "updated", "active": data["active"], "roles": data["roles"]} diff --git a/agent/main.py b/agent/main.py index 46f3a2ba8..4d3bc351a 100644 --- a/agent/main.py +++ b/agent/main.py @@ -113,7 +113,7 @@ async def lifespan(app: FastAPI): logger.info("Flow Kit stopped") -app = FastAPI(title="Flow Kit", version="1.2.0", lifespan=lifespan) +app = FastAPI(title="Flow Kit", version="1.3.0", lifespan=lifespan) app.add_middleware( CORSMiddleware, diff --git a/agent/models/review.py b/agent/models/review.py index d834f3f2e..562f2bb14 100644 --- a/agent/models/review.py +++ b/agent/models/review.py @@ -1,6 +1,6 @@ """Pydantic models for video review results.""" from pydantic import BaseModel -from typing import Optional +from typing import Literal, Optional class SegmentScore(BaseModel): @@ -9,7 +9,12 @@ class SegmentScore(BaseModel): class VideoError(BaseModel): - severity: str # CRITICAL / HIGH / MINOR + # Closed on purpose. `has_critical_errors`, the character_consistency cap + # and `_fix_guide` all branch on this exact string, so a severity outside + # the set is not a cosmetic oddity — it silently disables all three. + # Reviews are computed and returned, never read back from storage, so + # narrowing the type cannot break a load of old data. + severity: Literal["CRITICAL", "HIGH", "MINOR"] time_range: str description: str diff --git a/agent/providers.json b/agent/providers.json index 80d74b117..705c0bc33 100644 --- a/agent/providers.json +++ b/agent/providers.json @@ -1,3 +1,10 @@ { - "active": "claude" + "active": "claude", + "roles": { + "video_review": { + "provider": "claude", + "model": null, + "effort": null + } + } } diff --git a/agent/services/cli_providers.py b/agent/services/cli_providers.py new file mode 100644 index 000000000..ea73bc61b --- /dev/null +++ b/agent/services/cli_providers.py @@ -0,0 +1,289 @@ +"""What each AI CLI accepts, and which one a given role runs on. + +Three CLIs back the vision work: Claude Code (`claude`), Google Antigravity +(`agy`) and OpenAI Codex (`codex`). They disagree about almost everything — +flag names, effort ladders, whether an unknown model slug is an error — so the +differences live here rather than being re-derived at each call site. + +Config lives in `agent/providers.json`, hot-reloaded into `config.CLI_PROVIDERS`: + + {"active": "claude", + "roles": {"video_review": {"provider": "agy", "model": null, "effort": "low"}}} + +`active` predates `roles` and is still the fallback for any role without an +entry, so an old providers.json keeps working untouched. +""" +from __future__ import annotations + +import asyncio +import json +import logging +import shutil +import time +from pathlib import Path + +from agent import config + +logger = logging.getLogger(__name__) + + +PROVIDER_BINARIES = { + "claude": "claude", + "agy": "agy", + "codex": "codex", +} + +# Reasoning-effort ladders, as each CLI actually accepts them. agy's own help +# spells out "(low|medium|high)" and it rejects anything outside that; claude +# and codex both take the longer ladder. Codex's real ladder is per-model +# (`supported_reasoning_levels` in its cache) — this is the union, and codex +# itself rejects a level its chosen model does not support. +PROVIDER_EFFORTS = { + "claude": ("low", "medium", "high", "xhigh", "max"), + "agy": ("low", "medium", "high"), + "codex": ("low", "medium", "high", "xhigh", "max"), +} + +# agy's model slugs carry the effort in them — gemini-3.8-flash-low, +# gemini-3.1-pro-high — so --model and --effort are not independent there. +# Verified against agy 1.2.7: a mismatched pair is rejected ("--model +# gpt-oss-120b-medium conflicts with --effort=low") and a model with no effort +# in its name rejects --effort outright ("--effort is not supported for model +# claude-sonnet-4-6"). Even a *matching* pair only restates the slug. So for +# agy, effort is what you set when you have NOT picked a model. +PROVIDER_MODEL_ENCODES_EFFORT = { + "claude": False, + "agy": True, + "codex": False, +} + +# Whether the catalog we can list is the whole truth. agy validates --model +# against `agy models` and errors out on anything else, so its list is closed. +# claude takes aliases (sonnet, opus) as well as full names, and codex takes +# slugs newer than whatever its on-disk cache happens to hold — for those two, +# an unlisted value is a legitimate escape hatch, not a typo to reject. +PROVIDER_CATALOG_IS_AUTHORITATIVE = { + "claude": False, + "agy": True, + "codex": False, +} + +# Claude Code resolves these aliases itself; full model names also work, which +# is why claude's catalog is not authoritative. +_CLAUDE_ALIASES = [ + {"id": "fable", "label": "Fable"}, + {"id": "opus", "label": "Opus"}, + {"id": "sonnet", "label": "Sonnet"}, + {"id": "haiku", "label": "Haiku"}, +] + +_CODEX_MODELS_CACHE = Path.home() / ".codex" / "models_cache.json" + +# Roles are the jobs an AI CLI does for Flow Kit. One today; the shape is a map +# so adding the next one is a dict entry rather than a schema change. +ROLES = { + "video_review": { + "label": "Video Review", + "description": "Vision analysis of contact sheets during scene video review", + }, +} + +DEFAULT_PROVIDER = "claude" + +_CATALOG_TTL_S = 300.0 +# Unlocked on purpose. Two concurrent misses for the same provider both run the +# listing and the second overwrites the first with the same answer — a wasted +# subprocess, never a wrong result. A lock would cost more than it buys. +_catalog_cache: dict[str, tuple[float, list[dict]]] = {} + + +# ── role resolution ─────────────────────────────────────────── + + +def resolve_role(role: str) -> dict: + """Return {provider, model, effort} for `role`. + + Never raises and never returns an unusable provider: a role naming a + provider we do not know, or an effort outside that provider's ladder, is + logged and dropped rather than passed to a subprocess that would reject it + several seconds later with a worse error. + """ + cfg = config.CLI_PROVIDERS + roles = cfg.get("roles") or {} + entry = roles.get(role) or {} + + provider = entry.get("provider") or cfg.get("active") or DEFAULT_PROVIDER + if provider not in PROVIDER_BINARIES: + logger.warning( + "Role %r names unknown provider %r — falling back to %s", + role, provider, DEFAULT_PROVIDER, + ) + provider = DEFAULT_PROVIDER + + effort = entry.get("effort") or None + if effort and effort not in PROVIDER_EFFORTS[provider]: + logger.warning( + "Dropping effort %r for role %r — %s accepts %s", + effort, role, provider, list(PROVIDER_EFFORTS[provider]), + ) + effort = None + + return { + "provider": provider, + "model": entry.get("model") or None, + "effort": effort, + } + + +def validate_role_entry(role: str, entry: dict) -> dict: + """Normalise one role entry from an API body. Raises ValueError on bad input. + + The model is deliberately *not* checked against the catalog for claude and + codex — see PROVIDER_CATALOG_IS_AUTHORITATIVE. + """ + if role not in ROLES: + raise ValueError(f"Unknown role '{role}'. Known: {sorted(ROLES)}") + if not isinstance(entry, dict): + raise ValueError(f"Role '{role}' must be an object, got {type(entry).__name__}") + + provider = entry.get("provider") + if provider not in PROVIDER_BINARIES: + raise ValueError( + f"Unknown provider '{provider}' for role '{role}'. Known: {sorted(PROVIDER_BINARIES)}" + ) + if not shutil.which(PROVIDER_BINARIES[provider]): + raise ValueError( + f"'{PROVIDER_BINARIES[provider]}' binary not found on PATH — install it first" + ) + + effort = entry.get("effort") or None + if effort is not None and effort not in PROVIDER_EFFORTS[provider]: + raise ValueError( + f"Effort '{effort}' is not supported by {provider}. " + f"Supported: {list(PROVIDER_EFFORTS[provider])}" + ) + + model = entry.get("model") or None + if model is not None and effort is not None and PROVIDER_MODEL_ENCODES_EFFORT[provider]: + raise ValueError( + f"{provider} encodes the effort in the model name, so '{model}' and " + f"effort '{effort}' cannot both be set — pick one" + ) + if model is not None and not isinstance(model, str): + raise ValueError(f"Model for role '{role}' must be a string or null") + if model is not None and model.startswith("-"): + # The model is otherwise unvalidated on purpose (the escape hatch for a + # slug newer than any catalog), and it lands in argv next to --model. + # No real slug starts with a dash, and refusing them removes any + # argument left to have about what a CLI's parser does with one. + raise ValueError(f"Model for role '{role}' must not start with '-'") + + return {"provider": provider, "model": model, "effort": effort} + + +def current_roles() -> dict: + """Every known role resolved, including ones absent from providers.json.""" + return {role: resolve_role(role) for role in ROLES} + + +# ── model catalogs ──────────────────────────────────────────── + + +async def _list_agy_models() -> list[dict]: + """Parse `agy models`, whose output is a header line then `<id>\\tLabel`.""" + proc = await asyncio.create_subprocess_exec( + "agy", "models", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + stdin=asyncio.subprocess.DEVNULL, + ) + try: + stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=30) + except asyncio.TimeoutError: + proc.kill() + await proc.communicate() + raise RuntimeError("`agy models` timed out after 30s") + if proc.returncode != 0: + raise RuntimeError(f"`agy models` failed (rc={proc.returncode}): {stderr.decode()[-300:]}") + + models = [] + for line in stdout.decode().splitlines(): + # The first line is "Fetching available models..." — no tab, so it and + # any other chatter drop out without needing to be named here. + if "\t" not in line: + continue + slug, _, label = line.partition("\t") + slug, label = slug.strip(), label.strip() + if slug: + models.append({"id": slug, "label": label or slug}) + return models + + +def _list_codex_models() -> list[dict]: + """Read codex's own on-disk catalog. + + `codex models` is interactive — run headlessly it dies with "stdin is not + a terminal" — so the cache the CLI maintains is the only listing available + to a server process. + """ + if not _CODEX_MODELS_CACHE.exists(): + return [] + with open(_CODEX_MODELS_CACHE) as f: + data = json.load(f) + models = [] + for entry in data.get("models") or []: + if not isinstance(entry, dict) or entry.get("visibility") != "list": + continue + slug = entry.get("slug") + if not slug: + continue + efforts = [ + lvl.get("effort") + for lvl in entry.get("supported_reasoning_levels") or [] + if isinstance(lvl, dict) and lvl.get("effort") + ] + models.append({ + "id": slug, + "label": entry.get("display_name") or slug, + "efforts": efforts, + }) + return models + + +async def list_models(provider: str, force: bool = False) -> list[dict]: + """Model catalog for `provider`, TTL-cached. + + An empty catalog is never cached: it means the binary was missing or the + listing call failed, and both are transient in a way a real empty list is + not. + """ + if provider not in PROVIDER_BINARIES: + raise ValueError(f"Unknown provider '{provider}'") + + now = time.monotonic() + if not force: + hit = _catalog_cache.get(provider) + if hit and now - hit[0] < _CATALOG_TTL_S: + return hit[1] + + if not shutil.which(PROVIDER_BINARIES[provider]): + return [] + + try: + if provider == "agy": + models = await _list_agy_models() + elif provider == "codex": + models = await asyncio.to_thread(_list_codex_models) + else: + models = list(_CLAUDE_ALIASES) + except Exception as e: + logger.warning("Model catalog for %s unavailable: %s", provider, e) + return [] + + if models: + _catalog_cache[provider] = (now, models) + return models + + +def clear_catalog_cache() -> None: + _catalog_cache.clear() diff --git a/agent/services/video_reviewer.py b/agent/services/video_reviewer.py index 013d4e15b..f47cfa440 100644 --- a/agent/services/video_reviewer.py +++ b/agent/services/video_reviewer.py @@ -6,9 +6,11 @@ """ import asyncio import base64 +import functools import json import logging import os +import re import subprocess import tempfile from pathlib import Path @@ -31,6 +33,10 @@ ) from agent.db.crud import list_scenes, get_project_characters from agent.models.review import DimensionScores, SceneReview, SegmentScore, VideoError, VideoReview +from agent.services.cli_providers import ( # noqa: F401 (PROVIDER_BINARIES re-exported) + PROVIDER_BINARIES, + resolve_role, +) logger = logging.getLogger(__name__) @@ -189,8 +195,49 @@ def _frame_to_base64(path: Path) -> str: return base64.standard_b64encode(path.read_bytes()).decode() +@functools.lru_cache(maxsize=1) +def _has_drawtext() -> bool: + """Whether this ffmpeg build carries the `drawtext` filter. + + Homebrew's ffmpeg 8.x is built without libfreetype, so `drawtext` is simply + absent and any filter chain naming it aborts with "No such filter: + 'drawtext'". That took down the whole review path, not just the timestamps + it was there to draw. Probe once and degrade to untimestamped frames. + """ + try: + out = subprocess.run( + ["ffmpeg", "-hide_banner", "-filters"], + capture_output=True, text=True, timeout=30, + ) + except (OSError, subprocess.SubprocessError) as e: + logger.warning("Could not list ffmpeg filters (%s) — assuming no drawtext", e) + return False + present = re.search(r"^\s*\S+\s+drawtext\s", out.stdout, re.MULTILINE) is not None + if not present: + logger.warning( + "ffmpeg has no drawtext filter (no libfreetype) — contact sheets will " + "carry no burned-in timestamps; the vision prompt compensates by " + "describing frame order and interval instead" + ) + return present + + +def _frame_filter(fps: float) -> str: + """Filter chain for contact-sheet frames, timestamped where ffmpeg allows.""" + chain = f"fps={fps},scale=320:-1" + if _has_drawtext(): + chain += ( + ",drawtext=text='%{pts\\:hms}':x=5:y=5:fontsize=14:" + "fontcolor=white:borderw=1:bordercolor=black" + ) + return chain + + def _create_contact_sheets(video_path: str, fps: float, out_dir: str) -> tuple[list[Path], int]: - """Extract all frames (timestamped) and tile them into REVIEW_SHEET_COLSxREVIEW_SHEET_ROWS sheets. + """Extract all frames and tile them into REVIEW_SHEET_COLSxREVIEW_SHEET_ROWS sheets. + + Frames carry burned-in timestamps only where ffmpeg has `drawtext` — see + `_frame_filter`. `_analyze_cli` words the prompt to match either way. Returns (sheet_paths in chronological order, total_frames after any REVIEW_MAX_FRAMES cap). """ @@ -198,12 +245,7 @@ def _create_contact_sheets(video_path: str, fps: float, out_dir: str) -> tuple[l frames_dir.mkdir(exist_ok=True) extract_cmd = [ "ffmpeg", "-y", "-i", video_path, - "-vf", ( - f"fps={fps}," - f"scale=320:-1," - f"drawtext=text='%{{pts\\:hms}}':x=5:y=5:fontsize=14:" - f"fontcolor=white:borderw=1:bordercolor=black" - ), + "-vf", _frame_filter(fps), "-q:v", "2", f"{frames_dir}/frame_%04d.jpg", ] @@ -330,6 +372,31 @@ def _build_prompt(n_frames: int, fps: float, n_sheets: int, scene: dict) -> str: ) +# Model answers stray on field *names* far more often than on values. These are +# the near-misses worth absorbing; anything outside the map is left alone and +# judged on its merits below. Keys are compared with underscores stripped and +# lowercased, so `timeRange` and `time_range` land on the same entry. +_ERROR_KEY_ALIASES = { + "timerange": "time_range", + "time": "time_range", + "desc": "description", + "level": "severity", +} +_SEGMENT_KEY_ALIASES = { + "timerange": "time_range", + "time": "time_range", +} +_SEVERITIES = ("CRITICAL", "HIGH", "MINOR") + + +def _normalise_keys(entry: dict, aliases: dict) -> dict: + """Rename near-miss keys onto the names the rubric asked for.""" + return { + aliases.get(str(k).replace("_", "").lower(), k): v + for k, v in entry.items() + } + + def _parse_json_response(raw: str) -> dict: """Extract JSON from a response that may contain markdown fences.""" raw = raw.strip() @@ -348,11 +415,8 @@ def _parse_json_response(raw: str) -> dict: # ─── Backend 1: CLI providers (default, no API key needed) ─── -PROVIDER_BINARIES = { - "claude": "claude", - "agy": "agy", - "codex": "codex", -} +# PROVIDER_BINARIES and resolve_role are imported from agent.services.cli_providers, +# which is where everything the three CLIs disagree about now lives. async def _communicate_with_timeout(proc, provider: str) -> tuple: @@ -365,8 +429,16 @@ async def _communicate_with_timeout(proc, provider: str) -> tuple: async def _spawn_and_check(args: tuple, provider: str) -> bytes: + # stdin is closed deliberately. All three CLIs read piped stdin when it is + # not a terminal and append it to the prompt — codex says so in its own + # --help ("stdin is appended as a `<stdin>` block"). Under uvicorn stdin is + # whatever the launching shell handed down, which is nothing we want in a + # vision prompt. proc = await asyncio.create_subprocess_exec( - *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, + *args, + stdin=asyncio.subprocess.DEVNULL, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) stdout, stderr = await _communicate_with_timeout(proc, provider) if proc.returncode != 0: @@ -374,38 +446,153 @@ async def _spawn_and_check(args: tuple, provider: str) -> bytes: return stdout -async def _run_claude_cli(prompt: str) -> str: - stdout = await _spawn_and_check( - ("claude", "-p", prompt, "--allowedTools", "Read", "--output-format", "text"), "claude" - ) +def _model_effort_args(model: str | None, effort: str | None) -> list: + """claude and agy happen to spell these the same way; codex does not.""" + args = [] + if model: + args += ["--model", model] + if effort: + args += ["--effort", effort] + return args + + +async def _run_claude_cli( + prompt: str, + *, + model: str | None = None, + effort: str | None = None, + add_dirs: tuple = (), +) -> str: + args = ["claude", "-p", prompt, "--allowedTools", "Read", "--output-format", "text"] + for d in add_dirs: + args += ["--add-dir", str(d)] + args += _model_effort_args(model, effort) + stdout = await _spawn_and_check(tuple(args), "claude") return stdout.decode() -async def _run_agy_cli(prompt: str) -> str: - stdout = await _spawn_and_check( - ("agy", "-p", prompt, "--dangerously-skip-permissions", "--output-format", "text"), "agy" - ) - return stdout.decode() +# agy is agentic: handed a bare file path it reaches for a shell command to look +# at the file, headless mode cannot prompt for that permission, so the tool is +# auto-denied and the run returns an empty response on a *zero* exit code. +# Pointing it at its own file-reading tool is what makes the read happen +# unprivileged — verified against agy 1.2.7. The remedy agy itself suggests in +# that error, --dangerously-skip-permissions, auto-approves every tool including +# arbitrary shell commands, for a job whose whole need is reading three JPEGs. +_AGY_READ_STEER = ( + "Use your file-reading tool to read the image file(s). " + "Do NOT run any shell command." +) -async def _run_codex_cli(prompt: str, contact_sheets: list[Path]) -> str: +def _parse_agy_envelope(raw: str) -> str: + """Pull the answer out of `agy --output-format json`, or explain the silence.""" + raw = raw.strip() + if not raw: + raise RuntimeError("agy CLI returned no output") + try: + env = json.loads(raw) + except json.JSONDecodeError: + # Permission refusals and startup errors arrive as bare prose on a zero + # exit code, so _spawn_and_check never sees them. They land here. + raise RuntimeError(f"agy CLI returned non-JSON output: {raw[:300]}") + if not isinstance(env, dict): + raise RuntimeError(f"agy CLI returned unexpected JSON: {raw[:300]}") + + response = (env.get("response") or "").strip() + denied = env.get("denied_actions") or [] + if denied: + # Any denial at all, answer or no answer. The prompt tells agy to read + # the sheets with its file-reading tool and run no shell command, so a + # denial means the steering did not hold — and the prompt also carries + # the full scoring rubric, the scene's image prompt, its video prompt + # and the character names. That is more than enough for a plausible + # review written entirely from the text, without the images ever being + # looked at. A denial plus a confident answer is the more dangerous of + # the two cases, not the safer one. + # + # status stays "SUCCESS" here, which is why this is caught by name + # rather than by the status field. + names = ", ".join( + str(d.get("display_name") or d.get("action")) + for d in denied if isinstance(d, dict) + ) + raise RuntimeError( + f"agy CLI had tools auto-denied headlessly ({names or denied}) — " + f"its {len(response)}-character answer cannot be trusted to have " + f"come from the images" + ) + status = env.get("status") + if status is not None and status != "SUCCESS": + raise RuntimeError(f"agy CLI reported status={status!r}: {raw[:300]}") + if not response: + raise RuntimeError("agy CLI returned an empty response") + return response + + +async def _run_agy_cli( + prompt: str, + *, + model: str | None = None, + effort: str | None = None, + add_dirs: tuple = (), +) -> str: + # --print-timeout is set just inside our own wait_for so agy gets to finish + # and report on its own terms rather than being SIGKILLed with its answer + # still buffered. Left unset it defaults to 0, meaning "wait forever". + print_timeout = max(10, int(REVIEW_CLI_TIMEOUT_S) - 5) + args = [ + "agy", "-p", prompt, + "--output-format", "json", + "--print-timeout", f"{print_timeout}s", + ] + for d in add_dirs: + args += ["--add-dir", str(d)] + if model and effort: + # agy's slugs carry the effort (gemini-3.8-flash-low), so the pair is + # rejected unless it is redundant. The API refuses to store both; this + # covers a hand-edited providers.json, which is supported. + logger.warning( + "Dropping effort %r — agy model %r already names its effort", effort, model + ) + effort = None + args += _model_effort_args(model, effort) + stdout = await _spawn_and_check(tuple(args), "agy") + return _parse_agy_envelope(stdout.decode()) + + +async def _run_codex_cli( + prompt: str, + contact_sheets: list, + *, + model: str | None = None, + effort: str | None = None, +) -> str: with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as tmp: out_path = Path(tmp.name) try: - image_args = [] + # read-only, not --dangerously-bypass-approvals-and-sandbox: -i hands + # codex the image bytes directly, so the run needs no filesystem write + # and no shell at all. read-only still implies approval:never, so it + # cannot hang waiting for a prompt. --skip-git-repo-check keeps the run + # working if the server is ever started outside a git checkout. + args = ["codex", "exec", "--skip-git-repo-check", "--sandbox", "read-only"] for sheet in contact_sheets: - image_args.extend(["-i", str(sheet)]) - await _spawn_and_check( - ( - "codex", "exec", - *image_args, - "-o", str(out_path), - "--dangerously-bypass-approvals-and-sandbox", - prompt, - ), - "codex", - ) - return out_path.read_text() + args += ["-i", str(sheet)] + args += ["-o", str(out_path)] + if model: + args += ["-m", model] + if effort: + # codex has no --effort; reasoning level is a config override, and + # -c parses its value as TOML, hence the quotes around the string. + args += ["-c", f'model_reasoning_effort="{effort}"'] + args.append(prompt) + await _spawn_and_check(tuple(args), "codex") + answer = out_path.read_text().strip() + if not answer: + raise RuntimeError( + "codex CLI exited cleanly but wrote no answer to its output file" + ) + return answer finally: out_path.unlink(missing_ok=True) @@ -415,31 +602,61 @@ async def _analyze_cli( n_frames: int, fps: float, scene: dict, + timestamped: bool | None = None, ) -> dict: - """Analyze contact sheets via the active CLI provider (claude/agy/codex).""" + """Analyze contact sheets via the CLI provider configured for video_review.""" + if timestamped is None: + timestamped = _has_drawtext() n_sheets = len(contact_sheets) base_prompt = _build_prompt(n_frames, fps, n_sheets, scene) - provider = config.CLI_PROVIDERS["active"] - logger.info("Calling %s CLI for vision analysis (%d frames, %d sheets)", provider, n_frames, n_sheets) + + role = resolve_role("video_review") + provider = role["provider"] + logger.info( + "Calling %s CLI for vision analysis (%d frames, %d sheets, model=%s, effort=%s, timestamps=%s)", + provider, n_frames, n_sheets, + role["model"] or "default", role["effort"] or "default", timestamped, + ) + + if timestamped: + stamp_note = "with timestamps" + else: + # Without burned-in timestamps the model still has to answer in + # time_range, so hand it the arithmetic instead of the labels. + stamp_note = ( + f"without timestamps — frames run left to right then top to bottom, " + f"one every {1 / fps:.2f}s, so frame N starts at (N-1)*{1 / fps:.2f}s" + ) + if n_sheets == 1: - sheet_intro = f"It is a contact sheet of {n_frames} video frames at {fps}fps with timestamps." + sheet_intro = f"It is a contact sheet of {n_frames} video frames at {fps}fps {stamp_note}." else: sheet_intro = ( f"These are {n_sheets} sequential contact sheets covering {n_frames} video frames " - f"at {fps}fps with timestamps, in chronological order (sheet 1 is earliest)." + f"at {fps}fps {stamp_note}, in chronological order (sheet 1 is earliest)." ) + if provider == "codex": full_prompt = f"{sheet_intro}\n\n{base_prompt}" - raw = await _run_codex_cli(full_prompt, contact_sheets) + raw = await _run_codex_cli( + full_prompt, contact_sheets, model=role["model"], effort=role["effort"] + ) else: if n_sheets == 1: read_instruction = f"Read the image at {contact_sheets[0]}." else: sheet_list = ", ".join(str(s) for s in contact_sheets) read_instruction = f"Read the images at: {sheet_list}, in that order." + if provider == "agy": + read_instruction = f"{read_instruction} {_AGY_READ_STEER}" full_prompt = f"{read_instruction} {sheet_intro}\n\n{base_prompt}" + # The sheets live in a TemporaryDirectory outside the server's cwd; + # naming it keeps the read inside a workspace the CLI was told about. + add_dirs = tuple(sorted({str(Path(s).parent) for s in contact_sheets})) runner = {"claude": _run_claude_cli, "agy": _run_agy_cli}[provider] - raw = await runner(full_prompt) + raw = await runner( + full_prompt, model=role["model"], effort=role["effort"], add_dirs=add_dirs + ) return _parse_json_response(raw) @@ -541,22 +758,64 @@ async def review_scene_video( logger.info("Analyzing %d frames across %d sheets via CLI provider", n_frames, len(contact_sheets)) result = await _analyze_cli(contact_sheets, n_frames, fps, scene) - # Parse structured errors with severity + # Parse structured errors with severity. + # + # The three fields are NOT equal, so they are not treated equally. Only + # `severity` can change the outcome: CRITICAL is what caps + # character_consistency at 3.0 and forces the score below "acceptable". + # This block used to require all three keys exactly and silently drop any + # entry that missed one, so a model writing `timeRange` turned "this video + # is unusable" into a clean pass. Now a missing time_range or description + # is repaired and logged — losing those costs the reader context, not the + # verdict — while an unrecognisable severity fails the scene, because at + # that point we genuinely do not know whether the video passed. errors = [] - for e in result.get("errors", []): - if isinstance(e, dict) and "severity" in e and "time_range" in e and "description" in e: - errors.append(VideoError( - severity=e["severity"].upper(), - time_range=e["time_range"], - description=e["description"], - )) - elif isinstance(e, str): - # Fallback: plain string from older response format + repaired_fields = 0 + for e in result.get("errors") or []: + if isinstance(e, str): + # Legacy shape: a bare sentence, no severity to lose. errors.append(VideoError(severity="HIGH", time_range="?", description=e)) + continue + if not isinstance(e, dict): + raise RuntimeError( + f"review answer had an unreadable error entry: {str(e)[:200]}" + ) + + entry = _normalise_keys(e, _ERROR_KEY_ALIASES) + severity = str(entry.get("severity", "")).strip().upper() + if severity not in _SEVERITIES: + raise RuntimeError( + f"review answer had an error entry with no usable severity " + f"(expected one of {list(_SEVERITIES)}): {str(e)[:200]}" + ) + + time_range = entry.get("time_range") + if not isinstance(time_range, str) or not time_range.strip(): + time_range = "?" # the same placeholder the legacy string path uses + repaired_fields += 1 + description = entry.get("description") + if not isinstance(description, str) or not description.strip(): + description = "(no description given)" + repaired_fields += 1 + + errors.append(VideoError( + severity=severity, time_range=time_range, description=description, + )) has_critical = any(e.severity == "CRITICAL" for e in errors) - dims_raw = result.get("dimensions", {}) + dims_raw = result.get("dimensions") or {} + if not isinstance(dims_raw, dict) or not dims_raw: + # Every field below has a 5.0 default, so an answer with no dimensions + # at all becomes a complete, plausible review: 5.0 across the board, + # verdict "poor", no errors. That is a fabricated score wearing the + # shape of a real one, and it reads as a bad video rather than a failed + # review. Refuse it — review_video logs and skips the scene. + raise RuntimeError( + f"{'CLI' if not ANTHROPIC_API_KEY else 'SDK'} answer had no dimensions: " + f"{str(result)[:300]}" + ) + dims = DimensionScores( character_consistency=float(dims_raw.get("character_consistency", 5.0)), prompt_adherence=float(dims_raw.get("prompt_adherence", 5.0)), @@ -577,11 +836,34 @@ async def review_scene_video( if has_critical and overall > 5.9: overall = 5.9 - usable_segments = [ - SegmentScore(time_range=s["time_range"], score=float(s["score"])) - for s in result.get("usable_segments", []) - if isinstance(s, dict) and "time_range" in s and "score" in s - ] + # A segment that cannot be read is dropped rather than raised on: losing one + # errs toward "less usable footage", which cannot turn a bad video into a + # good score the way a lost CRITICAL can. It is still logged — the absence + # of any signal is what kept the error-entry version of this invisible. + usable_segments = [] + dropped_segments = 0 + for seg in result.get("usable_segments") or []: + if not isinstance(seg, dict): + dropped_segments += 1 + continue + norm = _normalise_keys(seg, _SEGMENT_KEY_ALIASES) + try: + score = float(norm["score"]) + except (KeyError, TypeError, ValueError): + dropped_segments += 1 + continue + time_range = norm.get("time_range") + usable_segments.append(SegmentScore( + time_range=time_range if isinstance(time_range, str) and time_range.strip() else "?", + score=score, + )) + + if repaired_fields or dropped_segments: + logger.warning( + "Scene %s: review answer needed repair — %d error field(s) defaulted, " + "%d usable segment(s) unreadable", + scene["id"], repaired_fields, dropped_segments, + ) return SceneReview( scene_id=scene["id"], diff --git a/dashboard/src/App.tsx b/dashboard/src/App.tsx index b0b0125b8..46e3cf333 100644 --- a/dashboard/src/App.tsx +++ b/dashboard/src/App.tsx @@ -1,6 +1,6 @@ import { useState, useEffect } from 'react' import { BrowserRouter, NavLink, Routes, Route, useLocation, useParams, useSearchParams } from 'react-router-dom' -import { LayoutDashboard, FolderOpen, Film, ScrollText, BookOpen } from 'lucide-react' +import { LayoutDashboard, FolderOpen, Film, ScrollText, BookOpen, SlidersHorizontal } from 'lucide-react' import { TooltipProvider } from '@/components/ui/tooltip' import { WebSocketProvider } from './api/WebSocketContext' import { useWebSocketContext } from './api/useWebSocketContext' @@ -15,6 +15,7 @@ import ProjectsPage from './pages/ProjectsPage' import LogsPage from './pages/LogsPage' import GalleryPage from './pages/GalleryPage' import GuidePage from './pages/GuidePage' +import SettingsPage from './pages/SettingsPage' const NAV: { to: string; icon: typeof LayoutDashboard; labelKey: TranslationKey; exact: boolean }[] = [ { to: '/', icon: LayoutDashboard, labelKey: 'nav.dashboard', exact: true }, @@ -22,6 +23,7 @@ const NAV: { to: string; icon: typeof LayoutDashboard; labelKey: TranslationKey; { to: '/gallery', icon: Film, labelKey: 'nav.gallery', exact: false }, { to: '/logs', icon: ScrollText, labelKey: 'nav.logs', exact: false }, { to: '/guide', icon: BookOpen, labelKey: 'nav.guide', exact: false }, + { to: '/settings', icon: SlidersHorizontal, labelKey: 'nav.settings', exact: false }, ] const BREADCRUMB_TAB_KEY: Record<string, TranslationKey> = { @@ -65,6 +67,7 @@ function useBreadcrumbs() { } else if (loc.pathname.startsWith('/gallery')) crumbs.push(t('app.breadcrumb.gallery')) else if (loc.pathname.startsWith('/logs')) crumbs.push(t('app.breadcrumb.logs')) else if (loc.pathname.startsWith('/guide')) crumbs.push(t('app.breadcrumb.guide')) + else if (loc.pathname.startsWith('/settings')) crumbs.push(t('app.breadcrumb.settings')) return crumbs } @@ -187,6 +190,7 @@ function Layout() { <Route path="/gallery" element={<GalleryPage />} /> <Route path="/logs" element={<LogsPage />} /> <Route path="/guide" element={<GuidePage />} /> + <Route path="/settings" element={<SettingsPage />} /> </Routes> </main> </div> diff --git a/dashboard/src/i18n/translations.ts b/dashboard/src/i18n/translations.ts index 695be91a7..c1d240b39 100644 --- a/dashboard/src/i18n/translations.ts +++ b/dashboard/src/i18n/translations.ts @@ -52,6 +52,7 @@ const en = { 'nav.gallery': 'Gallery', 'nav.logs': 'Logs', 'nav.guide': 'Guide', + 'nav.settings': 'Settings', 'app.brandName': 'FLOW KIT', 'app.brandTag': 'ops console', 'app.breadcrumbRoot': 'flow kit', @@ -60,6 +61,7 @@ const en = { 'app.breadcrumb.gallery': 'gallery', 'app.breadcrumb.logs': 'logs', 'app.breadcrumb.guide': 'guide', + 'app.breadcrumb.settings': 'settings', 'app.workers': 'WORKERS', 'app.extensionConnected': 'extension connected', 'app.extensionDisconnected': 'extension disconnected', @@ -296,6 +298,43 @@ const en = { 'sceneSheet.retrying': 'Retrying…', 'sceneSheet.retryStage': 'Retry stage', + // ---- Settings (AI providers) ---- + 'settings.title': 'AI PROVIDERS', + 'settings.desc': 'Which CLI agent runs each automated role, and with what model and effort level.', + 'settings.loading': 'Loading provider settings...', + 'settings.loadFailed': 'Could not load provider settings.', + 'settings.retry': 'Retry', + 'settings.activeProvider': 'ACTIVE', + 'settings.test': 'Test binaries', + 'settings.testing': 'Testing…', + 'settings.testHint': 'Runs <binary> --version for every provider. Takes a few seconds.', + 'settings.providers.title': 'PROVIDER BINARIES', + 'settings.providers.installed': 'installed', + 'settings.providers.missing': 'not installed', + 'settings.providers.untested': 'not tested', + 'settings.providers.ok': 'responded', + 'settings.providers.failed': 'failed', + 'settings.field.agent': 'AGENT', + 'settings.field.model': 'MODEL', + 'settings.field.effort': 'EFFORT', + 'settings.effortLockedHint': '{binary} model names already include the effort.', + 'settings.optionDefault': 'Default', + 'settings.optionCustom': 'Custom…', + 'settings.notInstalled': 'not installed', + 'settings.installHint': 'Install the {binary} CLI before assigning this role to it.', + 'settings.modelsLoading': 'Loading models…', + 'settings.modelsEmpty': 'No catalog available for this provider.', + 'settings.modelsFreeText': 'This provider has no authoritative catalog — a custom model slug is accepted.', + 'settings.modelCustomPlaceholder': 'model slug', + 'settings.modelBackToList': 'Pick from list', + 'settings.refreshModels': 'Refresh model catalog', + 'settings.save': 'Save', + 'settings.saving': 'Saving…', + 'settings.saved': 'Saved', + 'settings.unsaved': 'UNSAVED', + 'settings.inSync': 'IN SYNC', + 'settings.empty': 'No roles are configured.', + // ---- EditableText ---- 'editableText.clickToEdit': 'Click to edit', 'editableText.empty': '(empty)', @@ -341,6 +380,7 @@ const vi: Partial<Record<TranslationKey, string>> = { 'nav.gallery': 'Thư viện', 'nav.logs': 'Nhật ký', 'nav.guide': 'Hướng dẫn', + 'nav.settings': 'Cài đặt', 'app.brandName': 'FLOW KIT', 'app.brandTag': 'ops console', 'app.breadcrumbRoot': 'flow kit', @@ -349,6 +389,7 @@ const vi: Partial<Record<TranslationKey, string>> = { 'app.breadcrumb.gallery': 'thư viện', 'app.breadcrumb.logs': 'nhật ký', 'app.breadcrumb.guide': 'hướng dẫn', + 'app.breadcrumb.settings': 'cài đặt', 'app.workers': 'WORKERS', 'app.extensionConnected': 'extension đã kết nối', 'app.extensionDisconnected': 'extension chưa kết nối', @@ -575,6 +616,42 @@ const vi: Partial<Record<TranslationKey, string>> = { 'sceneSheet.retrying': 'Đang thử lại…', 'sceneSheet.retryStage': 'Thử lại giai đoạn', + 'settings.title': 'NHÀ CUNG CẤP AI', + 'settings.desc': 'Chọn CLI agent chạy từng vai trò tự động, cùng model và mức nỗ lực.', + 'settings.loading': 'Đang tải cài đặt nhà cung cấp...', + 'settings.loadFailed': 'Không tải được cài đặt nhà cung cấp.', + 'settings.retry': 'Thử lại', + 'settings.activeProvider': 'ĐANG DÙNG', + 'settings.test': 'Kiểm tra binary', + 'settings.testing': 'Đang kiểm tra…', + 'settings.testHint': 'Chạy <binary> --version cho từng nhà cung cấp. Mất vài giây.', + 'settings.providers.title': 'BINARY NHÀ CUNG CẤP', + 'settings.providers.installed': 'đã cài', + 'settings.providers.missing': 'chưa cài', + 'settings.providers.untested': 'chưa kiểm tra', + 'settings.providers.ok': 'phản hồi tốt', + 'settings.providers.failed': 'lỗi', + 'settings.field.agent': 'AGENT', + 'settings.field.model': 'MODEL', + 'settings.field.effort': 'MỨC NỖ LỰC', + 'settings.effortLockedHint': 'Tên model của {binary} đã bao gồm mức nỗ lực.', + 'settings.optionDefault': 'Mặc định', + 'settings.optionCustom': 'Tuỳ chỉnh…', + 'settings.notInstalled': 'chưa cài', + 'settings.installHint': 'Hãy cài CLI {binary} trước khi giao vai trò này cho nó.', + 'settings.modelsLoading': 'Đang tải danh sách model…', + 'settings.modelsEmpty': 'Không có danh mục model cho nhà cung cấp này.', + 'settings.modelsFreeText': 'Nhà cung cấp này không có danh mục chuẩn — có thể nhập model tuỳ ý.', + 'settings.modelCustomPlaceholder': 'mã model', + 'settings.modelBackToList': 'Chọn từ danh sách', + 'settings.refreshModels': 'Làm mới danh mục model', + 'settings.save': 'Lưu', + 'settings.saving': 'Đang lưu…', + 'settings.saved': 'Đã lưu', + 'settings.unsaved': 'CHƯA LƯU', + 'settings.inSync': 'ĐÃ ĐỒNG BỘ', + 'settings.empty': 'Chưa có vai trò nào được cấu hình.', + 'editableText.clickToEdit': 'Nhấn để sửa', 'editableText.empty': '(trống)', } @@ -615,6 +692,7 @@ const hi: Partial<Record<TranslationKey, string>> = { 'nav.gallery': 'गैलरी', 'nav.logs': 'लॉग्स', 'nav.guide': 'गाइड', + 'nav.settings': 'सेटिंग्स', 'app.brandName': 'FLOW KIT', 'app.brandTag': 'ops console', 'app.breadcrumbRoot': 'flow kit', @@ -623,6 +701,7 @@ const hi: Partial<Record<TranslationKey, string>> = { 'app.breadcrumb.gallery': 'गैलरी', 'app.breadcrumb.logs': 'लॉग्स', 'app.breadcrumb.guide': 'गाइड', + 'app.breadcrumb.settings': 'सेटिंग्स', 'app.workers': 'वर्कर्स', 'app.extensionConnected': 'एक्सटेंशन जुड़ा है', 'app.extensionDisconnected': 'एक्सटेंशन नहीं जुड़ा है', @@ -849,6 +928,42 @@ const hi: Partial<Record<TranslationKey, string>> = { 'sceneSheet.retrying': 'पुनः प्रयास हो रहा है…', 'sceneSheet.retryStage': 'स्टेज पुनः प्रयास करें', + 'settings.title': 'AI प्रदाता', + 'settings.desc': 'कौन सा CLI एजेंट हर स्वचालित भूमिका चलाए, और किस मॉडल व प्रयास स्तर के साथ।', + 'settings.loading': 'प्रदाता सेटिंग्स लोड हो रही हैं...', + 'settings.loadFailed': 'प्रदाता सेटिंग्स लोड नहीं हो सकीं।', + 'settings.retry': 'पुनः प्रयास', + 'settings.activeProvider': 'सक्रिय', + 'settings.test': 'बाइनरी जाँचें', + 'settings.testing': 'जाँच हो रही है…', + 'settings.testHint': 'हर प्रदाता के लिए <binary> --version चलाता है। इसमें कुछ सेकंड लगते हैं।', + 'settings.providers.title': 'प्रदाता बाइनरी', + 'settings.providers.installed': 'इंस्टॉल है', + 'settings.providers.missing': 'इंस्टॉल नहीं है', + 'settings.providers.untested': 'जाँचा नहीं गया', + 'settings.providers.ok': 'उत्तर मिला', + 'settings.providers.failed': 'विफल', + 'settings.field.agent': 'एजेंट', + 'settings.field.model': 'मॉडल', + 'settings.field.effort': 'प्रयास', + 'settings.effortLockedHint': '{binary} के मॉडल नामों में प्रयास स्तर पहले से शामिल है।', + 'settings.optionDefault': 'डिफ़ॉल्ट', + 'settings.optionCustom': 'कस्टम…', + 'settings.notInstalled': 'इंस्टॉल नहीं है', + 'settings.installHint': 'यह भूमिका सौंपने से पहले {binary} CLI इंस्टॉल करें।', + 'settings.modelsLoading': 'मॉडल लोड हो रहे हैं…', + 'settings.modelsEmpty': 'इस प्रदाता के लिए कोई कैटलॉग उपलब्ध नहीं है।', + 'settings.modelsFreeText': 'इस प्रदाता की कोई आधिकारिक सूची नहीं है — कस्टम मॉडल स्लग स्वीकार्य है।', + 'settings.modelCustomPlaceholder': 'मॉडल स्लग', + 'settings.modelBackToList': 'सूची से चुनें', + 'settings.refreshModels': 'मॉडल कैटलॉग ताज़ा करें', + 'settings.save': 'सहेजें', + 'settings.saving': 'सहेजा जा रहा है…', + 'settings.saved': 'सहेजा गया', + 'settings.unsaved': 'असहेजा', + 'settings.inSync': 'समन्वयित', + 'settings.empty': 'कोई भूमिका कॉन्फ़िगर नहीं है।', + 'editableText.clickToEdit': 'संपादित करने के लिए क्लिक करें', 'editableText.empty': '(खाली)', } @@ -889,6 +1004,7 @@ const id: Partial<Record<TranslationKey, string>> = { 'nav.gallery': 'Galeri', 'nav.logs': 'Log', 'nav.guide': 'Panduan', + 'nav.settings': 'Pengaturan', 'app.brandName': 'FLOW KIT', 'app.brandTag': 'ops console', 'app.breadcrumbRoot': 'flow kit', @@ -897,6 +1013,7 @@ const id: Partial<Record<TranslationKey, string>> = { 'app.breadcrumb.gallery': 'galeri', 'app.breadcrumb.logs': 'log', 'app.breadcrumb.guide': 'panduan', + 'app.breadcrumb.settings': 'pengaturan', 'app.workers': 'WORKER', 'app.extensionConnected': 'ekstensi terhubung', 'app.extensionDisconnected': 'ekstensi tidak terhubung', @@ -1123,6 +1240,42 @@ const id: Partial<Record<TranslationKey, string>> = { 'sceneSheet.retrying': 'Mencoba lagi…', 'sceneSheet.retryStage': 'Coba lagi tahap ini', + 'settings.title': 'PENYEDIA AI', + 'settings.desc': 'Agen CLI mana yang menjalankan tiap peran otomatis, beserta model dan tingkat usahanya.', + 'settings.loading': 'Memuat pengaturan penyedia...', + 'settings.loadFailed': 'Gagal memuat pengaturan penyedia.', + 'settings.retry': 'Coba lagi', + 'settings.activeProvider': 'AKTIF', + 'settings.test': 'Uji biner', + 'settings.testing': 'Menguji…', + 'settings.testHint': 'Menjalankan <binary> --version untuk setiap penyedia. Butuh beberapa detik.', + 'settings.providers.title': 'BINER PENYEDIA', + 'settings.providers.installed': 'terpasang', + 'settings.providers.missing': 'belum terpasang', + 'settings.providers.untested': 'belum diuji', + 'settings.providers.ok': 'merespons', + 'settings.providers.failed': 'gagal', + 'settings.field.agent': 'AGEN', + 'settings.field.model': 'MODEL', + 'settings.field.effort': 'USAHA', + 'settings.effortLockedHint': 'Nama model {binary} sudah memuat tingkat usahanya.', + 'settings.optionDefault': 'Bawaan', + 'settings.optionCustom': 'Kustom…', + 'settings.notInstalled': 'belum terpasang', + 'settings.installHint': 'Pasang CLI {binary} sebelum menugaskan peran ini kepadanya.', + 'settings.modelsLoading': 'Memuat model…', + 'settings.modelsEmpty': 'Tidak ada katalog untuk penyedia ini.', + 'settings.modelsFreeText': 'Penyedia ini tidak punya katalog resmi — slug model kustom tetap diterima.', + 'settings.modelCustomPlaceholder': 'slug model', + 'settings.modelBackToList': 'Pilih dari daftar', + 'settings.refreshModels': 'Muat ulang katalog model', + 'settings.save': 'Simpan', + 'settings.saving': 'Menyimpan…', + 'settings.saved': 'Tersimpan', + 'settings.unsaved': 'BELUM DISIMPAN', + 'settings.inSync': 'SINKRON', + 'settings.empty': 'Belum ada peran yang dikonfigurasi.', + 'editableText.clickToEdit': 'Klik untuk mengedit', 'editableText.empty': '(kosong)', } @@ -1163,6 +1316,7 @@ const zh: Partial<Record<TranslationKey, string>> = { 'nav.gallery': '素材库', 'nav.logs': '日志', 'nav.guide': '使用指南', + 'nav.settings': '设置', 'app.brandName': 'FLOW KIT', 'app.brandTag': 'ops console', 'app.breadcrumbRoot': 'flow kit', @@ -1171,6 +1325,7 @@ const zh: Partial<Record<TranslationKey, string>> = { 'app.breadcrumb.gallery': '素材库', 'app.breadcrumb.logs': '日志', 'app.breadcrumb.guide': '使用指南', + 'app.breadcrumb.settings': '设置', 'app.workers': '工作进程', 'app.extensionConnected': '扩展已连接', 'app.extensionDisconnected': '扩展未连接', @@ -1397,6 +1552,42 @@ const zh: Partial<Record<TranslationKey, string>> = { 'sceneSheet.retrying': '重试中…', 'sceneSheet.retryStage': '重试该阶段', + 'settings.title': 'AI 提供方', + 'settings.desc': '为每个自动化角色选择运行的 CLI 代理,以及模型与思考强度。', + 'settings.loading': '正在加载提供方设置...', + 'settings.loadFailed': '无法加载提供方设置。', + 'settings.retry': '重试', + 'settings.activeProvider': '当前', + 'settings.test': '测试二进制', + 'settings.testing': '测试中…', + 'settings.testHint': '对每个提供方执行 <binary> --version,需要几秒钟。', + 'settings.providers.title': '提供方二进制', + 'settings.providers.installed': '已安装', + 'settings.providers.missing': '未安装', + 'settings.providers.untested': '未测试', + 'settings.providers.ok': '已响应', + 'settings.providers.failed': '失败', + 'settings.field.agent': '代理', + 'settings.field.model': '模型', + 'settings.field.effort': '强度', + 'settings.effortLockedHint': '{binary} 的模型名称已经包含思考强度。', + 'settings.optionDefault': '默认', + 'settings.optionCustom': '自定义…', + 'settings.notInstalled': '未安装', + 'settings.installHint': '请先安装 {binary} CLI,再把该角色分配给它。', + 'settings.modelsLoading': '正在加载模型…', + 'settings.modelsEmpty': '该提供方没有可用的模型目录。', + 'settings.modelsFreeText': '该提供方没有权威目录 — 可直接填写自定义模型标识。', + 'settings.modelCustomPlaceholder': '模型标识', + 'settings.modelBackToList': '从列表选择', + 'settings.refreshModels': '刷新模型目录', + 'settings.save': '保存', + 'settings.saving': '保存中…', + 'settings.saved': '已保存', + 'settings.unsaved': '未保存', + 'settings.inSync': '已同步', + 'settings.empty': '尚未配置任何角色。', + 'editableText.clickToEdit': '点击编辑', 'editableText.empty': '(空)', } @@ -1437,6 +1628,7 @@ const ko: Partial<Record<TranslationKey, string>> = { 'nav.gallery': '갤러리', 'nav.logs': '로그', 'nav.guide': '가이드', + 'nav.settings': '설정', 'app.brandName': 'FLOW KIT', 'app.brandTag': 'ops console', 'app.breadcrumbRoot': 'flow kit', @@ -1445,6 +1637,7 @@ const ko: Partial<Record<TranslationKey, string>> = { 'app.breadcrumb.gallery': '갤러리', 'app.breadcrumb.logs': '로그', 'app.breadcrumb.guide': '가이드', + 'app.breadcrumb.settings': '설정', 'app.workers': '워커', 'app.extensionConnected': '익스텐션 연결됨', 'app.extensionDisconnected': '익스텐션 연결 안 됨', @@ -1671,6 +1864,42 @@ const ko: Partial<Record<TranslationKey, string>> = { 'sceneSheet.retrying': '재시도 중…', 'sceneSheet.retryStage': '단계 재시도', + 'settings.title': 'AI 제공자', + 'settings.desc': '각 자동화 역할을 실행할 CLI 에이전트와 모델, 노력 수준을 지정합니다.', + 'settings.loading': '제공자 설정을 불러오는 중...', + 'settings.loadFailed': '제공자 설정을 불러오지 못했습니다.', + 'settings.retry': '다시 시도', + 'settings.activeProvider': '활성', + 'settings.test': '바이너리 테스트', + 'settings.testing': '테스트 중…', + 'settings.testHint': '각 제공자에 대해 <binary> --version 을 실행합니다. 몇 초 걸립니다.', + 'settings.providers.title': '제공자 바이너리', + 'settings.providers.installed': '설치됨', + 'settings.providers.missing': '설치 안 됨', + 'settings.providers.untested': '테스트 안 함', + 'settings.providers.ok': '응답함', + 'settings.providers.failed': '실패', + 'settings.field.agent': '에이전트', + 'settings.field.model': '모델', + 'settings.field.effort': '노력', + 'settings.effortLockedHint': '{binary} 의 모델 이름에 이미 노력 수준이 포함되어 있습니다.', + 'settings.optionDefault': '기본값', + 'settings.optionCustom': '직접 입력…', + 'settings.notInstalled': '설치 안 됨', + 'settings.installHint': '이 역할을 맡기기 전에 {binary} CLI 를 설치하세요.', + 'settings.modelsLoading': '모델을 불러오는 중…', + 'settings.modelsEmpty': '이 제공자의 카탈로그가 없습니다.', + 'settings.modelsFreeText': '이 제공자는 공식 카탈로그가 없습니다 — 직접 입력한 모델 슬러그도 허용됩니다.', + 'settings.modelCustomPlaceholder': '모델 슬러그', + 'settings.modelBackToList': '목록에서 선택', + 'settings.refreshModels': '모델 카탈로그 새로고침', + 'settings.save': '저장', + 'settings.saving': '저장 중…', + 'settings.saved': '저장됨', + 'settings.unsaved': '저장 안 됨', + 'settings.inSync': '동기화됨', + 'settings.empty': '구성된 역할이 없습니다.', + 'editableText.clickToEdit': '클릭하여 수정', 'editableText.empty': '(비어 있음)', } @@ -1711,6 +1940,7 @@ const ja: Partial<Record<TranslationKey, string>> = { 'nav.gallery': 'ギャラリー', 'nav.logs': 'ログ', 'nav.guide': 'ガイド', + 'nav.settings': '設定', 'app.brandName': 'FLOW KIT', 'app.brandTag': 'ops console', 'app.breadcrumbRoot': 'flow kit', @@ -1719,6 +1949,7 @@ const ja: Partial<Record<TranslationKey, string>> = { 'app.breadcrumb.gallery': 'ギャラリー', 'app.breadcrumb.logs': 'ログ', 'app.breadcrumb.guide': 'ガイド', + 'app.breadcrumb.settings': '設定', 'app.workers': 'ワーカー', 'app.extensionConnected': '拡張機能 接続済み', 'app.extensionDisconnected': '拡張機能 未接続', @@ -1945,6 +2176,42 @@ const ja: Partial<Record<TranslationKey, string>> = { 'sceneSheet.retrying': '再試行中…', 'sceneSheet.retryStage': 'ステージを再試行', + 'settings.title': 'AI プロバイダ', + 'settings.desc': '各自動ロールを実行する CLI エージェントと、モデル・努力レベルを設定します。', + 'settings.loading': 'プロバイダ設定を読み込み中...', + 'settings.loadFailed': 'プロバイダ設定を読み込めませんでした。', + 'settings.retry': '再試行', + 'settings.activeProvider': '有効', + 'settings.test': 'バイナリをテスト', + 'settings.testing': 'テスト中…', + 'settings.testHint': '各プロバイダで <binary> --version を実行します。数秒かかります。', + 'settings.providers.title': 'プロバイダのバイナリ', + 'settings.providers.installed': 'インストール済み', + 'settings.providers.missing': '未インストール', + 'settings.providers.untested': '未テスト', + 'settings.providers.ok': '応答あり', + 'settings.providers.failed': '失敗', + 'settings.field.agent': 'エージェント', + 'settings.field.model': 'モデル', + 'settings.field.effort': '努力レベル', + 'settings.effortLockedHint': '{binary} のモデル名には努力レベルが含まれています。', + 'settings.optionDefault': 'デフォルト', + 'settings.optionCustom': 'カスタム…', + 'settings.notInstalled': '未インストール', + 'settings.installHint': 'このロールを割り当てる前に {binary} CLI をインストールしてください。', + 'settings.modelsLoading': 'モデルを読み込み中…', + 'settings.modelsEmpty': 'このプロバイダのカタログはありません。', + 'settings.modelsFreeText': 'このプロバイダには公式カタログがありません — カスタムのモデル名も使えます。', + 'settings.modelCustomPlaceholder': 'モデル名', + 'settings.modelBackToList': '一覧から選ぶ', + 'settings.refreshModels': 'モデルカタログを更新', + 'settings.save': '保存', + 'settings.saving': '保存中…', + 'settings.saved': '保存しました', + 'settings.unsaved': '未保存', + 'settings.inSync': '同期済み', + 'settings.empty': 'ロールが設定されていません。', + 'editableText.clickToEdit': 'クリックして編集', 'editableText.empty': '(空)', } diff --git a/dashboard/src/pages/SettingsPage.tsx b/dashboard/src/pages/SettingsPage.tsx new file mode 100644 index 000000000..8022b70d5 --- /dev/null +++ b/dashboard/src/pages/SettingsPage.tsx @@ -0,0 +1,359 @@ +import { useState, useEffect, useCallback } from 'react' +import { RefreshCw } from 'lucide-react' +import { fetchAPI, patchAPI } from '../api/client' +import { useTranslation } from '../i18n/useTranslation' +import type { RoleAssignment, ProvidersResponse, ProviderModelsResponse, ProvidersUpdateResponse } from '../types' +import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardAction } from '../components/ui/card' +import { Button } from '../components/ui/button' + +const DEFAULT_OPTION = '__default__' +const CUSTOM_OPTION = '__custom__' + +const CONTROL_CLASS = 'text-xs px-2 py-1.5 rounded outline-none w-full' +const CONTROL_STYLE = { background: 'var(--card)', color: 'var(--text)', border: '1px solid var(--border)' } + +interface SaveState { + ok: boolean + text: string +} + +// fetchAPI throws `API <status>: <body>` — pull the backend's `detail` back out so a 400 reads verbatim. +function apiDetail(err: unknown): string { + const raw = err instanceof Error ? err.message : String(err) + const body = raw.replace(/^API \d+: /, '') + try { + const parsed = JSON.parse(body) as { detail?: unknown } + if (typeof parsed.detail === 'string') return parsed.detail + } catch { + // not JSON — fall through to the raw message + } + return raw +} + +function cloneRoles(roles: Record<string, RoleAssignment>): Record<string, RoleAssignment> { + return Object.fromEntries(Object.entries(roles).map(([id, r]) => [id, { ...r }])) +} + +function sameAssignment(a: RoleAssignment, b: RoleAssignment): boolean { + return a.provider === b.provider && a.model === b.model && a.effort === b.effort +} + +export default function SettingsPage() { + const { t } = useTranslation() + const [data, setData] = useState<ProvidersResponse | null>(null) + const [loading, setLoading] = useState(true) + const [loadError, setLoadError] = useState<string | null>(null) + const [drafts, setDrafts] = useState<Record<string, RoleAssignment>>({}) + const [models, setModels] = useState<Record<string, ProviderModelsResponse>>({}) + const [modelsLoading, setModelsLoading] = useState<Record<string, boolean>>({}) + const [customModel, setCustomModel] = useState<Record<string, boolean>>({}) + const [saving, setSaving] = useState<Record<string, boolean>>({}) + const [saveState, setSaveState] = useState<Record<string, SaveState>>({}) + const [testing, setTesting] = useState(false) + const [testError, setTestError] = useState<string | null>(null) + + const loadModels = useCallback(async (provider: string, refresh: boolean) => { + setModelsLoading(prev => ({ ...prev, [provider]: true })) + try { + const res = await fetchAPI<ProviderModelsResponse>( + `/api/providers/models?provider=${encodeURIComponent(provider)}&refresh=${refresh}` + ) + setModels(prev => ({ ...prev, [provider]: res })) + } catch { + // an unreachable catalog is not fatal — render it as "no catalog available" + setModels(prev => ({ ...prev, [provider]: { provider, models: [], authoritative: false } })) + } finally { + setModelsLoading(prev => ({ ...prev, [provider]: false })) + } + }, []) + + const load = useCallback(async () => { + setLoading(true) + setLoadError(null) + try { + const res = await fetchAPI<ProvidersResponse>('/api/providers?live=false') + setData(res) + setDrafts(cloneRoles(res.roles)) + setCustomModel({}) + setSaveState({}) + Array.from(new Set(Object.values(res.roles).map(r => r.provider))).forEach(p => { loadModels(p, false) }) + } catch (err) { + setData(null) + setLoadError(apiDetail(err)) + } finally { + setLoading(false) + } + }, [loadModels]) + + useEffect(() => { Promise.resolve().then(load) }, [load]) + + function updateDraft(roleId: string, patch: Partial<RoleAssignment>) { + setDrafts(prev => ({ ...prev, [roleId]: { ...prev[roleId], ...patch } })) + setSaveState(prev => { + if (!(roleId in prev)) return prev + const next = { ...prev } + delete next[roleId] + return next + }) + } + + function changeProvider(roleId: string, provider: string) { + // a model slug from one CLI means nothing to another, and effort ladders differ per provider + const efforts = data?.providers[provider]?.efforts ?? [] + const current = drafts[roleId] + const effort = current.effort !== null && efforts.includes(current.effort) ? current.effort : null + updateDraft(roleId, { provider, model: null, effort }) + setCustomModel(prev => ({ ...prev, [roleId]: false })) + if (!models[provider] && !modelsLoading[provider]) loadModels(provider, false) + } + + function setModel(roleId: string, model: string | null) { + // a provider whose slugs name their own effort rejects --model and --effort together + const encodesEffort = data?.providers[drafts[roleId].provider]?.model_encodes_effort ?? false + updateDraft(roleId, model !== null && encodesEffort ? { model, effort: null } : { model }) + } + + function selectModel(roleId: string, value: string) { + if (value === CUSTOM_OPTION) { + setCustomModel(prev => ({ ...prev, [roleId]: true })) + setModel(roleId, null) + return + } + setModel(roleId, value === DEFAULT_OPTION ? null : value) + } + + async function save(roleId: string) { + const draft = drafts[roleId] + const model = draft.model !== null && draft.model.trim() !== '' ? draft.model.trim() : null + const encodesEffort = data?.providers[draft.provider]?.model_encodes_effort ?? false + const effort = model !== null && encodesEffort ? null : draft.effort + setSaving(prev => ({ ...prev, [roleId]: true })) + try { + const res = await patchAPI<ProvidersUpdateResponse>('/api/providers', { + roles: { [roleId]: { provider: draft.provider, model, effort } }, + }) + setData(prev => (prev ? { ...prev, active: res.active, roles: res.roles } : prev)) + setDrafts(prev => ({ ...prev, [roleId]: { ...(res.roles[roleId] ?? prev[roleId]) } })) + setSaveState(prev => ({ ...prev, [roleId]: { ok: true, text: t('settings.saved') } })) + } catch (err) { + setSaveState(prev => ({ ...prev, [roleId]: { ok: false, text: apiDetail(err) } })) + } finally { + setSaving(prev => ({ ...prev, [roleId]: false })) + } + } + + async function runTest() { + setTesting(true) + setTestError(null) + try { + const res = await fetchAPI<ProvidersResponse>('/api/providers?live=true') + setData(prev => (prev ? { ...prev, providers: res.providers } : res)) + } catch (err) { + setTestError(apiDetail(err)) + } finally { + setTesting(false) + } + } + + if (loading) { + return <div className="text-xs" style={{ color: 'var(--muted)' }}>{t('settings.loading')}</div> + } + + if (!data) { + return ( + <div className="flex flex-col items-start gap-2.5"> + <span className="text-xs" style={{ color: 'var(--red)' }}>{loadError ?? t('settings.loadFailed')}</span> + <Button variant="outline" size="sm" onClick={() => { Promise.resolve().then(load) }}>{t('settings.retry')}</Button> + </div> + ) + } + + const providers = data.providers + const roleIds = Object.keys(data.roles) + + return ( + <div className="flex flex-col gap-4"> + <div className="flex flex-col gap-1.5"> + <h1 className="m-0 text-lg font-semibold" style={{ color: 'var(--text)' }}>{t('settings.title')}</h1> + <span className="text-[11px]" style={{ color: 'var(--muted)' }}>{t('settings.desc')}</span> + </div> + + <Card className="py-4"> + <CardHeader> + <CardTitle className="text-xs tracking-widest uppercase">{t('settings.providers.title')}</CardTitle> + <CardDescription className="text-[11px]">{t('settings.testHint')}</CardDescription> + <CardAction> + <Button variant="outline" size="sm" disabled={testing} onClick={runTest}> + {testing ? t('settings.testing') : t('settings.test')} + </Button> + </CardAction> + </CardHeader> + <CardContent> + {testError && <div className="text-[10px] pb-2" style={{ color: 'var(--red)' }}>{testError}</div>} + <div className="flex flex-col gap-1.5"> + {Object.entries(providers).map(([name, info]) => ( + <div key={name} className="flex items-center gap-3 text-[11px]"> + <span className="w-1.5 h-1.5 rounded-full flex-shrink-0" style={{ background: info.installed ? 'var(--green)' : 'var(--red)' }} /> + <span style={{ width: 90 }}>{info.binary}</span> + <span style={{ color: 'var(--muted)', width: 100 }}> + {info.installed ? t('settings.providers.installed') : t('settings.providers.missing')} + </span> + <span style={{ width: 100, color: info.tested === null ? 'var(--muted)' : info.tested ? 'var(--green)' : 'var(--red)' }}> + {info.tested === null ? t('settings.providers.untested') : info.tested ? t('settings.providers.ok') : t('settings.providers.failed')} + </span> + {info.error && <span className="truncate" style={{ color: 'var(--muted)' }}>{info.error}</span>} + {name === data.active && ( + <span className="ml-auto text-[9px] tracking-widest flex-shrink-0" style={{ color: 'var(--accent)' }}>{t('settings.activeProvider')}</span> + )} + </div> + ))} + </div> + </CardContent> + </Card> + + {roleIds.length === 0 ? ( + <div className="text-xs" style={{ color: 'var(--muted)' }}>{t('settings.empty')}</div> + ) : roleIds.map(roleId => { + const draft = drafts[roleId] + const meta = data.role_meta[roleId] + const info = providers[draft.provider] + const efforts = info?.efforts ?? [] + const catalog = models[draft.provider] + const modelList = catalog?.models ?? [] + const authoritative = catalog?.authoritative ?? false + const modelBusy = modelsLoading[draft.provider] ?? false + const custom = customModel[roleId] ?? false + const knownModel = draft.model !== null && modelList.some(m => m.id === draft.model) + const effortLocked = (info?.model_encodes_effort ?? false) && draft.model !== null + const dirty = !sameAssignment(draft, data.roles[roleId]) + const busy = saving[roleId] ?? false + const state = saveState[roleId] + + return ( + <Card key={roleId} className="py-4"> + <CardHeader> + <CardTitle className="text-xs tracking-widest uppercase">{meta?.label ?? roleId}</CardTitle> + <CardDescription className="text-[11px]">{meta?.description ?? roleId}</CardDescription> + <CardAction> + <span className="text-[9px] tracking-widest" style={{ color: dirty ? 'var(--yellow)' : 'var(--muted)' }}> + {dirty ? t('settings.unsaved') : t('settings.inSync')} + </span> + </CardAction> + </CardHeader> + <CardContent> + <div className="grid gap-3.5 items-start" style={{ gridTemplateColumns: '1fr 1.6fr 1fr' }}> + <div className="flex flex-col gap-1"> + <span className="text-[9px] tracking-widest" style={{ color: 'var(--muted)' }}>{t('settings.field.agent')}</span> + <select + value={draft.provider} + onChange={e => changeProvider(roleId, e.target.value)} + className={CONTROL_CLASS} + style={CONTROL_STYLE} + > + {Object.entries(providers).map(([name, p]) => ( + <option key={name} value={name} disabled={!p.installed}> + {p.installed ? p.binary : `${p.binary} · ${t('settings.notInstalled')}`} + </option> + ))} + </select> + {info && !info.installed && ( + <span className="text-[10px] leading-snug" style={{ color: 'var(--red)' }}> + {t('settings.installHint', { binary: info.binary })} + </span> + )} + </div> + + <div className="flex flex-col gap-1"> + <span className="text-[9px] tracking-widest" style={{ color: 'var(--muted)' }}>{t('settings.field.model')}</span> + <div className="flex items-center gap-1.5"> + {custom ? ( + <input + value={draft.model ?? ''} + onChange={e => setModel(roleId, e.target.value === '' ? null : e.target.value)} + placeholder={t('settings.modelCustomPlaceholder')} + className={CONTROL_CLASS} + style={CONTROL_STYLE} + /> + ) : ( + <select + value={draft.model ?? DEFAULT_OPTION} + onChange={e => selectModel(roleId, e.target.value)} + className={CONTROL_CLASS} + style={CONTROL_STYLE} + > + <option value={DEFAULT_OPTION}>{t('settings.optionDefault')}</option> + {modelList.map(m => <option key={m.id} value={m.id}>{m.label}</option>)} + {draft.model !== null && !knownModel && <option value={draft.model}>{draft.model}</option>} + {!authoritative && <option value={CUSTOM_OPTION}>{t('settings.optionCustom')}</option>} + </select> + )} + <Button + variant="outline" + size="icon-xs" + aria-label={t('settings.refreshModels')} + title={t('settings.refreshModels')} + disabled={modelBusy} + onClick={() => { loadModels(draft.provider, true) }} + > + <RefreshCw className={modelBusy ? 'animate-spin' : undefined} /> + </Button> + </div> + <span className="text-[10px] leading-snug" style={{ color: 'var(--muted)' }}> + {modelBusy + ? t('settings.modelsLoading') + : modelList.length === 0 + ? t('settings.modelsEmpty') + : !authoritative + ? t('settings.modelsFreeText') + : ''} + </span> + {custom && ( + <button + type="button" + className="text-[10px] text-left cursor-pointer bg-transparent border-0 p-0" + style={{ color: 'var(--accent)' }} + onClick={() => { + setCustomModel(prev => ({ ...prev, [roleId]: false })) + setModel(roleId, null) + }} + > + {t('settings.modelBackToList')} + </button> + )} + </div> + + <div className="flex flex-col gap-1"> + <span className="text-[9px] tracking-widest" style={{ color: 'var(--muted)' }}>{t('settings.field.effort')}</span> + <select + value={effortLocked ? DEFAULT_OPTION : draft.effort ?? DEFAULT_OPTION} + disabled={effortLocked} + onChange={e => updateDraft(roleId, { effort: e.target.value === DEFAULT_OPTION ? null : e.target.value })} + className={CONTROL_CLASS} + style={{ ...CONTROL_STYLE, opacity: effortLocked ? 0.5 : 1 }} + > + <option value={DEFAULT_OPTION}>{t('settings.optionDefault')}</option> + {efforts.map(x => <option key={x} value={x}>{x}</option>)} + </select> + {effortLocked && ( + <span className="text-[10px] leading-snug" style={{ color: 'var(--muted)' }}> + {t('settings.effortLockedHint', { binary: info.binary })} + </span> + )} + </div> + </div> + + <div className="flex items-center gap-3 pt-3.5"> + <Button size="sm" disabled={!dirty || busy} onClick={() => save(roleId)}> + {busy ? t('settings.saving') : t('settings.save')} + </Button> + {state && ( + <span className="text-[10px] leading-snug" style={{ color: state.ok ? 'var(--green)' : 'var(--red)' }}>{state.text}</span> + )} + </div> + </CardContent> + </Card> + ) + })} + </div> + ) +} diff --git a/dashboard/src/types/index.ts b/dashboard/src/types/index.ts index 2c8cccbd1..5eebdd6d5 100644 --- a/dashboard/src/types/index.ts +++ b/dashboard/src/types/index.ts @@ -147,3 +147,50 @@ export interface SceneReview { fps_used: number has_critical_errors: boolean } + +// AI provider settings — match the /api/providers payload exactly +export interface RoleAssignment { + provider: string + model: string | null + effort: string | null +} + +export interface RoleMeta { + label: string + description: string +} + +export interface ProviderInfo { + binary: string + installed: boolean + tested: boolean | null + error: string | null + efforts: string[] + default_model: string | null + catalog_is_authoritative: boolean + model_encodes_effort: boolean +} + +export interface ProvidersResponse { + active: string + roles: Record<string, RoleAssignment> + role_meta: Record<string, RoleMeta> + providers: Record<string, ProviderInfo> +} + +export interface ProviderModel { + id: string + label: string +} + +export interface ProviderModelsResponse { + provider: string + models: ProviderModel[] + authoritative: boolean +} + +export interface ProvidersUpdateResponse { + status: string + active: string + roles: Record<string, RoleAssignment> +} diff --git a/skills/fk-change-provider.md b/skills/fk-change-provider.md index eff478185..42b46cdd7 100644 --- a/skills/fk-change-provider.md +++ b/skills/fk-change-provider.md @@ -1,11 +1,18 @@ -# fk-change-provider — View & Switch AI CLI Provider (Video Review) +# fk-change-provider — View & Switch the AI CLI for a Role -View or switch which AI CLI backend (`claude`, `agy`, or `codex`) is used for vision analysis during video review. +View or change which AI CLI (`claude`, `agy`, `codex`) — and which model and +reasoning effort — runs each AI role. One role exists today: `video_review`, +the vision analysis behind `/fk-review-video`. Usage: -- `/fk-change-provider` — show current provider status -- `/fk-change-provider list` — show current provider status -- `/fk-change-provider set <claude|agy|codex>` — switch active provider +- `/fk-change-provider` — show current status +- `/fk-change-provider list` — show current status +- `/fk-change-provider set <claude|agy|codex>` — switch the provider +- `/fk-change-provider set <provider> --model <id>` — switch provider and model +- `/fk-change-provider set <provider> --effort <level>` — switch provider and effort + (for `agy`, model and effort are mutually exclusive — see Step 2) + +The dashboard has the same controls under **Settings**. --- @@ -15,54 +22,112 @@ Usage: curl -s "http://127.0.0.1:8100/api/providers?live=true" | python3 -m json.tool ``` -Display in a readable table: +The response carries `active` (the legacy whole-agent provider), `roles` (what +each role actually runs on), `role_meta` (labels), and `providers` (per-CLI +status and the effort ladder that CLI accepts). + +Display two tables — first the roles: + +| Role | Provider | Model | Effort | +|------|----------|-------|--------| +| Video Review | agy | gemini-3.8-flash-low | low | + +`null` model or effort means "whatever that CLI defaults to" — render it as +`default`, not as an empty cell. + +Then the providers: -| Provider | Binary | Installed | Tested | Active | -|----------|--------|-----------|--------|--------| -| claude | `claude` | Yes | Yes | ✅ | -| agy | `agy` | Yes | Yes | | -| codex | `codex` | Yes | No | | +| Provider | Binary | Installed | Tested | Efforts | +|----------|--------|-----------|--------|---------| +| claude | `claude` | Yes | Yes | low, medium, high, xhigh, max | +| agy | `agy` | Yes | Yes | low, medium, high | +| codex | `codex` | Yes | No | low, medium, high, xhigh, max | - `Installed` reflects whether the binary is found on PATH. -- `Tested` reflects the live `<binary> --version` probe (populated because of `?live=true`); `null`/missing means not yet probed. -- `Active` gets a checkmark on whichever provider matches the top-level `active` field in the response. +- `Tested` reflects the live `<binary> --version` probe (populated because of + `?live=true`); `null` means not yet probed. ## Step 2: Quick Select (Interactive) -If no provider was given as an argument, use `AskUserQuestion` to let the user pick — only offer providers where `installed: true` as selectable options. +If nothing was given as an argument, use `AskUserQuestion` to let the user pick +— only offer providers where `installed: true`. For any provider with +`installed: false`, list it as unavailable with "install `<binary>` first" +instead of offering it. + +To offer models, list them for the chosen provider: + +```bash +curl -s "http://127.0.0.1:8100/api/providers/models?provider=<provider>" | python3 -m json.tool +``` + +- An **empty** `models` array is a normal answer, not an error — the binary is + missing or the listing call failed. Fall back to the provider's default. +- `authoritative: true` (agy only) means that list is the whole truth and agy + rejects anything outside it. For `claude` and `codex` an unlisted slug is a + legitimate escape hatch — claude takes aliases like `sonnet` and full model + names, codex takes slugs newer than its on-disk cache. +- Offer only efforts from that provider's `efforts` array. **agy has no `xhigh` + or `max`** and the API rejects them with a 400. +- **If the provider has `model_encodes_effort: true` (agy), do not offer both.** + agy's slugs name their own effort, so `--model` and `--effort` together are + rejected — a mismatch conflicts, and a slug with no effort in its name + (`claude-sonnet-4-6`) refuses `--effort` at all. Ask for a model **or** an + effort, not both; the API answers 400 for the pair. -For any provider with `installed: false`, list it as unavailable with a note like "install `<binary>` first" instead of offering it as a selectable option. +## Step 3: Change It -## Step 3: Change the Provider +Per role — this is the one to use: ```bash curl -X PATCH http://127.0.0.1:8100/api/providers \ -H "Content-Type: application/json" \ - -d '{"active": "<provider>"}' + -d '{"roles": {"video_review": {"provider": "claude", "model": "sonnet", "effort": "high"}}}' ``` -- Returns `{"status": "updated", "active": "<provider>"}` on success. -- Returns `400` if the provider name is unknown, or if its binary isn't found on PATH. +- `model` and `effort` are optional and nullable; omit or send `null` for the + CLI's own default. +- For `agy`, send a model **or** an effort, never both — `{"provider": "agy", + "model": "gemini-3.8-flash-low"}` is right, adding `"effort": "low"` is a 400. +- Returns `{"status": "updated", "active": ..., "roles": {...}}`. +- `400` on an unknown role or provider, a binary missing from PATH, or an + effort the provider does not have. The `detail` string says which. -## Step 4: Verify - -After changing, verify the update took effect: +Whole-agent switch (legacy, still supported): ```bash -curl -s "http://127.0.0.1:8100/api/providers?live=true" | python3 -m json.tool +curl -X PATCH http://127.0.0.1:8100/api/providers \ + -H "Content-Type: application/json" -d '{"active": "agy"}' ``` -Confirm the `active` field now matches the provider you selected. +This moves every role onto that provider, **clears each role's model** and +**drops an effort the new provider lacks** — a model slug means nothing to a +different CLI, and agy would reject `sonnet` outright. + +## Step 4: Verify + +```bash +curl -s "http://127.0.0.1:8100/api/providers" | python3 -m json.tool +``` -Changes are **hot-reloaded** — no server restart needed. The new provider is used immediately for all subsequent video review requests. +Confirm `roles.video_review` matches what you set. Changes are **hot-reloaded** +— no server restart, and the next review uses them. --- ## Notes -- `claude` = Claude Code CLI (default) -- `agy` = Google Antigravity CLI -- `codex` = OpenAI Codex CLI -- Switching is hot-reloaded — no server restart needed. -- **`codex` requires a separate one-time `codex login` (interactive OAuth in a terminal) before it will actually work.** Being listed as `installed: true` only means the binary is present on PATH — it does not mean it's authenticated. If a codex-backed review fails with an auth error, run `codex login` and retry. -- If you set a provider whose binary later goes missing, the next review request will fail clearly (not silently) — switch back via this skill. +- `claude` = Claude Code CLI (default) · `agy` = Google Antigravity CLI · + `codex` = OpenAI Codex CLI +- **`codex` needs two things beyond the binary**: a one-time `codex login` + (interactive OAuth in a terminal), and credits on its OpenAI workspace. With + no balance every review fails with `ERROR: Your workspace is out of credits`. + `installed: true` only means the binary is on PATH. +- `agy` is never run with `--dangerously-skip-permissions`. It reads contact + sheets with its own file-reading tool because the prompt tells it to, which + needs no elevated permission. If a review ever comes back saying tools were + "auto-denied headlessly", that steering was lost — do not add the flag, fix + the prompt. +- `codex` runs `--sandbox read-only`. `-i` hands it the image bytes directly, + so it needs no shell and no writable filesystem. +- `agent/providers.json` is the file behind all of this and is safe to edit by + hand; the next API call re-reads it. diff --git a/skills/fk-doctor.md b/skills/fk-doctor.md index cd505235f..f26c8db38 100644 --- a/skills/fk-doctor.md +++ b/skills/fk-doctor.md @@ -11,6 +11,7 @@ Diagnose any FlowKit error and prescribe a fix. Knows the full error taxonomy ac - An HTTP 4xx/5xx reaches the main agent from any endpoint under `127.0.0.1:8100` - A YouTube upload returns `HttpError` from `googleapiclient` - `cryptography` / architecture / import errors surface during setup +- A `/fk-review-video` run fails or returns nothing, or an error mentions `No such filter`, `Frame extraction failed`, `auto-denied`, `out of credits`, `CLI failed`, `CLI timed out`, `invalid model selection` **DO NOT use when:** - The request is still `PENDING` and hasn't been attempted yet @@ -202,6 +203,25 @@ When the user describes a symptom in plain language, map it here first. | Python `cryptography` arch mismatch | Use `python3.10`, not `python3.13` (x86/arm64 binary mismatch) | | `curl: (7) Failed to connect to 127.0.0.1:8100` | Agent not running — `python -m agent.main` | +### G. Video review errors (`services/video_reviewer.py`) + +Review runs outside the worker — no retry policy applies, the call just raises. +Providers, models and efforts come from `agent/providers.json`; see +`/fk-change-provider`. + +| Error | Cause | Fix | +|---|---|---| +| `Frame extraction failed: ... No such filter: 'drawtext'` | ffmpeg built without libfreetype. Should no longer happen — the filter is probed and skipped — so seeing it means the probe was bypassed | `ffmpeg -filters \| grep drawtext`. Absent is fine; sheets just lose their burned-in timestamps | +| `agy CLI had tools auto-denied headlessly (RunCommand) — its N-character answer cannot be trusted to have come from the images` | agy tried to shell out to read the contact sheet instead of using its file-reading tool; headless mode cannot prompt, so the tool was denied. Raised whether or not agy still produced an answer — the prompt carries the rubric, both scene prompts and the character names, which is enough to write a plausible review without ever looking at a frame | Restore the steering in `_AGY_READ_STEER`. **Do not** add `--dangerously-skip-permissions` — it auto-approves every tool including arbitrary shell commands, for a job that only reads JPEGs | +| `agy CLI returned non-JSON output: ...` | agy answered with bare prose on a zero exit code — usually a permission or startup error | Read the quoted text; it names the real problem | +| `agy CLI failed (rc=1): invalid model selection ... conflicts with --effort=` | agy's slugs name their own effort (`gemini-3.8-flash-low`), so model and effort cannot both be set | Clear one of them. The API rejects the pair with a 400; this only reaches the CLI from a hand-edited `providers.json` | +| `codex CLI failed (rc=1): ... Your workspace is out of credits` | The OpenAI workspace has no balance. `installed: true` only means the binary is on PATH | Refill, or switch the role to `claude`/`agy` | +| `codex CLI exited cleanly but wrote no answer to its output file` | codex returned success but produced nothing | Re-run; if it repeats, switch provider | +| `<provider> CLI timed out after Ns` | The review exceeded `REVIEW_CLI_TIMEOUT_S` (default 120) | Raise the env var, or lower `REVIEW_FPS_*` / `REVIEW_MAX_FRAMES` so there is less to look at | +| `review answer had an error entry with no usable severity (expected one of ['CRITICAL', 'HIGH', 'MINOR']): ...` | The model graded an error with something outside the three severities. `has_critical_errors`, the `character_consistency` cap and the fix guide all branch on that exact string, so anything else silently disables all three — the model flagged a defect and the score would not show it | Read the quoted entry. A model that keeps doing this is not following the rubric; switch the role to another one | +| `Scene <id>: review answer needed repair — N error field(s) defaulted, M usable segment(s) unreadable` (warning, not a failure) | A near-miss field name (`timeRange` for `time_range`) or a missing description. Repaired, because losing those costs context but cannot move a score | Nothing required. A rising count means the model is drifting from the rubric | +| `CLI answer had no dimensions: ...` | The CLI returned parseable JSON with no scores in it. Every dimension defaults to 5.0, so this would otherwise have become a complete, plausible "poor" review of a video nobody actually looked at | Read the quoted answer. Usually the model wrote prose around the JSON, or ran out of context — lower `REVIEW_MAX_FRAMES` or try another model | + ## Worker retry policy (`processor.py:_handle_failure`) Decision order — stop at first match: diff --git a/tests/unit/test_cli_providers.py b/tests/unit/test_cli_providers.py index 68ff56ca3..2178eb448 100644 --- a/tests/unit/test_cli_providers.py +++ b/tests/unit/test_cli_providers.py @@ -19,7 +19,10 @@ _run_codex_cli, _analyze_cli, _build_prompt, + _frame_filter, + _parse_agy_envelope, ) +from agent.services import cli_providers from agent.api import providers as providers_api @@ -59,10 +62,24 @@ async def test_argv_and_return_value(self): # _run_agy_cli # --------------------------------------------------------------------------- +def agy_envelope(response: str, **extra) -> bytes: + """A realistic `agy --output-format json` envelope.""" + env = { + "conversation_id": "c-1", + "status": "SUCCESS", + "response": response, + "duration_seconds": 1.0, + "num_turns": 1, + "usage": {"total_tokens": 10}, + } + env.update(extra) + return json.dumps(env).encode() + + class TestRunAgyCli: @pytest.mark.asyncio - async def test_argv_and_return_value(self): - proc = make_proc(stdout=b'{"ok": true}', stderr=b"", returncode=0) + async def test_argv_asks_for_json_and_unwraps_the_envelope(self): + proc = make_proc(stdout=agy_envelope('{"ok": true}'), returncode=0) with patch( "agent.services.video_reviewer.asyncio.create_subprocess_exec", new=AsyncMock(return_value=proc), @@ -70,44 +87,149 @@ async def test_argv_and_return_value(self): result = await _run_agy_cli("hello") args, kwargs = mock_exec.call_args - assert args == ("agy", "-p", "hello", "--dangerously-skip-permissions", "--output-format", "text") + assert args[:6] == ("agy", "-p", "hello", "--output-format", "json", "--print-timeout") + # The answer is the envelope's `response`, not the raw stdout. assert result == '{"ok": true}' + @pytest.mark.asyncio + async def test_never_passes_the_skip_permissions_flag(self): + """--dangerously-skip-permissions auto-approves *every* tool, shell + commands included, for a job whose only need is reading a few JPEGs. + Steering agy at its file-reading tool achieves the read unprivileged + (verified against agy 1.2.7), so the flag must never come back.""" + proc = make_proc(stdout=agy_envelope("x"), returncode=0) + with patch( + "agent.services.video_reviewer.asyncio.create_subprocess_exec", + new=AsyncMock(return_value=proc), + ) as mock_exec: + await _run_agy_cli("hello") + assert "--dangerously-skip-permissions" not in mock_exec.call_args[0] + + @staticmethod + async def _argv_for(**kwargs): + proc = make_proc(stdout=agy_envelope("x"), returncode=0) + with patch( + "agent.services.video_reviewer.asyncio.create_subprocess_exec", + new=AsyncMock(return_value=proc), + ) as mock_exec: + await _run_agy_cli("hello", **kwargs) + return mock_exec.call_args[0] + + @pytest.mark.asyncio + async def test_model_and_add_dirs_reach_the_argv(self): + argv = await self._argv_for(model="gemini-3.8-flash-low", add_dirs=("/tmp/sheets",)) + assert argv[argv.index("--model") + 1] == "gemini-3.8-flash-low" + assert argv[argv.index("--add-dir") + 1] == "/tmp/sheets" + + @pytest.mark.asyncio + async def test_effort_alone_reaches_the_argv(self): + argv = await self._argv_for(effort="high") + assert argv[argv.index("--effort") + 1] == "high" + assert "--model" not in argv + + @pytest.mark.asyncio + async def test_effort_is_dropped_when_a_model_is_set(self): + """agy slugs carry the effort — gemini-3.8-flash-low. Verified against + agy 1.2.7: a mismatched pair is rejected outright ("--model + gpt-oss-120b-medium conflicts with --effort=low") and a slug with no + effort in its name refuses --effort at all. The API will not store both, + but providers.json is hand-editable, so the runner defends too.""" + argv = await self._argv_for(model="gemini-3.8-flash-low", effort="high") + assert argv[argv.index("--model") + 1] == "gemini-3.8-flash-low" + assert "--effort" not in argv + + +class TestParseAgyEnvelope: + def test_returns_the_response_field(self): + assert _parse_agy_envelope(agy_envelope(" hi ").decode()) == "hi" + + def test_denied_tool_with_empty_response_is_an_error_not_an_empty_answer(self): + """The exact shape of the bug this rewrite fixes: agy auto-denies a + tool it cannot prompt for, returns an empty response, and still reports + status SUCCESS on a zero exit code. Read naively that is a silent + empty review; it has to be an error, and it has to name the tool.""" + raw = agy_envelope( + "", denied_actions=[{"action": "command", "display_name": "RunCommand"}] + ).decode() + with pytest.raises(RuntimeError) as excinfo: + _parse_agy_envelope(raw) + assert "RunCommand" in str(excinfo.value) + + def test_a_denied_tool_with_a_confident_answer_is_also_an_error(self): + """The more dangerous half. The prompt carries the full scoring rubric, + the scene's image prompt, its video prompt and the character names — so + agy can write a complete, plausible review from the text alone without + ever having looked at a frame. A denial means the "use your file-reading + tool, run no shell command" steering did not hold, so the answer cannot + be attributed to the images no matter how well-formed it is.""" + raw = agy_envelope( + '{"dimensions": {"character_consistency": 9.0}, "errors": []}', + denied_actions=[{"action": "command", "display_name": "RunCommand"}], + ).decode() + with pytest.raises(RuntimeError, match="auto-denied"): + _parse_agy_envelope(raw) + + def test_a_clean_success_carries_no_denials_and_passes(self): + """The happy path must stay clean — live agy 1.2.7 runs that succeed + omit denied_actions entirely, so widening the guard costs nothing.""" + assert _parse_agy_envelope(agy_envelope("the answer").decode()) == "the answer" + + def test_bare_prose_on_a_zero_exit_code_is_an_error(self): + """What agy actually prints when the permission is denied and no + --output-format json is honoured. rc is 0, so _spawn_and_check lets it + through and this is the only place left to catch it.""" + with pytest.raises(RuntimeError, match="non-JSON"): + _parse_agy_envelope( + "jetski: no output produced — a tool required the \"command\" permission" + ) + + def test_empty_stdout_is_an_error(self): + with pytest.raises(RuntimeError, match="no output"): + _parse_agy_envelope(" ") + + def test_empty_response_is_an_error(self): + with pytest.raises(RuntimeError, match="empty response"): + _parse_agy_envelope(agy_envelope("").decode()) + + def test_non_success_status_is_an_error(self): + with pytest.raises(RuntimeError, match="status"): + _parse_agy_envelope(agy_envelope("hi", status="ERROR").decode()) + # --------------------------------------------------------------------------- # _run_codex_cli # --------------------------------------------------------------------------- +def fake_codex_exec(captured, answer: str = "codex analysis result", returncode: int = 0): + """Stand in for the codex binary: record argv, write the -o file, exit.""" + async def _run(*args, **kwargs): + captured["args"] = args + captured["kwargs"] = kwargs + out_path = Path(args[args.index("-o") + 1]) + out_path.write_text(answer) + return make_proc(stdout=b"", stderr=b"", returncode=returncode) + return _run + + class TestRunCodexCli: @pytest.mark.asyncio async def test_argv_structure_and_output_file_roundtrip(self): contact_sheets = [Path("/tmp/sheet_00.jpg"), Path("/tmp/sheet_01.jpg")] captured = {} - async def fake_create_subprocess_exec(*args, **kwargs): - captured["args"] = args - # Locate the -o path and write our known content to it, simulating - # what the real codex CLI would do before exiting. - o_index = args.index("-o") - out_path = Path(args[o_index + 1]) - out_path.write_text("codex analysis result") - return make_proc(stdout=b"", stderr=b"", returncode=0) - with patch( "agent.services.video_reviewer.asyncio.create_subprocess_exec", - new=AsyncMock(side_effect=fake_create_subprocess_exec), + new=AsyncMock(side_effect=fake_codex_exec(captured)), ): result = await _run_codex_cli("analyze this", contact_sheets) args = captured["args"] - o_index = args.index("-o") - out_path = Path(args[o_index + 1]) + out_path = Path(args[args.index("-o") + 1]) assert args == ( - "codex", "exec", + "codex", "exec", "--skip-git-repo-check", "--sandbox", "read-only", "-i", str(contact_sheets[0]), "-i", str(contact_sheets[1]), "-o", str(out_path), - "--dangerously-bypass-approvals-and-sandbox", "analyze this", ) @@ -115,6 +237,78 @@ async def fake_create_subprocess_exec(*args, **kwargs): # finally: out_path.unlink(missing_ok=True) must have run assert not out_path.exists() + @pytest.mark.asyncio + async def test_never_bypasses_the_sandbox(self): + """-i hands codex the image bytes directly, so the run needs neither a + shell nor a writable filesystem. read-only already implies + approval:never, so nothing hangs — the bypass flag bought nothing and + cost the sandbox.""" + captured = {} + with patch( + "agent.services.video_reviewer.asyncio.create_subprocess_exec", + new=AsyncMock(side_effect=fake_codex_exec(captured)), + ): + await _run_codex_cli("analyze this", [Path("/tmp/sheet_00.jpg")]) + assert "--dangerously-bypass-approvals-and-sandbox" not in captured["args"] + assert "--sandbox" in captured["args"] + + @pytest.mark.asyncio + async def test_model_and_effort_reach_the_argv(self): + captured = {} + with patch( + "agent.services.video_reviewer.asyncio.create_subprocess_exec", + new=AsyncMock(side_effect=fake_codex_exec(captured)), + ): + await _run_codex_cli( + "analyze this", [Path("/tmp/s.jpg")], model="gpt-5.6-sol", effort="high" + ) + argv = captured["args"] + assert argv[argv.index("-m") + 1] == "gpt-5.6-sol" + # codex has no --effort; the reasoning level is a TOML config override. + assert argv[argv.index("-c") + 1] == 'model_reasoning_effort="high"' + + @pytest.mark.asyncio + async def test_empty_output_file_is_an_error_not_an_empty_answer(self): + """codex can exit 0 having written nothing. Returning "" from here + surfaces as a JSON decode error three frames away from the cause.""" + captured = {} + with patch( + "agent.services.video_reviewer.asyncio.create_subprocess_exec", + new=AsyncMock(side_effect=fake_codex_exec(captured, answer="")), + ): + with pytest.raises(RuntimeError, match="no answer"): + await _run_codex_cli("analyze this", [Path("/tmp/s.jpg")]) + + +class TestStdinIsClosed: + """All three CLIs append piped stdin to the prompt when stdin is not a + terminal — codex documents it as a `<stdin>` block. Under uvicorn stdin is + inherited from the launching shell, so it has to be closed explicitly.""" + + @pytest.mark.asyncio + @pytest.mark.parametrize("runner,stdout", [ + (_run_claude_cli, b"ok"), + (_run_agy_cli, None), + ]) + async def test_stdin_is_devnull(self, runner, stdout): + proc = make_proc(stdout=stdout if stdout is not None else agy_envelope("ok"), returncode=0) + with patch( + "agent.services.video_reviewer.asyncio.create_subprocess_exec", + new=AsyncMock(return_value=proc), + ) as mock_exec: + await runner("hello") + assert mock_exec.call_args.kwargs["stdin"] == asyncio.subprocess.DEVNULL + + @pytest.mark.asyncio + async def test_codex_stdin_is_devnull(self): + captured = {} + with patch( + "agent.services.video_reviewer.asyncio.create_subprocess_exec", + new=AsyncMock(side_effect=fake_codex_exec(captured)), + ): + await _run_codex_cli("analyze this", [Path("/tmp/s.jpg")]) + assert captured["kwargs"]["stdin"] == asyncio.subprocess.DEVNULL + # --------------------------------------------------------------------------- # Timeout path (shared by all three runners via _communicate_with_timeout) @@ -150,6 +344,18 @@ async def fake_wait_for(coro, timeout): # _analyze_cli prompt branching per provider # --------------------------------------------------------------------------- +EMPTY_REVIEW = '{"dimensions": {}, "errors": [], "usable_segments": []}' + + +def capture_runner(captured): + """Stand in for a claude/agy runner, recording prompt and per-role kwargs.""" + async def _run(full_prompt, **kwargs): + captured["prompt"] = full_prompt + captured.update(kwargs) + return EMPTY_REVIEW + return _run + + class TestAnalyzeCliPromptBranching: @pytest.mark.asyncio @pytest.mark.parametrize( @@ -157,36 +363,56 @@ class TestAnalyzeCliPromptBranching: ) async def test_claude_agy_providers_include_read_the_images_at(self, provider, runner_name): captured = {} - - async def fake_run(full_prompt): - captured["prompt"] = full_prompt - return '{"dimensions": {}, "errors": [], "usable_segments": []}' - contact_sheets = [Path("/tmp/sheet_00.jpg"), Path("/tmp/sheet_01.jpg")] with patch("agent.services.video_reviewer.config.CLI_PROVIDERS", {"active": provider}), \ patch("agent.services.video_reviewer._build_prompt", return_value="BASE_PROMPT"), \ - patch(f"agent.services.video_reviewer.{runner_name}", new=AsyncMock(side_effect=fake_run)): - result = await _analyze_cli(contact_sheets, 10, 4.0, {}) + patch(f"agent.services.video_reviewer.{runner_name}", + new=AsyncMock(side_effect=capture_runner(captured))): + result = await _analyze_cli(contact_sheets, 10, 4.0, {}, timestamped=True) assert "Read the images at:" in captured["prompt"] assert str(contact_sheets[0]) in captured["prompt"] assert str(contact_sheets[1]) in captured["prompt"] assert "BASE_PROMPT" in captured["prompt"] + # The sheets live outside the server cwd, so the directory holding them + # is named to the CLI rather than left to be discovered. + assert captured["add_dirs"] == ("/tmp",) assert result == {"dimensions": {}, "errors": [], "usable_segments": []} + @pytest.mark.asyncio + async def test_only_agy_gets_the_file_read_steering(self): + """The steering line is what makes agy read the sheet with its + file-reading tool instead of shelling out and being auto-denied. claude + needs no such nudge, and an extra instruction is an extra thing for it + to obey oddly.""" + prompts = {} + for provider, runner_name in [("claude", "_run_claude_cli"), ("agy", "_run_agy_cli")]: + captured = {} + with patch("agent.services.video_reviewer.config.CLI_PROVIDERS", {"active": provider}), \ + patch("agent.services.video_reviewer._build_prompt", return_value="BASE_PROMPT"), \ + patch(f"agent.services.video_reviewer.{runner_name}", + new=AsyncMock(side_effect=capture_runner(captured))): + await _analyze_cli([Path("/tmp/s.jpg")], 9, 4.0, {}, timestamped=True) + prompts[provider] = captured["prompt"] + + assert "Do NOT run any shell command" in prompts["agy"] + assert "file-reading tool" in prompts["agy"] + assert "Do NOT run any shell command" not in prompts["claude"] + @pytest.mark.asyncio async def test_codex_provider_excludes_read_the_image_at(self): captured = {} - async def fake_run_codex(full_prompt, contact_sheets): + async def fake_run_codex(full_prompt, contact_sheets, **kwargs): captured["prompt"] = full_prompt - return '{"dimensions": {}, "errors": [], "usable_segments": []}' + captured.update(kwargs) + return EMPTY_REVIEW contact_sheets = [Path("/tmp/sheet_00.jpg"), Path("/tmp/sheet_01.jpg")] with patch("agent.services.video_reviewer.config.CLI_PROVIDERS", {"active": "codex"}), \ patch("agent.services.video_reviewer._build_prompt", return_value="BASE_PROMPT"), \ patch("agent.services.video_reviewer._run_codex_cli", new=AsyncMock(side_effect=fake_run_codex)): - result = await _analyze_cli(contact_sheets, 10, 4.0, {}) + result = await _analyze_cli(contact_sheets, 10, 4.0, {}, timestamped=True) assert "Read the image at" not in captured["prompt"] assert "sequential contact sheets" in captured["prompt"] @@ -201,22 +427,50 @@ async def test_single_sheet_wrapper_wording_matches_original_singular_form(self) contact sheets...' which is both grammatically wrong and misleading. """ captured = {} - - async def fake_run_claude(full_prompt): - captured["prompt"] = full_prompt - return '{"dimensions": {}, "errors": [], "usable_segments": []}' - contact_sheets = [Path("/tmp/sheet_00.jpg")] with patch("agent.services.video_reviewer.config.CLI_PROVIDERS", {"active": "claude"}), \ patch("agent.services.video_reviewer._build_prompt", return_value="BASE_PROMPT"), \ - patch("agent.services.video_reviewer._run_claude_cli", new=AsyncMock(side_effect=fake_run_claude)): - await _analyze_cli(contact_sheets, 9, 4.0, {}) + patch("agent.services.video_reviewer._run_claude_cli", + new=AsyncMock(side_effect=capture_runner(captured))): + await _analyze_cli(contact_sheets, 9, 4.0, {}, timestamped=True) assert captured["prompt"].startswith("Read the image at /tmp/sheet_00.jpg.") assert "Read the images at:" not in captured["prompt"] assert "sequential contact sheets" not in captured["prompt"] assert "It is a contact sheet of 9 video frames at 4.0fps with timestamps." in captured["prompt"] + @pytest.mark.asyncio + async def test_untimestamped_sheets_hand_the_model_the_arithmetic(self): + """Every review answer is expressed in time ranges. When the ffmpeg + build cannot burn timestamps in, the prompt must stop claiming they are + there and give the frame interval instead, or the model invents times + off labels that do not exist.""" + captured = {} + with patch("agent.services.video_reviewer.config.CLI_PROVIDERS", {"active": "claude"}), \ + patch("agent.services.video_reviewer._build_prompt", return_value="BASE_PROMPT"), \ + patch("agent.services.video_reviewer._run_claude_cli", + new=AsyncMock(side_effect=capture_runner(captured))): + await _analyze_cli([Path("/tmp/s.jpg")], 9, 4.0, {}, timestamped=False) + + assert "with timestamps" not in captured["prompt"] + assert "without timestamps" in captured["prompt"] + assert "0.25s" in captured["prompt"] # 1/4fps + + @pytest.mark.asyncio + async def test_role_model_and_effort_reach_the_runner(self): + captured = {} + cfg = {"active": "agy", "roles": {"video_review": { + "provider": "claude", "model": "sonnet", "effort": "high"}}} + with patch("agent.services.video_reviewer.config.CLI_PROVIDERS", cfg), \ + patch("agent.services.video_reviewer._build_prompt", return_value="BASE_PROMPT"), \ + patch("agent.services.video_reviewer._run_claude_cli", + new=AsyncMock(side_effect=capture_runner(captured))): + await _analyze_cli([Path("/tmp/s.jpg")], 9, 4.0, {}, timestamped=True) + + # The role entry wins over `active`, and both knobs reach the runner. + assert captured["model"] == "sonnet" + assert captured["effort"] == "high" + # --------------------------------------------------------------------------- # _build_prompt :: sheet_note behavior (single-sheet vs multi-sheet) @@ -238,6 +492,22 @@ def test_multi_sheet_includes_sheet_note(self): # agent/api/providers.py :: patch_providers # --------------------------------------------------------------------------- +@pytest.fixture +def providers_file(monkeypatch, tmp_path): + """Point the API at a throwaway providers.json and isolate config.""" + tmp_file = tmp_path / "providers.json" + tmp_file.write_text(json.dumps({"active": "claude"})) + monkeypatch.setattr(providers_api, "_PROVIDERS_FILE", tmp_file) + monkeypatch.setattr(providers_api.shutil, "which", lambda binary: "/usr/local/bin/fake") + monkeypatch.setattr(cli_providers.shutil, "which", lambda binary: "/usr/local/bin/fake") + # Ensure config.CLI_PROVIDERS mutation doesn't leak to other tests. + monkeypatch.setattr( + providers_api.config, "CLI_PROVIDERS", + dict(providers_api.config.CLI_PROVIDERS), raising=False, + ) + return tmp_file + + class TestPatchProviders: @pytest.mark.asyncio async def test_unknown_provider_raises_400(self): @@ -253,21 +523,323 @@ async def test_known_provider_missing_binary_raises_400(self, monkeypatch): assert excinfo.value.status_code == 400 @pytest.mark.asyncio - async def test_known_provider_with_binary_updates_file_and_config(self, monkeypatch, tmp_path): - tmp_file = tmp_path / "providers.json" - tmp_file.write_text(json.dumps({"active": "claude"})) + async def test_empty_body_raises_400(self): + with pytest.raises(HTTPException) as excinfo: + await providers_api.patch_providers({}) + assert excinfo.value.status_code == 400 + + @pytest.mark.asyncio + async def test_known_provider_with_binary_updates_file_and_config(self, providers_file): + result = await providers_api.patch_providers({"active": "codex"}) + + assert result["status"] == "updated" + assert result["active"] == "codex" + assert json.loads(providers_file.read_text())["active"] == "codex" + assert providers_api.config.CLI_PROVIDERS["active"] == "codex" + + @pytest.mark.asyncio + async def test_legacy_active_switch_migrates_a_file_with_no_roles(self, providers_file): + """providers.json predates roles. Switching `active` on an old file has + to leave a roles map behind, or the dashboard shows nothing to edit.""" + result = await providers_api.patch_providers({"active": "agy"}) + assert result["roles"]["video_review"]["provider"] == "agy" + assert json.loads(providers_file.read_text())["roles"]["video_review"]["provider"] == "agy" + + @pytest.mark.asyncio + async def test_legacy_active_switch_clears_model_and_clamps_effort(self, providers_file): + """A model slug is meaningless to a different CLI — agy rejects + "sonnet" outright — and agy's effort ladder stops at high. Carrying + either across a provider switch turns the next review into a hard CLI + error several seconds in.""" + providers_file.write_text(json.dumps({"active": "claude", "roles": { + "video_review": {"provider": "claude", "model": "sonnet", "effort": "max"}}})) + + result = await providers_api.patch_providers({"active": "agy"}) + + entry = result["roles"]["video_review"] + assert entry == {"provider": "agy", "model": None, "effort": None} + + @pytest.mark.asyncio + async def test_legacy_active_switch_keeps_an_effort_the_new_provider_supports(self, providers_file): + providers_file.write_text(json.dumps({"active": "claude", "roles": { + "video_review": {"provider": "claude", "model": "sonnet", "effort": "high"}}})) + result = await providers_api.patch_providers({"active": "agy"}) + assert result["roles"]["video_review"]["effort"] == "high" + + @pytest.mark.asyncio + async def test_roles_patch_round_trips(self, providers_file): + result = await providers_api.patch_providers({"roles": {"video_review": { + "provider": "claude", "model": "sonnet", "effort": "high"}}}) + + assert result["roles"]["video_review"] == { + "provider": "claude", "model": "sonnet", "effort": "high"} + assert json.loads(providers_file.read_text())["roles"]["video_review"]["model"] == "sonnet" + + @pytest.mark.asyncio + async def test_roles_patch_rejects_model_plus_effort_for_agy(self, providers_file): + """agy's slugs name their own effort, so the pair is either redundant or + contradictory — and agy rejects it either way. Better a 400 here than a + subprocess failure on the next review.""" + with pytest.raises(HTTPException) as excinfo: + await providers_api.patch_providers({"roles": {"video_review": { + "provider": "agy", "model": "gemini-3.8-flash-low", "effort": "low"}}}) + assert excinfo.value.status_code == 400 + assert "pick one" in excinfo.value.detail + + @pytest.mark.asyncio + async def test_roles_patch_allows_agy_with_a_model_and_no_effort(self, providers_file): + result = await providers_api.patch_providers({"roles": {"video_review": { + "provider": "agy", "model": "gemini-3.8-flash-low"}}}) + assert result["roles"]["video_review"] == { + "provider": "agy", "model": "gemini-3.8-flash-low", "effort": None} + + @pytest.mark.asyncio + async def test_active_and_roles_in_one_body_keeps_the_explicit_role(self, providers_file): + """The handler advertises "active, roles, or both". The whole-agent + sweep must not undo a role the same request named: that entry is the + more specific instruction and it already passed validation.""" + result = await providers_api.patch_providers({ + "active": "codex", + "roles": {"video_review": { + "provider": "codex", "model": "gpt-5.6-sol", "effort": "high"}}, + }) + assert result["active"] == "codex" + assert result["roles"]["video_review"] == { + "provider": "codex", "model": "gpt-5.6-sol", "effort": "high"} + + @pytest.mark.asyncio + async def test_reasserting_the_same_provider_keeps_the_model(self, providers_file): + """`/fk-change-provider set claude` on a config already on claude must + be a no-op, not a quiet reset. The reason a model is dropped on a + switch — a slug means nothing to a different CLI — does not apply when + the CLI did not change.""" + providers_file.write_text(json.dumps({"active": "claude", "roles": { + "video_review": {"provider": "claude", "model": "opus", "effort": "high"}}})) - monkeypatch.setattr(providers_api, "_PROVIDERS_FILE", tmp_file) - monkeypatch.setattr(providers_api.shutil, "which", lambda binary: "/usr/local/bin/fake") + result = await providers_api.patch_providers({"active": "claude"}) - # Ensure config.CLI_PROVIDERS mutation doesn't leak to other tests. - original_cli_providers = dict(providers_api.config.CLI_PROVIDERS) - monkeypatch.setattr( - providers_api.config, "CLI_PROVIDERS", dict(original_cli_providers), raising=False + assert result["roles"]["video_review"] == { + "provider": "claude", "model": "opus", "effort": "high"} + + @pytest.mark.asyncio + async def test_roles_patch_keeps_active_in_step(self, providers_file): + """`active` is what /fk-change-provider and the statusline read. If the + dashboard can move video_review without moving `active`, those two + report a provider that is not running.""" + await providers_api.patch_providers( + {"roles": {"video_review": {"provider": "codex"}}} ) + assert json.loads(providers_file.read_text())["active"] == "codex" - result = await providers_api.patch_providers({"active": "codex"}) + @pytest.mark.asyncio + async def test_roles_patch_rejects_an_effort_the_provider_lacks(self, providers_file): + with pytest.raises(HTTPException) as excinfo: + await providers_api.patch_providers({"roles": {"video_review": { + "provider": "agy", "effort": "xhigh"}}}) + assert excinfo.value.status_code == 400 + assert "xhigh" in excinfo.value.detail - assert result == {"status": "updated", "active": "codex"} - assert json.loads(tmp_file.read_text())["active"] == "codex" - assert providers_api.config.CLI_PROVIDERS["active"] == "codex" + @pytest.mark.asyncio + async def test_roles_patch_rejects_an_unknown_role(self, providers_file): + with pytest.raises(HTTPException) as excinfo: + await providers_api.patch_providers({"roles": {"nope": {"provider": "claude"}}}) + assert excinfo.value.status_code == 400 + assert "nope" in excinfo.value.detail + + @pytest.mark.asyncio + async def test_roles_patch_accepts_an_unlisted_model_for_a_non_authoritative_cli( + self, providers_file + ): + """claude takes aliases and full model names, codex takes slugs newer + than its on-disk cache. Validating those against a catalog would break + the day a new model ships.""" + result = await providers_api.patch_providers({"roles": {"video_review": { + "provider": "claude", "model": "claude-something-not-in-any-catalog"}}}) + assert result["roles"]["video_review"]["model"] == "claude-something-not-in-any-catalog" + + +class TestGetProviders: + @pytest.mark.asyncio + async def test_reports_efforts_and_roles_without_probing(self, providers_file): + """live=false must not spawn anything — the dashboard polls this.""" + with patch.object(providers_api, "_probe_version", new=AsyncMock()) as probe: + body = await providers_api.get_providers() + probe.assert_not_called() + + assert body["providers"]["agy"]["efforts"] == ["low", "medium", "high"] + assert "xhigh" in body["providers"]["claude"]["efforts"] + assert body["providers"]["agy"]["catalog_is_authoritative"] is True + assert body["providers"]["claude"]["catalog_is_authoritative"] is False + assert body["roles"]["video_review"]["provider"] == "claude" + assert "video_review" in body["role_meta"] + + @pytest.mark.asyncio + async def test_unknown_provider_models_raises_400(self): + with pytest.raises(HTTPException) as excinfo: + await providers_api.get_provider_models(provider="nope", refresh=False) + assert excinfo.value.status_code == 400 + + +# --------------------------------------------------------------------------- +# agent/services/cli_providers.py :: role resolution +# --------------------------------------------------------------------------- + +class TestResolveRole: + def test_falls_back_to_legacy_active_when_the_role_is_absent(self, monkeypatch): + """An untouched providers.json has no `roles` key at all.""" + monkeypatch.setattr(cli_providers.config, "CLI_PROVIDERS", {"active": "codex"}) + assert cli_providers.resolve_role("video_review") == { + "provider": "codex", "model": None, "effort": None} + + def test_role_entry_wins_over_active(self, monkeypatch): + monkeypatch.setattr(cli_providers.config, "CLI_PROVIDERS", { + "active": "claude", + "roles": {"video_review": {"provider": "agy", "model": "m", "effort": "high"}}}) + assert cli_providers.resolve_role("video_review") == { + "provider": "agy", "model": "m", "effort": "high"} + + def test_unknown_provider_degrades_to_the_default(self, monkeypatch): + """Hand-edited config should not take the review path down with a + KeyError deep inside the runner dispatch.""" + monkeypatch.setattr(cli_providers.config, "CLI_PROVIDERS", {"active": "gemini"}) + assert cli_providers.resolve_role("video_review")["provider"] == "claude" + + def test_effort_outside_the_ladder_is_dropped_not_forwarded(self, monkeypatch): + """agy rejects xhigh. Forwarding it costs a subprocess round trip to + learn what the ladder already says here.""" + monkeypatch.setattr(cli_providers.config, "CLI_PROVIDERS", { + "roles": {"video_review": {"provider": "agy", "effort": "xhigh"}}}) + assert cli_providers.resolve_role("video_review")["effort"] is None + + def test_empty_config_still_resolves(self, monkeypatch): + monkeypatch.setattr(cli_providers.config, "CLI_PROVIDERS", {}) + assert cli_providers.resolve_role("video_review")["provider"] == "claude" + + +class TestValidateRoleEntry: + def test_missing_binary_is_rejected(self, monkeypatch): + monkeypatch.setattr(cli_providers.shutil, "which", lambda b: None) + with pytest.raises(ValueError, match="not found on PATH"): + cli_providers.validate_role_entry("video_review", {"provider": "claude"}) + + def test_non_string_model_is_rejected(self, monkeypatch): + monkeypatch.setattr(cli_providers.shutil, "which", lambda b: "/bin/fake") + with pytest.raises(ValueError, match="string or null"): + cli_providers.validate_role_entry("video_review", {"provider": "claude", "model": 7}) + + def test_a_model_starting_with_a_dash_is_rejected(self, monkeypatch): + """Models are otherwise unvalidated on purpose, and the value lands in + argv right after --model. Nothing legitimate starts with a dash.""" + monkeypatch.setattr(cli_providers.shutil, "which", lambda b: "/bin/fake") + with pytest.raises(ValueError, match="must not start with"): + cli_providers.validate_role_entry( + "video_review", + {"provider": "claude", "model": "--dangerously-skip-permissions"}, + ) + + def test_blank_model_and_effort_normalise_to_none(self, monkeypatch): + """The dashboard's "Default" option sends an empty value; it must mean + "let the CLI decide", not an empty --model argument.""" + monkeypatch.setattr(cli_providers.shutil, "which", lambda b: "/bin/fake") + assert cli_providers.validate_role_entry( + "video_review", {"provider": "claude", "model": "", "effort": ""} + ) == {"provider": "claude", "model": None, "effort": None} + + +# --------------------------------------------------------------------------- +# agent/services/cli_providers.py :: model catalogs +# --------------------------------------------------------------------------- + +class TestModelCatalogs: + @pytest.mark.asyncio + async def test_agy_catalog_skips_the_header_line(self, monkeypatch): + """`agy models` prints "Fetching available models..." before the real + rows. Only the tab-separated lines are models.""" + stdout = ( + b"Fetching available models...\n" + b"gemini-3.8-flash-low\tGemini 3.8 Flash (Low)\n" + b"claude-sonnet-4-6\tClaude Sonnet 4.6 (Thinking)\n" + ) + proc = make_proc(stdout=stdout, returncode=0) + monkeypatch.setattr(cli_providers.shutil, "which", lambda b: "/bin/fake") + with patch("agent.services.cli_providers.asyncio.create_subprocess_exec", + new=AsyncMock(return_value=proc)): + models = await cli_providers.list_models("agy", force=True) + + assert models == [ + {"id": "gemini-3.8-flash-low", "label": "Gemini 3.8 Flash (Low)"}, + {"id": "claude-sonnet-4-6", "label": "Claude Sonnet 4.6 (Thinking)"}, + ] + + @pytest.mark.asyncio + async def test_a_failed_listing_is_an_empty_list_not_an_exception(self, monkeypatch): + """The dashboard asks for this on every provider change. A missing or + broken CLI must degrade to "no catalog", not 500 the settings page.""" + proc = make_proc(stdout=b"", stderr=b"boom", returncode=1) + monkeypatch.setattr(cli_providers.shutil, "which", lambda b: "/bin/fake") + with patch("agent.services.cli_providers.asyncio.create_subprocess_exec", + new=AsyncMock(return_value=proc)): + assert await cli_providers.list_models("agy", force=True) == [] + + @pytest.mark.asyncio + async def test_a_missing_binary_is_an_empty_list(self, monkeypatch): + monkeypatch.setattr(cli_providers.shutil, "which", lambda b: None) + assert await cli_providers.list_models("agy", force=True) == [] + + @pytest.mark.asyncio + async def test_an_empty_catalog_is_not_cached(self, monkeypatch): + """Emptiness here always means a transient failure, so caching it would + wedge the picker for five minutes after the CLI comes back.""" + monkeypatch.setattr(cli_providers.shutil, "which", lambda b: "/bin/fake") + cli_providers.clear_catalog_cache() + + fail = make_proc(stdout=b"", stderr=b"boom", returncode=1) + with patch("agent.services.cli_providers.asyncio.create_subprocess_exec", + new=AsyncMock(return_value=fail)): + assert await cli_providers.list_models("agy") == [] + + ok = make_proc(stdout=b"x\tX\n", returncode=0) + with patch("agent.services.cli_providers.asyncio.create_subprocess_exec", + new=AsyncMock(return_value=ok)): + assert await cli_providers.list_models("agy") == [{"id": "x", "label": "X"}] + cli_providers.clear_catalog_cache() + + def test_codex_catalog_hides_models_codex_hides(self, monkeypatch, tmp_path): + """`codex models` cannot run headlessly ("stdin is not a terminal"), so + its own cache is the only listing available — and it marks some entries + hidden, which are not offerable.""" + cache = tmp_path / "models_cache.json" + cache.write_text(json.dumps({"models": [ + {"slug": "gpt-5.6-sol", "display_name": "GPT-5.6-Sol", "visibility": "list", + "supported_reasoning_levels": [{"effort": "low"}, {"effort": "high"}]}, + {"slug": "gpt-reserve", "display_name": "GPT-Reserve", "visibility": "hide"}, + ]})) + monkeypatch.setattr(cli_providers, "_CODEX_MODELS_CACHE", cache) + + models = cli_providers._list_codex_models() + assert [m["id"] for m in models] == ["gpt-5.6-sol"] + assert models[0]["efforts"] == ["low", "high"] + + def test_codex_catalog_without_a_cache_file_is_empty(self, monkeypatch, tmp_path): + monkeypatch.setattr(cli_providers, "_CODEX_MODELS_CACHE", tmp_path / "nope.json") + assert cli_providers._list_codex_models() == [] + + +# --------------------------------------------------------------------------- +# ffmpeg drawtext fallback +# --------------------------------------------------------------------------- + +class TestFrameFilter: + def test_includes_drawtext_when_ffmpeg_has_it(self, monkeypatch): + monkeypatch.setattr("agent.services.video_reviewer._has_drawtext", lambda: True) + chain = _frame_filter(4.0) + assert chain.startswith("fps=4.0,scale=320:-1,drawtext=") + assert "%{pts\\:hms}" in chain + + def test_omits_drawtext_when_ffmpeg_lacks_it(self, monkeypatch): + """Homebrew's ffmpeg 8.x ships without libfreetype. Naming a filter + that does not exist aborts the whole chain with "No such filter", which + took down frame extraction and therefore every review — not just the + timestamps.""" + monkeypatch.setattr("agent.services.video_reviewer._has_drawtext", lambda: False) + assert _frame_filter(4.0) == "fps=4.0,scale=320:-1" diff --git a/tests/unit/test_video_reviewer.py b/tests/unit/test_video_reviewer.py index 3219504f3..bc5ff39e6 100644 --- a/tests/unit/test_video_reviewer.py +++ b/tests/unit/test_video_reviewer.py @@ -137,3 +137,173 @@ def test_partial_trailing_chunk_uses_zero_waste_layout( ) finally: shutil.rmtree(out_dir, ignore_errors=True) + + +# --------------------------------------------------------------------------- +# review_scene_video :: what a malformed CLI answer is allowed to become +# --------------------------------------------------------------------------- + +class TestReviewScoringRefusesAFabricatedScore: + """Every field of DimensionScores has a 5.0 default, so an answer carrying + no `dimensions` used to become a complete, plausible review — 5.0 across + the board, verdict "poor", zero errors — indistinguishable from a real + verdict on a mediocre video. That is the same class of bug as a CLI + returning an empty response on a zero exit code, and it has to fail loudly + instead. + """ + + @staticmethod + def _patched(monkeypatch, analysis): + import agent.services.video_reviewer as vr + + async def fake_download(url, dest): + Path(dest).write_bytes(b"not really a video") + + def fake_sheets(video_path, fps, out_dir): + sheet = Path(out_dir) / "sheet_00.jpg" + sheet.write_bytes(b"jpeg") + return [sheet], 9 + + async def fake_analyze(sheets, n_frames, fps, scene, timestamped=None): + return analysis + + monkeypatch.setattr(vr, "ANTHROPIC_API_KEY", "") + monkeypatch.setattr(vr, "_download_video", fake_download) + monkeypatch.setattr(vr, "_create_contact_sheets", fake_sheets) + monkeypatch.setattr(vr, "_analyze_cli", fake_analyze) + return vr + + SCENE = {"id": "s1", "vertical_video_url": "https://example.test/v.mp4", + "prompt": "p", "video_prompt": "vp", "character_names": "[]"} + + @pytest.mark.asyncio + async def test_an_answer_with_no_dimensions_raises(self, monkeypatch): + vr = self._patched(monkeypatch, {"errors": [], "usable_segments": []}) + with pytest.raises(RuntimeError, match="no dimensions"): + await vr.review_scene_video(dict(self.SCENE), []) + + @pytest.mark.asyncio + async def test_an_empty_dimensions_object_raises(self, monkeypatch): + vr = self._patched(monkeypatch, {"dimensions": {}, "errors": []}) + with pytest.raises(RuntimeError, match="no dimensions"): + await vr.review_scene_video(dict(self.SCENE), []) + + @pytest.mark.asyncio + async def test_a_partial_dimensions_object_still_defaults(self, monkeypatch): + """A model that scored some axes and not others is answering, just + incompletely — that is worth keeping, unlike one that answered nothing. + """ + vr = self._patched(monkeypatch, { + "dimensions": {"character_consistency": 9.0}, "errors": [], "usable_segments": []}) + review = await vr.review_scene_video(dict(self.SCENE), []) + assert review.dimensions.character_consistency == 9.0 + assert review.dimensions.motion_quality == 5.0 # the documented default + + GOOD_DIMS = {"character_consistency": 9.0, "prompt_adherence": 9.0, + "motion_quality": 9.0, "visual_fidelity": 9.0, + "temporal_coherence": 9.0, "composition": 9.0} + + @pytest.mark.asyncio + async def test_a_near_miss_key_keeps_the_critical_instead_of_dropping_it(self, monkeypatch): + """`timeRange` for `time_range` used to drop the whole entry, and what + drops with it is usually CRITICAL — the one severity that caps + character_consistency at 3.0 and forces the verdict below acceptable. + An unusable video came back clean over a camelCase key. + + The entry is repaired rather than refused: the model found the defect + and said so, it just spelled one field name oddly. Failing the scene + here would throw away a correct finding. + """ + vr = self._patched(monkeypatch, { + "dimensions": dict(self.GOOD_DIMS), + "errors": [{"severity": "CRITICAL", "timeRange": "3s-5s", + "description": "the dog becomes a cat"}], + "usable_segments": [], + }) + review = await vr.review_scene_video(dict(self.SCENE), []) + + assert [e.severity for e in review.errors] == ["CRITICAL"] + assert review.errors[0].time_range == "3s-5s" + assert review.has_critical_errors is True + assert review.dimensions.character_consistency == 3.0 + assert review.overall_score <= 5.9 + + @pytest.mark.asyncio + async def test_a_missing_time_range_is_repaired_not_refused(self, monkeypatch): + """Losing a timestamp costs the reader context; it cannot move a score. + Same placeholder the legacy plain-string path has always used.""" + vr = self._patched(monkeypatch, { + "dimensions": dict(self.GOOD_DIMS), + "errors": [{"severity": "MINOR", "description": "candle count drifts"}], + "usable_segments": [], + }) + review = await vr.review_scene_video(dict(self.SCENE), []) + assert review.errors[0].time_range == "?" + assert review.errors[0].description == "candle count drifts" + + @pytest.mark.asyncio + @pytest.mark.parametrize("severity", [None, "", "SEVERE", "MAJOR", "Critical character drift"]) + async def test_an_unrecognisable_severity_fails_the_scene(self, monkeypatch, severity): + """The asymmetry that makes the rest safe. `has_critical_errors`, the + character_consistency cap and `_fix_guide` all branch on this exact + string, so a severity outside {CRITICAL, HIGH, MINOR} silently disables + all three — the model flagged something and the score does not show it. + Unlike a missing timestamp, there is no safe default: we do not know + whether the video passed.""" + entry = {"time_range": "3s-5s", "description": "character morphs"} + if severity is not None: + entry["severity"] = severity + vr = self._patched(monkeypatch, { + "dimensions": dict(self.GOOD_DIMS), "errors": [entry], "usable_segments": []}) + with pytest.raises(RuntimeError, match="no usable severity"): + await vr.review_scene_video(dict(self.SCENE), []) + + @pytest.mark.asyncio + async def test_an_unreadable_segment_is_dropped_not_raised(self, monkeypatch): + """A lost segment errs toward "less usable footage", which cannot turn + a bad video into a good score the way a lost CRITICAL can — so it is a + drop, not a failure. It is still logged.""" + vr = self._patched(monkeypatch, { + "dimensions": dict(self.GOOD_DIMS), + "errors": [], + "usable_segments": [ + {"time_range": "0s-4s", "score": 8.0}, + {"time_range": "4s-8s"}, # no score — unreadable + {"timeRange": "0s-2s", "score": 7.0}, # near-miss key — repaired + "not even a dict", + ], + }) + review = await vr.review_scene_video(dict(self.SCENE), []) + assert [(s.time_range, s.score) for s in review.usable_segments] == [ + ("0s-4s", 8.0), ("0s-2s", 7.0)] + + @pytest.mark.asyncio + async def test_a_well_formed_critical_still_caps_the_score(self, monkeypatch): + """The other half of the same property: a CRITICAL that IS readable + must go on capping the score, so the strictness above is not covering + for a parser that stopped working.""" + vr = self._patched(monkeypatch, { + "dimensions": {"character_consistency": 9.0, "prompt_adherence": 9.0, + "motion_quality": 9.0, "visual_fidelity": 9.0, + "temporal_coherence": 9.0, "composition": 9.0}, + "errors": [{"severity": "critical", "time_range": "3s-5s", + "description": "the dog becomes a cat"}], + "usable_segments": [], + }) + review = await vr.review_scene_video(dict(self.SCENE), []) + assert review.has_critical_errors is True + assert review.dimensions.character_consistency == 3.0 + assert review.overall_score <= 5.9 + assert review.verdict in ("poor", "unusable") + + @pytest.mark.asyncio + async def test_a_plain_string_error_is_still_accepted(self, monkeypatch): + """The documented legacy shape. Strictness must not break it.""" + vr = self._patched(monkeypatch, { + "dimensions": {"character_consistency": 8.0}, + "errors": ["camera drifts after 4s"], + "usable_segments": [], + }) + review = await vr.review_scene_video(dict(self.SCENE), []) + assert [e.description for e in review.errors] == ["camera drifts after 4s"] + assert review.errors[0].severity == "HIGH" From 32ea1a5e8f014647a552edbc79c5a1fdab949240 Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Sun, 20 Sep 2026 00:52:55 +0700 Subject: [PATCH 24/68] ci: drawtext is a warning now, not a build breaker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The step existed because naming an absent filter aborted the whole ffmpeg chain and took 13 contact-sheet tests down with it. video_reviewer.py now probes for drawtext and drops it when missing, and the untimestamped path has its own coverage, so its absence is a supported degradation. The render check stays — the timestamped path is the better one and a silent loss of it belongs in the log — but it no longer fails the build for a condition the code handles. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ka5BxVaWiQeWNDJakpCJJP --- .github/workflows/tests.yml | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 229aa5278..ed84785d8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -47,20 +47,27 @@ jobs: sudo apt-get update sudo apt-get install -y --no-install-recommends ffmpeg fonts-dejavu-core - - name: Assert drawtext actually renders - # 13 of these tests burn a timestamp into extracted frames. Checking - # `ffmpeg -filters` only proves the filter is compiled in, not that a - # font exists, so render one frame through the same filter the tests - # use. Both failure modes surface here with a message that says what is - # wrong, instead of as 13 tests failing on "Filter not found". + - name: Report whether drawtext renders + # This used to fail the build, because naming an absent filter aborted + # the whole chain and took 13 tests down with it. video_reviewer.py now + # probes for drawtext and drops it when it is missing, so its absence + # is a supported degradation (sheets lose their burned-in timestamps) + # rather than a build breaker — and the fallback has its own coverage. + # + # The check stays because the timestamped path is the better one and a + # silent loss of it is worth seeing in the log. Checking + # `ffmpeg -filters` would only prove the filter is compiled in, not + # that a font exists, so render a real frame through the filter the + # code uses. run: | ffmpeg -hide_banner -loglevel error \ -f lavfi -i "testsrc=duration=1:size=320x240:rate=5" \ -vf "drawtext=text='%{pts\:hms}':x=5:y=5:fontsize=14:fontcolor=white:borderw=1:bordercolor=black" \ - -frames:v 1 -y /tmp/drawtext-smoke.jpg || { - echo "::error::ffmpeg cannot render drawtext — missing --enable-libfreetype, or no font installed." + -frames:v 1 -y /tmp/drawtext-smoke.jpg \ + && echo "drawtext renders — contact sheets will carry timestamps" \ + || { + echo "::warning::ffmpeg cannot render drawtext (no --enable-libfreetype, or no font). Sheets will be untimestamped; the suite still covers that path." ffmpeg -hide_banner -version | head -3 - exit 1 } - name: Install dependencies From 4391da911abe83db3d4551afe0b9d6a76e4f5b9b Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Sun, 20 Sep 2026 11:46:48 +0700 Subject: [PATCH 25/68] fix(review): close the findings from the adversarial review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One review, one provider. `resolve_role` ran per scene, and each scene awaits a download, an executor hop and a subprocess, so the loop yields repeatedly — while providers.json is documented as hand-editable and a dashboard GET hot-reloads it. Scenes 4..N could run on a different backend than scenes 1..3, with overall_score averaging both and no record of which produced what. Resolved once in review_video and threaded down. The closed catalog is now enforced. catalog_is_authoritative was published to the client and checked nowhere, so a typo'd agy slug got a 200 and then failed seconds into the next review with a raw CLI error — the exact outcome resolve_role's own docstring says this module exists to prevent. An empty catalog still does not block: emptiness means the listing failed, not that the provider has no models. CLI failures carry stdout too. claude puts the readable sentence there ("There's an issue with the selected model (...)") and buries the machine tag under paragraphs of unrelated context advice on stderr. Dropping stdout left the operator reading about token windows. providers.json is written atomically. Truncating in place was survivable when the file changed on a rare provider switch; it is written on every dashboard settings change now, and a truncated file hard-fails agent/config.py at import, so the server would not boot at all. The drawtext probe is an optimisation, not a correctness check. `ffmpeg -filters` proves the filter is compiled in, not that it can render — a build with libfreetype and no resolvable font lists it and then dies on "Cannot find a valid font for the family Sans", which is the original symptom on a box where the probe says everything is fine. Extraction retries untimestamped, and _create_contact_sheets now returns what actually happened rather than letting the caller re-derive it. Smaller ones from the same pass: resolve_role drops a model the API would have rejected, since the file is hand-editable and the two paths have to agree; an `active` sweep no longer silently adopts a role name this build does not know, which the `roles` path 400s on; list_models hands back a copy rather than the cached list itself; and the comments claiming scripts/statusline.sh reads `active` are gone — it does not, the sole reader is skills/fk-change-provider.md. Test gaps the same pass named, now closed: _has_drawtext had zero coverage and its regex had never run against real `ffmpeg -filters` output; _run_claude_cli had no model/effort/add-dirs argv test while agy had three; _spawn_and_check's message was untested. The API tests also stubbed no catalog, so validating an agy model spawned a real `agy models` and passed in CI only because a missing binary degrades to empty. 338 -> 352 tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ka5BxVaWiQeWNDJakpCJJP --- README.md | 1 + agent/api/providers.py | 48 +++++-- agent/services/cli_providers.py | 46 +++++-- agent/services/video_reviewer.py | 107 ++++++++++++--- skills/fk-change-provider.md | 10 +- tests/unit/test_cli_providers.py | 207 ++++++++++++++++++++++++++++-- tests/unit/test_video_reviewer.py | 122 +++++++++++++++++- 7 files changed, 471 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index 5c3411477..e5094ae23 100644 --- a/README.md +++ b/README.md @@ -916,6 +916,7 @@ it looked fixable from the symptoms. | 2026-09-20 | **A review with no scores in it is now a failure, not a score.** Every dimension defaults to 5.0, so a CLI answer carrying no `dimensions` became a complete, plausible review — 5.0 across the board, verdict "poor", zero errors — of a video nothing had actually looked at | | 2026-09-20 | **stdin closed for all three CLIs.** Each appends piped stdin to the prompt when stdin is not a terminal — codex documents it as a `<stdin>` block. Under uvicorn that is whatever the launching shell handed down | | 2026-09-20 | **Per-role provider, model and effort**, editable in the dashboard under Settings or via `PATCH /api/providers`. Efforts are validated against each CLI's real ladder (agy stops at `high`); models are validated only for agy, whose catalog is closed, so a slug newer than claude's or codex's cache still goes through. A whole-agent `{"active": …}` switch clears each role's model and clamps its effort, because neither survives a change of CLI | +| 2026-09-20 | Review hardening from an adversarial pass: one review is pinned to one provider (the role was resolved per scene, so a hand edit or a dashboard poll mid-run could split a video's score across two backends); an unknown agy model is a 400 naming the known slugs instead of a failed review; CLI failures carry stdout as well as stderr (claude puts its readable sentence there); `providers.json` is written atomically (a truncated file hard-fails `config.py` at import, so the server would not boot); and the drawtext probe is an optimisation now — extraction retries untimestamped if the filter is listed but cannot render, which is what an ffmpeg with libfreetype and no font does | | 2026-09-20 | **agy's model and effort are mutually exclusive** and the config now says so. Its slugs name their own effort (`gemini-3.8-flash-low`), so the pair is rejected — a mismatch conflicts, and a slug with no effort in its name refuses `--effort` at all | ### v1.2.0 — 2026-09-18 — the Flow migration diff --git a/agent/api/providers.py b/agent/api/providers.py index a16f1430d..bc8e5f43c 100644 --- a/agent/api/providers.py +++ b/agent/api/providers.py @@ -1,13 +1,18 @@ """CLI provider config API — which AI CLI, model and effort each role runs on. -`active` is the legacy single-provider switch that `/fk-change-provider` and the -statusline still use; `roles` is the per-role configuration the dashboard edits. -The two are kept consistent by every write here, so neither reader ever sees a -stale answer. +`active` is the legacy single-provider switch; `roles` is the per-role +configuration the dashboard edits. Every write here keeps the two consistent, +so neither reader sees a stale answer. + +The only real consumer of `active` is `skills/fk-change-provider.md` +(`scripts/statusline.sh` does not read it — its `active` matches are the +unrelated `/api/active-project`). One reader is reason enough to keep the +field in step; it is not reason to grow more of them. """ import asyncio import json import logging +import os import shutil from pathlib import Path @@ -48,9 +53,25 @@ def _read() -> dict: def _write(data: dict): - with open(_PROVIDERS_FILE, "w") as f: - json.dump(data, f, indent=2) - f.write("\n") + """Write atomically. + + `open(..., "w")` truncates in place, so a crash or a full disk mid-write + leaves a truncated providers.json — which then 500s every request here and + hard-fails `agent/config.py`'s import, so the server will not boot at all. + That was survivable when this file changed on a rare provider switch; it is + written on every dashboard settings change now. + """ + tmp = _PROVIDERS_FILE.with_suffix(".json.tmp") + try: + with open(tmp, "w") as f: + json.dump(data, f, indent=2) + f.write("\n") + f.flush() + os.fsync(f.fileno()) + os.replace(tmp, _PROVIDERS_FILE) # atomic within the same directory + except Exception: + tmp.unlink(missing_ok=True) + raise def _apply(data: dict): @@ -152,7 +173,7 @@ async def patch_providers(body: dict): raise HTTPException(400, "'roles' must be an object keyed by role name") for role, entry in incoming.items(): try: - roles[role] = validate_role_entry(role, entry) + roles[role] = await validate_role_entry(role, entry) except ValueError as e: raise HTTPException(400, str(e)) explicit = set(incoming) @@ -165,7 +186,12 @@ async def patch_providers(body: dict): raise HTTPException(400, f"'{PROVIDER_BINARIES[provider]}' binary not found on PATH — install it first") data["active"] = provider # Switching the whole agent over has to carry the roles with it. - for role in list(roles) + [r for r in ROLES if r not in roles]: + # Only roles this build knows about. A name left behind by another + # version (or a typo in a hand-edited file) is neither rewritten here + # nor accepted by the `roles` path, which 400s on it — one policy for + # both, rather than silently adopting it on one and rejecting it on the + # other. + for role in ROLES: if role in explicit: # The same request configured this role by name. That is the # more specific instruction and it already passed validation — @@ -188,8 +214,8 @@ async def patch_providers(body: dict): data["roles"] = roles if "active" not in body and roles: - # Keep the legacy field meaningful for /fk-change-provider and the - # statusline: it reports whatever the primary role runs on. + # Keep the legacy field meaningful for /fk-change-provider: it reports + # whatever the primary role runs on. primary = next(iter(ROLES)) if primary in roles: data["active"] = roles[primary]["provider"] diff --git a/agent/services/cli_providers.py b/agent/services/cli_providers.py index ea73bc61b..81977d0cc 100644 --- a/agent/services/cli_providers.py +++ b/agent/services/cli_providers.py @@ -128,18 +128,22 @@ def resolve_role(role: str) -> dict: ) effort = None - return { - "provider": provider, - "model": entry.get("model") or None, - "effort": effort, - } + model = entry.get("model") or None + if model is not None and (not isinstance(model, str) or model.startswith("-")): + # The API refuses these, but providers.json is documented as safe to + # hand-edit, so the two paths have to agree on what is acceptable. + logger.warning("Dropping unusable model %r for role %r", model, role) + model = None + + return {"provider": provider, "model": model, "effort": effort} -def validate_role_entry(role: str, entry: dict) -> dict: +async def validate_role_entry(role: str, entry: dict) -> dict: """Normalise one role entry from an API body. Raises ValueError on bad input. - The model is deliberately *not* checked against the catalog for claude and - codex — see PROVIDER_CATALOG_IS_AUTHORITATIVE. + The model is checked against the catalog only where the catalog is closed + (agy) — see PROVIDER_CATALOG_IS_AUTHORITATIVE. For claude and codex an + unlisted slug is a legitimate escape hatch, not a typo. """ if role not in ROLES: raise ValueError(f"Unknown role '{role}'. Known: {sorted(ROLES)}") @@ -172,12 +176,24 @@ def validate_role_entry(role: str, entry: dict) -> dict: if model is not None and not isinstance(model, str): raise ValueError(f"Model for role '{role}' must be a string or null") if model is not None and model.startswith("-"): - # The model is otherwise unvalidated on purpose (the escape hatch for a - # slug newer than any catalog), and it lands in argv next to --model. - # No real slug starts with a dash, and refusing them removes any - # argument left to have about what a CLI's parser does with one. + # The model is otherwise unvalidated for the open-catalog providers (the + # escape hatch for a slug newer than any catalog), and it lands in argv + # next to --model. No real slug starts with a dash, and refusing them + # removes any argument left to have about what a CLI's parser does. raise ValueError(f"Model for role '{role}' must not start with '-'") + if model is not None and PROVIDER_CATALOG_IS_AUTHORITATIVE[provider]: + # agy validates --model itself and errors out several seconds into the + # run. Catching it here is the difference between a 400 that names the + # options and a failed review. An empty catalog means the listing call + # failed, not that no models exist, so it must not block the write. + known = await list_models(provider) + if known and not any(m["id"] == model for m in known): + raise ValueError( + f"Unknown {provider} model '{model}'. {provider} rejects anything " + f"outside its own catalog; known: {[m['id'] for m in known]}" + ) + return {"provider": provider, "model": model, "effort": effort} @@ -264,7 +280,7 @@ async def list_models(provider: str, force: bool = False) -> list[dict]: if not force: hit = _catalog_cache.get(provider) if hit and now - hit[0] < _CATALOG_TTL_S: - return hit[1] + return list(hit[1]) if not shutil.which(PROVIDER_BINARIES[provider]): return [] @@ -282,7 +298,9 @@ async def list_models(provider: str, force: bool = False) -> list[dict]: if models: _catalog_cache[provider] = (now, models) - return models + # A copy: the cache is shared for five minutes and a caller that mutated + # the list it got back would corrupt it for every later reader. + return list(models) def clear_catalog_cache() -> None: diff --git a/agent/services/video_reviewer.py b/agent/services/video_reviewer.py index f47cfa440..7afaf6fdc 100644 --- a/agent/services/video_reviewer.py +++ b/agent/services/video_reviewer.py @@ -222,10 +222,12 @@ def _has_drawtext() -> bool: return present -def _frame_filter(fps: float) -> str: +def _frame_filter(fps: float, drawtext: bool | None = None) -> str: """Filter chain for contact-sheet frames, timestamped where ffmpeg allows.""" + if drawtext is None: + drawtext = _has_drawtext() chain = f"fps={fps},scale=320:-1" - if _has_drawtext(): + if drawtext: chain += ( ",drawtext=text='%{pts\\:hms}':x=5:y=5:fontsize=14:" "fontcolor=white:borderw=1:bordercolor=black" @@ -233,23 +235,49 @@ def _frame_filter(fps: float) -> str: return chain -def _create_contact_sheets(video_path: str, fps: float, out_dir: str) -> tuple[list[Path], int]: +def _create_contact_sheets( + video_path: str, fps: float, out_dir: str +) -> tuple[list[Path], int, bool]: """Extract all frames and tile them into REVIEW_SHEET_COLSxREVIEW_SHEET_ROWS sheets. - Frames carry burned-in timestamps only where ffmpeg has `drawtext` — see - `_frame_filter`. `_analyze_cli` words the prompt to match either way. + Returns (sheet_paths in chronological order, total_frames after any + REVIEW_MAX_FRAMES cap, whether the frames carry burned-in timestamps). - Returns (sheet_paths in chronological order, total_frames after any REVIEW_MAX_FRAMES cap). + The caller is told what actually happened rather than re-deriving it from + `_has_drawtext()`: extraction can fall back to untimestamped frames at + runtime even on a build that lists the filter, and `_analyze_cli` has to + word the prompt for the sheets it really got. """ frames_dir = Path(out_dir) / "frames" frames_dir.mkdir(exist_ok=True) - extract_cmd = [ - "ffmpeg", "-y", "-i", video_path, - "-vf", _frame_filter(fps), - "-q:v", "2", - f"{frames_dir}/frame_%04d.jpg", - ] - result = subprocess.run(extract_cmd, capture_output=True, text=True) + + def _extract(with_drawtext: bool): + return subprocess.run( + [ + "ffmpeg", "-y", "-i", video_path, + "-vf", _frame_filter(fps, with_drawtext), + "-q:v", "2", + f"{frames_dir}/frame_%04d.jpg", + ], + capture_output=True, text=True, + ) + + timestamped = _has_drawtext() + result = _extract(timestamped) + if result.returncode != 0 and timestamped: + # The probe proves drawtext is compiled in, not that it can render. An + # ffmpeg with libfreetype but no resolvable font lists the filter and + # then dies on "Cannot find a valid font for the family Sans" — the + # original symptom all over again, on a box where the probe says + # everything is fine. One retry makes the probe an optimisation rather + # than a load-bearing correctness check. + tail = (result.stderr or "").strip().splitlines() + logger.warning( + "Frame extraction failed with drawtext (%s) — retrying untimestamped", + tail[-1] if tail else "no stderr", + ) + timestamped = False + result = _extract(False) if result.returncode != 0: raise RuntimeError(f"Frame extraction failed: {result.stderr[-500:]}") @@ -285,7 +313,7 @@ def _create_contact_sheets(video_path: str, fps: float, out_dir: str) -> tuple[l raise RuntimeError(f"Contact sheet tiling failed: {result.stderr[-500:]}") sheets.append(output) - return sheets, len(frames) + return sheets, len(frames), timestamped # ─── Claude Vision analysis ─────────────────────────────────── @@ -442,7 +470,15 @@ async def _spawn_and_check(args: tuple, provider: str) -> bytes: ) stdout, stderr = await _communicate_with_timeout(proc, provider) if proc.returncode != 0: - raise RuntimeError(f"{provider} CLI failed (rc={proc.returncode}): {stderr.decode()[-500:]}") + # Both streams. claude puts the readable sentence on stdout ("There's an + # issue with the selected model (...)") and buries the machine tag under + # paragraphs of unrelated context advice on stderr; codex is the other + # way round. Tail-slice each, because the useful part is always last. + detail = stderr.decode()[-500:] + out = stdout.decode().strip() + if out: + detail = f"{detail} | stdout: {out[-300:]}" + raise RuntimeError(f"{provider} CLI failed (rc={proc.returncode}): {detail}") return stdout @@ -603,14 +639,20 @@ async def _analyze_cli( fps: float, scene: dict, timestamped: bool | None = None, + role: dict | None = None, ) -> dict: - """Analyze contact sheets via the CLI provider configured for video_review.""" + """Analyze contact sheets via the CLI provider configured for video_review. + + `role` is passed in by a multi-scene review so every scene runs on the same + backend — see `review_video`. + """ if timestamped is None: timestamped = _has_drawtext() n_sheets = len(contact_sheets) base_prompt = _build_prompt(n_frames, fps, n_sheets, scene) - role = resolve_role("video_review") + if role is None: + role = resolve_role("video_review") provider = role["provider"] logger.info( "Calling %s CLI for vision analysis (%d frames, %d sheets, model=%s, effort=%s, timestamps=%s)", @@ -707,8 +749,13 @@ async def review_scene_video( mode: str = "light", orientation: str = "VERTICAL", project_id: str = None, + role: dict | None = None, ) -> SceneReview: - """Review a single scene's video via frame extraction + Claude Vision.""" + """Review a single scene's video via frame extraction + Claude Vision. + + `role` pins the provider/model/effort. `review_video` resolves it once and + passes it down; a single-scene call resolves it here. + """ fps = REVIEW_FPS_DEEP if mode == "deep" else REVIEW_FPS_LIGHT orient_prefix = "vertical" if orientation.upper() == "VERTICAL" else "horizontal" @@ -750,13 +797,16 @@ async def review_scene_video( else: # CLI path: contact sheets (no API key needed) logger.info("Creating contact sheets at %sfps (CLI mode)", fps) - contact_sheets, n_frames = await asyncio.get_event_loop().run_in_executor( + contact_sheets, n_frames, timestamped = await asyncio.get_event_loop().run_in_executor( None, _create_contact_sheets, str(video_path), fps, tmp ) if not contact_sheets or not all(s.exists() for s in contact_sheets): raise RuntimeError(f"Contact sheets not created for scene {scene['id']}") logger.info("Analyzing %d frames across %d sheets via CLI provider", n_frames, len(contact_sheets)) - result = await _analyze_cli(contact_sheets, n_frames, fps, scene) + result = await _analyze_cli( + contact_sheets, n_frames, fps, scene, + timestamped=timestamped, role=role, + ) # Parse structured errors with severity. # @@ -893,6 +943,18 @@ async def review_video( scenes = [s for s in scenes if s["id"] in id_set] characters = await get_project_characters(project_id) + # Resolved once, for the whole review. Each scene awaits a download, an + # executor hop and a subprocess, so the loop below yields repeatedly — and + # providers.json is documented as safe to hand-edit, while a dashboard GET + # hot-reloads it. Resolving per scene let scenes 4..N run on a different + # backend than scenes 1..3, and `overall_score` then averages two of them + # with no record of which produced what. + role = resolve_role("video_review") + logger.info( + "Reviewing %s on %s (model=%s, effort=%s)", + video_id, role["provider"], role["model"] or "default", role["effort"] or "default", + ) + orient_prefix = "vertical" if orientation.upper() == "VERTICAL" else "horizontal" scene_reviews = [] @@ -906,7 +968,10 @@ async def review_video( continue try: - review = await review_scene_video(scene, characters, mode=mode, orientation=orientation, project_id=project_id) + review = await review_scene_video( + scene, characters, mode=mode, orientation=orientation, + project_id=project_id, role=role, + ) scene_reviews.append(review) except Exception as e: logger.error("Failed to review scene %s: %s", scene["id"], e) diff --git a/skills/fk-change-provider.md b/skills/fk-change-provider.md index 42b46cdd7..9c48e7580 100644 --- a/skills/fk-change-provider.md +++ b/skills/fk-change-provider.md @@ -62,10 +62,12 @@ curl -s "http://127.0.0.1:8100/api/providers/models?provider=<provider>" | pytho - An **empty** `models` array is a normal answer, not an error — the binary is missing or the listing call failed. Fall back to the provider's default. -- `authoritative: true` (agy only) means that list is the whole truth and agy - rejects anything outside it. For `claude` and `codex` an unlisted slug is a - legitimate escape hatch — claude takes aliases like `sonnet` and full model - names, codex takes slugs newer than its on-disk cache. +- `authoritative: true` (agy only) means that list is the whole truth. The API + rejects a model outside it with a 400 naming the known slugs, rather than + letting agy reject it several seconds into the next review. For `claude` and + `codex` an unlisted slug is a legitimate escape hatch — claude takes aliases + like `sonnet` and full model names, codex takes slugs newer than its on-disk + cache — so those are not checked. - Offer only efforts from that provider's `efforts` array. **agy has no `xhigh` or `max`** and the API rejects them with a 400. - **If the provider has `model_encodes_effort: true` (agy), do not offer both.** diff --git a/tests/unit/test_cli_providers.py b/tests/unit/test_cli_providers.py index 2178eb448..0a046e1b0 100644 --- a/tests/unit/test_cli_providers.py +++ b/tests/unit/test_cli_providers.py @@ -44,6 +44,45 @@ def make_proc(stdout=b"", stderr=b"", returncode=0): # --------------------------------------------------------------------------- class TestRunClaudeCli: + @pytest.mark.asyncio + async def test_model_effort_and_add_dirs_reach_the_argv(self): + """The default provider's new arguments. agy had three tests for this + and claude had none, which is backwards — claude is what runs unless + someone changes the setting.""" + proc = make_proc(stdout=b"ok", returncode=0) + with patch( + "agent.services.video_reviewer.asyncio.create_subprocess_exec", + new=AsyncMock(return_value=proc), + ) as mock_exec: + await _run_claude_cli( + "hello", model="sonnet", effort="high", add_dirs=("/tmp/sheets",)) + argv = mock_exec.call_args[0] + assert argv[argv.index("--model") + 1] == "sonnet" + assert argv[argv.index("--effort") + 1] == "high" + assert argv[argv.index("--add-dir") + 1] == "/tmp/sheets" + # Unlike agy, claude's model does not encode the effort, so both stay. + assert "--effort" in argv and "--model" in argv + + @pytest.mark.asyncio + async def test_a_failure_carries_both_streams(self): + """claude puts the readable sentence on stdout and buries the machine + tag under paragraphs of unrelated context advice on stderr. Dropping + stdout left the operator reading about token windows.""" + proc = make_proc( + stdout=b"There's an issue with the selected model (nope-xyz).", + stderr=b"[claude-code:unrecognized_model] {\"model\":\"nope-xyz\"}", + returncode=1, + ) + with patch( + "agent.services.video_reviewer.asyncio.create_subprocess_exec", + new=AsyncMock(return_value=proc), + ): + with pytest.raises(RuntimeError) as excinfo: + await _run_claude_cli("hello", model="nope-xyz") + message = str(excinfo.value) + assert "unrecognized_model" in message # stderr tail + assert "issue with the selected model" in message # stdout, previously dropped + @pytest.mark.asyncio async def test_argv_and_return_value(self): proc = make_proc(stdout=b'{"ok": true}', stderr=b"", returncode=0) @@ -492,6 +531,12 @@ def test_multi_sheet_includes_sheet_note(self): # agent/api/providers.py :: patch_providers # --------------------------------------------------------------------------- +FAKE_AGY_CATALOG = [ + {"id": "gemini-3.8-flash-low", "label": "Gemini 3.8 Flash (Low)"}, + {"id": "gemini-3.1-pro-high", "label": "Gemini 3.1 Pro (High)"}, +] + + @pytest.fixture def providers_file(monkeypatch, tmp_path): """Point the API at a throwaway providers.json and isolate config.""" @@ -500,6 +545,15 @@ def providers_file(monkeypatch, tmp_path): monkeypatch.setattr(providers_api, "_PROVIDERS_FILE", tmp_file) monkeypatch.setattr(providers_api.shutil, "which", lambda binary: "/usr/local/bin/fake") monkeypatch.setattr(cli_providers.shutil, "which", lambda binary: "/usr/local/bin/fake") + # Stub the catalog. Validating an agy model otherwise spawns a real + # `agy models`, which makes these tests depend on a signed-in CLI and pass + # in CI only because the missing binary degrades to an empty catalog. + # Enforcement itself is covered in TestValidateRoleEntry. + monkeypatch.setattr( + cli_providers, "list_models", + AsyncMock(side_effect=lambda provider, force=False: list( + FAKE_AGY_CATALOG if provider == "agy" else [])), + ) # Ensure config.CLI_PROVIDERS mutation doesn't leak to other tests. monkeypatch.setattr( providers_api.config, "CLI_PROVIDERS", @@ -621,6 +675,32 @@ async def test_reasserting_the_same_provider_keeps_the_model(self, providers_fil assert result["roles"]["video_review"] == { "provider": "claude", "model": "opus", "effort": "high"} + @pytest.mark.asyncio + async def test_roles_patch_rejects_an_agy_model_outside_its_catalog(self, providers_file): + """agy's catalog is closed and it rejects anything else itself — several + seconds into the next review, with a raw CLI error. A 400 that names the + known slugs is the whole reason this module exists.""" + with pytest.raises(HTTPException) as excinfo: + await providers_api.patch_providers({"roles": {"video_review": { + "provider": "agy", "model": "gemini-9-does-not-exist"}}}) + assert excinfo.value.status_code == 400 + assert "gemini-3.8-flash-low" in excinfo.value.detail + + @pytest.mark.asyncio + async def test_roles_patch_leaves_an_unknown_role_in_the_file_alone(self, providers_file): + """An `active` sweep used to silently adopt a role name this build does + not know, while the `roles` path 400s on the same name. One policy for + both: names outside ROLES are neither rewritten nor accepted.""" + providers_file.write_text(json.dumps({"active": "claude", "roles": { + "legacy_role": {"provider": "agy", "model": None, "effort": None}, + "video_review": {"provider": "claude", "model": None, "effort": None}}})) + + result = await providers_api.patch_providers({"active": "codex"}) + + assert result["roles"]["video_review"]["provider"] == "codex" + assert result["roles"]["legacy_role"] == { + "provider": "agy", "model": None, "effort": None} + @pytest.mark.asyncio async def test_roles_patch_keeps_active_in_step(self, providers_file): """`active` is what /fk-change-provider and the statusline read. If the @@ -716,35 +796,75 @@ def test_empty_config_still_resolves(self, monkeypatch): assert cli_providers.resolve_role("video_review")["provider"] == "claude" +@pytest.fixture +def fake_binaries(monkeypatch): + monkeypatch.setattr(cli_providers.shutil, "which", lambda b: "/bin/fake") + + class TestValidateRoleEntry: - def test_missing_binary_is_rejected(self, monkeypatch): + @pytest.mark.asyncio + async def test_missing_binary_is_rejected(self, monkeypatch): monkeypatch.setattr(cli_providers.shutil, "which", lambda b: None) with pytest.raises(ValueError, match="not found on PATH"): - cli_providers.validate_role_entry("video_review", {"provider": "claude"}) + await cli_providers.validate_role_entry("video_review", {"provider": "claude"}) - def test_non_string_model_is_rejected(self, monkeypatch): - monkeypatch.setattr(cli_providers.shutil, "which", lambda b: "/bin/fake") + @pytest.mark.asyncio + async def test_non_string_model_is_rejected(self, fake_binaries): with pytest.raises(ValueError, match="string or null"): - cli_providers.validate_role_entry("video_review", {"provider": "claude", "model": 7}) + await cli_providers.validate_role_entry( + "video_review", {"provider": "claude", "model": 7}) - def test_a_model_starting_with_a_dash_is_rejected(self, monkeypatch): - """Models are otherwise unvalidated on purpose, and the value lands in - argv right after --model. Nothing legitimate starts with a dash.""" - monkeypatch.setattr(cli_providers.shutil, "which", lambda b: "/bin/fake") + @pytest.mark.asyncio + async def test_a_model_starting_with_a_dash_is_rejected(self, fake_binaries): + """Models are unvalidated for the open-catalog providers on purpose, + and the value lands in argv right after --model. Nothing legitimate + starts with a dash.""" with pytest.raises(ValueError, match="must not start with"): - cli_providers.validate_role_entry( + await cli_providers.validate_role_entry( "video_review", {"provider": "claude", "model": "--dangerously-skip-permissions"}, ) - def test_blank_model_and_effort_normalise_to_none(self, monkeypatch): + @pytest.mark.asyncio + async def test_blank_model_and_effort_normalise_to_none(self, fake_binaries): """The dashboard's "Default" option sends an empty value; it must mean "let the CLI decide", not an empty --model argument.""" - monkeypatch.setattr(cli_providers.shutil, "which", lambda b: "/bin/fake") - assert cli_providers.validate_role_entry( + assert await cli_providers.validate_role_entry( "video_review", {"provider": "claude", "model": "", "effort": ""} ) == {"provider": "claude", "model": None, "effort": None} + @pytest.mark.asyncio + async def test_an_unknown_model_is_rejected_where_the_catalog_is_closed( + self, fake_binaries + ): + """agy validates --model itself and errors out several seconds into the + run. Catching it here is the difference between a 400 that names the + options and a failed review.""" + with patch.object(cli_providers, "list_models", new=AsyncMock( + return_value=[{"id": "gemini-3.8-flash-low", "label": "x"}])): + with pytest.raises(ValueError, match="Unknown agy model"): + await cli_providers.validate_role_entry( + "video_review", {"provider": "agy", "model": "gemini-9-nope"}) + + @pytest.mark.asyncio + async def test_an_unknown_model_passes_where_the_catalog_is_open(self, fake_binaries): + """claude takes aliases and full names, codex takes slugs newer than + its cache. Validating those would break the day a new model ships.""" + with patch.object(cli_providers, "list_models", new=AsyncMock(return_value=[])): + entry = await cli_providers.validate_role_entry( + "video_review", {"provider": "claude", "model": "claude-brand-new"}) + assert entry["model"] == "claude-brand-new" + + @pytest.mark.asyncio + async def test_an_empty_catalog_does_not_block_the_write(self, fake_binaries): + """Emptiness means the listing call failed, not that agy has no models. + Blocking on it would make a transient `agy models` failure look like a + rejected setting.""" + with patch.object(cli_providers, "list_models", new=AsyncMock(return_value=[])): + entry = await cli_providers.validate_role_entry( + "video_review", {"provider": "agy", "model": "gemini-3.8-flash-low"}) + assert entry["model"] == "gemini-3.8-flash-low" + # --------------------------------------------------------------------------- # agent/services/cli_providers.py :: model catalogs @@ -829,6 +949,67 @@ def test_codex_catalog_without_a_cache_file_is_empty(self, monkeypatch, tmp_path # ffmpeg drawtext fallback # --------------------------------------------------------------------------- +# Real rows from `ffmpeg -hide_banner -filters`, kept verbatim: the probe is a +# regex over this exact shape and has never been run against it in a test. +_FILTERS_WITH_DRAWTEXT = """\ +Filters: + T.. = Timeline support + ... drawbox V->V Draw a colored box on the input video. + T.C drawtext V->V Draw text on top of video frames using libfreetype library. + ... scale V->V Scale the input video size and/or convert the image format. +""" + +_FILTERS_WITHOUT_DRAWTEXT = """\ +Filters: + T.. = Timeline support + ... drawbox V->V Draw a colored box on the input video. + ... drawgraph V->V Draw a graph using input video metadata. + ... scale V->V Scale the input video size and/or convert the image format. +""" + + +class TestHasDrawtext: + """The one function whose misbehaviour re-breaks every review. Both + _frame_filter tests stub it out, so without this its regex never runs + against real `ffmpeg -filters` output.""" + + @staticmethod + def _probe(stdout, returncode=0): + import agent.services.video_reviewer as vr + vr._has_drawtext.cache_clear() + completed = MagicMock(stdout=stdout, stderr="", returncode=returncode) + try: + with patch("agent.services.video_reviewer.subprocess.run", return_value=completed): + return vr._has_drawtext() + finally: + vr._has_drawtext.cache_clear() + + def test_finds_drawtext_in_a_real_filter_listing(self): + assert self._probe(_FILTERS_WITH_DRAWTEXT) is True + + def test_absent_drawtext_is_detected(self): + assert self._probe(_FILTERS_WITHOUT_DRAWTEXT) is False + + def test_a_description_mentioning_drawtext_is_not_a_match(self): + """The filter name is the second whitespace-delimited token. Matching + anywhere on the line would make any filter whose description mentions + drawtext a false positive — and a false positive here puts an absent + filter back into the chain, which aborts extraction entirely.""" + listing = " ... overlay V->V Like drawtext but for images.\n" + assert self._probe(listing) is False + + def test_an_ffmpeg_that_cannot_be_run_reports_no_drawtext(self): + """Fail safe: an unusable ffmpeg must not claim the filter is there.""" + import agent.services.video_reviewer as vr + vr._has_drawtext.cache_clear() + try: + with patch("agent.services.video_reviewer.subprocess.run", + side_effect=OSError("no ffmpeg")): + assert vr._has_drawtext() is False + finally: + vr._has_drawtext.cache_clear() + + class TestFrameFilter: def test_includes_drawtext_when_ffmpeg_has_it(self, monkeypatch): monkeypatch.setattr("agent.services.video_reviewer._has_drawtext", lambda: True) diff --git a/tests/unit/test_video_reviewer.py b/tests/unit/test_video_reviewer.py index bc5ff39e6..5287d11d5 100644 --- a/tests/unit/test_video_reviewer.py +++ b/tests/unit/test_video_reviewer.py @@ -33,7 +33,7 @@ class TestCreateContactSheetsChunking: def test_2s_video_at_4fps_produces_correct_sheet_count(self, synthetic_video): # 2s * 4fps = 8 frames -> ceil(8/9) = 1 sheet with tempfile.TemporaryDirectory() as out_dir: - sheets, total_frames = _create_contact_sheets(str(synthetic_video), 4, out_dir) + sheets, total_frames, _timestamped = _create_contact_sheets(str(synthetic_video), 4, out_dir) assert total_frames == 8 assert len(sheets) == 1 assert all(s.exists() and s.stat().st_size > 0 for s in sheets) @@ -41,7 +41,7 @@ def test_2s_video_at_4fps_produces_correct_sheet_count(self, synthetic_video): def test_2s_video_at_8fps_produces_correct_sheet_count(self, synthetic_video): # 2s * 8fps = 16 frames -> ceil(16/9) = 2 sheets with tempfile.TemporaryDirectory() as out_dir: - sheets, total_frames = _create_contact_sheets(str(synthetic_video), 8, out_dir) + sheets, total_frames, _timestamped = _create_contact_sheets(str(synthetic_video), 8, out_dir) assert total_frames == 16 assert len(sheets) == 2 assert all(s.exists() and s.stat().st_size > 0 for s in sheets) @@ -50,7 +50,7 @@ def test_review_max_frames_caps_total_and_sheet_count(self, synthetic_video, mon import agent.services.video_reviewer as vr monkeypatch.setattr(vr, "REVIEW_MAX_FRAMES", 5) with tempfile.TemporaryDirectory() as out_dir: - sheets, total_frames = _create_contact_sheets(str(synthetic_video), 8, out_dir) + sheets, total_frames, _timestamped = _create_contact_sheets(str(synthetic_video), 8, out_dir) # 16 natural frames capped to 5 -> ceil(5/9) = 1 sheet assert total_frames == 5 assert len(sheets) == 1 @@ -71,7 +71,7 @@ def test_downsampling_selects_correct_nonconsecutive_frames_across_chunks( monkeypatch.setattr(vr, "REVIEW_MAX_FRAMES", 20) out_dir = tempfile.mkdtemp() try: - sheets, total_frames = _create_contact_sheets(str(synthetic_video), 30, out_dir) + sheets, total_frames, _timestamped = _create_contact_sheets(str(synthetic_video), 30, out_dir) assert total_frames == 20 assert len(sheets) == 3 @@ -120,7 +120,7 @@ def test_partial_trailing_chunk_uses_zero_waste_layout( monkeypatch.setattr(vr, "REVIEW_MAX_FRAMES", chunk_size) out_dir = tempfile.mkdtemp() try: - sheets, total_frames = _create_contact_sheets(str(synthetic_video), 30, out_dir) + sheets, total_frames, _timestamped = _create_contact_sheets(str(synthetic_video), 30, out_dir) assert total_frames == chunk_size assert len(sheets) == 1 probe = subprocess.run( @@ -162,9 +162,9 @@ async def fake_download(url, dest): def fake_sheets(video_path, fps, out_dir): sheet = Path(out_dir) / "sheet_00.jpg" sheet.write_bytes(b"jpeg") - return [sheet], 9 + return [sheet], 9, True - async def fake_analyze(sheets, n_frames, fps, scene, timestamped=None): + async def fake_analyze(sheets, n_frames, fps, scene, timestamped=None, role=None): return analysis monkeypatch.setattr(vr, "ANTHROPIC_API_KEY", "") @@ -307,3 +307,111 @@ async def test_a_plain_string_error_is_still_accepted(self, monkeypatch): review = await vr.review_scene_video(dict(self.SCENE), []) assert [e.description for e in review.errors] == ["camera drifts after 4s"] assert review.errors[0].severity == "HIGH" + + +# --------------------------------------------------------------------------- +# drawtext: the probe is an optimisation, not a correctness check +# --------------------------------------------------------------------------- + +class TestDrawtextRuntimeFallback: + def test_extraction_retries_without_drawtext_when_the_filter_fails( + self, synthetic_video, monkeypatch + ): + """`ffmpeg -filters` proves drawtext is compiled in, not that it can + render. A build with libfreetype but no resolvable font lists the + filter and then dies on "Cannot find a valid font for the family Sans" + — the original symptom again, on a box where the probe says everything + is fine. One retry makes the probe an optimisation. + + The failure is forced through `_frame_filter` rather than by trusting + this machine's ffmpeg, so the retry is exercised on a runner that has a + working drawtext as well as on one that has none. + """ + import agent.services.video_reviewer as vr + + seen = [] + + def fake_filter(fps, drawtext=None): + seen.append(drawtext) + chain = f"fps={fps},scale=320:-1" + return chain + ",definitely_not_a_real_filter" if drawtext else chain + + monkeypatch.setattr(vr, "_has_drawtext", lambda: True) + monkeypatch.setattr(vr, "_frame_filter", fake_filter) + + with tempfile.TemporaryDirectory() as out_dir: + sheets, total_frames, timestamped = vr._create_contact_sheets( + str(synthetic_video), 4, out_dir) + + assert seen == [True, False] # tried timestamped, then fell back + assert timestamped is False # and says so, rather than guessing + assert total_frames == 8 + assert len(sheets) == 1 and sheets[0].stat().st_size > 0 + + def test_a_failure_unrelated_to_drawtext_is_not_retried_away( + self, synthetic_video, monkeypatch + ): + """The retry exists for one cause. A genuinely broken input must still + surface as an error instead of being masked by a second attempt.""" + import agent.services.video_reviewer as vr + + monkeypatch.setattr(vr, "_has_drawtext", lambda: False) + with tempfile.TemporaryDirectory() as out_dir: + with pytest.raises(RuntimeError, match="Frame extraction failed"): + vr._create_contact_sheets(str(Path(out_dir) / "nope.mp4"), 4, out_dir) + + +# --------------------------------------------------------------------------- +# one review, one provider +# --------------------------------------------------------------------------- + +class TestRoleIsPinnedForTheWholeReview: + @pytest.mark.asyncio + async def test_the_role_is_resolved_once_and_reused_for_every_scene(self, monkeypatch): + """Each scene awaits a download, an executor hop and a subprocess, so + the loop yields repeatedly — and providers.json is documented as safe + to hand-edit while a dashboard GET hot-reloads it. Resolving per scene + let scenes 4..N run on a different backend than scenes 1..3, and + `overall_score` then averages two of them with no record of which + produced what. + """ + import agent.services.video_reviewer as vr + + scenes = [{"id": f"s{i}", "vertical_video_url": f"https://example.test/{i}.mp4"} + for i in range(3)] + + async def fake_list_scenes(vid): + return scenes + + async def fake_characters(pid): + return [] + + resolved = [] + + def fake_resolve(role_name): + resolved.append(role_name) + return {"provider": "claude", "model": "sonnet", "effort": "high"} + + seen_roles = [] + + async def fake_scene_review(scene, characters, **kwargs): + seen_roles.append(kwargs.get("role")) + return vr.SceneReview( + scene_id=scene["id"], overall_score=8.0, verdict="good", + dimensions=vr.DimensionScores( + character_consistency=8.0, prompt_adherence=8.0, motion_quality=8.0, + visual_fidelity=8.0, temporal_coherence=8.0, composition=8.0), + errors=[], usable_segments=[], fix_guide="", frames_analyzed=9, fps_used=4.0) + + monkeypatch.setattr(vr, "list_scenes", fake_list_scenes) + monkeypatch.setattr(vr, "get_project_characters", fake_characters) + monkeypatch.setattr(vr, "resolve_role", fake_resolve) + monkeypatch.setattr(vr, "review_scene_video", fake_scene_review) + + review = await vr.review_video("v1", "p1") + + assert resolved == ["video_review"] # once, not once per scene + assert len(seen_roles) == 3 + assert all(r == {"provider": "claude", "model": "sonnet", "effort": "high"} + for r in seen_roles) + assert review.scenes_reviewed == 3 From 3e0e94aea610fac3a0b73fe668572f17870031ab Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Sun, 20 Sep 2026 16:39:01 +0700 Subject: [PATCH 26/68] docs(readme): record what the v1.3.0 verification actually covered MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two things the changelog was missing. First, why this went unnoticed for so long: the suite was red on any dev machine for the whole period, while CI stayed green because the workflow installs ffmpeg and a font and then asserts drawtext renders — the one environment that ran the tests was the one environment where they passed. Second, codex's happy path is no longer unproven. All three providers now have an end-to-end run against the real CLI: a synthetic clip with a planted defect, through extraction, contact sheets and a live vision call, on the default model and on an explicitly selected model + effort. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ka5BxVaWiQeWNDJakpCJJP --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e5094ae23..a03106bb0 100644 --- a/README.md +++ b/README.md @@ -905,7 +905,17 @@ Dates are merge dates. Older releases are tagged; `git log` is the full record. ### v1.3.0 — 2026-09-20 — video review works again Video review had been failing on every path at once, which is why nothing about -it looked fixable from the symptoms. +it looked fixable from the symptoms. The unit suite was red on a normal dev +machine for the whole period — 13 of these tests fail on v1.2.0 — while CI +stayed green, because the workflow installs ffmpeg *and* a font and asserts +`drawtext` renders. The one environment that ran the suite was the one +environment where it worked. + +All three providers are verified end-to-end against the real CLIs: a synthetic +clip with a planted mid-clip defect, through frame extraction, contact sheets +and a live vision call, with no mocks. claude, agy and codex each find the +defect and score it, on their default model and on an explicitly selected +model + effort. | Date | Change | |---|---| From acd05d320466f073bdaab8900e38039ecf1362d4 Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Sun, 20 Sep 2026 16:56:00 +0700 Subject: [PATCH 27/68] chore(setup): drop the dead Gemini target, make AGENTS.md generated again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `setup.py --tool gemini` wrote .gemini/commands/fk/*.toml and GEMINI.md for a CLI that is retired, and its replacement reads neither. Verified against agy 1.2.7, in a trusted folder, with a real project on disk: - a project's .gemini/commands/*.toml is not expanded - .claude/commands/*.md is not expanded either - GEMINI.md, AGENTS.md and CLAUDE.md are all absent from a print-mode run's context (input tokens identical to an empty directory) - `agy plugin import claude` answers "No claude extensions found" — it imports extensions, not command files So the target produced files nothing consumes. Removed, GEMINI.md deleted, and the interactive menu is down to Claude Code and Codex. `clean` still removes what the target left on disk, because nothing else ever will, and a .fk-setup.json from before this release — which records "gemini" — is skipped with a pointer to `clean` rather than crashing the sync. agy is not being dropped. It stays one of the three CLIs that can run video review; that is configured in agent/providers.json via /fk-change-provider, not by this script, which generates command files for the CLI you drive Flow Kit *from*. The docs now say which is which. Running the generator surfaced a second problem. AGENTS.md carries "do not edit" at the top and had been edited anyway: rules 14-16 (fact-check, real-people bypass, review-before-upscale) and pipeline steps 0 and 7.5 existed only in the committed artifact, so `setup.py sync` would have silently deleted three operational rules. They live in setup.py now, so regeneration is lossless. The same drift had left the skill table at 25 entries — missing 11 skills that exist, including /fk-doctor and /fk-change-provider, and naming /fk-gen-tts which does not — and that half is fixed by regenerating, since the table is built from skills/ at generation time. setup.py gains its first tests: 13, covering the legacy-state skip, the clean path (including that a hand-written instruction file without the generated header survives it), and the content that had drifted. 352 -> 365 tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ka5BxVaWiQeWNDJakpCJJP --- .gitignore | 2 - AGENTS.md | 24 +++++-- GEMINI.md | 105 ---------------------------- README.md | 17 ++++- agent/main.py | 2 +- setup.py | 133 ++++++++++++++++++----------------- skills/README.md | 11 ++- tests/unit/test_setup.py | 147 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 260 insertions(+), 181 deletions(-) delete mode 100644 GEMINI.md create mode 100644 tests/unit/test_setup.py diff --git a/.gitignore b/.gitignore index f77240ba3..0f317e30a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,9 +11,7 @@ agent/active_project.json # Generated AI tool configs (run: python setup.py) .claude/commands/fk-* -.gemini/commands/ AGENTS.md -GEMINI.md .fk-setup.json # design-sync (staged converter scripts, build output, machine state) diff --git a/AGENTS.md b/AGENTS.md index 6d6439fcd..0b6ce5fcf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,5 @@ <!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> -# Google Flow Agent — Codex CLI Instructions +# Flow Kit — Codex CLI Instructions Base URL: `http://127.0.0.1:8100` @@ -44,7 +44,7 @@ curl -s http://127.0.0.1:8100/health Wait for done=true, verify image_media_id = UUID 7. Gen videos POST /api/requests/batch → poll /batch-status?video_id=<VID> Wait for done=true (videos take 2-5 min each) -7.5 Review videos POST /api/videos/{vid}/review?mode=light (Claude Vision quality check) +7.5 Review videos POST /api/videos/{vid}/review?mode=light (AI vision quality check) Pass: score >= 7.5 | Fail: update video_prompt → regen → re-review (max 2 cycles) 8. (Optional) 4K POST /api/requests/batch (TIER_TWO only) 9. (Optional) TTS Create voice template → POST /api/videos/{vid}/narrate @@ -79,27 +79,37 @@ This project has reusable skills in `skills/`. When the user says `/fk-<name>`, | Skill | Purpose | |-------|---------| | `/fk-add-material` | fk-add-material — Image Material System | -| `/fk-brand-logo` | fk-brand-logo — Apply Channel Brand Logo to Video & Thumbnails | -| `/fk-camera-guide` | Camera Guide — Cinematic Video Prompts | -| `/fk-concat-fit-narrator` | Trim each scene video to fit its TTS narrator duration, then concatenate into a final video. | +| `/fk-brand-logo` | fk-brand-logo — Apply Channel Branding (Intro + Outro + Logo + 4K Badge) | +| `/fk-camera-guide` | Camera Guide — Cinematic Video Prompts (Veo 3) | +| `/fk-change-model` | fk-change-model — View & Change Video/Image Model Keys | +| `/fk-change-provider` | fk-change-provider — View & Switch the AI CLI for a Role | +| `/fk-concat-fit-narrator` | Trim each scene video to fit its TTS narrator duration, burn text overlays, then concatenate into a final video. | | `/fk-concat` | Download and concatenate all scene videos into a single video with optional TTS narration. | | `/fk-create-project` | Create a new Google Flow video project. Ask the user for: | | `/fk-creative-mix` | Creative video mixing — combine techniques for cinematic results. | | `/fk-dashboard` | Show live GLA status in Claude Code statusline. | +| `/fk-doctor` | Diagnose any FlowKit error and prescribe a fix. Knows the full error taxonomy across Google Flow, the Chrome extension, the FastAPI layer, the worker, and the YouTube upload pipeline. | | `/fk-fix-uuids` | Find and fix any non-UUID media_ids (CAMS... format) across all scenes and entities. | | `/fk-gen-chain-videos` | Generate videos with automatic scene chaining (start+end frame transitions). | | `/fk-gen-images` | Generate scene images for all scenes in a video. | | `/fk-gen-music` | fk-gen-music — Generate Music via Suno | | `/fk-gen-narrator` | fk-gen-narrator — Generate Narrator Text + TTS for All Scenes | | `/fk-gen-refs` | Generate reference images for all entities in a project. | +| `/fk-gen-text-overlays` | fk-gen-text-overlays — Generate Text Overlays from Narrator Text | | `/fk-gen-tts-template` | fk-gen-tts-template — Generate Voice Template | -| `/fk-gen-tts` | fk-gen-tts — Generate TTS Narration | | `/fk-gen-videos` | Generate videos for all scenes in a video. | +| `/fk-import-voice` | fk-import-voice — Import Existing Voice as Template | | `/fk-insert-scene` | Insert new scene(s) into an existing video chain — for multi-angle shots, cutaways, or close-ups. | -| `/fk-research` | Fact-check & research real events via web search before scripting documentary content. | +| `/fk-monitor` | fk-monitor — Full Pipeline Monitor | +| `/fk-pipeline` | fk-pipeline — Smart Full-Pipeline Orchestrator | +| `/fk-refresh-urls` | Re-sign expired media URLs for all scenes in a video (images, videos, upscale videos) and character reference images. | +| `/fk-research` | fk-research — Fact-Check & Research Before Scripting | +| `/fk-review-board` | Start the Scene Review Board web app for visual feedback on scene chains. | | `/fk-review-video` | Review AI-generated scene videos for quality using Claude Vision. | | `/fk-status` | Show full status dashboard for a project. | +| `/fk-switch-project` | fk-switch-project — Switch Active Project | | `/fk-thumbnail-guide` | YouTube Thumbnail Guide — Hook-Worthy Design Rules | | `/fk-thumbnail` | Generate 4 YouTube-optimized thumbnail variants for a project video. | +| `/fk-upload-image` | Upload a local image file to Google Flow and get a media_id (UUID). | | `/fk-youtube-seo` | fk-youtube-seo — Generate YouTube Metadata (SEO-Optimized) | | `/fk-youtube-upload` | fk-youtube-upload — Upload Video to YouTube (Shorts + Long-form) | diff --git a/GEMINI.md b/GEMINI.md deleted file mode 100644 index 6a16c6903..000000000 --- a/GEMINI.md +++ /dev/null @@ -1,105 +0,0 @@ -<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> -# Google Flow Agent — Gemini CLI Instructions - -Base URL: `http://127.0.0.1:8100` - -## Pre-flight - -Before ANY workflow: -```bash -curl -s http://127.0.0.1:8100/health -# Must return: {"extension_connected": true} -``` - -## Critical Rules (MUST follow) - -1. **Media ID is always UUID** — format `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`. Never use `CAMS...` / base64 strings. -2. **Scene prompts = ACTION only** — never describe character appearance. Reference images handle visual consistency via `imageInputs`. -3. **All reference images must exist before scene images** — verify every entity has `media_id` before generating scene images. -4. **No throwaway scripts** — NEVER write Python, shell, or any script file to loop over API requests. Use `POST /api/requests/batch` to submit all requests at once, then poll `GET /api/requests/batch-status`. The server throttles automatically. -5. **Locations use landscape, characters use portrait** — reference image orientation depends on entity type. -6. **UUID extraction** — if a response gives `CAMS...` instead of UUID, extract UUID from the `fifeUrl` in the response URL: `/image/{UUID}?...`. -7. **Cascade on regen** — regenerating an image auto-clears downstream video + upscale. -8. **REGENERATE vs GENERATE** — `GENERATE_*` skips if already COMPLETED. `REGENERATE_*` always runs (clears + regenerates). -9. **Image Material required** — every project needs a `material` field (e.g. `realistic`, `3d_pixar`, `anime`). List available: `GET /api/materials`. -10. **Server handles throttling** — worker enforces max 5 concurrent requests + 10s cooldown. Submit ALL requests via `/batch`; do NOT manually stagger or loop. -11. **Video prompts use sub-clip timing** — structure 8s video as time segments: `0-3s: [action]. 3-6s: [action]. 6-8s: [action].` -12. **Character dialogue in sub-clips** — embed speech in quotes: `Luna says "Goodnight."` Max 10-15 words per character per 2-3s segment. -13. **Scenes are mutable** — use `PATCH /api/scenes/{sid}` to update `prompt`, `video_prompt`, `narrator_text`, `character_names` after creation. Don't delete and recreate — patch instead. -14. **Fact-check before scripting** — ALWAYS research events via web search before writing project stories, scene prompts, or narrator text. Facts (events, dates, names, operations, outcomes) MUST match real sources. Editorial opinion and analysis are allowed but must be framed as such. Never invent events, operation names, or statistics. -15. **Real-people bypass** — when characters are based on real famous people (politicians, celebrities, military leaders), NEVER use their real name as entity `name` or anywhere in `description`, `image_prompt`, `prompt`, or `video_prompt`. AI image generators reject known public figures. Instead: (a) use a **role-based alias** as entity name (e.g. "Tổng Tư Lệnh" not "Trump", "Thủ Tướng Sắt" not "Netanyahu"), (b) describe **physical appearance only** — distinctive hair, face shape, build, clothing style — without naming who it is, (c) `narrator_text` may use real titles/roles for storytelling but real names never flow into image/video generation. Keep a `real_reference` mapping in the project plan file (`.omc/research/`) for internal tracking. -16. **Review before upscale** — ALWAYS run `/fk-review-video` (light mode) after video generation, before upscaling. Scenes scoring < 7.5 get `video_prompt` updated from review errors, then regen video. Max 2 review-regen cycles. - -## Pipeline Order - -``` -0. Research /fk-research "topic" (fact-check via web search, save to .omc/research/) -1. Health check GET /health → extension_connected: true -2. Create project POST /api/projects (with entities + material, story from research) -3. Create video POST /api/videos -4. Create scenes POST /api/scenes (with character_names, chain_type) -5. Gen ref images POST /api/requests/batch → poll /batch-status?project_id=<PID> - Wait for done=true, verify all entities have media_id -6. Gen scene images POST /api/requests/batch → poll /batch-status?video_id=<VID> - Wait for done=true, verify image_media_id = UUID -7. Gen videos POST /api/requests/batch → poll /batch-status?video_id=<VID> - Wait for done=true (videos take 2-5 min each) -7.5 Review videos POST /api/videos/{vid}/review?mode=light (Claude Vision quality check) - Pass: score >= 7.5 | Fail: update video_prompt → regen → re-review (max 2 cycles) -8. (Optional) 4K POST /api/requests/batch (TIER_TWO only) -9. (Optional) TTS Create voice template → POST /api/videos/{vid}/narrate -10. Concat ffmpeg normalize + concat -``` - -## Batch API - -Submit N requests at once (server throttles automatically — max 5 concurrent, 10s cooldown): - -```bash -curl -X POST http://127.0.0.1:8100/api/requests/batch \ - -H "Content-Type: application/json" \ - -d '{"requests": [{"type": "...", "scene_id": "...", "project_id": "...", "video_id": "...", "orientation": "VERTICAL"}, ...]}' -``` - -Poll aggregate status: - -```bash -curl -s "http://127.0.0.1:8100/api/requests/batch-status?video_id=<VID>&type=GENERATE_IMAGE" -# Returns: {"total": 40, "pending": 30, "processing": 5, "completed": 5, "failed": 0, "done": false} -# When "done": true → all requests have left the queue (completed or failed) -# When "all_succeeded": true → every request completed successfully -``` - -For full API reference, workflow recipes, and video prompt guidelines, see `CLAUDE.md`. - -## Skills - -This project has reusable skills in `skills/`. When the user says `/fk-<name>`, read `skills/fk-<name>.md` and follow the instructions inside. - -| Skill | Purpose | -|-------|---------| -| `/fk-add-material` | fk-add-material — Image Material System | -| `/fk-brand-logo` | fk-brand-logo — Apply Channel Brand Logo to Video & Thumbnails | -| `/fk-camera-guide` | Camera Guide — Cinematic Video Prompts | -| `/fk-concat-fit-narrator` | Trim each scene video to fit its TTS narrator duration, then concatenate into a final video. | -| `/fk-concat` | Download and concatenate all scene videos into a single video with optional TTS narration. | -| `/fk-create-project` | Create a new Google Flow video project. Ask the user for: | -| `/fk-creative-mix` | Creative video mixing — combine techniques for cinematic results. | -| `/fk-dashboard` | Show live GLA status in Claude Code statusline. | -| `/fk-fix-uuids` | Find and fix any non-UUID media_ids (CAMS... format) across all scenes and entities. | -| `/fk-gen-chain-videos` | Generate videos with automatic scene chaining (start+end frame transitions). | -| `/fk-gen-images` | Generate scene images for all scenes in a video. | -| `/fk-gen-music` | fk-gen-music — Generate Music via Suno | -| `/fk-gen-narrator` | fk-gen-narrator — Generate Narrator Text + TTS for All Scenes | -| `/fk-gen-refs` | Generate reference images for all entities in a project. | -| `/fk-gen-tts-template` | fk-gen-tts-template — Generate Voice Template | -| `/fk-gen-tts` | fk-gen-tts — Generate TTS Narration | -| `/fk-gen-videos` | Generate videos for all scenes in a video. | -| `/fk-insert-scene` | Insert new scene(s) into an existing video chain — for multi-angle shots, cutaways, or close-ups. | -| `/fk-research` | Fact-check & research real events via web search before scripting documentary content. | -| `/fk-review-video` | Review AI-generated scene videos for quality using Claude Vision. | -| `/fk-status` | Show full status dashboard for a project. | -| `/fk-thumbnail-guide` | YouTube Thumbnail Guide — Hook-Worthy Design Rules | -| `/fk-thumbnail` | Generate 4 YouTube-optimized thumbnail variants for a project video. | -| `/fk-youtube-seo` | fk-youtube-seo — Generate YouTube Metadata (SEO-Optimized) | -| `/fk-youtube-upload` | fk-youtube-upload — Upload Video to YouTube (Shorts + Long-form) | diff --git a/README.md b/README.md index a03106bb0..58e6a39b0 100644 --- a/README.md +++ b/README.md @@ -550,7 +550,11 @@ Skills are `.md` recipes any AI coding-assistant CLI can read and follow — thi |-----|-------------|-----------------| | Claude Code | `CLAUDE.md` (auto-loaded) | Native `/fk-*` slash commands | | Codex CLI | `AGENTS.md` → reads `CLAUDE.md` | User says `/fk-<name>`, agent reads `skills/fk-<name>.md` | -| Gemini CLI | `GEMINI.md` → reads `CLAUDE.md` | Same pattern | + +The Gemini CLI target was dropped in v1.3.1 — the CLI is retired, and its +replacement `agy` reads none of what that target generated (see the changelog). +`agy` is still supported, as one of the three CLIs that can run video review — +that is configured in `agent/providers.json`, not by `setup.py`. ### AI Vision Providers (Video Review) @@ -737,8 +741,7 @@ youtube/ ├── channel_rules.json # Upload rules + SEO defaults └── upload_history.json # Upload log CLAUDE.md # AI agent instructions (Claude Code) -AGENTS.md # AI agent instructions (Codex CLI) -GEMINI.md # AI agent instructions (Gemini CLI) +AGENTS.md # AI agent instructions (Codex CLI, generated) ``` ## TTS Narration (OmniVoice) @@ -902,6 +905,14 @@ From `youtube/upload.py` (HTTP errors from YouTube Data API v3): Dates are merge dates. Older releases are tagged; `git log` is the full record. +### v1.3.1 — 2026-09-20 — the dead Gemini target + +| Date | Change | +|---|---| +| 2026-09-20 | **`setup.py --tool gemini` removed.** It generated `.gemini/commands/fk/*.toml` and `GEMINI.md` for a CLI that is retired, and its replacement `agy` reads neither — verified against agy 1.2.7: a project's `.gemini/commands/*.toml` is not expanded, `.claude/commands/*.md` is not either, and `GEMINI.md`, `AGENTS.md` and `CLAUDE.md` are all absent from a print-mode run's context even inside a trusted folder. `agy plugin import` imports extensions, not command files. `GEMINI.md` is deleted; `setup.py clean` still removes what the target left on disk, because nothing else ever will. `agy` remains fully supported — as one of the three CLIs that run video review, configured in `agent/providers.json` rather than by `setup.py` | +| 2026-09-20 | **`AGENTS.md` is genuinely generated again.** It says "do not edit" and had been edited anyway: rules 14-16 (fact-check, real-people bypass, review-before-upscale) and pipeline steps 0 and 7.5 lived only in the committed artifact, so `setup.py sync` would have deleted three operational rules. They are in `setup.py` now. The same drift had left the skill table listing 25 skills — missing 11 that exist and naming one that does not; it is rebuilt from `skills/` at generation time | +| 2026-09-20 | `setup.py` gains its first tests (13), including that a `.fk-setup.json` written before this release — which records `"gemini"` — is skipped with a pointer to `clean` instead of crashing the sync | + ### v1.3.0 — 2026-09-20 — video review works again Video review had been failing on every path at once, which is why nothing about diff --git a/agent/main.py b/agent/main.py index 4d3bc351a..32bf03b3e 100644 --- a/agent/main.py +++ b/agent/main.py @@ -113,7 +113,7 @@ async def lifespan(app: FastAPI): logger.info("Flow Kit stopped") -app = FastAPI(title="Flow Kit", version="1.3.0", lifespan=lifespan) +app = FastAPI(title="Flow Kit", version="1.3.1", lifespan=lifespan) app.add_middleware( CORSMiddleware, diff --git a/setup.py b/setup.py index fd7094ae7..948994dbe 100644 --- a/setup.py +++ b/setup.py @@ -5,12 +5,24 @@ Usage: python setup.py # Interactive: pick your AI tool(s) - python setup.py --tool claude # Generate for Claude - python setup.py --tool gemini # Generate for Gemini + python setup.py --tool claude # Generate for Claude Code python setup.py --tool codex # Generate for Codex python setup.py --tool all # Generate for all tools python setup.py sync # Re-sync all previously selected tools python setup.py clean # Remove all generated tool configs + +The Gemini CLI target was removed in v1.3.1. The Gemini CLI is retired, and +its replacement `agy` (Antigravity) reads none of what that target produced — +verified against agy 1.2.7: a project's `.gemini/commands/*.toml` is not +expanded, `.claude/commands/*.md` is not either, and `GEMINI.md`, `AGENTS.md` +and `CLAUDE.md` are all absent from a print-mode run's context even inside a +trusted folder. agy's own commands come from its plugin system +(`agy plugin import`), which imports extensions rather than command files. + +`agy` is still a first-class part of Flow Kit — as one of the three AI CLIs +that can run video review. That is configured in `agent/providers.json` via +`/fk-change-provider` or the dashboard, not here: this script generates +per-project command files for the CLI you *drive* Flow Kit from. """ import argparse @@ -22,11 +34,14 @@ ROOT = Path(__file__).parent SKILLS_DIR = ROOT / "skills" CLAUDE_COMMANDS_DIR = ROOT / ".claude" / "commands" -GEMINI_COMMANDS_DIR = ROOT / ".gemini" / "commands" / "fk" AGENTS_MD = ROOT / "AGENTS.md" -GEMINI_MD = ROOT / "GEMINI.md" STATE_FILE = ROOT / ".fk-setup.json" +# Nothing generates these any more; `clean` still removes them so an install +# from before v1.3.1 does not keep stale files for a CLI that no longer exists. +LEGACY_GEMINI_COMMANDS_DIR = ROOT / ".gemini" / "commands" / "fk" +LEGACY_GEMINI_MD = ROOT / "GEMINI.md" + def discover_skills(): """Scan skills/fk-*.md and extract name + first-line description.""" @@ -69,28 +84,15 @@ def generate_claude(skills): return count -def generate_gemini(skills): - """Create .gemini/commands/fk/<name>.toml for each skill.""" - GEMINI_COMMANDS_DIR.mkdir(parents=True, exist_ok=True) - count = 0 - for skill in skills: - name = skill["name"] - desc = skill["description"].replace('"', '\\"') - dest = GEMINI_COMMANDS_DIR / f"{name}.toml" - content = ( - f'# AUTO-GENERATED by setup.py — do not edit. Source: skills/\n' - f'description = "{desc}"\n' - f'prompt = "Read the skill file at skills/fk-{name}.md and follow the instructions inside. Arguments: $ARGUMENTS"\n' - ) - dest.write_text(content, encoding="utf-8") - count += 1 - print(f"Generated {count} Gemini commands in .gemini/commands/fk/") - return count - - -## ── Inline content for GEMINI.md / AGENTS.md ── -# Keep in sync with CLAUDE.md rules. These are inlined so non-Claude AI tools -# see the critical rules directly without needing to follow a "read CLAUDE.md" pointer. +## ── Inline content for AGENTS.md ── +# Inlined so a non-Claude tool sees the rules directly instead of following a +# "read CLAUDE.md" pointer. +# +# This block is the ONLY source for the generated file. AGENTS.md says +# "do not edit" and was edited anyway: rules 14-16 and pipeline steps 0 and 7.5 +# lived only in the generated artifact, so `setup.py sync` would have deleted +# them. They are here now. Anything added to AGENTS.md by hand is lost on the +# next sync — put it here instead. _CRITICAL_RULES = """\ ## Critical Rules (MUST follow) @@ -108,14 +110,18 @@ def generate_gemini(skills): 11. **Video prompts use sub-clip timing** — structure 8s video as time segments: `0-3s: [action]. 3-6s: [action]. 6-8s: [action].` 12. **Character dialogue in sub-clips** — embed speech in quotes: `Luna says "Goodnight."` Max 10-15 words per character per 2-3s segment. 13. **Scenes are mutable** — use `PATCH /api/scenes/{sid}` to update `prompt`, `video_prompt`, `narrator_text`, `character_names` after creation. Don't delete and recreate — patch instead. +14. **Fact-check before scripting** — ALWAYS research events via web search before writing project stories, scene prompts, or narrator text. Facts (events, dates, names, operations, outcomes) MUST match real sources. Editorial opinion and analysis are allowed but must be framed as such. Never invent events, operation names, or statistics. +15. **Real-people bypass** — when characters are based on real famous people (politicians, celebrities, military leaders), NEVER use their real name as entity `name` or anywhere in `description`, `image_prompt`, `prompt`, or `video_prompt`. AI image generators reject known public figures. Instead: (a) use a **role-based alias** as entity name (e.g. "Tổng Tư Lệnh" not "Trump", "Thủ Tướng Sắt" not "Netanyahu"), (b) describe **physical appearance only** — distinctive hair, face shape, build, clothing style — without naming who it is, (c) `narrator_text` may use real titles/roles for storytelling but real names never flow into image/video generation. Keep a `real_reference` mapping in the project plan file (`.omc/research/`) for internal tracking. +16. **Review before upscale** — ALWAYS run `/fk-review-video` (light mode) after video generation, before upscaling. Scenes scoring < 7.5 get `video_prompt` updated from review errors, then regen video. Max 2 review-regen cycles. """ _PIPELINE_OVERVIEW = """\ ## Pipeline Order ``` +0. Research /fk-research "topic" (fact-check via web search, save to .omc/research/) 1. Health check GET /health → extension_connected: true -2. Create project POST /api/projects (with entities + material) +2. Create project POST /api/projects (with entities + material, story from research) 3. Create video POST /api/videos 4. Create scenes POST /api/scenes (with character_names, chain_type) 5. Gen ref images POST /api/requests/batch → poll /batch-status?project_id=<PID> @@ -124,6 +130,8 @@ def generate_gemini(skills): Wait for done=true, verify image_media_id = UUID 7. Gen videos POST /api/requests/batch → poll /batch-status?video_id=<VID> Wait for done=true (videos take 2-5 min each) +7.5 Review videos POST /api/videos/{vid}/review?mode=light (AI vision quality check) + Pass: score >= 7.5 | Fail: update video_prompt → regen → re-review (max 2 cycles) 8. (Optional) 4K POST /api/requests/batch (TIER_TWO only) 9. (Optional) TTS Create voice template → POST /api/videos/{vid}/narrate 10. Concat ffmpeg normalize + concat @@ -155,7 +163,7 @@ def generate_gemini(skills): def _agents_md_body(skills, title): - """Build the shared AGENTS.md / GEMINI.md body with critical rules inlined.""" + """Build the AGENTS.md body with the critical rules inlined.""" rows = "\n".join( f"| `/fk-{s['name']}` | {s['description']} |" for s in skills ) @@ -189,14 +197,6 @@ def generate_codex(skills): return len(skills) -def generate_gemini_md(skills): - """Generate GEMINI.md for Gemini CLI.""" - content = _agents_md_body(skills, "Gemini CLI Instructions") - GEMINI_MD.write_text(content, encoding="utf-8") - print(f"Generated GEMINI.md ({len(skills)} skills)") - return len(skills) - - def save_state(tools, skill_count): state = { "tools": tools, @@ -215,30 +215,35 @@ def load_state(): return None +TOOLS = { + "claude": generate_claude, + "codex": generate_codex, +} + + def run_generators(tools, skills): """Run the appropriate generators for the given tool list.""" - generators = { - "claude": generate_claude, - "gemini": generate_gemini, - "codex": generate_codex, - "gemini_md": generate_gemini_md, - } for tool in tools: - if tool == "gemini": - generators["gemini"](skills) - generators["gemini_md"](skills) - elif tool in generators: - generators[tool](skills) + if tool in TOOLS: + TOOLS[tool](skills) + else: + # Reachable from a .fk-setup.json written before v1.3.1, which + # records "gemini". Skipping beats crashing a sync on a target + # that no longer exists; `clean` removes what it left behind. + print(f"Skipping '{tool}' — no longer a supported target. " + f"Run 'python setup.py clean' to remove its leftover files.") def do_interactive(skills): """Interactive mode: prompt user to pick tools.""" print("\nFlow Kit — AI Tool Setup\n") - print("Which AI tools do you use with this project?") + print("Which AI tool do you drive this project from?") print(" [1] Claude Code (.claude/commands/)") - print(" [2] Gemini CLI (.gemini/commands/fk/ + GEMINI.md)") - print(" [3] Codex CLI (AGENTS.md)") - print(" [4] All of the above") + print(" [2] Codex CLI (AGENTS.md)") + print(" [3] Both") + print() + print(" (agy / Antigravity reads none of these — it is configured as a") + print(" video-review provider instead, via /fk-change-provider.)") print() raw = input("Select (comma-separated, e.g. 1,2): ").strip() @@ -246,7 +251,7 @@ def do_interactive(skills): print("No selection made. Exiting.") return - mapping = {"1": "claude", "2": "gemini", "3": "codex", "4": "all"} + mapping = {"1": "claude", "2": "codex", "3": "all"} choices = [c.strip() for c in raw.split(",")] tools = [] @@ -256,7 +261,7 @@ def do_interactive(skills): continue val = mapping[c] if val == "all": - tools = ["claude", "gemini", "codex"] + tools = list(TOOLS) break if val not in tools: tools.append(val) @@ -273,7 +278,7 @@ def do_interactive(skills): def do_tool(tool, skills): """Non-interactive: generate for a specific tool or all.""" if tool == "all": - tools = ["claude", "gemini", "codex"] + tools = list(TOOLS) else: tools = [tool] run_generators(tools, skills) @@ -307,18 +312,22 @@ def do_clean(): f.unlink() removed.append(str(f)) - # Gemini commands dir - if GEMINI_COMMANDS_DIR.exists(): - for f in GEMINI_COMMANDS_DIR.glob("*.toml"): + # Whatever the retired Gemini target left behind. Removed here even + # though nothing writes it any more — an install from before v1.3.1 has + # these files, and `clean` is the only thing that will ever take them away. + if LEGACY_GEMINI_COMMANDS_DIR.exists(): + for f in LEGACY_GEMINI_COMMANDS_DIR.glob("*.toml"): f.unlink() removed.append(str(f)) try: - GEMINI_COMMANDS_DIR.rmdir() + LEGACY_GEMINI_COMMANDS_DIR.rmdir() + LEGACY_GEMINI_COMMANDS_DIR.parent.rmdir() # .gemini/commands + LEGACY_GEMINI_COMMANDS_DIR.parent.parent.rmdir() # .gemini except OSError: - pass # not empty, leave it + pass # not empty (agy keeps its own state here), leave it - # AGENTS.md and GEMINI.md - for md in [AGENTS_MD, GEMINI_MD]: + # AGENTS.md, plus the legacy GEMINI.md + for md in [AGENTS_MD, LEGACY_GEMINI_MD]: if md.exists(): first_line = md.read_text(encoding="utf-8").splitlines()[0] if "AUTO-GENERATED by setup.py" in first_line: @@ -349,7 +358,7 @@ def main(): ) parser.add_argument( "--tool", - choices=["claude", "gemini", "codex", "all"], + choices=[*TOOLS, "all"], help="Generate configs for a specific tool (non-interactive)", ) diff --git a/skills/README.md b/skills/README.md index e77be36f6..bd9bf2f1e 100644 --- a/skills/README.md +++ b/skills/README.md @@ -47,11 +47,20 @@ python setup.py clean # Remove generated configs | Tool | Generated Config | Instruction File | Invocation | |------|-----------------|------------------|------------| | Claude Code | `.claude/commands/fk-<name>.md` (stubs) | `CLAUDE.md` (committed) | `/fk-<name>` | -| Gemini CLI | `.gemini/commands/fk/<name>.toml` | `GEMINI.md` (generated) | `/fk-<name>` | | Codex CLI | — | `AGENTS.md` (generated) | Read `skills/fk-<name>.md` | +`agy` (Antigravity) is not a target here: it expands neither `.gemini/commands/*.toml` +nor `.claude/commands/*.md`, and does not auto-load `AGENTS.md`, `GEMINI.md` or +`CLAUDE.md` in print mode. It is supported as a **video-review provider** +instead — see `/fk-change-provider`. + **Adding a new skill:** Create `skills/fk-<name>.md`, then run `python setup.py sync`. +**Never hand-edit `AGENTS.md`** — it says so at the top and it means it. Rules +added there directly are deleted by the next `sync`. Put them in `setup.py`'s +`_CRITICAL_RULES` or `_PIPELINE_OVERVIEW` instead, which is where the file is +built from. + --- ## Full Example: "Luna the Space Cat" (3 scenes, vertical) diff --git a/tests/unit/test_setup.py b/tests/unit/test_setup.py new file mode 100644 index 000000000..4798c31d2 --- /dev/null +++ b/tests/unit/test_setup.py @@ -0,0 +1,147 @@ +"""Tests for setup.py, the script that generates per-project AI tool configs. + +It had none. Two things here are worth pinning: `clean` still has to remove +what the retired Gemini target left on disk, and the generated AGENTS.md has +to keep carrying the rules that had drifted into it by hand. +""" +import importlib.util +import sys +from pathlib import Path + +import pytest + +REPO_ROOT = Path(__file__).resolve().parents[2] + + +@pytest.fixture(scope="module") +def setup_mod(): + """Import setup.py by path — it lives at the repo root, not in a package.""" + spec = importlib.util.spec_from_file_location("fk_setup", REPO_ROOT / "setup.py") + mod = importlib.util.module_from_spec(spec) + sys.modules["fk_setup"] = mod + spec.loader.exec_module(mod) + yield mod + sys.modules.pop("fk_setup", None) + + +@pytest.fixture +def sandbox(setup_mod, monkeypatch, tmp_path): + """Repoint every path constant at a throwaway tree.""" + monkeypatch.setattr(setup_mod, "ROOT", tmp_path) + monkeypatch.setattr(setup_mod, "SKILLS_DIR", tmp_path / "skills") + monkeypatch.setattr(setup_mod, "CLAUDE_COMMANDS_DIR", tmp_path / ".claude" / "commands") + monkeypatch.setattr(setup_mod, "AGENTS_MD", tmp_path / "AGENTS.md") + monkeypatch.setattr(setup_mod, "STATE_FILE", tmp_path / ".fk-setup.json") + monkeypatch.setattr( + setup_mod, "LEGACY_GEMINI_COMMANDS_DIR", tmp_path / ".gemini" / "commands" / "fk") + monkeypatch.setattr(setup_mod, "LEGACY_GEMINI_MD", tmp_path / "GEMINI.md") + (tmp_path / "skills").mkdir() + (tmp_path / "skills" / "fk-demo.md").write_text("# fk-demo — A demo skill\n") + return tmp_path + + +# ── the retired Gemini target ───────────────────────────────── + + +class TestRetiredGeminiTarget: + def test_gemini_is_not_a_generator_any_more(self, setup_mod): + assert "gemini" not in setup_mod.TOOLS + assert set(setup_mod.TOOLS) == {"claude", "codex"} + assert not hasattr(setup_mod, "generate_gemini") + assert not hasattr(setup_mod, "generate_gemini_md") + + def test_a_stale_state_file_naming_gemini_does_not_crash_sync( + self, setup_mod, sandbox, capsys + ): + """`.fk-setup.json` written before v1.3.1 records "gemini". A sync that + raised on it would strand the user with no way to regenerate the + targets that do still exist.""" + skills = setup_mod.discover_skills() + setup_mod.run_generators(["claude", "gemini", "codex"], skills) + + out = capsys.readouterr().out + assert "Skipping 'gemini'" in out + assert "setup.py clean" in out # and says how to tidy up + assert (sandbox / "AGENTS.md").exists() # the live targets still ran + assert list((sandbox / ".claude" / "commands").glob("fk-*.md")) + + def test_clean_removes_what_the_gemini_target_left_behind(self, setup_mod, sandbox): + """Nothing writes these any more, so `clean` is the only thing that + will ever take them away from an install made before v1.3.1.""" + legacy_dir = sandbox / ".gemini" / "commands" / "fk" + legacy_dir.mkdir(parents=True) + (legacy_dir / "demo.toml").write_text('description = "x"\n') + (sandbox / "GEMINI.md").write_text( + "<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ -->\n# old\n") + + setup_mod.do_clean() + + assert not (legacy_dir / "demo.toml").exists() + assert not (sandbox / "GEMINI.md").exists() + assert not (sandbox / ".gemini").exists() # the empty tree goes too + + def test_clean_leaves_a_hand_written_instruction_file_alone(self, setup_mod, sandbox): + """`clean` keys off the generated header. A file someone wrote + themselves must survive it.""" + (sandbox / "GEMINI.md").write_text("# My own notes, not generated\n") + (sandbox / "AGENTS.md").write_text("# Hand-written\n") + + setup_mod.do_clean() + + assert (sandbox / "GEMINI.md").exists() + assert (sandbox / "AGENTS.md").exists() + + +# ── AGENTS.md is generated, and must stay lossless ──────────── + + +class TestGeneratedAgentsMdIsComplete: + """AGENTS.md says "do not edit" and was edited anyway: rules 14-16 and + pipeline steps 0 and 7.5 existed only in the committed artifact, so a + `sync` would have silently deleted three operational rules. They live in + setup.py now — these pin them there. + """ + + @pytest.fixture + def generated(self, setup_mod, sandbox): + setup_mod.generate_codex(setup_mod.discover_skills()) + return (sandbox / "AGENTS.md").read_text() + + @pytest.mark.parametrize("marker", [ + "14. **Fact-check before scripting**", + "15. **Real-people bypass**", + "16. **Review before upscale**", + ]) + def test_the_hand_added_rules_survive_regeneration(self, generated, marker): + assert marker in generated + + @pytest.mark.parametrize("marker", ["0. Research", "7.5 Review videos"]) + def test_the_hand_added_pipeline_steps_survive_regeneration(self, generated, marker): + assert marker in generated + + def test_the_skill_table_is_built_from_the_skills_directory(self, generated): + """The committed file had drifted to 25 skills — missing 11 that exist + and listing one that does not. Deriving it at generation time is what + stops that happening again.""" + assert "| `/fk-demo` |" in generated + + def test_the_generated_file_is_marked_generated(self, generated): + assert generated.splitlines()[0].startswith("<!-- AUTO-GENERATED by setup.py") + + +# ── argument surface ────────────────────────────────────────── + + +def test_tool_choices_reject_gemini(setup_mod, monkeypatch, capsys): + monkeypatch.setattr(sys, "argv", ["setup.py", "--tool", "gemini"]) + with pytest.raises(SystemExit) as excinfo: + setup_mod.main() + assert excinfo.value.code == 2 + assert "invalid choice: 'gemini'" in capsys.readouterr().err + + +def test_discover_skills_reads_the_first_line_as_the_description(setup_mod, sandbox): + (sandbox / "skills" / "fk-other.md").write_text("# fk-other — Does a thing\n\nBody.\n") + found = {s["name"]: s["description"] for s in setup_mod.discover_skills()} + assert found["other"] == "fk-other — Does a thing" + assert found["demo"] == "fk-demo — A demo skill" From 2030b0861be3371c914a5176a15620a3e28b6818 Mon Sep 17 00:00:00 2001 From: Le Tien <tienoho@gmail.com> Date: Tue, 22 Sep 2026 11:32:04 +0700 Subject: [PATCH 28/68] feat: add core agent API routes, background services, YouTube integration, and test suite --- .gitignore | 2 +- agent/api/flow.py | 30 +-- agent/api/models.py | 4 +- agent/api/projects.py | 4 +- agent/api/providers.py | 6 +- agent/api/tts.py | 4 +- agent/config.py | 6 +- agent/services/post_process.py | 31 ++- agent/services/tts.py | 6 +- agent/services/video_reviewer.py | 30 ++- agent/worker/processor.py | 18 +- extension/background.js | 6 +- tests/unit/test_cli_providers.py | 4 +- tests/unit/test_processor.py | 27 ++- tests/unit/test_setup.py | 10 +- tests/unit/test_video_reviewer.py | 41 ++-- tests/unit/test_youtube.py | 84 ++++++++ tools/review_server.py | 4 +- youtube/__init__.py | 1 + youtube/auth.py | 63 ++++++ youtube/upload.py | 326 ++++++++++++++++++++++++++++++ 21 files changed, 634 insertions(+), 73 deletions(-) create mode 100644 tests/unit/test_youtube.py create mode 100644 youtube/__init__.py create mode 100644 youtube/auth.py create mode 100644 youtube/upload.py diff --git a/.gitignore b/.gitignore index 0f317e30a..d2bbb216a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ __pycache__/ *.db-journal .env output/ -youtube +youtube/channels/ agent/active_project.json # Generated AI tool configs (run: python setup.py) diff --git a/agent/api/flow.py b/agent/api/flow.py index 7aed5ef3f..2a55935bb 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -1,7 +1,7 @@ """Direct Flow API endpoints — for manual operations outside the queue.""" from fastapi import APIRouter, HTTPException, Response from pydantic import BaseModel, Field -from typing import Literal, Optional +from typing import Any, Literal, Optional from agent.config import FLOW_PROJECT_ID, FLOW_ALLOW_DEGRADED from agent.services.flow_client import get_flow_client @@ -16,6 +16,12 @@ router = APIRouter(prefix="/flow", tags=["flow"]) +def _safe_status_code(status: Any, default: int = 502) -> int: + if isinstance(status, int) and 400 <= status <= 599: + return status + return default + + class GenerateImageRequest(BaseModel): prompt: str project_id: str @@ -165,7 +171,7 @@ async def generate_image(body: GenerateImageRequest): data["character_media_ids"] = refs or None result = await client.generate_images(**data) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): - raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) + raise HTTPException(_safe_status_code(result.get("status")), result.get("error", result.get("data"))) return result.get("data", result) @@ -212,7 +218,7 @@ async def generate_video(body: GenerateVideoRequest): ) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): - raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) + raise HTTPException(_safe_status_code(result.get("status")), result.get("error", result.get("data"))) return result.get("data", result) @@ -249,7 +255,7 @@ async def generate_video_refs(body: GenerateVideoRefsRequest): ) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): - raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) + raise HTTPException(_safe_status_code(result.get("status")), result.get("error", result.get("data"))) return result.get("data", result) @@ -270,7 +276,7 @@ async def generate_video_omni_text(body: GenerateOmniFlashTextVideoRequest): isinstance(result.get("status"), int) and result["status"] >= 400 ): raise HTTPException( - result.get("status", 502), + _safe_status_code(result.get("status")), result.get("error", result.get("data")), ) return result.get("data", result) @@ -291,7 +297,7 @@ async def generate_video_omni(body: GenerateOmniFlashVideoRequest): except ValueError as exc: raise HTTPException(400, str(exc)) from exc if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): - raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) + raise HTTPException(_safe_status_code(result.get("status")), result.get("error", result.get("data"))) return result.get("data", result) @@ -303,7 +309,7 @@ async def upscale_video(body: UpscaleVideoRequest): raise HTTPException(503, "Extension not connected") result = await client.upscale_video(**body.model_dump()) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): - raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) + raise HTTPException(_safe_status_code(result.get("status")), result.get("error", result.get("data"))) return result.get("data", result) @@ -337,7 +343,7 @@ async def check_status(body: CheckStatusRequest): if result.get("error"): raise HTTPException(502, result["error"]) if isinstance(result.get("status"), int) and result["status"] >= 400: - raise HTTPException(result["status"], result.get("data", "Flow polling failed")) + raise HTTPException(_safe_status_code(result["status"]), result.get("data", "Flow polling failed")) return result.get("data", result) @@ -386,7 +392,7 @@ async def get_media(media_id: str): raise HTTPException(502, result["error"]) status = result.get("status", 200) if isinstance(status, int) and status >= 400: - raise HTTPException(status, result.get("data", "Media not found")) + raise HTTPException(_safe_status_code(status, 404), result.get("data", "Media not found")) return result.get("data", result) @@ -408,7 +414,7 @@ async def edit_image(body: EditImageRequest): seed=body.seed, ) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): - raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) + raise HTTPException(_safe_status_code(result.get("status")), result.get("error", result.get("data"))) return result.get("data", result) @@ -428,7 +434,7 @@ async def export_image(body: UpscaleImageRequest): resolution=body.quality.upper(), ) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): - raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) + raise HTTPException(_safe_status_code(result.get("status")), result.get("error", result.get("data"))) data = result.get("data", result) try: content = base64.b64decode(data["encodedImage"], validate=True) @@ -461,6 +467,6 @@ async def upload_image(body: UploadImageRequest): mime = mimetypes.guess_type(body.file_path)[0] or "image/png" result = await client.upload_image(b64, mime_type=mime, project_id=body.project_id, file_name=body.file_name) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): - raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) + raise HTTPException(_safe_status_code(result.get("status")), result.get("error", result.get("data"))) media_id = result.get("_mediaId") return {"media_id": media_id, "raw": result.get("data", result)} diff --git a/agent/api/models.py b/agent/api/models.py index 43634f208..d22cd5963 100644 --- a/agent/api/models.py +++ b/agent/api/models.py @@ -14,12 +14,12 @@ def _read_models() -> dict: - with open(_MODELS_FILE) as f: + with open(_MODELS_FILE, encoding="utf-8") as f: return json.load(f) def _write_models(data: dict): - with open(_MODELS_FILE, "w") as f: + with open(_MODELS_FILE, "w", encoding="utf-8") as f: json.dump(data, f, indent=2) f.write("\n") diff --git a/agent/api/projects.py b/agent/api/projects.py index 4b87aa847..8421ead69 100644 --- a/agent/api/projects.py +++ b/agent/api/projects.py @@ -326,9 +326,9 @@ async def get_output_dir(pid: str): } meta_path = output_dir / "meta.json" if meta_path.exists(): - existing = json.loads(meta_path.read_text()) + existing = json.loads(meta_path.read_text(encoding="utf-8")) meta["created_at"] = existing.get("created_at", now) - meta_path.write_text(json.dumps(meta, indent=2, ensure_ascii=False)) + meta_path.write_text(json.dumps(meta, indent=2, ensure_ascii=False), encoding="utf-8") return {"slug": slug, "path": f"output/{slug}", "meta": meta} diff --git a/agent/api/providers.py b/agent/api/providers.py index bc8e5f43c..1c1e6f14e 100644 --- a/agent/api/providers.py +++ b/agent/api/providers.py @@ -36,13 +36,13 @@ def _read() -> dict: - """Read providers.json and hot-reload it into `config.CLI_PROVIDERS`. + """Read providers.json from disk and refresh config.CLI_PROVIDERS in place. The file is the source of truth, and it is editable by hand (the skills do), so re-reading it here is what makes a hand edit take effect without a restart — and what stops a GET describing a state the worker is not in. """ - with open(_PROVIDERS_FILE) as f: + with open(_PROVIDERS_FILE, encoding="utf-8") as f: data = json.load(f) data.setdefault("active", "claude") data.setdefault("roles", {}) @@ -63,7 +63,7 @@ def _write(data: dict): """ tmp = _PROVIDERS_FILE.with_suffix(".json.tmp") try: - with open(tmp, "w") as f: + with open(tmp, "w", encoding="utf-8") as f: json.dump(data, f, indent=2) f.write("\n") f.flush() diff --git a/agent/api/tts.py b/agent/api/tts.py index e2d3d068f..486dc4961 100644 --- a/agent/api/tts.py +++ b/agent/api/tts.py @@ -296,13 +296,13 @@ async def delete_voice_template(name: str): def _load_templates_meta() -> dict: if TEMPLATES_META.exists(): - return json.loads(TEMPLATES_META.read_text()) + return json.loads(TEMPLATES_META.read_text(encoding="utf-8")) return {} def _save_templates_meta(meta: dict): TEMPLATES_META.parent.mkdir(parents=True, exist_ok=True) - TEMPLATES_META.write_text(json.dumps(meta, indent=2, ensure_ascii=False)) + TEMPLATES_META.write_text(json.dumps(meta, indent=2, ensure_ascii=False), encoding="utf-8") def _wav_duration(path: str) -> float | None: diff --git a/agent/config.py b/agent/config.py index 743198e2d..371e68197 100644 --- a/agent/config.py +++ b/agent/config.py @@ -48,7 +48,7 @@ # ─── Model Keys (loaded from models.json for easy updates) ── _MODELS_FILE = Path(__file__).parent / "models.json" -with open(_MODELS_FILE) as _f: +with open(_MODELS_FILE, encoding="utf-8") as _f: _MODELS = json.load(_f) VIDEO_MODELS = _MODELS["video_models"] @@ -81,7 +81,7 @@ # ─── CLI Providers (video review vision analysis) ──────────── _PROVIDERS_FILE = Path(__file__).parent / "providers.json" -with open(_PROVIDERS_FILE) as _pvf: +with open(_PROVIDERS_FILE, encoding="utf-8") as _pvf: CLI_PROVIDERS = json.load(_pvf) # mutable dict, hot-reloaded like VIDEO_MODELS REVIEW_CLI_TIMEOUT_S = float(os.environ.get("REVIEW_CLI_TIMEOUT_S", "120")) @@ -95,7 +95,7 @@ def _load_suno_key() -> str: if channels_dir.exists(): for rules_file in channels_dir.glob("*/channel_rules.json"): try: - rules = json.loads(rules_file.read_text()) + rules = json.loads(rules_file.read_text(encoding="utf-8")) key = rules.get("api_keys", {}).get("suno", "") if key: return key diff --git a/agent/services/post_process.py b/agent/services/post_process.py index a8287c036..d4473142d 100644 --- a/agent/services/post_process.py +++ b/agent/services/post_process.py @@ -1,10 +1,25 @@ -"""Post-processing: trim, merge, add music via ffmpeg.""" +import os +import shutil import subprocess import logging from pathlib import Path logger = logging.getLogger(__name__) + +def _ffmpeg_bin() -> str: + env_bin = os.environ.get("FFMPEG_BIN") + if env_bin: + return env_bin + if shutil.which("ffmpeg"): + return "ffmpeg" + try: + import imageio_ffmpeg + return imageio_ffmpeg.get_ffmpeg_exe() + except Exception: + return "ffmpeg" + + _FLOAT_MIN = 0.0 _FLOAT_MAX = 2.0 @@ -24,7 +39,7 @@ def trim_video(input_path: str, output_path: str, start: float, end: float) -> b return False duration = end - start cmd = [ - "ffmpeg", "-y", "-i", input_path, + _ffmpeg_bin(), "-y", "-i", input_path, "-ss", str(start), "-t", str(duration), "-c:v", "libx264", "-preset", "fast", "-crf", "18", "-force_key_frames", "expr:gte(t,0)", @@ -43,14 +58,14 @@ def merge_videos(video_paths: list[str], output_path: str) -> bool: """Concatenate videos using ffmpeg concat demuxer.""" concat_file = output_path + ".concat.txt" try: - with open(concat_file, "w") as f: + with open(concat_file, "w", encoding="utf-8") as f: for p in video_paths: - # Escape single quotes to prevent path injection in concat file - escaped = str(p).replace("'", "'\\''") + # Escape single quotes and use POSIX forward slashes for ffmpeg concat demuxer + escaped = Path(p).as_posix().replace("'", "'\\''") f.write(f"file '{escaped}'\n") cmd = [ - "ffmpeg", "-y", "-f", "concat", "-safe", "0", + _ffmpeg_bin(), "-y", "-f", "concat", "-safe", "0", "-i", concat_file, "-c:v", "copy", "-c:a", "copy", "-movflags", "+faststart", @@ -94,7 +109,7 @@ def add_narration(video_path: str, narration_path: str, output_path: str, fade_start = max(0, duration - fade_out) cmd = [ - "ffmpeg", "-y", "-i", video_path, "-i", narration_path, + _ffmpeg_bin(), "-y", "-i", video_path, "-i", narration_path, "-c:v", "copy", "-c:a", "aac", "-b:a", "192k", "-filter_complex", f"[0:a]volume={sfx_volume}[sfx];[1:a]volume={narration_volume},afade=t=in:st=0:d={fade_in},afade=t=out:st={fade_start}:d={fade_out}[narr];[sfx][narr]amerge=inputs=2,pan=stereo|c0=c0+c2|c1=c1+c3[aout]", @@ -137,7 +152,7 @@ def add_music(video_path: str, music_path: str, output_path: str, fade_start = max(0, duration - fade_out) cmd = [ - "ffmpeg", "-y", "-i", video_path, "-i", music_path, + _ffmpeg_bin(), "-y", "-i", video_path, "-i", music_path, "-c:v", "copy", "-c:a", "aac", "-b:a", "192k", "-filter_complex", f"[0:a]volume=1.0[orig];[1:a]volume={music_volume},afade=t=in:st=0:d={fade_in},afade=t=out:st={fade_start}:d={fade_out}[music];[orig][music]amerge=inputs=2,pan=stereo|c0=c0+c2|c1=c1+c3[aout]", diff --git a/agent/services/tts.py b/agent/services/tts.py index 14a729856..d70a89f06 100644 --- a/agent/services/tts.py +++ b/agent/services/tts.py @@ -4,6 +4,7 @@ import logging import os import subprocess +import sys from pathlib import Path from typing import Optional @@ -11,8 +12,9 @@ logger = logging.getLogger(__name__) -# Default to python3.10 (has torch/torchaudio/omnivoice); override with TTS_PYTHON_BIN if needed -PYTHON_BIN = os.environ.get("TTS_PYTHON_BIN", "python3.10") +# Default to python3.10 on POSIX or sys.executable on Windows; override with TTS_PYTHON_BIN if needed +_DEFAULT_PYTHON = sys.executable if sys.platform == "win32" else "python3.10" +PYTHON_BIN = os.environ.get("TTS_PYTHON_BIN", _DEFAULT_PYTHON) # Inline script template for TTS generation via subprocess _TTS_SCRIPT = """ diff --git a/agent/services/video_reviewer.py b/agent/services/video_reviewer.py index 7afaf6fdc..cd6cf9f98 100644 --- a/agent/services/video_reviewer.py +++ b/agent/services/video_reviewer.py @@ -13,6 +13,7 @@ import re import subprocess import tempfile +import shutil from pathlib import Path import ssl @@ -177,10 +178,23 @@ async def _download_via_get_media(media_id: str, dest: Path) -> None: logger.info("Downloaded %s via get_media (%d bytes)", media_id[:12], len(video_bytes)) +def _ffmpeg_bin() -> str: + env_bin = os.environ.get("FFMPEG_BIN") + if env_bin: + return env_bin + if shutil.which("ffmpeg"): + return "ffmpeg" + try: + import imageio_ffmpeg + return imageio_ffmpeg.get_ffmpeg_exe() + except Exception: + return "ffmpeg" + + def _extract_frames(video_path: str, fps: float, out_dir: str) -> list: """Extract frames as JPEGs using ffmpeg. Returns sorted list of frame paths.""" cmd = [ - "ffmpeg", "-y", "-i", video_path, + _ffmpeg_bin(), "-y", "-i", video_path, "-vf", f"fps={fps},scale=640:-1", "-q:v", "4", f"{out_dir}/frame_%04d.jpg", @@ -206,7 +220,7 @@ def _has_drawtext() -> bool: """ try: out = subprocess.run( - ["ffmpeg", "-hide_banner", "-filters"], + [_ffmpeg_bin(), "-hide_banner", "-filters"], capture_output=True, text=True, timeout=30, ) except (OSError, subprocess.SubprocessError) as e: @@ -254,7 +268,7 @@ def _create_contact_sheets( def _extract(with_drawtext: bool): return subprocess.run( [ - "ffmpeg", "-y", "-i", video_path, + _ffmpeg_bin(), "-y", "-i", video_path, "-vf", _frame_filter(fps, with_drawtext), "-q:v", "2", f"{frames_dir}/frame_%04d.jpg", @@ -293,7 +307,11 @@ def _extract(with_drawtext: bool): chunk_dir = Path(out_dir) / f"_chunk_{sheet_idx:02d}" chunk_dir.mkdir(exist_ok=True) for i, frame_path in enumerate(chunk, start=1): - os.symlink(frame_path.resolve(), chunk_dir / f"f_{i:04d}.jpg") + target_link = chunk_dir / f"f_{i:04d}.jpg" + try: + os.symlink(frame_path.resolve(), target_link) + except OSError: + shutil.copy2(frame_path.resolve(), target_link) output = Path(out_dir) / f"sheet_{sheet_idx:02d}.jpg" # Pick the largest divisor of the chunk size (up to REVIEW_SHEET_COLS) as the # column count, so every cell in the tile is filled — zero unfilled cells for any @@ -303,7 +321,7 @@ def _extract(with_drawtext: bool): cols_eff = max(c for c in range(1, REVIEW_SHEET_COLS + 1) if len(chunk) % c == 0) rows_eff = len(chunk) // cols_eff tile_cmd = [ - "ffmpeg", "-y", + _ffmpeg_bin(), "-y", "-i", f"{chunk_dir}/f_%04d.jpg", "-vf", f"tile={cols_eff}x{rows_eff}:nb_frames={len(chunk)}", "-q:v", "2", str(output), @@ -623,7 +641,7 @@ async def _run_codex_cli( args += ["-c", f'model_reasoning_effort="{effort}"'] args.append(prompt) await _spawn_and_check(tuple(args), "codex") - answer = out_path.read_text().strip() + answer = out_path.read_text(encoding="utf-8").strip() if not answer: raise RuntimeError( "codex CLI exited cleanly but wrote no answer to its output file" diff --git a/agent/worker/processor.py b/agent/worker/processor.py index c23039afe..daff27e16 100644 --- a/agent/worker/processor.py +++ b/agent/worker/processor.py @@ -242,7 +242,7 @@ async def _process_one(req: dict, deferred: dict = None, retry_after: dict = Non char = await crud.get_character(req.get("character_id")) if char: skip_kwargs["media_id"] = char.get("media_id") - skip_kwargs["output_url"] = char.get("image_url") + skip_kwargs["output_url"] = char.get("reference_image_url") or char.get("image_url") else: scene = await crud.get_scene(req.get("scene_id")) if scene: @@ -508,16 +508,24 @@ async def _mark_scene_failed(req: dict): async def _is_already_completed(req: dict, orientation: str) -> bool: - scene_id = req.get("scene_id") req_type = req.get("type", "") - if not scene_id or req_type == "GENERATE_CHARACTER_IMAGE": + if req_type in ("EDIT_IMAGE", "REGENERATE_IMAGE", "REGENERATE_VIDEO", "REGENERATE_CHARACTER_IMAGE", "EDIT_CHARACTER_IMAGE"): + return False # Always run — explicitly requesting new generation + + if req_type == "GENERATE_CHARACTER_IMAGE": + char_id = req.get("character_id") + if not char_id: + return False + char = await crud.get_character(char_id) + return bool(char and char.get("media_id")) + + scene_id = req.get("scene_id") + if not scene_id: return False scene = await crud.get_scene(scene_id) if not scene: return False prefix = "vertical" if orientation == "VERTICAL" else "horizontal" - if req_type in ("EDIT_IMAGE", "REGENERATE_IMAGE", "REGENERATE_VIDEO", "REGENERATE_CHARACTER_IMAGE", "EDIT_CHARACTER_IMAGE"): - return False # Always run — explicitly requesting new generation if req_type == "GENERATE_IMAGE": return scene.get(f"{prefix}_image_status") == "COMPLETED" if req_type in ("GENERATE_VIDEO", "GENERATE_VIDEO_REFS"): diff --git a/extension/background.js b/extension/background.js index 6def15cfd..56e2ed47c 100644 --- a/extension/background.js +++ b/extension/background.js @@ -298,9 +298,13 @@ function keepAlive() { function sendToAgent(msg) { // API responses (with msg.id) go via HTTP — immune to WS disconnect if (msg.id) { + const headers = { 'Content-Type': 'application/json' }; + if (callbackSecret) { + headers['X-Callback-Secret'] = callbackSecret; + } fetch('http://127.0.0.1:8100/api/ext/callback', { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers, body: JSON.stringify(msg), }).catch(() => { // HTTP failed — fallback to WS diff --git a/tests/unit/test_cli_providers.py b/tests/unit/test_cli_providers.py index 0a046e1b0..aff62a834 100644 --- a/tests/unit/test_cli_providers.py +++ b/tests/unit/test_cli_providers.py @@ -415,7 +415,7 @@ async def test_claude_agy_providers_include_read_the_images_at(self, provider, r assert "BASE_PROMPT" in captured["prompt"] # The sheets live outside the server cwd, so the directory holding them # is named to the CLI rather than left to be discovered. - assert captured["add_dirs"] == ("/tmp",) + assert captured["add_dirs"] == (str(contact_sheets[0].parent),) assert result == {"dimensions": {}, "errors": [], "usable_segments": []} @pytest.mark.asyncio @@ -473,7 +473,7 @@ async def test_single_sheet_wrapper_wording_matches_original_singular_form(self) new=AsyncMock(side_effect=capture_runner(captured))): await _analyze_cli(contact_sheets, 9, 4.0, {}, timestamped=True) - assert captured["prompt"].startswith("Read the image at /tmp/sheet_00.jpg.") + assert captured["prompt"].startswith(f"Read the image at {contact_sheets[0]}.") assert "Read the images at:" not in captured["prompt"] assert "sequential contact sheets" not in captured["prompt"] assert "It is a contact sheet of 9 video frames at 4.0fps with timestamps." in captured["prompt"] diff --git a/tests/unit/test_processor.py b/tests/unit/test_processor.py index c2f7e9850..c0f029e02 100644 --- a/tests/unit/test_processor.py +++ b/tests/unit/test_processor.py @@ -21,16 +21,21 @@ def make_req( orientation="VERTICAL", retry_count=0, rid="aaaaaaaa-bbbb-cccc-dddd-000000000001", + character_id=None, + **extra, ): - return { + d = { "id": rid, "type": req_type, "scene_id": scene_id, + "character_id": character_id, "orientation": orientation, "retry_count": retry_count, "project_id": "proj-001", "video_id": "video-001", } + d.update(extra) + return d # --------------------------------------------------------------------------- @@ -59,14 +64,24 @@ async def test_returns_false_when_vertical_image_pending(self, sample_scene_row) assert result is False @pytest.mark.asyncio - async def test_returns_false_for_generate_character_image(self, sample_scene_row): - """GENERATE_CHARACTER_IMAGE has no scene — should always return False.""" - req = make_req(req_type="GENERATE_CHARACTER_IMAGE", scene_id="scene-001") + async def test_returns_false_for_generate_character_image_without_media_id(self): + """GENERATE_CHARACTER_IMAGE should return False if character has no media_id.""" + req = make_req(req_type="GENERATE_CHARACTER_IMAGE", character_id="char-001") with patch("agent.worker.processor.crud") as mock_crud: - mock_crud.get_scene = AsyncMock(return_value=sample_scene_row) + mock_crud.get_character = AsyncMock(return_value={"id": "char-001", "media_id": None}) result = await _is_already_completed(req, "VERTICAL") assert result is False - mock_crud.get_scene.assert_not_called() + mock_crud.get_character.assert_called_once_with("char-001") + + @pytest.mark.asyncio + async def test_returns_true_for_generate_character_image_with_media_id(self): + """GENERATE_CHARACTER_IMAGE should return True if character already has media_id.""" + req = make_req(req_type="GENERATE_CHARACTER_IMAGE", character_id="char-001") + with patch("agent.worker.processor.crud") as mock_crud: + mock_crud.get_character = AsyncMock(return_value={"id": "char-001", "media_id": "uuid-1234"}) + result = await _is_already_completed(req, "VERTICAL") + assert result is True + mock_crud.get_character.assert_called_once_with("char-001") @pytest.mark.asyncio async def test_returns_false_when_no_scene_id(self): diff --git a/tests/unit/test_setup.py b/tests/unit/test_setup.py index 4798c31d2..3e35a13ad 100644 --- a/tests/unit/test_setup.py +++ b/tests/unit/test_setup.py @@ -36,7 +36,7 @@ def sandbox(setup_mod, monkeypatch, tmp_path): setup_mod, "LEGACY_GEMINI_COMMANDS_DIR", tmp_path / ".gemini" / "commands" / "fk") monkeypatch.setattr(setup_mod, "LEGACY_GEMINI_MD", tmp_path / "GEMINI.md") (tmp_path / "skills").mkdir() - (tmp_path / "skills" / "fk-demo.md").write_text("# fk-demo — A demo skill\n") + (tmp_path / "skills" / "fk-demo.md").write_text("# fk-demo — A demo skill\n", encoding="utf-8") return tmp_path @@ -70,9 +70,11 @@ def test_clean_removes_what_the_gemini_target_left_behind(self, setup_mod, sandb will ever take them away from an install made before v1.3.1.""" legacy_dir = sandbox / ".gemini" / "commands" / "fk" legacy_dir.mkdir(parents=True) - (legacy_dir / "demo.toml").write_text('description = "x"\n') + (legacy_dir / "demo.toml").write_text('description = "x"\n', encoding="utf-8") (sandbox / "GEMINI.md").write_text( - "<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ -->\n# old\n") + "<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ -->\n# old\n", + encoding="utf-8", + ) setup_mod.do_clean() @@ -141,7 +143,7 @@ def test_tool_choices_reject_gemini(setup_mod, monkeypatch, capsys): def test_discover_skills_reads_the_first_line_as_the_description(setup_mod, sandbox): - (sandbox / "skills" / "fk-other.md").write_text("# fk-other — Does a thing\n\nBody.\n") + (sandbox / "skills" / "fk-other.md").write_text("# fk-other — Does a thing\n\nBody.\n", encoding="utf-8") found = {s["name"]: s["description"] for s in setup_mod.discover_skills()} assert found["other"] == "fk-other — Does a thing" assert found["demo"] == "fk-demo — A demo skill" diff --git a/tests/unit/test_video_reviewer.py b/tests/unit/test_video_reviewer.py index 5287d11d5..3562b4322 100644 --- a/tests/unit/test_video_reviewer.py +++ b/tests/unit/test_video_reviewer.py @@ -19,11 +19,22 @@ def synthetic_video(): """A real ~2-second synthetic test video generated once for this test module.""" tmp_dir = tempfile.mkdtemp() video_path = Path(tmp_dir) / "synthetic.mp4" - result = subprocess.run( - ["ffmpeg", "-y", "-f", "lavfi", "-i", "testsrc=duration=2:size=320x240:rate=30", - str(video_path)], - capture_output=True, text=True, - ) + ffmpeg_cmd = "ffmpeg" + import shutil + if not shutil.which("ffmpeg"): + try: + import imageio_ffmpeg + ffmpeg_cmd = imageio_ffmpeg.get_ffmpeg_exe() + except ImportError: + pass + try: + result = subprocess.run( + [ffmpeg_cmd, "-y", "-f", "lavfi", "-i", "testsrc=duration=2:size=320x240:rate=30", + str(video_path)], + capture_output=True, text=True, + ) + except FileNotFoundError: + pytest.skip("ffmpeg not found in PATH") if result.returncode != 0: pytest.skip(f"ffmpeg unavailable or failed to generate test video: {result.stderr[-300:]}") yield video_path @@ -122,13 +133,19 @@ def test_partial_trailing_chunk_uses_zero_waste_layout( try: sheets, total_frames, _timestamped = _create_contact_sheets(str(synthetic_video), 30, out_dir) assert total_frames == chunk_size - assert len(sheets) == 1 - probe = subprocess.run( - ["ffprobe", "-v", "error", "-select_streams", "v:0", - "-show_entries", "stream=width,height", "-of", "csv=p=0", str(sheets[0])], - capture_output=True, text=True, - ) - width, height = (int(x) for x in probe.stdout.strip().split(",")) + try: + probe = subprocess.run( + ["ffprobe", "-v", "error", "-select_streams", "v:0", + "-show_entries", "stream=width,height", "-of", "csv=p=0", str(sheets[0])], + capture_output=True, text=True, + ) + if probe.returncode != 0: + raise FileNotFoundError + width, height = (int(x) for x in probe.stdout.strip().split(",")) + except (FileNotFoundError, ValueError): + from PIL import Image + with Image.open(sheets[0]) as im: + width, height = im.size frame_w, frame_h = 320, 240 # scale=320:-1 applied to the 320x240 synthetic_video assert (width, height) == (expected_cols * frame_w, expected_rows * frame_h), ( f"chunk_size={chunk_size}: expected a {expected_cols}x{expected_rows} " diff --git a/tests/unit/test_youtube.py b/tests/unit/test_youtube.py new file mode 100644 index 000000000..7068ac6ba --- /dev/null +++ b/tests/unit/test_youtube.py @@ -0,0 +1,84 @@ +"""Unit tests for youtube/upload.py and youtube/auth.py.""" +import json +from datetime import datetime, timezone +from pathlib import Path +from unittest.mock import MagicMock, patch + +import pytest + +from youtube.upload import ( + auto_schedule, + detect_video_type, + load_channel_rules, + validate_upload, +) + + +def test_load_channel_rules_fallback(): + rules = load_channel_rules("non_existent_channel_xyz") + assert "upload_rules" in rules + assert "shorts" in rules["upload_rules"] + assert rules["timezone"] == "Asia/Ho_Chi_Minh" + + +def test_load_channel_rules_from_disk(tmp_path, monkeypatch): + from youtube import auth + + monkeypatch.setattr(auth, "CHANNELS_DIR", tmp_path) + chan_dir = tmp_path / "custom_chan" + chan_dir.mkdir() + custom_rules = { + "upload_rules": { + "shorts": {"max_per_day": 5, "optimal_times": ["08:00"]}, + "long": {"max_per_day": 2, "optimal_times": ["20:00"]}, + }, + "timezone": "UTC", + } + (chan_dir / "channel_rules.json").write_text( + json.dumps(custom_rules), encoding="utf-8" + ) + + rules = load_channel_rules("custom_chan") + assert rules["upload_rules"]["shorts"]["max_per_day"] == 5 + assert rules["timezone"] == "UTC" + + +def test_detect_video_type_short(): + with patch("youtube.upload._probe_video", return_value=(45.0, 1080, 1920)): + vtype, orient = detect_video_type("test.mp4") + assert vtype == "short" + assert orient == "vertical" + + +def test_detect_video_type_long(): + with patch("youtube.upload._probe_video", return_value=(120.0, 1920, 1080)): + vtype, orient = detect_video_type("test.mp4") + assert vtype == "long" + assert orient == "horizontal" + + +def test_validate_upload_avoid_hours(): + # 03:00 is in default avoid_hours (0..5) + avoid_dt = datetime(2026, 9, 22, 3, 0, tzinfo=timezone.utc) + ok, reason = validate_upload("chan1", avoid_dt, is_short=True) + assert not ok + assert "avoid_hours" in reason + + +def test_validate_upload_valid_slot(): + valid_dt = datetime(2026, 9, 22, 12, 0, tzinfo=timezone.utc) + with patch("youtube.upload.load_upload_history", return_value=[]): + ok, reason = validate_upload("chan1", valid_dt, is_short=True) + assert ok + assert reason == "OK" + + +def test_auto_schedule_generates_slots(): + start_dt = datetime(2026, 9, 22, 6, 0, tzinfo=timezone.utc) + with patch("youtube.upload.load_upload_history", return_value=[]): + slots = auto_schedule("chan1", count=3, is_short=True, start_from=start_dt) + assert len(slots) == 3 + # Should start from the first optimal time >= 6:00 (which is 07:00, 12:00, 17:00) + assert "07:00:00" in slots[0] + assert "12:00:00" in slots[1] + assert "17:00:00" in slots[2] diff --git a/tools/review_server.py b/tools/review_server.py index b4017efef..f343e86db 100644 --- a/tools/review_server.py +++ b/tools/review_server.py @@ -80,7 +80,7 @@ def do_GET(self): if path == "/api/feedback": data = {} if FEEDBACK_FILE.exists(): - data = json.loads(FEEDBACK_FILE.read_text()) + data = json.loads(FEEDBACK_FILE.read_text(encoding="utf-8")) self._json_response(data) return @@ -120,7 +120,7 @@ def do_POST(self): body = self.rfile.read(length) try: data = json.loads(body) - FEEDBACK_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False)) + FEEDBACK_FILE.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding="utf-8") self._json_response({"ok": True, "saved": str(FEEDBACK_FILE)}) except Exception as e: self.send_error(400, str(e)) diff --git a/youtube/__init__.py b/youtube/__init__.py new file mode 100644 index 000000000..ae9e4a4d7 --- /dev/null +++ b/youtube/__init__.py @@ -0,0 +1 @@ +"""YouTube integration package for Flow Kit.""" diff --git a/youtube/auth.py b/youtube/auth.py new file mode 100644 index 000000000..51536a275 --- /dev/null +++ b/youtube/auth.py @@ -0,0 +1,63 @@ +"""YouTube OAuth2 authentication helper for Flow Kit.""" +import json +import logging +from pathlib import Path +from typing import Optional + +from google.auth.transport.requests import Request +from google.oauth2.credentials import Credentials +from google_auth_oauthlib.flow import InstalledAppFlow +from googleapiclient.discovery import build + +logger = logging.getLogger(__name__) + +SCOPES = [ + "https://www.googleapis.com/auth/youtube.upload", + "https://www.googleapis.com/auth/youtube.readonly", +] + +BASE_DIR = Path(__file__).resolve().parent.parent +CHANNELS_DIR = BASE_DIR / "youtube" / "channels" + + +def get_channel_dir(channel_name: str) -> Path: + """Return directory path for a channel.""" + return CHANNELS_DIR / channel_name + + +def get_authenticated_service(channel_name: str): + """Authenticate and return a YouTube Data API v3 service resource.""" + cdir = get_channel_dir(channel_name) + cdir.mkdir(parents=True, exist_ok=True) + token_file = cdir / "token.json" + secrets_file = cdir / "client_secrets.json" + + creds: Optional[Credentials] = None + + if token_file.exists(): + try: + creds = Credentials.from_authorized_user_file(str(token_file), SCOPES) + except Exception as e: + logger.warning("Failed to load existing token for %s: %s", channel_name, e) + creds = None + + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + logger.info("Refreshing expired token for channel %s", channel_name) + creds.refresh(Request()) + else: + if not secrets_file.exists(): + raise FileNotFoundError( + f"client_secrets.json not found for channel '{channel_name}' at {secrets_file}. " + "Download OAuth client ID from Google Cloud Console and place it there." + ) + logger.info("Running OAuth flow for channel %s", channel_name) + flow = InstalledAppFlow.from_client_secrets_file(str(secrets_file), SCOPES) + creds = flow.run_local_server(port=0) + + # Save credentials for subsequent runs + token_file.write_text(creds.to_json(), encoding="utf-8") + logger.info("Saved token to %s", token_file) + + service = build("youtube", "v3", credentials=creds) + return service diff --git a/youtube/upload.py b/youtube/upload.py new file mode 100644 index 000000000..1da4f6df3 --- /dev/null +++ b/youtube/upload.py @@ -0,0 +1,326 @@ +"""YouTube upload service and video scheduling for Flow Kit.""" +import json +import logging +import os +import subprocess +from datetime import datetime, timedelta, timezone +from pathlib import Path +from typing import Any, Optional, Tuple + +from googleapiclient.http import MediaFileUpload + +from youtube.auth import get_authenticated_service, get_channel_dir + +logger = logging.getLogger(__name__) + +DEFAULT_RULES = { + "upload_rules": { + "shorts": { + "max_per_day": 3, + "optimal_times": ["07:00", "12:00", "17:00"], + "min_gap_hours": 4, + "avoid_hours": [0, 1, 2, 3, 4, 5], + }, + "long": { + "max_per_day": 1, + "optimal_times": ["19:00"], + "min_gap_hours": 4, + "avoid_hours": [0, 1, 2, 3, 4, 5], + }, + }, + "seo": { + "title_max_chars": 65, + "always_include_hashtags": ["#Shorts"], + "default_tags": [], + "default_category": "25", + }, + "timezone": "Asia/Ho_Chi_Minh", +} + + +def _probe_video(video_path: str | Path) -> Tuple[float, int, int]: + """Return (duration_seconds, width, height) using ffprobe or ffmpeg.""" + path_str = str(video_path) + # Try ffprobe first + try: + cmd = [ + "ffprobe", + "-v", "error", + "-select_streams", "v:0", + "-show_entries", "stream=width,height,duration:format=duration", + "-of", "json", + path_str, + ] + res = subprocess.run(cmd, capture_output=True, text=True, timeout=30) + if res.returncode == 0: + data = json.loads(res.stdout) + stream = (data.get("streams") or [{}])[0] + width = int(stream.get("width", 1080)) + height = int(stream.get("height", 1920)) + duration_str = stream.get("duration") or data.get("format", {}).get("duration", "0") + return float(duration_str), width, height + except Exception as e: + logger.warning("ffprobe probe failed: %s, attempting fallback", e) + + # Fallback to ffmpeg -i info parsing + try: + ffmpeg_bin = "ffmpeg" + try: + import imageio_ffmpeg + ffmpeg_bin = imageio_ffmpeg.get_ffmpeg_exe() + except ImportError: + pass + + res = subprocess.run([ffmpeg_bin, "-i", path_str], capture_output=True, text=True, timeout=30) + stderr = res.stderr or "" + duration = 0.0 + width, height = 1080, 1920 + for line in stderr.splitlines(): + if "Duration:" in line: + parts = line.split("Duration:")[1].split(",")[0].strip() + h, m, s = parts.split(":") + duration = float(h) * 3600 + float(m) * 60 + float(s) + if "Video:" in line and ("x" in line or "," in line): + import re + match = re.search(r"(\d{3,5})x(\d{3,5})", line) + if match: + width, height = int(match.group(1)), int(match.group(2)) + return duration, width, height + except Exception as e: + logger.error("Failed to probe video %s: %s", video_path, e) + return 0.0, 1080, 1920 + + +def detect_video_type(video_path: str | Path) -> Tuple[str, str]: + """Detect if video is Short or Long-form. + + Returns: + tuple[str, str]: ("short", "vertical") or ("long", "horizontal") + """ + duration, width, height = _probe_video(video_path) + is_vertical = height > width + is_short = duration < 61.0 and is_vertical + video_type = "short" if is_short else "long" + orientation = "vertical" if is_vertical else "horizontal" + return video_type, orientation + + +def load_channel_rules(channel_name: str) -> dict: + """Load channel rules from youtube/channels/<channel_name>/channel_rules.json.""" + rules_file = get_channel_dir(channel_name) / "channel_rules.json" + if rules_file.exists(): + try: + return json.loads(rules_file.read_text(encoding="utf-8")) + except Exception as e: + logger.warning("Error reading %s: %s, using defaults", rules_file, e) + return DEFAULT_RULES.copy() + + +def load_upload_history(channel_name: str) -> list[dict]: + """Load history of uploads for a channel.""" + hist_file = get_channel_dir(channel_name) / "upload_history.json" + if hist_file.exists(): + try: + return json.loads(hist_file.read_text(encoding="utf-8")) + except Exception: + return [] + return [] + + +def save_upload_history_entry(channel_name: str, entry: dict): + """Save an entry to upload_history.json.""" + cdir = get_channel_dir(channel_name) + cdir.mkdir(parents=True, exist_ok=True) + hist_file = cdir / "upload_history.json" + history = load_upload_history(channel_name) + history.append(entry) + hist_file.write_text(json.dumps(history, indent=2, ensure_ascii=False), encoding="utf-8") + + +def _parse_dt(val: Any) -> datetime: + """Normalize datetime to timezone-aware UTC datetime.""" + if not val: + return datetime.fromtimestamp(0, tz=timezone.utc) + if isinstance(val, datetime): + return val if val.tzinfo else val.replace(tzinfo=timezone.utc) + try: + val_clean = str(val).replace("Z", "+00:00") + dt = datetime.fromisoformat(val_clean) + return dt if dt.tzinfo else dt.replace(tzinfo=timezone.utc) + except (ValueError, TypeError): + return datetime.fromtimestamp(0, tz=timezone.utc) + + +def validate_upload( + channel_name: str, + schedule_at: str | datetime, + is_short: bool = True, +) -> Tuple[bool, str]: + """Validate scheduled upload against channel rules. + + Checks: + 1. Max uploads per day + 2. Min gap between uploads + 3. Avoid hours + """ + rules = load_channel_rules(channel_name) + upload_rules = rules.get("upload_rules") or DEFAULT_RULES["upload_rules"] + type_key = "shorts" if is_short else "long" + type_rules = upload_rules.get(type_key) or DEFAULT_RULES["upload_rules"][type_key] + + sched_dt = _parse_dt(schedule_at) + target_date = sched_dt.date() + + history = load_upload_history(channel_name) + + # 1. Max per day + max_per_day = type_rules.get("max_per_day", 3 if is_short else 1) + day_count = sum( + 1 for h in history + if h.get("is_short", True) == is_short + and _parse_dt(h.get("schedule_at") or h.get("timestamp", "")).date() == target_date + ) + if day_count >= max_per_day: + return False, f"Max {max_per_day} {type_key}/day reached for {target_date}" + + # 2. Min gap hours + min_gap = timedelta(hours=type_rules.get("min_gap_hours", 4)) + for h in history: + prev_dt = _parse_dt(h.get("schedule_at") or h.get("timestamp", "")) + if abs(sched_dt - prev_dt) < min_gap: + return False, f"Min gap of {min_gap} not met relative to {prev_dt.isoformat()}" + + # 3. Avoid hours + avoid = type_rules.get("avoid_hours", [0, 1, 2, 3, 4, 5]) + if sched_dt.hour in avoid: + return False, f"Schedule hour {sched_dt.hour}:00 is in avoid_hours {avoid}" + + return True, "OK" + + +def auto_schedule( + channel_name: str, + count: int, + is_short: bool = True, + start_from: Optional[datetime] = None, +) -> list[str]: + """Auto-generate N valid schedule slots adhering to channel rules.""" + rules = load_channel_rules(channel_name) + upload_rules = rules.get("upload_rules", DEFAULT_RULES["upload_rules"]) + type_key = "shorts" if is_short else "long" + type_rules = upload_rules.get(type_key, DEFAULT_RULES["upload_rules"][type_key]) + optimal_times = type_rules.get("optimal_times", ["07:00", "12:00", "17:00"] if is_short else ["19:00"]) + + current = start_from or datetime.now(timezone.utc) + current_date = current.date() + + slots: list[str] = [] + day_offset = 0 + + while len(slots) < count and day_offset < 60: + day = current_date + timedelta(days=day_offset) + for t_str in optimal_times: + hh, mm = map(int, t_str.split(":")) + candidate = datetime(day.year, day.month, day.day, hh, mm, tzinfo=timezone.utc) + if candidate <= current: + continue + ok, _ = validate_upload(channel_name, candidate, is_short=is_short) + if ok: + slots.append(candidate.isoformat()) + if len(slots) == count: + break + day_offset += 1 + + return slots + + +def upload_video( + channel_name: str, + video_path: str | Path, + title: str, + description: str = "", + tags: Optional[list[str]] = None, + category_id: str = "25", + schedule_at: Optional[str] = None, + is_short: bool = True, + privacy_status: str = "private", +) -> str: + """Upload a video to YouTube with resume support, auto-hashtags, and schedule.""" + video_file = Path(video_path) + if not video_file.exists(): + raise FileNotFoundError(f"Video file not found: {video_file}") + + rules = load_channel_rules(channel_name) + seo_rules = rules.get("seo", DEFAULT_RULES["seo"]) + + # Ensure #Shorts in title if short + if is_short and "#Shorts" not in title and "#shorts" not in title.lower(): + title = f"{title} #Shorts" + + title_max = seo_rules.get("title_max_chars", 65) + if len(title) > title_max: + title = title[:title_max] + + all_tags = list(tags or []) + for d_tag in seo_rules.get("default_tags", []): + if d_tag not in all_tags: + all_tags.append(d_tag) + + body: dict[str, Any] = { + "snippet": { + "title": title, + "description": description, + "tags": all_tags, + "categoryId": category_id or seo_rules.get("default_category", "25"), + }, + "status": { + "privacyStatus": privacy_status, + "selfDeclaredMadeForKids": False, + }, + } + + if schedule_at: + sched_dt = _parse_dt(schedule_at) + body["status"]["privacyStatus"] = "private" + body["status"]["publishAt"] = sched_dt.strftime("%Y-%m-%dT%H:%M:%SZ") + + service = get_authenticated_service(channel_name) + + chunksize = 10 * 1024 * 1024 # 10MB chunk + media = MediaFileUpload( + str(video_file), + mimetype="video/mp4", + chunksize=chunksize, + resumable=True, + ) + + request = service.videos().insert( + part="snippet,status", + body=body, + media_body=media, + ) + + response = None + logger.info("Uploading %s to channel %s...", video_file.name, channel_name) + while response is None: + status, response = request.next_chunk() + if status: + logger.info("Upload progress: %d%%", int(status.progress() * 100)) + + video_id = response.get("id", "") + logger.info("Uploaded video %s successfully with ID %s", video_file.name, video_id) + + # Save to history + save_upload_history_entry( + channel_name, + { + "video_id": video_id, + "title": title, + "video_path": str(video_file), + "is_short": is_short, + "schedule_at": schedule_at, + "timestamp": datetime.now(timezone.utc).isoformat(), + }, + ) + + return video_id From f6caa5116ff366057b24c65080a9df677aa6bfa6 Mon Sep 17 00:00:00 2001 From: Le Tien <tienoho@gmail.com> Date: Tue, 22 Sep 2026 11:53:27 +0700 Subject: [PATCH 29/68] feat: add CLI providers service, active project API, request handlers, and SDK operations --- agent/api/active_project.py | 6 +++--- agent/api/requests.py | 5 ++++- agent/sdk/services/operations.py | 5 ++--- agent/services/cli_providers.py | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/agent/api/active_project.py b/agent/api/active_project.py index b0b0389ca..596544234 100644 --- a/agent/api/active_project.py +++ b/agent/api/active_project.py @@ -18,7 +18,7 @@ def _read_state() -> dict | None: if _STATE_FILE.exists(): try: - with open(_STATE_FILE) as f: + with open(_STATE_FILE, encoding="utf-8") as f: return json.load(f) except (json.JSONDecodeError, OSError) as e: logger.warning("Corrupt active_project.json, clearing: %s", e) @@ -28,10 +28,10 @@ def _read_state() -> dict | None: def _write_state(data: dict): """Atomic write — temp file + os.replace to avoid partial reads.""" - content = json.dumps(data, indent=2) + "\n" + content = json.dumps(data, indent=2, ensure_ascii=False) + "\n" fd, tmp = tempfile.mkstemp(dir=_STATE_FILE.parent, suffix=".tmp") try: - os.write(fd, content.encode()) + os.write(fd, content.encode("utf-8")) os.close(fd) os.replace(tmp, _STATE_FILE) except BaseException: diff --git a/agent/api/requests.py b/agent/api/requests.py index 6c1b5f330..b1f73d6cc 100644 --- a/agent/api/requests.py +++ b/agent/api/requests.py @@ -36,13 +36,14 @@ async def create(body: RequestCreate): data = body.model_dump(exclude_none=True) data["req_type"] = data.pop("type") - # Reject if there's already an active request for the same scene + type scene_id = data.get("scene_id") req_type = data.get("req_type") + orient = data.get("orientation") if scene_id and req_type: existing = await crud.list_requests(scene_id=scene_id) active = [r for r in existing if r.get("type") == req_type + and (not orient or r.get("orientation") == orient) and r.get("status") in ("PENDING", "PROCESSING")] if active: raise HTTPException( @@ -79,11 +80,13 @@ async def create_batch(body: BatchRequestCreate): scene_id = data.get("scene_id") character_id = data.get("character_id") req_type = data.get("req_type") + orient = data.get("orientation") # Idempotent: skip if active request already exists if scene_id and req_type: existing = await crud.list_requests(scene_id=scene_id) active = [r for r in existing if r.get("type") == req_type + and (not orient or r.get("orientation") == orient) and r.get("status") in ("PENDING", "PROCESSING")] if active: results.append(active[0]) diff --git a/agent/sdk/services/operations.py b/agent/sdk/services/operations.py index e7157cd45..20a4a8168 100644 --- a/agent/sdk/services/operations.py +++ b/agent/sdk/services/operations.py @@ -209,9 +209,8 @@ async def _poll_workflows( for op in operations: mid = op.get("_primary_media_id", "") wf_name = op.get("operation", {}).get("name", "") - local = completed.get(mid, {}).get("path", "") - # Use file:// so downstream sees a URL-shaped string - local_url = f"file://{_os.path.abspath(local)}" if local else "" + from pathlib import Path as _Path + local_url = _Path(local).resolve().as_uri() if local else "" synth_ops.append({ "operation": { "name": wf_name, diff --git a/agent/services/cli_providers.py b/agent/services/cli_providers.py index 81977d0cc..98dd8d105 100644 --- a/agent/services/cli_providers.py +++ b/agent/services/cli_providers.py @@ -244,7 +244,7 @@ def _list_codex_models() -> list[dict]: """ if not _CODEX_MODELS_CACHE.exists(): return [] - with open(_CODEX_MODELS_CACHE) as f: + with open(_CODEX_MODELS_CACHE, encoding="utf-8") as f: data = json.load(f) models = [] for entry in data.get("models") or []: From 0e0a94e5318f5334b5caad0799df387729166ea4 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Wed, 23 Sep 2026 08:44:33 +0300 Subject: [PATCH 30/68] fix(flow): stop retrying unusual activity blocks --- agent/worker/processor.py | 12 ++++++++++++ skills/fk-doctor.md | 2 +- tests/unit/test_processor.py | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/agent/worker/processor.py b/agent/worker/processor.py index c23039afe..829ed4950 100644 --- a/agent/worker/processor.py +++ b/agent/worker/processor.py @@ -444,6 +444,18 @@ async def _handle_failure(rid: str, req: dict, result: dict, retry_after: dict = error_lower = str(error_msg).lower() + # PUBLIC_ERROR_UNUSUAL_ACTIVITY is a Google anti-abuse/session trust block, + # not an ordinary CAPTCHA mint failure. Retrying it in the generic CAPTCHA + # loop only creates more generation submits while Google is asking us to + # slow down, so stop this request and require an explicit resubmit after + # the session/network has recovered. + if "public_error_unusual_activity" in error_lower or "unusual activity" in error_lower: + await crud.update_request(rid, status="FAILED", error_message=str(error_msg)) + await _mark_scene_failed(req) + logger.error("Request %s FAILED (Google unusual-activity block; manual recovery required): %s", + rid[:8], error_msg) + return + # A capability the batch path does not have, or a missing Flow project, is # a configuration answer — not something a retry can reach. Fail it once. if "unsupported_on_batch_api" in error_lower or "no_flow_project" in error_lower: diff --git a/skills/fk-doctor.md b/skills/fk-doctor.md index f26c8db38..b5f3ccf20 100644 --- a/skills/fk-doctor.md +++ b/skills/fk-doctor.md @@ -140,7 +140,7 @@ Detection lives in `agent/worker/_parsing.py:_is_error`. A result is treated as | `NO_INJECTION_RESULT` | `chrome.scripting.executeScript` resolved with no frame result (`background.js:540`), so the envelope never ran — the Flow tab went away or was still booting at the moment of the call. Most likely on the first captcha-bearing RPC after an agent restart | Retried with backoff, counts against `MAX_RETRIES` | Usually transient — retry first. Rule out the lookalikes before digging: a failed mint reports `CAPTCHA_FAILED`, an oversized payload is not it (`MAX_RPC_TEXT` is 32 MB), and a structured-clone failure surfaces as 500, not 502. If it repeats, pin the Flow tab and reload the extension | | `NO_FLOW_PROJECT` | No Flow project to scope the RPC to | **Terminal — not retried** | Create a project in the Flow UI, pin its uuid as `FLOW_PROJECT_ID` (or pass `flow_project_id` on `POST /api/projects`) | | `UNSUPPORTED_ON_BATCH_API` | A capability whose payload was never captured off the new UI, all on the Veo path: **video upscale**, **Veo r2v**, **Veo start+end-frame chaining**. Every Omni mode is ported, so this never names Omni any more | **Terminal — not retried** | For chaining and r2v, `FLOW_ALLOW_DEGRADED=1` falls back to plain i2v off the start frame. Upscale has no fallback. Real fix: capture the payload — `docs/CAPTURE.md` | -| `PUBLIC_ERROR_UNUSUAL_ACTIVITY` | A reCAPTCHA token was replayed — they are single-use | Retried as a captcha error | Usually self-clears; if it persists the extension is reusing a token, reload it | +| `PUBLIC_ERROR_UNUSUAL_ACTIVITY` | Google rejected the generation as unusual activity / reCAPTCHA risk evaluation | **Do not auto-retry** — repeated submits can prolong the block | Pause generation submits, keep the browser/session/network stable, and retry manually only after the trust signal has had time to recover | | `no ogiZ0b envelope in response` | The RPC answered but not with the payload we came for — usually a signed-out page returning an HTML redirect | Retried with backoff | Re-sign in on the Flow tab | | `Polling timeout after Ns: Media not found.` | The job never produced media inside the budget | Terminal after `MAX_RETRIES` | The quoted complaint is a **diagnostic, not the cause** — finished jobs report it too. Check the Flow UI: if the clip is there, raise `VIDEO_POLL_TIMEOUT` | diff --git a/tests/unit/test_processor.py b/tests/unit/test_processor.py index c2f7e9850..46f23c55b 100644 --- a/tests/unit/test_processor.py +++ b/tests/unit/test_processor.py @@ -169,6 +169,24 @@ async def test_marks_failed_when_at_max_retries(self): # Scene should also be marked failed mock_crud.update_scene.assert_awaited_once_with("scene-001", vertical_image_status="FAILED") + @pytest.mark.asyncio + async def test_unusual_activity_is_not_retried_as_captcha(self): + """Google unusual-activity blocks must stop instead of entering the CAPTCHA retry loop.""" + req = make_req(req_type="GENERATE_VIDEO", scene_id="scene-001", retry_count=0) + rid = req["id"] + result = {"error": "reCAPTCHA evaluation failed [PUBLIC_ERROR_UNUSUAL_ACTIVITY]"} + + with patch("agent.worker.processor.crud") as mock_crud: + mock_crud.update_request = AsyncMock() + mock_crud.update_scene = AsyncMock() + await _handle_failure(rid, req, result) + + call_kwargs = mock_crud.update_request.call_args + assert call_kwargs[0][0] == rid + assert call_kwargs[1]["status"] == "FAILED" + assert "retry_count" not in call_kwargs[1] + mock_crud.update_scene.assert_awaited_once_with("scene-001", vertical_video_status="FAILED") + @pytest.mark.asyncio async def test_extracts_error_message_from_nested_data(self): """Error message extraction from data.error.message should work.""" From 64cdf00ecfe13dd054e89bb28621e814d0e1ec75 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Wed, 23 Sep 2026 10:49:38 +0300 Subject: [PATCH 31/68] feat(flow): add project sessions and generation guard --- agent/api/flow.py | 71 +++++++++++--- agent/api/projects.py | 4 +- agent/config.py | 15 +++ agent/main.py | 25 +++++ agent/models/project.py | 5 +- agent/services/flow_batch.py | 17 ++++ agent/services/flow_client.py | 125 +++++++++++++++++++----- agent/services/flow_project_session.py | 91 +++++++++++++++++ skills/fk-create-project.md | 23 ++--- skills/fk-doctor.md | 2 +- tests/unit/test_flow_client_batch.py | 22 +++-- tests/unit/test_flow_global_throttle.py | 76 ++++++++++++++ tests/unit/test_flow_project_session.py | 48 +++++++++ 13 files changed, 456 insertions(+), 68 deletions(-) create mode 100644 agent/services/flow_project_session.py create mode 100644 tests/unit/test_flow_global_throttle.py create mode 100644 tests/unit/test_flow_project_session.py diff --git a/agent/api/flow.py b/agent/api/flow.py index 7aed5ef3f..5f00b6f6e 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -3,8 +3,13 @@ from pydantic import BaseModel, Field from typing import Literal, Optional -from agent.config import FLOW_PROJECT_ID, FLOW_ALLOW_DEGRADED +from agent.config import ( + FLOW_PROJECT_ID, FLOW_ALLOW_DEGRADED, + FLOW_GENERATION_MIN_INTERVAL_S, FLOW_GENERATION_MAX_CONCURRENT, + FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, +) from agent.services.flow_client import get_flow_client +from agent.services.flow_project_session import current_session_project, ensure_session_project from agent.services.omni_flash import ( check_omni_flash_status, generate_omni_flash_first_frame_video, @@ -18,7 +23,7 @@ class GenerateImageRequest(BaseModel): prompt: str - project_id: str + project_id: str = "" aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT" user_paygate_tier: str = "PAYGATE_TIER_ONE" image_model: Optional[str] = None @@ -31,7 +36,7 @@ class GenerateImageRequest(BaseModel): class GenerateVideoRequest(BaseModel): start_image_media_id: str prompt: str - project_id: str + project_id: str = "" scene_id: str aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT" end_image_media_id: Optional[str] = None @@ -45,7 +50,7 @@ class GenerateVideoRequest(BaseModel): class GenerateVideoRefsRequest(BaseModel): reference_media_ids: list[str] prompt: str - project_id: str + project_id: str = "" scene_id: str aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT" user_paygate_tier: str = "PAYGATE_TIER_ONE" @@ -59,7 +64,7 @@ class GenerateVideoRefsRequest(BaseModel): class GenerateOmniFlashVideoRequest(BaseModel): reference_media_ids: list[str] prompt: str - project_id: str + project_id: str = "" scene_id: str = "" duration_s: int = 8 resolution: Literal["360p", "720p"] = "720p" @@ -69,7 +74,7 @@ class GenerateOmniFlashVideoRequest(BaseModel): class GenerateOmniFlashTextVideoRequest(BaseModel): prompt: str - project_id: str + project_id: str = "" scene_id: str = "" duration_s: int = 8 aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT" @@ -123,6 +128,20 @@ class UpscaleImageRequest(BaseModel): quality: Literal["2k", "4k"] = "2k" +async def _resolve_direct_project(client, project_id: str) -> str: + pid = str(project_id or "").strip() + if pid: + return pid + try: + session = await ensure_session_project(client) + except Exception as exc: + raise HTTPException(502, f"Could not create Flow session project: {exc}") from exc + pid = str(session.get("project_id") or "") + if not pid: + raise HTTPException(502, "Flow session project did not return an id") + return pid + + @router.get("/status") async def extension_status(): """Extension health. @@ -139,6 +158,13 @@ async def extension_status(): "flow_project_id": FLOW_PROJECT_ID or None, "allow_degraded": FLOW_ALLOW_DEGRADED, "flow_key_present": client._flow_key is not None, + "generation_throttle": { + "min_interval_s": FLOW_GENERATION_MIN_INTERVAL_S, + "max_concurrent": FLOW_GENERATION_MAX_CONCURRENT, + "unusual_activity_cooldown_s": FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, + **client.generation_guard_status, + }, + "session_project": current_session_project(), } @@ -160,7 +186,9 @@ async def generate_image(body: GenerateImageRequest): client = get_flow_client() if not client.connected: raise HTTPException(503, "Extension not connected") + project_id = await _resolve_direct_project(client, body.project_id) data = body.model_dump(exclude={"reference_media_ids"}) + data["project_id"] = project_id refs = list(dict.fromkeys((body.reference_media_ids or []) + (body.character_media_ids or []))) data["character_media_ids"] = refs or None result = await client.generate_images(**data) @@ -184,13 +212,14 @@ async def generate_video(body: GenerateVideoRequest): client = get_flow_client() if not client.connected: raise HTTPException(503, "Extension not connected") + project_id = await _resolve_direct_project(client, body.project_id) if body.model_family == "omni_flash": try: common = dict( start_image_media_id=body.start_image_media_id, prompt=body.prompt, - project_id=body.project_id, + project_id=project_id, scene_id=body.scene_id, duration_s=body.duration_s, resolution=body.resolution, @@ -207,9 +236,11 @@ async def generate_video(body: GenerateVideoRequest): except ValueError as exc: raise HTTPException(400, str(exc)) from exc else: - result = await client.generate_video( - **body.model_dump(exclude={"model_family", "duration_s", "resolution"}, exclude_none=True) + payload = body.model_dump( + exclude={"model_family", "duration_s", "resolution"}, exclude_none=True ) + payload["project_id"] = project_id + result = await client.generate_video(**payload) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) @@ -228,13 +259,14 @@ async def generate_video_refs(body: GenerateVideoRefsRequest): client = get_flow_client() if not client.connected: raise HTTPException(503, "Extension not connected") + project_id = await _resolve_direct_project(client, body.project_id) if body.model_family == "omni_flash": try: result = await generate_omni_flash_video( reference_media_ids=body.reference_media_ids, prompt=body.prompt, - project_id=body.project_id, + project_id=project_id, scene_id=body.scene_id, duration_s=body.duration_s, resolution=body.resolution, @@ -244,9 +276,9 @@ async def generate_video_refs(body: GenerateVideoRefsRequest): except ValueError as exc: raise HTTPException(400, str(exc)) from exc else: - result = await client.generate_video_from_references( - **body.model_dump(exclude={"model_family", "duration_s", "resolution"}) - ) + payload = body.model_dump(exclude={"model_family", "duration_s", "resolution"}) + payload["project_id"] = project_id + result = await client.generate_video_from_references(**payload) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) @@ -262,8 +294,11 @@ async def generate_video_omni_text(body: GenerateOmniFlashTextVideoRequest): client = get_flow_client() if not client.connected: raise HTTPException(503, "Extension not connected") + project_id = await _resolve_direct_project(client, body.project_id) try: - result = await generate_omni_flash_text_video(**body.model_dump()) + payload = body.model_dump() + payload["project_id"] = project_id + result = await generate_omni_flash_text_video(**payload) except ValueError as exc: raise HTTPException(400, str(exc)) from exc if result.get("error") or ( @@ -286,8 +321,11 @@ async def generate_video_omni(body: GenerateOmniFlashVideoRequest): client = get_flow_client() if not client.connected: raise HTTPException(503, "Extension not connected") + project_id = await _resolve_direct_project(client, body.project_id) try: - result = await generate_omni_flash_video(**body.model_dump()) + payload = body.model_dump() + payload["project_id"] = project_id + result = await generate_omni_flash_video(**payload) except ValueError as exc: raise HTTPException(400, str(exc)) from exc if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): @@ -452,6 +490,7 @@ async def upload_image(body: UploadImageRequest): client = get_flow_client() if not client.connected: raise HTTPException(503, "Extension not connected") + project_id = await _resolve_direct_project(client, body.project_id) try: with open(body.file_path, "rb") as f: image_bytes = f.read() @@ -459,7 +498,7 @@ async def upload_image(body: UploadImageRequest): raise HTTPException(404, f"File not found: {body.file_path}") b64 = base64.b64encode(image_bytes).decode() mime = mimetypes.guess_type(body.file_path)[0] or "image/png" - result = await client.upload_image(b64, mime_type=mime, project_id=body.project_id, file_name=body.file_name) + result = await client.upload_image(b64, mime_type=mime, project_id=project_id, file_name=body.file_name) if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) media_id = result.get("_mediaId") diff --git a/agent/api/projects.py b/agent/api/projects.py index 4b87aa847..c46105a3f 100644 --- a/agent/api/projects.py +++ b/agent/api/projects.py @@ -172,8 +172,8 @@ async def create(body: ProjectCreate): detected_tier = await _detect_user_tier(client) - # Flow no longer creates projects for us — the uuid comes from the request - # or from FLOW_PROJECT_ID. + # Explicit flow_project_id means intentional reuse. Otherwise create a + # fresh real Flow project through the current batchexecute endpoint. flow_project_id = client.flow_project_id(body.flow_project_id) if flow_project_id: logger.info("Flow project reused: %s", flow_project_id) diff --git a/agent/config.py b/agent/config.py index 743198e2d..bebbcc954 100644 --- a/agent/config.py +++ b/agent/config.py @@ -33,6 +33,21 @@ # both drop to plain i2v off the start frame. Upscale has no fallback. FLOW_ALLOW_DEGRADED = os.environ.get("FLOW_ALLOW_DEGRADED", "0") == "1" +# Process-wide guard for every CAPTCHA-bearing generation submit, including +# direct API calls that bypass the background worker's limiter. +FLOW_GENERATION_MIN_INTERVAL_S = max( + 0.0, float(os.environ.get("FLOW_GENERATION_MIN_INTERVAL_S", "3")) +) +FLOW_GENERATION_MAX_CONCURRENT = max( + 1, int(os.environ.get("FLOW_GENERATION_MAX_CONCURRENT", "1")) +) +FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S = max( + 0.0, float(os.environ.get("FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S", "120")) +) +FLOW_SESSION_PROJECT_IDLE_S = max( + 300.0, float(os.environ.get("FLOW_SESSION_PROJECT_IDLE_S", "7200")) +) + # The tier no longer picks a model — aspect is its own slot and the model names # are fixed — so it is only carried for the DB column and the dashboard. DEFAULT_PAYGATE_TIER = os.environ.get("DEFAULT_PAYGATE_TIER", "PAYGATE_TIER_TWO") diff --git a/agent/main.py b/agent/main.py index 32bf03b3e..7299b4614 100644 --- a/agent/main.py +++ b/agent/main.py @@ -122,6 +122,31 @@ async def lifespan(app: FastAPI): allow_headers=["*"], ) +_GENERATION_PATHS = { + "/api/flow/generate-image", + "/api/flow/generate-video", + "/api/flow/generate-video-refs", + "/api/flow/generate-video-omni", + "/api/flow/generate-video-omni-text", + "/api/flow/edit-image", +} + + +@app.middleware("http") +async def flow_caller_observability(request: Request, call_next): + """Attribute generation submits without logging prompts, media or secrets.""" + response = await call_next(request) + if request.method == "POST" and request.url.path in _GENERATION_PATHS: + caller = (request.headers.get("x-flowkit-caller") or "unknown")[:80] + logger.info( + "Flow generation request caller=%s path=%s status=%s", + caller, + request.url.path, + response.status_code, + ) + return response + + app.include_router(characters_router, prefix="/api") app.include_router(projects_router, prefix="/api") app.include_router(videos_router, prefix="/api") diff --git a/agent/models/project.py b/agent/models/project.py index bf3a677fb..fdc6489fd 100644 --- a/agent/models/project.py +++ b/agent/models/project.py @@ -18,9 +18,8 @@ class ProjectCreate(BaseModel): language: str = "en" user_paygate_tier: PaygateTier = "PAYGATE_TIER_ONE" tool_name: str = "PINHOLE" - # Flow stopped letting clients create projects in the September 2026 - # migration, so a project is made once in the Flow UI and its uuid supplied - # here. Falls back to FLOW_PROJECT_ID when omitted. + # Optional explicit reuse. When omitted, FlowKit creates a fresh real Flow + # project through the current batchexecute endpoint. flow_project_id: Optional[str] = None material: str = Field("realistic", pattern=r"^[a-z0-9][a-z0-9_]{1,63}$") # material ID from GET /api/materials style: Optional[str] = None # deprecated: use material instead; "3D"→"3d_pixar", "photorealistic"→"realistic" diff --git a/agent/services/flow_batch.py b/agent/services/flow_batch.py index e2f41c00e..3b08ea0e0 100644 --- a/agent/services/flow_batch.py +++ b/agent/services/flow_batch.py @@ -40,6 +40,7 @@ RPC_GEN_VIDEO_FIRST_LAST = "nprQif" RPC_GEN_VIDEO_REFERENCES = "MZZa6b" RPC_OPERATION = "jwpduf" +RPC_CREATE_PROJECT = "jHPbke" RPC_PROJECT_MEDIA = "Zzl0ze" RPC_MEDIA = "as29s" RPC_UPLOAD_IMAGE = "maseQ" @@ -539,6 +540,22 @@ def upload_request(image_b64: str, project_id: str, mime_type: str = "image/jpeg ]) +def create_project_request(title: str) -> str: + """Create a current Flow project (captured from flow.google.com UI).""" + clean = " ".join(str(title or "FlowKit project").split())[:160] or "FlowKit project" + return build_envelope( + RPC_CREATE_PROJECT, + ["projects/*", [None, [clean]], [None, SURFACE_ID]], + ) + + +def read_created_project(payload: Any) -> tuple[str, str | None]: + if not isinstance(payload, list) or not payload or not isinstance(payload[0], str): + raise FlowBatchError("project create response did not contain a project id") + title = payload[1][0] if len(payload) > 1 and isinstance(payload[1], list) and payload[1] else None + return payload[0], title if isinstance(title, str) else None + + def operation_request(operation_id: str) -> str: return build_envelope(RPC_OPERATION, [None, None, [[operation_id]]]) diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index 92c1b003f..b4033677b 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -28,6 +28,8 @@ VIDEO_MODELS, FLOW_PROJECT_ID, FLOW_ALLOW_DEGRADED, DEFAULT_PAYGATE_TIER, + FLOW_GENERATION_MIN_INTERVAL_S, FLOW_GENERATION_MAX_CONCURRENT, + FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, ) from agent import config as _config from agent.services import flow_batch as fb @@ -64,6 +66,12 @@ def __init__(self): self._operation_projects: dict[str, str] = {} self._operation_media: dict[str, str] = {} self._operation_polls: dict[str, int] = {} + self._generation_slots = asyncio.Semaphore(FLOW_GENERATION_MAX_CONCURRENT) + self._generation_rate_gate = asyncio.Lock() + self._generation_last_submit_at = 0.0 + self._generation_unusual_until = 0.0 + self._generation_last_unusual_at: Optional[float] = None + self._generation_last_unusual_rpc: Optional[str] = None # WS stats self._ws_connect_count = 0 self._ws_disconnect_count = 0 @@ -196,6 +204,16 @@ def set_flow_key(self, key: str): def connected(self) -> bool: return bool(self._extensions) + @property + def generation_guard_status(self) -> dict: + remaining = max(0.0, self._generation_unusual_until - time.monotonic()) + return { + "cooldown_active": remaining > 0, + "cooldown_remaining_s": round(remaining, 3), + "last_unusual_activity_at": self._generation_last_unusual_at, + "last_unusual_activity_rpc": self._generation_last_unusual_rpc, + } + @property def ws_stats(self) -> dict: uptime = None @@ -490,17 +508,70 @@ async def batch_rpc(self, rpcid: str, freq: str, timeout: float = 300) -> dict: """Run one batchexecute RPC in the Flow page. Returns the raw body. - ``match`` asks the extension to cut the response down to an 800-byte - window around that string before handing it back. The project listing - is tens of megabytes for the one entry we want, and the cheapest place - to throw the rest away is inside the tab. + CAPTCHA-bearing image/video submits pass through one process-wide guard + so direct API callers cannot accidentally bypass the worker limiter. + Non-generation RPCs (polling/media/project metadata) remain unthrottled. """ params: dict = {"rpcid": rpcid, "freq": freq} if captcha_action: params["captchaAction"] = captcha_action if match: params["match"] = match - return await self._send("batch_rpc", params, timeout=timeout) + + is_generation = captcha_action in {fb.CAPTCHA_IMAGE, fb.CAPTCHA_VIDEO} + if not is_generation: + return await self._send("batch_rpc", params, timeout=timeout) + + now = time.monotonic() + if now < self._generation_unusual_until: + remaining = max(1, int(self._generation_unusual_until - now + 0.999)) + return { + "status": 429, + "error": ( + "PUBLIC_ERROR_UNUSUAL_ACTIVITY local cooldown active; " + f"retry in about {remaining}s" + ), + } + + await self._generation_slots.acquire() + try: + async with self._generation_rate_gate: + now = time.monotonic() + if now < self._generation_unusual_until: + remaining = max(1, int(self._generation_unusual_until - now + 0.999)) + return { + "status": 429, + "error": ( + "PUBLIC_ERROR_UNUSUAL_ACTIVITY local cooldown active; " + f"retry in about {remaining}s" + ), + } + delay = FLOW_GENERATION_MIN_INTERVAL_S - ( + now - self._generation_last_submit_at + ) + if delay > 0: + await asyncio.sleep(delay) + self._generation_last_submit_at = time.monotonic() + + result = await self._send("batch_rpc", params, timeout=timeout) + blob = f"{result.get('error', '')} {result.get('data', '')}" + if ( + "PUBLIC_ERROR_UNUSUAL_ACTIVITY" in blob + or "unusual activity" in blob.lower() + ): + self._generation_unusual_until = max( + self._generation_unusual_until, + time.monotonic() + FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, + ) + self._generation_last_unusual_at = time.time() + self._generation_last_unusual_rpc = rpcid + logger.warning( + "Google unusual-activity block detected; pausing generation submits for %.0fs", + FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, + ) + return result + finally: + self._generation_slots.release() async def _batch_payload(self, rpcid: str, freq: str, captcha_action: str | None = None, @@ -514,9 +585,10 @@ async def _batch_payload(self, rpcid: str, freq: str, def _batch_project_id(self, project_id: str) -> str: """The Flow project an RPC is scoped to. - Flow Kit stores the Flow project uuid as the local project id, but a - few call sites pass "0" or "" for project-less work; those fall back to - the pinned FLOW_PROJECT_ID. + Flow Kit stores the Flow project uuid as the local project id. Public + direct endpoints resolve project-less work through the persistent + session-project lease before reaching this lower-level helper. The + legacy FLOW_PROJECT_ID fallback remains for older internal callers. """ if project_id and self._UUID_RE.match(str(project_id)): return str(project_id) @@ -556,22 +628,28 @@ def _remember_operation(self, operation_id: str, project_id: str): # ─── High-level API Methods ────────────────────────────── def flow_project_id(self, requested: str | None = None) -> str | None: - """The Flow project to attach a new Flow Kit project to, if any. - - Project creation went with the labs.google tRPC endpoint the migration - unauthenticated, so on the batch path a project is made once in the - Flow UI and its uuid supplied here or pinned as FLOW_PROJECT_ID. - """ + """Validate an explicitly requested Flow project id.""" if requested and self._UUID_RE.match(requested): return requested - return FLOW_PROJECT_ID or None + return None async def create_project(self, project_title: str, tool_name: str = "PINHOLE") -> dict: - pid = self.flow_project_id() - if not pid: - return {"error": _UNSUPPORTED_CREATE_PROJECT} - logger.info("Reusing pinned Flow project %s for '%s'", pid[:12], project_title) - return {"status": 200, "data": {"projectId": pid}} + try: + result = await self.batch_rpc( + fb.RPC_CREATE_PROJECT, + fb.create_project_request(project_title), + timeout=60, + ) + if result.get("error"): + return {"status": result.get("status", 502), "error": result["error"]} + payload = fb.first_payload(result.get("data") or "", fb.RPC_CREATE_PROJECT) + pid, title = fb.read_created_project(payload) + if not self._UUID_RE.match(pid): + raise fb.FlowBatchError(f"invalid project id returned by Flow: {pid!r}") + logger.info("Flow project created: %s title=%r", pid, title or project_title) + return {"status": 200, "data": {"projectId": pid, "title": title or project_title}} + except Exception as exc: + return _batch_error(exc) async def generate_images(self, prompt: str, project_id: str, aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT", @@ -981,13 +1059,6 @@ async def upload_image(self, image_base64: str, mime_type: str = "image/jpeg", _CAPTURE_HINT = "see docs/CAPTURE.md to record its payload off the new UI" -_UNSUPPORTED_CREATE_PROJECT = ( - "NO_FLOW_PROJECT: Flow's project.createProject endpoint went with the September 2026 " - "migration, so Flow Kit cannot create one. Make a project in the Flow UI, then either " - "pass its uuid as flow_project_id or pin it as FLOW_PROJECT_ID." -) - - def _unsupported(feature: str, why: str) -> str: return f"UNSUPPORTED_ON_BATCH_API: {feature} — {why}; {_CAPTURE_HINT}." diff --git a/agent/services/flow_project_session.py b/agent/services/flow_project_session.py new file mode 100644 index 000000000..1432fa45a --- /dev/null +++ b/agent/services/flow_project_session.py @@ -0,0 +1,91 @@ +"""Persistent lease for ad-hoc Flow API work. + +Direct callers that do not own a durable Flow project share one project while +there is recent activity. The lease survives agent restarts and rotates after +the configured idle interval. +""" +from __future__ import annotations + +import asyncio +import json +import os +import re +import time +from datetime import datetime +from pathlib import Path + +from agent.config import BASE_DIR, FLOW_SESSION_PROJECT_IDLE_S + +_UUID_RE = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") +_STATE_PATH = Path( + os.environ.get( + "FLOW_SESSION_PROJECT_STATE", + str(BASE_DIR / "flow_session_project.json"), + ) +) +_lock = asyncio.Lock() + + +def _read_state() -> dict: + try: + value = json.loads(_STATE_PATH.read_text(encoding="utf-8")) + except Exception: + return {} + return value if isinstance(value, dict) else {} + + +def _write_state(state: dict) -> None: + _STATE_PATH.parent.mkdir(parents=True, exist_ok=True) + tmp = _STATE_PATH.with_suffix(_STATE_PATH.suffix + ".tmp") + tmp.write_text(json.dumps(state, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") + os.replace(tmp, _STATE_PATH) + + +def current_session_project() -> dict: + state = _read_state() + pid = str(state.get("project_id") or "") + last = float(state.get("last_activity_at") or 0) + age = max(0.0, time.time() - last) if last else None + active = bool(_UUID_RE.fullmatch(pid)) and age is not None and age <= FLOW_SESSION_PROJECT_IDLE_S + return { + "project_id": pid if _UUID_RE.fullmatch(pid) else None, + "title": state.get("title"), + "last_activity_at": last or None, + "idle_age_s": round(age, 3) if age is not None else None, + "idle_limit_s": FLOW_SESSION_PROJECT_IDLE_S, + "active": active, + } + + +def touch_session_project(project_id: str) -> None: + state = _read_state() + if state.get("project_id") != project_id: + return + state["last_activity_at"] = time.time() + _write_state(state) + + +async def ensure_session_project(client, *, title: str | None = None, force_new: bool = False) -> dict: + async with _lock: + state = current_session_project() + if not force_new and state.get("active") and state.get("project_id"): + touch_session_project(state["project_id"]) + return current_session_project() + + if not title: + title = "FlowKit session " + datetime.now().astimezone().strftime("%Y-%m-%d %H:%M") + result = await client.create_project(title) + if result.get("error"): + raise RuntimeError(result["error"]) + data = result.get("data") or {} + pid = str(data.get("projectId") or "") + if not _UUID_RE.fullmatch(pid): + raise RuntimeError("Flow did not return a valid project id") + state = { + "project_id": pid, + "title": str(data.get("title") or title), + "created_at": time.time(), + "last_activity_at": time.time(), + } + _write_state(state) + return current_session_project() diff --git a/skills/fk-create-project.md b/skills/fk-create-project.md index 1eacc340c..e140d33e4 100644 --- a/skills/fk-create-project.md +++ b/skills/fk-create-project.md @@ -104,28 +104,29 @@ Camera stays behind. Viewers see the leader's power through body language, not f | Military rank + origin | The Field Marshal, The Admiral | Military figures | | Generic role | The Royal Advisor, The Strategist | Secondary characters | -## Step 0: Make sure there is a Flow project to attach to +## Step 0: Project lifecycle -Since Flow moved to `flow.google.com`, Flow Kit cannot create Flow projects — -the endpoint that did it went with the migration. Every generation is scoped to -an existing one. +FlowKit can create real Flow projects through the current `jHPbke` +`batchexecute` RPC. `POST /api/projects` creates a fresh Flow project when +`flow_project_id` is omitted. Pass `flow_project_id` only when intentional +reuse of an existing Flow project is required. + +Ad-hoc `/api/flow/*` calls may omit `project_id`; FlowKit then uses a persistent +session project. The session survives agent restarts and rotates after 2 hours +of inactivity by default (`FLOW_SESSION_PROJECT_IDLE_S`). ```bash curl -s http://127.0.0.1:8100/api/flow/status | python3 -c " import sys, json s = json.load(sys.stdin) -print('Flow project:', s.get('flow_project_id') or 'NONE — create one in the Flow UI') +print('Session project:', s.get('session_project')) " ``` -If it prints NONE, ask the user to open `https://flow.google.com/`, create a -project, and copy the uuid out of the URL. Then either pin it -(`export FLOW_PROJECT_ID=<uuid>` before starting the agent) or pass it as -`flow_project_id` in Step 1. Without it every request fails `NO_FLOW_PROJECT`. - ## Step 1: Create project with all entities -Add `"flow_project_id": "<uuid>"` if you are not using the pinned one. +Omit `flow_project_id` for a fresh Flow project. Supply it only for deliberate +reuse of a known project. ```bash curl -X POST http://127.0.0.1:8100/api/projects \ diff --git a/skills/fk-doctor.md b/skills/fk-doctor.md index b5f3ccf20..54da6a3bb 100644 --- a/skills/fk-doctor.md +++ b/skills/fk-doctor.md @@ -138,7 +138,7 @@ Detection lives in `agent/worker/_parsing.py:_is_error`. A result is treated as | `NO_FLOW_TAB` | No Flow tab to sign the request | Extension opens one and retries once | Leave one signed-in Flow tab open; nothing here works headless | | `FLOW_TAB_DISCARDED` | Chrome discarded the backgrounded tab and the reload did not revive it | Retried with backoff | Pin the Flow tab, or keep its window visible | | `NO_INJECTION_RESULT` | `chrome.scripting.executeScript` resolved with no frame result (`background.js:540`), so the envelope never ran — the Flow tab went away or was still booting at the moment of the call. Most likely on the first captcha-bearing RPC after an agent restart | Retried with backoff, counts against `MAX_RETRIES` | Usually transient — retry first. Rule out the lookalikes before digging: a failed mint reports `CAPTCHA_FAILED`, an oversized payload is not it (`MAX_RPC_TEXT` is 32 MB), and a structured-clone failure surfaces as 500, not 502. If it repeats, pin the Flow tab and reload the extension | -| `NO_FLOW_PROJECT` | No Flow project to scope the RPC to | **Terminal — not retried** | Create a project in the Flow UI, pin its uuid as `FLOW_PROJECT_ID` (or pass `flow_project_id` on `POST /api/projects`) | +| `NO_FLOW_PROJECT` | A low-level caller reached batchexecute without a project id | **Terminal — not retried** | Use `POST /api/projects` to create a real Flow project, or call a public `/api/flow/*` endpoint without `project_id` so the session-project lease resolves one automatically | | `UNSUPPORTED_ON_BATCH_API` | A capability whose payload was never captured off the new UI, all on the Veo path: **video upscale**, **Veo r2v**, **Veo start+end-frame chaining**. Every Omni mode is ported, so this never names Omni any more | **Terminal — not retried** | For chaining and r2v, `FLOW_ALLOW_DEGRADED=1` falls back to plain i2v off the start frame. Upscale has no fallback. Real fix: capture the payload — `docs/CAPTURE.md` | | `PUBLIC_ERROR_UNUSUAL_ACTIVITY` | Google rejected the generation as unusual activity / reCAPTCHA risk evaluation | **Do not auto-retry** — repeated submits can prolong the block | Pause generation submits, keep the browser/session/network stable, and retry manually only after the trust signal has had time to recover | | `no ogiZ0b envelope in response` | The RPC answered but not with the payload we came for — usually a signed-out page returning an HTML redirect | Retried with backoff | Re-sign in on the Flow tab | diff --git a/tests/unit/test_flow_client_batch.py b/tests/unit/test_flow_client_batch.py index f91d61da0..688cd7444 100644 --- a/tests/unit/test_flow_client_batch.py +++ b/tests/unit/test_flow_client_batch.py @@ -442,16 +442,22 @@ async def test_upload_carries_a_captcha_like_a_generate(self, client): class TestProjectAndCredits: - async def test_create_project_hands_back_the_pinned_one(self, client): + async def test_create_project_uses_current_batch_rpc(self, client): + client.responses[fb.RPC_CREATE_PROJECT] = { + "data": envelope(fb.RPC_CREATE_PROJECT, [PROJECT, ["My Film"]]) + } result = await client.create_project("My Film") assert result["data"]["projectId"] == PROJECT - - async def test_create_project_without_a_pin_explains_itself(self, client, monkeypatch): - import agent.services.flow_client as module - monkeypatch.setattr(module, "FLOW_PROJECT_ID", "") - result = await client.create_project("My Film") - assert "NO_FLOW_PROJECT" in result["error"] - assert "FLOW_PROJECT_ID" in result["error"] + assert result["data"]["title"] == "My Film" + assert client.calls[0]["rpcid"] == fb.RPC_CREATE_PROJECT + outer = json.loads(client.calls[0]["freq"]) + inner = json.loads(outer[0][0][1]) + assert inner == ["projects/*", [None, ["My Film"]], [None, fb.SURFACE_ID]] + + async def test_flow_project_id_only_accepts_explicit_ids(self, client): + assert client.flow_project_id(PROJECT) == PROJECT + assert client.flow_project_id("") is None + assert client.flow_project_id("not-a-project") is None async def test_credits_answers_the_configured_tier_rather_than_guessing(self, client): result = await client.get_credits() diff --git a/tests/unit/test_flow_global_throttle.py b/tests/unit/test_flow_global_throttle.py new file mode 100644 index 000000000..9fed7740a --- /dev/null +++ b/tests/unit/test_flow_global_throttle.py @@ -0,0 +1,76 @@ +import asyncio + +import pytest + +from agent.services import flow_batch as fb +from agent.services import flow_client as fc + + +@pytest.mark.asyncio +async def test_generation_rpc_is_globally_serialized(monkeypatch): + monkeypatch.setattr(fc, "FLOW_GENERATION_MAX_CONCURRENT", 1) + monkeypatch.setattr(fc, "FLOW_GENERATION_MIN_INTERVAL_S", 0.0) + client = fc.FlowClient() + active = 0 + max_active = 0 + + async def fake_send(method, params, timeout=300): + nonlocal active, max_active + assert method == "batch_rpc" + active += 1 + max_active = max(max_active, active) + await asyncio.sleep(0.01) + active -= 1 + return {"status": 200, "data": "ok"} + + monkeypatch.setattr(client, "_send", fake_send) + await asyncio.gather( + client.batch_rpc("a", "x", captcha_action=fb.CAPTCHA_VIDEO), + client.batch_rpc("b", "y", captcha_action=fb.CAPTCHA_IMAGE), + ) + assert max_active == 1 + + +@pytest.mark.asyncio +async def test_unusual_activity_opens_local_circuit_breaker(monkeypatch): + monkeypatch.setattr(fc, "FLOW_GENERATION_MAX_CONCURRENT", 1) + monkeypatch.setattr(fc, "FLOW_GENERATION_MIN_INTERVAL_S", 0.0) + monkeypatch.setattr(fc, "FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S", 120.0) + client = fc.FlowClient() + calls = 0 + + async def fake_send(method, params, timeout=300): + nonlocal calls + calls += 1 + return { + "status": 200, + "data": "PUBLIC_ERROR_UNUSUAL_ACTIVITY reCAPTCHA evaluation failed", + } + + monkeypatch.setattr(client, "_send", fake_send) + first = await client.batch_rpc("a", "x", captcha_action=fb.CAPTCHA_VIDEO) + second = await client.batch_rpc("b", "y", captcha_action=fb.CAPTCHA_VIDEO) + + assert first["status"] == 200 + assert second["status"] == 429 + assert "local cooldown active" in second["error"] + assert calls == 1 + assert client.generation_guard_status["cooldown_active"] is True + assert client.generation_guard_status["last_unusual_activity_rpc"] == "a" + + +@pytest.mark.asyncio +async def test_non_generation_rpc_bypasses_generation_guard(monkeypatch): + client = fc.FlowClient() + client._generation_unusual_until = asyncio.get_running_loop().time() + 60 + calls = 0 + + async def fake_send(method, params, timeout=300): + nonlocal calls + calls += 1 + return {"status": 200, "data": "metadata"} + + monkeypatch.setattr(client, "_send", fake_send) + result = await client.batch_rpc("meta", "x") + assert result["status"] == 200 + assert calls == 1 diff --git a/tests/unit/test_flow_project_session.py b/tests/unit/test_flow_project_session.py new file mode 100644 index 000000000..38283130b --- /dev/null +++ b/tests/unit/test_flow_project_session.py @@ -0,0 +1,48 @@ +import time + +import pytest + +from agent.services import flow_project_session as fps + +PROJECT_A = "11111111-2222-3333-4444-555555555555" +PROJECT_B = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" + + +class FakeClient: + def __init__(self): + self.created = [] + + async def create_project(self, title): + self.created.append(title) + pid = PROJECT_A if len(self.created) == 1 else PROJECT_B + return {"status": 200, "data": {"projectId": pid, "title": title}} + + +@pytest.mark.asyncio +async def test_session_project_reuses_inside_idle_window(tmp_path, monkeypatch): + monkeypatch.setattr(fps, "_STATE_PATH", tmp_path / "lease.json") + monkeypatch.setattr(fps, "FLOW_SESSION_PROJECT_IDLE_S", 7200.0) + client = FakeClient() + + first = await fps.ensure_session_project(client, title="Session A") + second = await fps.ensure_session_project(client, title="Ignored") + + assert first["project_id"] == PROJECT_A + assert second["project_id"] == PROJECT_A + assert len(client.created) == 1 + + +@pytest.mark.asyncio +async def test_session_project_rotates_after_idle(tmp_path, monkeypatch): + monkeypatch.setattr(fps, "_STATE_PATH", tmp_path / "lease.json") + monkeypatch.setattr(fps, "FLOW_SESSION_PROJECT_IDLE_S", 10.0) + client = FakeClient() + + await fps.ensure_session_project(client, title="Session A") + state = fps._read_state() + state["last_activity_at"] = time.time() - 11 + fps._write_state(state) + + rotated = await fps.ensure_session_project(client, title="Session B") + assert rotated["project_id"] == PROJECT_B + assert len(client.created) == 2 From 3db71e6cf433a37bd2f22ecdbc5445010a648815 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Wed, 23 Sep 2026 16:37:30 +0300 Subject: [PATCH 32/68] fix(flow): sync Omni payloads with current UI --- agent/api/flow.py | 1 + agent/services/flow_batch.py | 33 ++++++++++++++++++++++------ agent/services/omni_flash.py | 13 +++++++++-- docs/CAPTURE.md | 9 ++++++++ tests/unit/test_flow_batch.py | 29 +++++++++++++++++++++++- tests/unit/test_flow_batch_golden.py | 4 ++-- 6 files changed, 77 insertions(+), 12 deletions(-) diff --git a/agent/api/flow.py b/agent/api/flow.py index 5f00b6f6e..d23f6fce9 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -77,6 +77,7 @@ class GenerateOmniFlashTextVideoRequest(BaseModel): project_id: str = "" scene_id: str = "" duration_s: int = 8 + resolution: Literal["360p", "720p"] = "720p" aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT" user_paygate_tier: str = "PAYGATE_TIER_ONE" diff --git a/agent/services/flow_batch.py b/agent/services/flow_batch.py index 3b08ea0e0..bf9db1d3b 100644 --- a/agent/services/flow_batch.py +++ b/agent/services/flow_batch.py @@ -132,9 +132,9 @@ #: Surface id the web client stamps on every call. Constant in every capture. SURFACE_ID = 22 -#: Crop box on the reference image, verbatim from the UI when nothing was -#: reframed by hand: a hair inside the edges, spanning 128/129 of the frame. -FULL_FRAME_CROP = [None, 0.0038759689922481244, 1, 0.9961240310077519] +#: Crop box on the reference image, verbatim from the current Flow UI when +#: nothing was reframed by hand (live-captured 2026-09-23). +FULL_FRAME_CROP = [None, None, 1, 1] #: Image inputs put the media id first and the input type four slots later. #: Type 1 is a reference; type 2 is the image being edited (BASE_IMAGE). @@ -511,19 +511,38 @@ def omni_reference_video_request(prompt: str, project_id: str, def text_video_request(prompt: str, project_id: str, aspect: Any = VIDEO_ASPECT_LANDSCAPE, - model: str = "abra_t2v_4s") -> str: - """Build the migrated text-to-video submit (YhhmEf).""" + model: str = "abra_t2v_4s", + resolution: str | None = None) -> str: + """Build the current text-to-video submit (YhhmEf). + + Flow encodes 360p in both the model key (``*_360p``) and the low-resolution + option slot. Current UI also uses client descriptor type 2 for video submits. + """ + resolved_model = str(model) + res = ( + "360p" if resolution is None and resolved_model.endswith("_360p") + else "720p" if resolution is None + else str(resolution).strip().lower() + ) + if res not in {"360p", "720p"}: + raise ValueError("Omni resolution must be 360p or 720p") + if res == "360p" and not resolved_model.endswith("_360p"): + resolved_model += "_360p" + if res == "720p" and resolved_model.endswith("_360p"): + resolved_model = resolved_model.removesuffix("_360p") request = [ [None, None, [[[prompt]]]], - model, + resolved_model, resolve_video_aspect(aspect), None, [None, None, None, None, _client_uuid(), _client_uuid()], ] + if res == "360p": + request.extend([None, None, [4]]) return build_envelope(RPC_GEN_VIDEO_TEXT, [ [request], _context(project_id), - [_client_uuid(), 1], + [_client_uuid(), 2], ]) diff --git a/agent/services/omni_flash.py b/agent/services/omni_flash.py index 21895f1dc..277a87364 100644 --- a/agent/services/omni_flash.py +++ b/agent/services/omni_flash.py @@ -174,18 +174,26 @@ async def generate_omni_flash_text_video( project_id: str, scene_id: str = "", duration_s: int = 8, + resolution: str = "720p", aspect_ratio: str = "VIDEO_ASPECT_RATIO_PORTRAIT", user_paygate_tier: str = "PAYGATE_TIER_ONE", seed: int | None = None, ) -> dict: """Submit Omni 1.1 Flash text-to-video on the migrated Flow batch API.""" _validate_duration(duration_s) + resolution = _validate_resolution(resolution) _validate_aspect(aspect_ratio) client = get_flow_client() try: pid = client._batch_project_id(project_id) - model_key = f"abra_t2v_{duration_s}s" - freq = fb.text_video_request(prompt, pid, aspect=aspect_ratio, model=model_key) + model_key = f"abra_t2v_{duration_s}s" + ("_360p" if resolution == "360p" else "") + freq = fb.text_video_request( + prompt, + pid, + aspect=aspect_ratio, + model=model_key, + resolution=resolution, + ) payload = await client._batch_payload( fb.RPC_GEN_VIDEO_TEXT, freq, fb.CAPTCHA_VIDEO, timeout=120) submitted = fb.read_text_video_submit(payload) @@ -205,6 +213,7 @@ async def generate_omni_flash_text_video( "workflows": [workflow], "model": model_key, "duration_s": duration_s, + "resolution": resolution, "flowkitPolling": { "mode": "batch_media", "project_id": pid, diff --git a/docs/CAPTURE.md b/docs/CAPTURE.md index 366e6169b..8680433d0 100644 --- a/docs/CAPTURE.md +++ b/docs/CAPTURE.md @@ -75,3 +75,12 @@ field name. **Slots do not share encodings.** Image aspect is 1 square / 2 portrait / 3 landscape / 4 is 3:4 / 5 is 4:3. Video aspect is 1 portrait / 2 landscape, in its own slot. Conflating them renders the wrong shape silently. + +## 2026-09-23 UI refresh notes + +A live `flow.google.com` capture showed two migrated Omni video details had changed from older fixtures: + +- default first-frame crop is now `[null, null, 1, 1]` when the user has not reframed the source; +- text-to-video 360p uses the `*_360p` model key, appends the low-resolution `[4]` option slot, and uses client descriptor type `2`. + +The same capture verified current first-frame `eb1hJf` structure and was followed by a successful direct FlowKit submit using that shape. Keep the golden fixtures aligned with these live-captured slots; do not restore the older near-edge crop or text-video descriptor `1` without a newer UI capture. diff --git a/tests/unit/test_flow_batch.py b/tests/unit/test_flow_batch.py index 2a0804593..98d72fd4c 100644 --- a/tests/unit/test_flow_batch.py +++ b/tests/unit/test_flow_batch.py @@ -204,9 +204,36 @@ def test_text_video_matches_the_captured_yhhmef_shape(self): assert request[3] is None assert len(request[4]) == 6 assert payload[1][5] == self.PID - assert payload[2][1] == 1 + assert payload[2][1] == 2 assert fb.CAPTCHA_SLOT in json.dumps(payload) + def test_text_video_360p_matches_current_ui_slots(self): + payload = inner(fb.text_video_request( + "a boat", + self.PID, + aspect="VIDEO_ASPECT_RATIO_LANDSCAPE", + model="abra_t2v_4s", + resolution="360p", + )) + request = payload[0][0] + assert request[1] == "abra_t2v_4s_360p" + assert request[-1] == [4] + assert payload[2][1] == 2 + + def test_first_frame_default_crop_matches_current_ui(self): + payload = inner(fb.omni_first_frame_request( + "move gently", + self.PID, + "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", + duration_s=4, + resolution="360p", + aspect="VIDEO_ASPECT_RATIO_LANDSCAPE", + )) + request = payload[0][0] + assert request[4][5] == [None, None, 1, 1] + assert request[-1] == [4] + assert payload[2][1] == 2 + class TestReaders: OP = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" diff --git a/tests/unit/test_flow_batch_golden.py b/tests/unit/test_flow_batch_golden.py index be4c0364b..5feb20fba 100644 --- a/tests/unit/test_flow_batch_golden.py +++ b/tests/unit/test_flow_batch_golden.py @@ -49,7 +49,7 @@ def pinned_uuids(monkeypatch): '[[["eb1hJf","[[[[null,null,[[[\\"a cat walks\\"]]]],' '\\"veo_3_1_i2v_lite_low_priority\\",1,null,[null,' '\\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\\",null,null,null,' - '[null,0.0038759689922481244,1,0.9961240310077519]],' + '[null,null,1,1]],' '[null,null,null,null,\\"00000000-0000-4000-8000-000000000001\\",' '\\"00000000-0000-4000-8000-000000000002\\"]]],[null,22,null,null,null,' '\\"11111111-2222-3333-4444-555555555555\\",null,null,null,null,' @@ -62,7 +62,7 @@ def pinned_uuids(monkeypatch): '[null,null,null,null,\\"00000000-0000-4000-8000-000000000001\\",' '\\"00000000-0000-4000-8000-000000000002\\"]]],[null,22,null,null,null,' '\\"11111111-2222-3333-4444-555555555555\\",null,null,null,null,' - '[\\"__CAPTCHA__\\",1]],[\\"00000000-0000-4000-8000-000000000003\\",1]]",' + '[\\"__CAPTCHA__\\",1]],[\\"00000000-0000-4000-8000-000000000003\\",2]]",' 'null,"generic"]]]' ) From a29c2e7c7b95e2b0ad0693437b1602b455d5be01 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Wed, 23 Sep 2026 18:05:22 +0300 Subject: [PATCH 33/68] feat(flow): add direct multipart image uploads --- README.md | 15 +++ agent/api/flow.py | 197 ++++++++++++++++++++++++--- requirements.txt | 1 + tests/unit/test_flow_upload_api.py | 206 +++++++++++++++++++++++++++++ 4 files changed, 399 insertions(+), 20 deletions(-) create mode 100644 tests/unit/test_flow_upload_api.py diff --git a/README.md b/README.md index 58e6a39b0..b9033f3ee 100644 --- a/README.md +++ b/README.md @@ -239,6 +239,21 @@ native 2K image export. Exact future Flow image model wire ids pass through without being silently replaced by the default model. See [`docs/IMAGE_API.md`](docs/IMAGE_API.md). +### Upload images from API callers + +External callers should upload bytes instead of passing caller-local filesystem paths. The recommended direct-file endpoint is multipart: + +```bash +curl -X POST http://127.0.0.1:8100/api/flow/upload-image-file \ + -F 'file=@./source.jpg;type=image/jpeg' +``` + +JSON-only clients can use `POST /api/flow/upload-image` with `image_base64`. Base64 costs roughly 33% more request bytes than multipart, but avoids filesystem visibility problems. + +`file_path` remains a server-local convenience mode only. The path is opened by the FlowKit service user, so it must be readable and visible inside that service's namespace. In systemd deployments with `PrivateTmp=yes`, a caller's `/tmp/...` is not the same `/tmp` seen by FlowKit. Permission failures return 403; paths invisible in the service namespace return a descriptive 404. + +When `project_id` is omitted on the maintained session-project path, the upload uses/creates the current Flow session project. + ### What does not work on the new API yet Three capabilities have no captured payload, so they fail with diff --git a/agent/api/flow.py b/agent/api/flow.py index d23f6fce9..f2472a7b4 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -1,5 +1,8 @@ """Direct Flow API endpoints — for manual operations outside the queue.""" -from fastapi import APIRouter, HTTPException, Response +import base64 +import mimetypes + +from fastapi import APIRouter, File, Form, HTTPException, Response, UploadFile from pydantic import BaseModel, Field from typing import Literal, Optional @@ -90,9 +93,30 @@ class UpscaleVideoRequest(BaseModel): class UploadImageRequest(BaseModel): - file_path: str # absolute path to local image file - project_id: str = "" - file_name: str = "image.png" + image_base64: Optional[str] = Field( + default=None, + description=( + "Recommended for external/API callers. Base64-encoded image bytes; " + "avoids filesystem namespace and permission issues." + ), + ) + file_path: Optional[str] = Field( + default=None, + description=( + "Server-local convenience mode only. The path is opened by the FlowKit " + "service user and must be visible/readable inside its systemd namespace. " + "Caller-local /tmp and protected home paths may not be accessible." + ), + ) + mime_type: Optional[str] = Field( + default=None, + description="Optional MIME override; otherwise inferred from file_name/file_path.", + ) + project_id: str = Field( + default="", + description="Existing Flow project id, or empty to use/create the session project.", + ) + file_name: str = Field(default="image.png", description="Filename sent to Google Flow.") class CheckStatusRequest(BaseModel): @@ -484,23 +508,156 @@ async def export_image(body: UpscaleImageRequest): ) -@router.post("/upload-image") +async def _upload_image_bytes( + client, + image_bytes: bytes, + *, + project_id: str, + mime_type: str, + file_name: str, +) -> dict: + """Upload bytes through the shared Flow path and return the public response.""" + if not image_bytes: + raise HTTPException(422, "image payload is empty") + resolved_project_id = await _resolve_direct_project(client, project_id) + b64 = base64.b64encode(image_bytes).decode() + result = await client.upload_image( + b64, + mime_type=mime_type, + project_id=resolved_project_id, + file_name=file_name, + ) + if result.get("error") or ( + isinstance(result.get("status"), int) and result["status"] >= 400 + ): + raise HTTPException( + result.get("status", 502), + result.get("error", result.get("data")), + ) + media_id = result.get("_mediaId") + return { + "media_id": media_id, + "project_id": resolved_project_id, + "raw": result.get("data", result), + } + + +def _read_server_local_image(file_path: str) -> bytes: + """Read a path from FlowKit's own service namespace with useful API errors.""" + try: + with open(file_path, "rb") as f: + return f.read() + except FileNotFoundError as exc: + raise HTTPException( + 404, + ( + "Server-local file is not visible to the FlowKit service: " + f"{file_path}. External callers should use image_base64 or " + "/api/flow/upload-image-file; caller-local /tmp paths may be hidden " + "by systemd PrivateTmp." + ), + ) from exc + except PermissionError as exc: + raise HTTPException( + 403, + ( + "File is not readable by FlowKit service: " + f"{file_path}. The path must be readable by the service user; " + "external callers should use image_base64 or /api/flow/upload-image-file." + ), + ) from exc + except IsADirectoryError as exc: + raise HTTPException(422, f"file_path is a directory, not an image file: {file_path}") from exc + except OSError as exc: + raise HTTPException(422, f"Could not read server-local file {file_path}: {exc}") from exc + + +@router.post( + "/upload-image", + summary="Upload image bytes or a server-local image", + description=( + "JSON upload endpoint. External/API callers should send image_base64. " + "file_path is a server-local convenience mode only: the path is opened by " + "the FlowKit service user and must be visible inside its systemd namespace." + ), +) async def upload_image(body: UploadImageRequest): - """Upload a local image file to Google Flow and get a media_id.""" - import base64, mimetypes + """Upload image bytes to Google Flow; prefer image_base64 for external callers.""" client = get_flow_client() if not client.connected: raise HTTPException(503, "Extension not connected") - project_id = await _resolve_direct_project(client, body.project_id) - try: - with open(body.file_path, "rb") as f: - image_bytes = f.read() - except FileNotFoundError: - raise HTTPException(404, f"File not found: {body.file_path}") - b64 = base64.b64encode(image_bytes).decode() - mime = mimetypes.guess_type(body.file_path)[0] or "image/png" - result = await client.upload_image(b64, mime_type=mime, project_id=project_id, file_name=body.file_name) - if result.get("error") or (isinstance(result.get("status"), int) and result["status"] >= 400): - raise HTTPException(result.get("status", 502), result.get("error", result.get("data"))) - media_id = result.get("_mediaId") - return {"media_id": media_id, "raw": result.get("data", result)} + if body.image_base64: + try: + image_bytes = base64.b64decode(body.image_base64, validate=True) + except Exception as exc: + raise HTTPException(422, "image_base64 is not valid base64") from exc + if not image_bytes: + raise HTTPException(422, "image_base64 is empty") + mime = body.mime_type or mimetypes.guess_type(body.file_name)[0] or "image/png" + elif body.file_path: + image_bytes = _read_server_local_image(body.file_path) + if not image_bytes: + raise HTTPException(422, f"Server-local image is empty: {body.file_path}") + mime = body.mime_type or mimetypes.guess_type(body.file_path)[0] or "image/png" + else: + raise HTTPException( + 422, + "image_base64 is recommended; alternatively provide server-local file_path", + ) + + return await _upload_image_bytes( + client, + image_bytes, + project_id=body.project_id, + mime_type=mime, + file_name=body.file_name, + ) + + +@router.post( + "/upload-image-file", + summary="Upload an image file with multipart/form-data", + description=( + "Recommended direct-file endpoint for external callers. The uploaded bytes are " + "read from the HTTP request, so the caller does not need to share a filesystem " + "namespace with the FlowKit service. Leave project_id empty to use/create the " + "session project." + ), +) +async def upload_image_file( + file: UploadFile = File(..., description="Image file bytes from the caller."), + project_id: str = Form( + default="", + description="Existing Flow project id, or empty to use/create the session project.", + ), + file_name: Optional[str] = Form( + default=None, + description="Optional filename override sent to Google Flow.", + ), + mime_type: Optional[str] = Form( + default=None, + description="Optional MIME override; defaults to upload Content-Type or filename inference.", + ), +): + """Upload a multipart file without requiring server-local filesystem access.""" + client = get_flow_client() + if not client.connected: + raise HTTPException(503, "Extension not connected") + + image_bytes = await file.read() + if not image_bytes: + raise HTTPException(422, "uploaded image file is empty") + resolved_name = file_name or file.filename or "image.png" + resolved_mime = ( + mime_type + or file.content_type + or mimetypes.guess_type(resolved_name)[0] + or "image/png" + ) + return await _upload_image_bytes( + client, + image_bytes, + project_id=project_id, + mime_type=resolved_mime, + file_name=resolved_name, + ) diff --git a/requirements.txt b/requirements.txt index c2cd265b7..be00c9dbd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ pydantic>=2.5.0 aiohttp>=3.9.0 httpx>=0.25.0 anthropic>=0.40.0 +python-multipart>=0.0.9 diff --git a/tests/unit/test_flow_upload_api.py b/tests/unit/test_flow_upload_api.py new file mode 100644 index 000000000..29918d2ed --- /dev/null +++ b/tests/unit/test_flow_upload_api.py @@ -0,0 +1,206 @@ +import base64 +import builtins +import io + +import httpx +import pytest +from fastapi import FastAPI, HTTPException +from starlette.datastructures import Headers, UploadFile + +from agent.api import flow as flow_api + + +PROJECT = "11111111-2222-3333-4444-555555555555" +SESSION_PROJECT = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" +MEDIA = "99999999-8888-7777-6666-555555555555" +IMAGE = b"\x89PNG\r\n\x1a\nflowkit-test-image" + + +class FakeFlowClient: + connected = True + + def __init__(self): + self.uploads = [] + + async def upload_image(self, image_base64, mime_type="image/jpeg", project_id="", file_name="image.jpg"): + self.uploads.append( + { + "bytes": base64.b64decode(image_base64), + "mime_type": mime_type, + "project_id": project_id, + "file_name": file_name, + } + ) + return { + "status": 200, + "data": {"media": {"name": MEDIA}}, + "_mediaId": MEDIA, + } + + +@pytest.mark.asyncio +async def test_base64_upload_is_direct_bytes_path(monkeypatch): + client = FakeFlowClient() + monkeypatch.setattr(flow_api, "get_flow_client", lambda: client) + + result = await flow_api.upload_image( + flow_api.UploadImageRequest( + image_base64=base64.b64encode(IMAGE).decode(), + mime_type="image/png", + file_name="source.png", + project_id=PROJECT, + ) + ) + + assert result["media_id"] == MEDIA + assert result["project_id"] == PROJECT + assert client.uploads == [ + { + "bytes": IMAGE, + "mime_type": "image/png", + "project_id": PROJECT, + "file_name": "source.png", + } + ] + + +@pytest.mark.asyncio +async def test_unreadable_server_local_path_returns_403(monkeypatch): + client = FakeFlowClient() + monkeypatch.setattr(flow_api, "get_flow_client", lambda: client) + + def deny_open(*args, **kwargs): + raise PermissionError("permission denied") + + monkeypatch.setattr(builtins, "open", deny_open) + + with pytest.raises(HTTPException) as excinfo: + await flow_api.upload_image( + flow_api.UploadImageRequest(file_path="/root/private/source.jpg", project_id=PROJECT) + ) + + assert excinfo.value.status_code == 403 + assert "not readable by FlowKit service" in excinfo.value.detail + assert client.uploads == [] + + +@pytest.mark.asyncio +async def test_private_tmp_like_invisible_path_returns_descriptive_404(monkeypatch): + client = FakeFlowClient() + monkeypatch.setattr(flow_api, "get_flow_client", lambda: client) + + def missing_open(*args, **kwargs): + raise FileNotFoundError("not in service namespace") + + monkeypatch.setattr(builtins, "open", missing_open) + + with pytest.raises(HTTPException) as excinfo: + await flow_api.upload_image( + flow_api.UploadImageRequest(file_path="/tmp/caller-only/source.jpg", project_id=PROJECT) + ) + + assert excinfo.value.status_code == 404 + assert "not visible to the FlowKit service" in excinfo.value.detail + assert "PrivateTmp" in excinfo.value.detail + assert "/api/flow/upload-image-file" in excinfo.value.detail + assert client.uploads == [] + + +@pytest.mark.asyncio +async def test_session_project_auto_creation_then_base64_upload(monkeypatch): + client = FakeFlowClient() + monkeypatch.setattr(flow_api, "get_flow_client", lambda: client) + calls = [] + + async def fake_ensure_session_project(received_client): + calls.append(received_client) + return {"project_id": SESSION_PROJECT} + + monkeypatch.setattr(flow_api, "ensure_session_project", fake_ensure_session_project) + + result = await flow_api.upload_image( + flow_api.UploadImageRequest( + image_base64=base64.b64encode(IMAGE).decode(), + file_name="auto.png", + ) + ) + + assert calls == [client] + assert result["project_id"] == SESSION_PROJECT + assert client.uploads[0]["project_id"] == SESSION_PROJECT + + +@pytest.mark.asyncio +async def test_multipart_upload_uses_request_bytes_and_session_project(monkeypatch): + client = FakeFlowClient() + monkeypatch.setattr(flow_api, "get_flow_client", lambda: client) + + async def fake_ensure_session_project(received_client): + assert received_client is client + return {"project_id": SESSION_PROJECT} + + monkeypatch.setattr(flow_api, "ensure_session_project", fake_ensure_session_project) + upload = UploadFile( + file=io.BytesIO(IMAGE), + filename="caller.jpg", + headers=Headers({"content-type": "image/jpeg"}), + ) + + result = await flow_api.upload_image_file( + file=upload, + project_id="", + file_name=None, + mime_type=None, + ) + + assert result["project_id"] == SESSION_PROJECT + assert client.uploads == [ + { + "bytes": IMAGE, + "mime_type": "image/jpeg", + "project_id": SESSION_PROJECT, + "file_name": "caller.jpg", + } + ] + + +def test_openapi_distinguishes_json_base64_and_multipart_uploads(): + app = FastAPI() + app.include_router(flow_api.router, prefix="/api") + schema = app.openapi() + + json_upload = schema["paths"]["/api/flow/upload-image"]["post"] + multipart_upload = schema["paths"]["/api/flow/upload-image-file"]["post"] + request_schema = schema["components"]["schemas"]["UploadImageRequest"]["properties"] + + assert "application/json" in json_upload["requestBody"]["content"] + assert "multipart/form-data" in multipart_upload["requestBody"]["content"] + assert "Recommended for external/API callers" in request_schema["image_base64"]["description"] + assert "Server-local convenience mode only" in request_schema["file_path"]["description"] + + +@pytest.mark.asyncio +async def test_multipart_route_parses_real_form_data(monkeypatch): + client = FakeFlowClient() + monkeypatch.setattr(flow_api, "get_flow_client", lambda: client) + + async def fake_ensure_session_project(received_client): + assert received_client is client + return {"project_id": SESSION_PROJECT} + + monkeypatch.setattr(flow_api, "ensure_session_project", fake_ensure_session_project) + app = FastAPI() + app.include_router(flow_api.router, prefix="/api") + transport = httpx.ASGITransport(app=app) + + async with httpx.AsyncClient(transport=transport, base_url="http://testserver") as http: + response = await http.post( + "/api/flow/upload-image-file", + files={"file": ("browser.png", IMAGE, "image/png")}, + ) + + assert response.status_code == 200 + assert response.json()["project_id"] == SESSION_PROJECT + assert client.uploads[0]["bytes"] == IMAGE + assert client.uploads[0]["file_name"] == "browser.png" + assert client.uploads[0]["mime_type"] == "image/png" From 1eae10b0aff0f6b4dd879b8dea29294cbca232a7 Mon Sep 17 00:00:00 2001 From: Matro Nguyen <matronguyen81@gmail.com> Date: Thu, 24 Sep 2026 10:27:00 +0700 Subject: [PATCH 34/68] fix(extension): mint reCAPTCHA via hidden widget + preload grecaptcha bundles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 2026-09-22 frontend build (boq_labs-ai-sandbox-frontend_20260922.00_p0) started rejecting tokens obtained by calling grecaptcha.enterprise.execute(SITE_KEY, {action}) directly — every generate RPC answers PUBLIC_ERROR_UNUSUAL_ACTIVITY, while clicking Generate in the Flow UI still works. Sitekey, action, payload and headers were verified byte-for-byte identical to the UI, so the constraint moved into the mint mechanism itself. Fix ported from FlowBridge2's mint, which passes on the same build (A/B tested with the same account/project, 2026-09-24): - resolveSitekey(): read the real sitekey off ___grecaptcha_cfg (fallback to the hardcoded one) - grecaptcha.enterprise.ready() -> render an invisible widget in a hidden div -> execute(widgetId, {action}) with retry, mint serialized - content.js now preloads recaptcha_enterprise.js + recaptcha__en.js (bundled from the reCAPTCHA CDN) into the MAIN world: flow.google.com no longer ships grecaptcha at page load and its Trusted-Types CSP blocks <script src=google.com/...>, so the only exible route is the extension's own chrome-extension:// URL - cache-buster ?v=<manifest.version> on all injected scripts (Chrome has been observed to reuse a stale injected.js after reload otherwise) - bump extension to 0.3.4, add both bundles to web_accessible_resources Verified end to end: direct generate (ogiZ0b) COMPLETED + image bytes served from flow-content.google; the full pipeline (POST /api/requests -> worker queue -> generate -> media_id/url persisted) COMPLETED. Rejection before the fix was 100% reproducible on three independent requests. Refs #58 --- extension/content.js | 28 +- extension/injected.js | 83 +- extension/manifest.json | 6 +- extension/recaptcha__en.js | 1693 +++++++++++++++++++++++++++++ extension/recaptcha_enterprise.js | 1 + 5 files changed, 1802 insertions(+), 9 deletions(-) create mode 100644 extension/recaptcha__en.js create mode 100644 extension/recaptcha_enterprise.js diff --git a/extension/content.js b/extension/content.js index b3ff64d36..ec9c2c1b5 100644 --- a/extension/content.js +++ b/extension/content.js @@ -1,12 +1,32 @@ /** * Content script — bridge between background.js and injected.js * Injects injected.js into MAIN world to access window.grecaptcha + * + * reCAPTCHA preload (ported from FlowBridge2): flow.google.com enforces + * `require-trusted-types-for 'script'` with a policy that rejects google.com + * URLs, and it no longer ships grecaptcha in the MAIN world at page load — a + * plain <script src="https://www.google.com/recaptcha/enterprise.js"> tag is + * blocked and the lazy wait then times out with `grecaptcha not available`. + * Scripts fetched from the extension's own chrome-extension:// URL bypass the + * page CSP entirely, so we ship enterprise.js + its real client locally and + * feed them in right after the anchor evaluates. */ (function () { - const s = document.createElement('script'); - s.src = chrome.runtime.getURL('injected.js'); - s.onload = () => s.remove(); - (document.head || document.documentElement).appendChild(s); + function addExtScript(name) { + const s = document.createElement('script'); + // Cache-buster: Chrome may serve a stale injected.js out of its + // chrome-extension:// resource cache after an extension reload. + s.src = chrome.runtime.getURL(name) + '?v=' + chrome.runtime.getManifest().version; + s.onload = () => s.remove(); + s.setAttribute('data-flowkit', name); + (document.head || document.documentElement).appendChild(s); + } + + addExtScript('injected.js'); + // The anchor sets ___grecaptcha_cfg stubs; its own gstatic append is + // CSP-blocked, so the real client (bundled locally) follows. + addExtScript('recaptcha_enterprise.js'); + setTimeout(() => addExtScript('recaptcha__en.js'), 50); })(); chrome.runtime.onMessage.addListener((msg, _, reply) => { diff --git a/extension/injected.js b/extension/injected.js index a955a5f82..1ae4ec7fd 100644 --- a/extension/injected.js +++ b/extension/injected.js @@ -36,6 +36,85 @@ window.fetch = async function (...args) { let captchaMintTail = Promise.resolve(); +// ─── reCAPTCHA mint (ported from FlowBridge2 — live-verified on the 2026-09-22 build) ─── +// Flow's current build rejects a token obtained by calling +// `grecaptcha.enterprise.execute(SITE_KEY, {action})` directly with +// PUBLIC_ERROR_UNUSUAL_ACTIVITY ("reCAPTCHA evaluation failed"), even though the +// site key and action match the UI byte for byte, while the same account's UI +// still generates. The working recipe is the one the page itself uses: ready() → +// render an invisible widget bound to the page's own site key → execute(widgetId). +// Prefer the site key the page is currently configured with; the constant is only +// a fallback for a page that has not configured one yet. +function resolveSitekey() { + try { + const cfg = window.___grecaptcha_cfg || {}; + const clients = cfg.clients || {}; + for (const k of Object.keys(clients)) { + const c = clients[k]; + if (c && c.sitekey) return c.sitekey; + } + } catch (e) { /* fall through to the constant */ } + return SITE_KEY; +} + +function waitReady(timeout = 5000) { + return new Promise((resolve) => { + let done = false; + const fin = () => { if (!done) { done = true; resolve(); } }; + try { window.grecaptcha?.enterprise?.ready?.(fin); } catch (e) { /* ignore */ } + setTimeout(fin, timeout); + }); +} + +let _widgetPromise = null; +function ensureWidget(sitekey) { + if (_widgetPromise) return _widgetPromise; + _widgetPromise = (async () => { + await waitReady(5000); + let host = document.getElementById('flowkit-recaptcha-host'); + if (!host) { + host = document.createElement('div'); + host.id = 'flowkit-recaptcha-host'; + host.style.cssText = 'position:fixed;left:-9999px;top:0;width:1px;height:1px;'; + document.documentElement.appendChild(host); + } + return await new Promise((resolve, reject) => { + try { + const widgetId = window.grecaptcha.enterprise.render(host, { + sitekey, + size: 'invisible', + callback: () => {}, + 'error-callback': (m) => reject(new Error('render_error: ' + m)), + }); + resolve(widgetId); + } catch (e) { + reject(new Error('render_threw: ' + (e && e.message || e))); + } + }); + })().catch((e) => { _widgetPromise = null; throw e; }); + return _widgetPromise; +} + +async function executeWithRetry(sitekey, action, attempts = 2) { + let lastErr = null; + for (let i = 0; i < attempts; i++) { + try { + await waitReady(2500); + const widgetId = await ensureWidget(sitekey); + const token = await Promise.race([ + window.grecaptcha.enterprise.execute(widgetId, { action }), + new Promise((_, rej) => setTimeout(() => rej(new Error('execute_hang')), 8000)), + ]); + if (token) return String(token); + lastErr = new Error('empty_token'); + } catch (e) { + lastErr = e; + } + await new Promise((r) => setTimeout(r, 600)); + } + throw lastErr || new Error('execute_failed'); +} + async function mintCaptcha(pageAction) { const previous = captchaMintTail.catch(() => {}); let release; @@ -43,9 +122,7 @@ async function mintCaptcha(pageAction) { await previous; try { await waitForGrecaptcha(); - return await window.grecaptcha.enterprise.execute(SITE_KEY, { - action: pageAction, - }); + return await executeWithRetry(resolveSitekey(), pageAction); } finally { release(); } diff --git a/extension/manifest.json b/extension/manifest.json index 78eebc2d8..13c168b2c 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Flow Kit", - "version": "0.3.2", + "version": "0.3.4", "description": "Local agent bridge for Google Flow \u2014 runs batchexecute RPCs inside a signed-in flow.google.com tab, mints reCAPTCHA, proxies API calls", "permissions": [ "storage", @@ -38,7 +38,9 @@ "web_accessible_resources": [ { "resources": [ - "injected.js" + "injected.js", + "recaptcha_enterprise.js", + "recaptcha__en.js" ], "matches": [ "https://flow.google.com/*", diff --git a/extension/recaptcha__en.js b/extension/recaptcha__en.js new file mode 100644 index 000000000..6feb18e05 --- /dev/null +++ b/extension/recaptcha__en.js @@ -0,0 +1,1693 @@ +(function(){/* + + Copyright The Closure Library Authors. + SPDX-License-Identifier: Apache-2.0 +*/ +/* + + Copyright Google LLC + SPDX-License-Identifier: Apache-2.0 +*/ +/* + Copyright The Closure Library Authors. + SPDX-License-Identifier: Apache-2.0 +*/ +/* + + + Copyright (c) 2015-2018 Google, Inc., Netflix, Inc., Microsoft Corp. and contributors + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + + Copyright 2005, 2007 Bob Ippolito. All Rights Reserved. + Copyright The Closure Library Authors. + SPDX-License-Identifier: MIT +*/ +/* + + Copyright 2018 Google Inc + SPDX-License-Identifier: Apache-2.0 +*/ +/* + + Copyright (c) 2013-2016 Dmitry Chestnykh. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +var f=function(){return[function(N,C,e,L,h,Q,m,O,t,D,q,u){if((N-9|36)>=((u=[34,939,1],(N+u[2]^14)>=N)&&(N-5^11)<N&&(m=[3,2,0],Q=new N4,t=U[4](u[0],3610)(23,45,40,24,m[0]),D=K[45](14,9,CB.get()),y[33](u[2],K[16](24),function(B,G,c,A,n,R,F,Z,X,Y,k,E){for(k=(E=[4,66,56],E)[1];k!=93;)if(k==8)k=D&&v[12](71,n[0],D)?26:31;else if(k==25)k=U[E[0]](34,7264)(B.name+B.id+(B.getAttribute(t[E[0]]())||""),t[0](),ep())?76:E[2];else{if(k==31)return!0;if(k==49)X=Z().length,I[22](27,n[0],Q,l[36].bind(null,74),T[45].bind(null, +E[0]),n[0],X),k=8;else{if(k==E[2])return!1;k==E[1]?(n=[2,null,7],k=25):k==76?(Z=U[E[0]](18,8360)(U[E[0]](26,8529)(B).replace(/\s/g,"")),k=6):k==6?k=Z()&&Z().length>E[0]?49:E[2]:k==26&&(c=v[12](70,n[0],D),A=Z().substr(0,QE[1])+Z().substr(Z().length-QE[0]),R=T[7](10).call(parseFloat(c+A)+c,30),P[0](78,Q,R,5),Y=((F=B.parentElement)==n[1]?0:(G=F.lastChild)==n[1]?0:G.src)?B.parentElement.lastChild.className:"",P[0](76,Q,Y,n[2]),k=31)}}}),h=U[4](u[0],3042)(L(f[38](86),41).slice(m[2],5E4)),O=U[4](18,u[1])(U[4](2, +9376)(h(),t[m[0]](),ep()).replace(/\D/g,"").slice(-4)),O()&&D&&v[12](65,m[u[2]],D)&&S[49](45,6,Q,f[0](5,35,m[2],v[12](69,m[u[2]],D),O)),q=W[43](24,4,I[32](13,m[0],U[4](u[0],9481)(h(),t[m[u[2]]]()+t[u[2]](),ep(),10),Q),U[4](18,1962)(h(),t[u[2]]())).G2()),N)&&(N-9^6)<N)a:{for(e=C;e<window[Bh][jp()];e++)if(f[38](85).contains(window[Bh][GN()][e].kU)){q=e;break a}throw Error(ch());}return(N+9^21)>=N&&N+u[2]>>u[2]<N&&(Q=h().substr(e,QE[e]),q=T[7](8).call(parseFloat(L+Q-L)^L,C)),q},function(N,C,e,L,h,Q, +m,O,t){return(N+(((N|7)>>(t=["call",120,9],4)||(h="",P[20](6,L,function(D,q){h+=q,h+=e,h+=D,h+=C}),O=h),(N&t[1])==N&&(yE[t[0]](this),this.o=C!==void 0?C:1,this.K=Q!==void 0?vh(0,Q):0,this.P=!!m,this.B=new I6(e,L,h,m),this.i=new lr,this.G=new TN(this)),N)-3&14||(y[42](5,C.i),f[6](63,C.i),y[42](3,C.i),O=C.UC()),t)[2]&62)>=N&&(N+7^t[2])<N&&(L&&!e.o&&(f[28](46,null,e),e.G=C,e.i.forEach(function(D,q,u,B){q!=(B=[30,(u=q.toLowerCase(),null),"remove"],u)&&(this[B[2]](q),H[B[0]](3,0,B[1],this,D,u))},e)),e.o= +L),O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R){if(((N>>(A=[6,43,0],1)&11)==2&&(n=function(F,Z){F!=e&&(Array.isArray(F)?F.forEach(function(X){return n(X,Z)}):(O+=D+encodeURIComponent(Z)+C+encodeURIComponent(F),D=L))},D=O.length?"&":"?",t.constructor===Object&&(t=Object.entries(t)),Array.isArray(t)?t.forEach(function(F){return n(F[h],F[0])}):t.forEach(n),R=y[5](17,e,m+O+Q)),N|72)==N){if(Q=(h=Zf[Wh()]||Zf[Hh()],h[e]),!Q)throw Error(e+" not on global?");(h[e]=function(F,Z){var X=["apply",!1,!0]; +if((typeof F==="string"&&(F=kW(v[11].bind(null,4),F)),F)&&(arguments[0]=F=U[1](1,X[1],X[2],F,L)),Q[X[0]])return Q[X[0]](this,arguments);var Y=F;if(arguments.length>C)var k=Array.prototype.slice.call(arguments,(Y=function(){F.apply(this,k)},C));return Q(Y,Z)},h)[e][K[44](55,"__",L,!1)]=Q}if(N-8<<1<N&&N-A[0]<<2>=N){G=(Q=(t=new r8,P[4](12,h.S)),Q).next();try{for(;!G.done;G=Q.next())m=P[4](12,G.value),c=m.next().value,O=m.next().value,D=new pB,q=K[23](1,C,c,D),B=K[23](17,e,O,q),v[A[2]](81,L,B,pB,t)}finally{G&& +!G.done&&(u=Q.return)&&u.call(Q)}R=t}return(N-7|A[1])<N&&(N-8|65)>=N&&(R="https://play.google.com/log?format=json&hasfast=true"),R},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){if((N&51)==(Z=[71,2,"createDocumentFragment"],N))a:{if(m=(G=(R=(O=S[48].bind(null,Z[0]),R===void 0?!1:R),W)[46](3,L),t=O(Q||JA,void 0))&&t.Ty?t.Ty():null){F=m;break a}if(c=U[40](1,C,t),R){F=((D=S[11](64,null,G),K)[41](11,e,D,c),n=H[0](Z[0],"",D),n).childNodes.length===1?n.removeChild(n.firstChild):n;break a}if((K[41](7, +e,(u=y[41]((q=G.i,15),q,EC),u),c),u.childNodes.length)==h)A=u.removeChild(u.firstChild);else{for(B=q[Z[2]]();u.firstChild;)B.appendChild(u.firstChild);A=B}F=A}return(N>>1&11)==Z[1]&&(e=H[Z[1]](24,C),H[Z[1]](68,C)===0&&H[23](6,3,e,C)),N<<1>=24&&N+Z[1]<38&&p.call(this,C),F},function(N,C,e,L,h,Q,m,O){return((((N^(m=["X",1,"u"],5))>>4||(h=T[46](2,0,3,e,L),O=T[16](29,C,w8,h)),(N&93)==N&&(xW.call(this,a6,C),this.size=e),N)+6&58)>=N&&(N+2^19)<N&&(this.o=e,Q=[null,!1,45E3],this.G=L,this.K=h,this.O=C||m[1], +this.j_=new TN(this),this[m[0]]=0,this.l=Q[0],this.Y=[],this.h=Q[0],this.j=Q[0],this.iI=Q[0],this.A=Q[0],this.W=-1,this.F=Q[m[1]],this.Z=Q[0],this.J=Q[0],this.P=Q[m[1]],this.I=Q[m[1]],this.S=Q[0],this.rq=Q[m[1]],this.VM=Q[2],this.C=Q[m[1]],this.R=0,this[m[2]]=Q[0],this.i=Q[0],this.o6=Q[m[1]],this.T=Q[0],this.V=Q[0],this.B=new M4),N+5&46)>=N&&(N+9&24)<N&&(this.i=C),O},function(N,C,e,L,h,Q,m,O,t,D,q,u){if((N+(N<<(u=[6,"z2",2],1)&7||(h=P[u[0]](10,null,h,e),H[38](8,C,h,L,Q),h&&!U[22](12,h)&&l[1](73,C[u[1]]), +q=C),8)&7)==1){for(e in(this.G=C,this).i=[],C)this.i.push(e);this.i.reverse()}if(!(N-u[2]&7))a:{if(!(t=[2,"",1],L)){q=e;break a}q=(h=(Q=((m=((O=e.indexOf(NY()),O)<0&&(O=e.length),e.indexOf(CJ())),m)<0||m>O?(D=t[1],m=O):D=e.substring(m+t[u[2]],O),[e.slice(0,m),D,e.slice(O)]),Q)[t[u[2]]],Q[t[u[2]]]=L?h?h+"&"+L:L:h,Q[0]+(Q[t[u[2]]]?C+Q[t[u[2]]]:"")+Q[t[0]])}return q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){if((N+(F=[30,11,127],2)&57)<N&&(N+7&60)>=N){if(D=(u=(B=(q=[3,"17.5","iPod"],{title:eN(), +tabindex:Q,width:String(h.width),height:String(h.height),role:LJ(),name:hd+L.F}),T)[45](18,C)&&T[48](15,e,q[1],f[16](28,"Edge","Opera",e,q[0]))>=e,P[35](10,q[2])&&T[48](14,e,q[1],v[16](53,"",1))>=e),u||D)B[mC()]=DH();t=(L.K=U[40](32,e,U[31](17,null,m),B),qY()),L.K.onload=function(X,Y){X=S[Y=[28,2,24],Y[0]](31,3,P[4](Y[2],Y[1],K[44](10,1,new u4,5),t),qY()-t),(0,B8.Ga)(X)},O.appendChild(L.K)}if((N|48)==N)a:{for(Q=(L=(e=(h=C.B,C.i),e+10),0);e<L;)if(m=h[e++],Q|=m,(m&128)===0){Z=(f[20](28,e,C),!!(Q&F[2])); +break a}throw Error();}if(!((N^((N&((N+3&58)>=N&&(N+7^28)<N&&(L=C.replace(/<\//g,jN()).replace(/\]\]>/g,GQ()),Z=e?L.replace(/{/g,Ad()).replace(/}/g,y$()).replace(/\/\*/g,i4()).replace(/\\$/,Iw()):L),25))==N&&p.call(this,C),89))>>3))a:{if((t=(R=(U[21](F[A=[null,0,5],0],e),e.z2),R[Rw]|A[1]),h)==A[0]){Z=(W[26](9,t,L,R),e);break a}if(!Array.isArray(h))throw P[22](7);u=(q=((O=(B=n=h===Fq?7:h[Rw]|A[1],(D=W[1](27,4,n))||TQ(h)),D||(n=A[1]),O)||(h=v[27](8,h),B=A[1],n=P[F[0]](71,2,n,t),O=!1),n|=A[2],G=I[32](32, +C,4,n))!=A[0]?G:1024,A[1]);for(n|=q;u<h.length;u++)c=h[u],m=Q(c,q),ZH(c,m)||(O&&(h=v[27](64,h),B=A[1],n=P[F[0]](67,2,n,t),O=!1),h[u]=m);Z=(n!==B&&(O&&(h=v[27](9,h),n=P[F[0]](70,2,n,t)),W[32](8,n,h)),W[26](F[1],t,L,R,h),e)}return Z},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((B=[32,((N|5)>>4==4&&(u=C),7),1],N+2)&15||p.call(this,C),(N+B[2]^5)>=N&&(N+5^21)<N){if(W[O=(D=['<div class="',"Please try again.",'"><div id="rc-imageselect-target" class="'],C.PS),49](30,O,ow())){q='<div id="rc-imageselect-candidate" class="'+ +H[B[1]](64,(Q=(L=C.label,C).eP,"rc-imageselect-candidates"))+'"><div class="'+H[B[1]](65,"rc-canonical-bounding-box")+'"></div></div><div class="'+H[B[1]](B[2],"rc-imageselect-desc")+'">';switch(I[6](20,L)?L.toString():L){case "TileSelectionStreetSign":q+="Select around the <strong>street signs</strong>";break;case "vehicle":case "/m/07yv9":case "/m/0k4j":q+="Outline the <strong>vehicles</strong>";break;case "USER_DEFINED_STRONGLABEL":q+="Select around the <strong>"+W[20](48,Q)+"s</strong>";break; +default:q+="Select around the object"}m=P8(q+"</div>")}else m=W[49](24,O,sW())?T[38](41,"</div>",'">',C.label):H[42](17,C,e);(((t=T[B[2]](81,(h=m,W[11](54,T[B[2]](17,fJ(),D[0]+H[B[1]](64,"rc-imageselect-instructions")+'"><div class="'+H[B[1]](B[2],"rc-imageselect-desc-wrapper")+'">'),h)),'</div><div class="'+H[B[1]](33,"rc-imageselect-progress")+'"></div></div><div class="'+H[B[1]](B[0],"rc-imageselect-challenge")+D[2]+H[B[1]](33,"rc-imageselect-target")+'" dir="ltr" role="presentation" aria-hidden="true"></div></div><div class="'+ +H[B[1]](B[0],"rc-imageselect-incorrect-response")+'" style="display:none">'),W[11](22,t,D[B[2]]),T)[B[2]](81,t,'</div><div aria-live="polite"><div class="'+H[B[1]](B[2],"rc-imageselect-error-select-more")+'" style="display:none">'),W[11](86,t,"Please select all matching images."),T)[B[2]](16,t,'</div><div class="'+H[B[1]](33,"rc-imageselect-error-dynamic-more")+'" style="display:none">'),W[11](54,t,"Please also check the new images."),T[B[2]](16,t,'</div><div class="'+H[B[1]](64,"rc-imageselect-error-select-something")+ +'" style="display:none">'),W[11](84,t,"Please select around the object, or reload if there are none."),T)[B[2]](B[2],t,W8()),u=t}if(((N-B[1]|47)>=N&&(N+2^6)<N&&(l[5](11,null,e),K[34](5,e.u),e.u=C,v[18](30,e.j_),e.i&&(L=e.i,e.i=C,L.abort(),L.dispose())),N-4^20)<N&&(N-6|26)>=N){try{throw Error();}catch(G){h=G[H8]||C}for(m=(L=(Q=h.split(k4()),new Set),e);m<Q.length;m++)Q[m]&&L.add(K[29](B[1],0,Q[m]));u=L}return u},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a){if(!((N^(a=[0, +"B",128],5))&7)){for(k=(L&(z=(J=(A=(Y=(B=!!(L&((u=[],X=P[18](22,(Q=(q=Q!==(n=[null,!0,1],void 0),!!Q),ro)),!q)&&Jd&&X&&(G=h[X])&&v[19](9,f[39].bind(null,56),G),64)),C),h.length),B?L&a[2]?0:-1:void 0),4294967295),n[2])||(F=A&&h[A-n[2]],F!=n[a[0]]&&typeof F==="object"&&F.constructor===Object?(A--,z=A):F=void 0,!B||L&a[2]||q||(Y=n[1],z=((D=zQ)!=n[a[0]]?D:wo)(z-J,J,h,F,void 0)+J)),a)[0],t=void 0;k<A;k++)m=h[k],m!=n[a[0]]&&(m=e(m,Q))!=n[a[0]]&&(B&&k>=z?(x=k-J,Z=void 0,((Z=t)!=n[a[0]]?Z:t={})[x]=m):u[k]= +m);if(F)for(R in F)d=F[R],d!=n[a[0]]&&(d=e(d,Q))!=n[a[0]]&&(E=void 0,r=+R,B&&!Number.isNaN(r)&&(E=r+J)<z?u[E]=d:(c=void 0,((c=t)!=n[a[0]]?c:t={})[R]=d));w=((t&&(Y?u.push(t):u[z]=t),q&&P[18](38,ro)&&(O=T[1](40,h)))&&O instanceof V$&&(u[ro]=S[33](1,O)),u)}return N-9<<2>=((N|40)==N&&(w=(""+h(e(),18)()).length||a[0]),N)&&(N-9|47)<N&&(C instanceof aw?(t=C.y,C=C.x):t=L,h=e.i-e.G,O=e[a[1]]-e.o,Q=e.G,m=e.o,w=((Number(C)-Q)*(e.i-Q)+(Number(t)-m)*(e[a[1]]-m))/(h*h+O*O)),w},function(N,C,e,L,h,Q,m){if((((Q=[6, +3,0],(N<<2&2)>=Q[2]&&((N^1)&8)<Q[0])&&(m=P[18](58,W[39](12,S[32](72,new b4,35),C),[y[38](8,e),y[38](40,L)])),N|5)&Q[1])==1)a:switch(h=[7,2,429],L){case 200:m=Q[2];break a;case e:m=Q[1];break a;case 401:m=16;break a;case C:m=h[Q[2]];break a;case 404:m=5;break a;case 409:m=10;break a;case 412:m=9;break a;case h[2]:m=8;break a;case 501:m=12;break a;case 503:m=14;break a;case 504:m=4;break a;default:m=h[1];break a}return m},function(N,C,e,L,h,Q,m,O,t){if((O=[((N^1)&2||(this.top=L,this.right=e,this.bottom= +h,this.left=C),8),"call",0],N)+O[0]>>1<N&&(N+1^19)>=N){if((m=[8192,null,0],e.length)<=m[O[2]])h=String.fromCharCode.apply(m[1],e);else{for(L=m[Q=C,2];L<e.length;L+=m[O[2]])Q+=String.fromCharCode.apply(m[1],Array.prototype.slice[O[1]](e,L,L+m[O[2]]));h=Q}t=h}return t},function(N,C,e,L,h,Q){if((((N|(h=[28,9,14],8))==N&&(e=C.c3,Q=P8('<div class="'+H[7](1,"rc-audiochallenge-play-button")+'"></div><audio id="audio-source" src="'+H[7](65,S[6](h[2],e))+'" style="display: none"></audio>')),N&47)==N&&(K[5](37, +[-77],H[32].bind(null,17)),K[5](23,[-108,-66],W[6].bind(null,13)),K[5](23,[-115,-35],H[1].bind(null,8)),K[5](19,[-74],T[43].bind(null,8))),(N-h[1]|h[2])<N)&&(N-7|22)>=N)a:{if(MY){Q=Zf.atob(e);break a}Q=(y[L=C,h[0]](16,6,e,function(m){L+=String.fromCharCode(m)}),L)}return Q},function(N,C,e,L,h,Q,m,O,t){if((N&106)==((N^(((t=[3,15,"freeze"],N+5)&t[1])==t[0]&&(C.raw=e,Object[t[2]]&&($4(C),$4(e)),O=C),11))>>t[0]==1&&(Q=L.HU.bind(L,C),((m=L.jo)==C?0:(h=m.document)==C?0:h.hidden)?ON.then(function(){Q()}): +C(Q,e)),N))a:{if(!e){O=C;break a}try{O=!!e[tJ];break a}catch(D){O=C;break a}}return N-7>>t[0]==1&&(C=function(){throw Error();},Object.setPrototypeOf(C,C.prototype),O=C),O},function(N,C,e,L,h,Q,m){if(!(N>>((N>>(m=["call",40,2],m[2])&15)==1&&(Q=P8("Click the button to start the verification process on your device.")),m[2])&5))p[m[0]](this,C);if((((N|m[1])==N&&(Q=H[38](5,e,L==null?L:U[45](1,C,L),h)),N)-3&7)==1)p[m[0]](this,C);return Q},function(N,C,e,L,h,Q,m,O){return((N^((N+1^((O=["O",48,"Np"],N)+ +7>>4||(h=C.i.get(e),!h||h.EC||h.dN>h.uA?(h&&(H[39](57,C.G,L,u8,h.gJ),C.i.remove(e)),Q=C.B,Q.i["delete"](L)&&Q.Am(L)):(h.dN++,L.send(h.S2(),h.G_(),h.U5(),h.A2()))),12))>=N&&(N-2|19)<N&&(L=C.document,e=L.compatMode=="CSS1Compat"?L.documentElement:L.body,m=new B2(e.clientWidth,e.clientHeight)),72))>>4||(this.o=[],e=[!1,null,1E3],this.DR=0,this.K=new j8,this.j=e[1],this.I=e[1],this.Ku=e[1],this.rq=e[1],this.Z=e[1],this.E5=e[1],this.jW=0,this.A=e[1],this.o6=0,this.i=e[1],this.qp=e[1],this.F=e[1],this.wq= +e[1],this.lz=H[18](55,G0(),e[0],C),this.l=e[1],this.Xe=0,this.T=-1,this.Y=0,this.X=e[1],this.PK=-1,this.J=0,this.mF=-1,this.h=e[1],this.hO=!0,this.V=e[1],this.P=e[1],this.Vk=H[18](51,yq(),5E3,C),this.PL=H[18](52,i8(),1E4,C),this.E_=H[18](O[1],v2(),2,C),this[O[2]]=H[18](53,nP(),2E4,C),this.R="",this.vK=C&&C.gK||void 0,this.C=void 0,this.u=C&&C.hW||e[0],this.ZM=C&&C.Xl||void 0,this.z$=C&&C.aF||e[0],this.G=new IY(C&&C.uJ),this.JO=RY(C&&C.WY||e[2],e[2]),this.mC=new F$,this[O[0]]=C&&C.ZZ||e[0],(this.iI= +C&&C.Ro||e[0])&&this[O[0]]&&(l8(),this[O[0]]=e[0]),this.hj=C&&C.cY||e[0],C&&C.Y_&&this.K.Y_(),C&&C.oM&&(this.hO=e[0]),this.Hm=!this.iI&&this.hO&&C&&C.pI||e[0],this.Fe=void 0,C&&C.oC&&C.oC>0&&(this.Fe=C.oC),this.s5=e[1],this.W=e[0],this.S=e[1],this.lI=void 0,this.j_=0),N|40)==N&&(C.B.length===0&&(C.B=C.i,C.B.reverse(),C.i=[]),m=C.B.pop()),m},function(N,C,e,L){return(N+8^((L=[31,null,32],N-6|35)<N&&(N+6^L[0])>=N&&p.call(this,C,37),L)[2])<N&&(N-1|28)>=N&&(K[5](9,[-13],f[3].bind(L[1],4)),K[5](7,[-76, +-59],y[11].bind(L[1],1))),e},function(N,C,e,L,h,Q,m,O,t,D,q,u){if(((q=[2,17,40],(N&43)==N)&&(U[35](77,C,ZI,U[41](1)),u=C),N+4&29)<N&&N-q[0]<<q[0]>=N)a:{if(l[43](q[0],(t=["",(Q=S[16](46),"6.0"),"CriOS"],"MSIE"))){u=W[36](28,"4.0",t[1],Q);break a}if(D=(m=f[36](34,h,q[0],Q),l[11](5,L,1,m)),S[20](55,e)){u=D(["Version","Opera"]);break a}if(I[q[2]](1,C)){u=D(["Edge"]);break a}if(K[21](q[1],L)){u=D(["Edg"]);break a}if(S[q[1]](35,"Silk")){u=D(["Silk"]);break a}if(S[1](21,t[q[0]])){u=D(["Chrome","CriOS","HeadlessChrome"]); +break a}u=(O=m[q[0]])&&O[1]||t[0]}return u},function(N,C,e,L,h,Q,m){return((N|((N&57)==((m=[72,null,"coords"],N|m[0])==N&&(h=P2.get(),h.o=e,h.G=L,h.B=C,Q=h),N)&&(sN=[],fP=m[1],X$=new Map),3))>>4||(xW.call(this,C),this[m[2]]=e[m[2]],this.x=e[m[2]][0],this.y=e[m[2]][1],this.z=e[m[2]][2],this.duration=e.duration,this.progress=e.progress,this.state=e.i),N+3^5)<N&&N-8<<1>=N&&(L=new S8,Q=f[5](4,L,kn,C,e,rY)),Q},function(N,C,e,L,h,Q,m,O){if(!((N^(((O=[5,null,"call"],N-1)<<2>=N&&(N+9^13)<N&&(this.i=C),N| +4)>=12&&(N<<1&28)<8&&(Q=U[13](24,e.i,pP,1),Q||(Q=new pP,l[12](55,O[0],Q,e)),h=Q,L=U[13](27,h,JJ,C),L||(L=new JJ,f[O[0]](28,h,JJ,C,L)),m=L),((N^23)&6)==2&&(m=Object.prototype.hasOwnProperty[O[2]](C,EN)&&C[EN]||(C[EN]=++z0)),24))>>4))a:{if(C.B!==0&&C.B!==2){m=!1;break a}(h=W[18](93,128,e,e[Rw]|0,L),C).B==2?P[2](12,W[4].bind(O[1],72),h,C):h.push(I[22](4,C.i)),m=!0}return(N&58)!=N||v[24](56,e.G)||e.V||(e.V=C,v[3](18,C,e.iz,e),e.Y=0),m},function(N,C,e,L,h,Q,m,O,t){if((((N+7>>3==(O=[null,2,"tagName"],1)&& +p.call(this,C),((N^37)&14)==O[1])&&(e=H[O[1]](76,C),e=(0,O[0])(H[O[1]](72,C),e),U[29](68,e,C)),N)+8&74)>=N&&(N+8&40)<N)for(h=e||[dY],m=[0,!0,"none"],L=m[0];L<h.length;L++)if((Q=T[0](13,h[L]))&&U[5](48,m[O[1]],Q)&&U[5](49,m[O[1]],Q.parentElement||C)){(Q[O[2]]==wY&&Q.hasAttribute(Vq())||Q[O[2]]==xn||Q[O[2]]==aY||Q[O[2]]==gY||Q[O[2]]==$n?Q.disabled||Q.hasAttribute(Nw())&&!v[0](5,m[0],Q):!W[O[1]](O[1],m[0],Q))?f[28](1,m[1],Q).focus():Q.focus();break}return(N|72)==N&&p.call(this,C),t},function(N,C,e,L, +h){if((((N|(L=[2,7,27],L[1]))<L[2]&&N<<1>=14&&(h=e),N)|8)==N&&(e.i=C,C>e.G))throw Error();return(N<<1&L[1])==L[0]&&p.call(this,C),h},function(N,C,e,L,h,Q,m,O,t,D,q){return(N+7&((N|7)>>((N<<2&(D=[6,"constructor",5],8))<D[2]&&N+D[0]>=4&&(O=C.visible,L=C.n0,e=C.resize,h=L===void 0?null:L,Q=e===void 0?null:e,m=C.XI,t=m===void 0?!1:m,this.visible=O,this.n0=h,this.resize=Q,this.XI=t),4)||L==null||(h==null?O=(m=Cy)!=null?m:Cy={}:O=h[D[1]],Q=O[L]||0,Q>=e||(O[L]=Q+C,U[3](96))),55))<N&&(N+9^11)>=N&&(eB.call(this, +Ly.width,Ly.height,ha),this.h=null,this.i=new Qn,I[D[2]](8,this,this.i),this.G=new mS,I[D[2]](11,this,this.G)),q},function(N,C,e,L,h,Q,m,O){return(N|72)==(((((N&70)==(m=["replace","xx",2],N)&&(e=T[41](4,C),H[m[2]](64,C)!==0&&H[23](14,3,(C.nI[m[1]]<<3)+e,C)),(N&61)==N)&&(h=[],H[37](m[2],C,e,!0,h),L=h.join(C),L=L[m[0]](/ \xAD /g,OY())[m[0]](/\xAD/g,C),L=L[m[0]](/\u200B/g,C),L=L[m[0]](/ +/g,OY()),L!=" "&&(L=L[m[0]](/^\s*/,C)),O=L),N)|32)==N&&(Q=C.n7,e=C.hE,L=C.Tk,h=f[20](20,ta(),L,UY(),DE()),O=T[1](16, +W[11](82,T[1](17,fJ(),'<iframe src="'+H[7](65,v[43](14,h,qw)?h.U5():h instanceof u5?H[41](56,h).toString():BV())+'" frameborder="0" scrolling="no"></iframe><div>'),P[31](64,{id:e,name:Q})),jB())),N)&&(O=y[39](14,null,C,!0)),O},function(N,C,e,L){if(!(((e=["call",5,8],N)^47)&6))p[e[0]](this,C);if((N&(N-2>=-43&&(N<<2&e[2])<4&&(K[e[1]](3,[-105],S[37].bind(null,1)),K[e[1]](39,[-55,-72],v[47].bind(null,24)),K[e[1]](25,[-117,-86],I[42].bind(null,1)),K[e[1]](3,[-20,-42],U[29].bind(null,1))),107))==N)p[e[0]](this, +C);return L},function(N,C,e,L,h,Q,m){if(((((m=[58,15,13],(N^66)<17&&(N<<1&m[1])>=0&&(L=L===void 0?null:L,Array.from(document.querySelectorAll(C+GU)).filter(function(O){return!I[1](4,O)}).filter(function(O){return L==null||O.getAttribute(cV)==L}).forEach(function(O){return H[10](23,O,{},e)})),N&93)==N&&p.call(this,C,0,Ky.yl),(N&m[0])==N)&&(h=Aa.indexOf(L),h!==-1&&(Aa.splice(h,e),Aa.length===0&&(yn=i5=C))),N|3)&m[1])==3)K[23](33,C,L,e);if(N+3>>2<N&&(N+4&52)>=N)a:{if(L[e]===(h=L.length,"-")?h<vV||h=== +vV&&L<=ny:h<RF||h===RF&&L<=F9){Q=L;break a}Q=(v[14](34,6,L),y[8](m[2],C,l5,TU))}return Q},function(N,C,e,L,h,Q,m,O,t,D,q){if((N&(N>>(q=[3,"i",14],1)>=26&&N+q[0]>>4<4&&(D=new ZE(function(u,B){return e.jn((B=C,function(){B===L.length?u.complete():(u.next(L[B++]),u.closed||this.jn())}))})),53))==N){if((t=(O=h[m=y[35](20,(Q=h[q[1]].G,h[q[1]])),q[1]][q[1]]+m,O-Q),t<=C)&&(h[q[1]].G=O,e(L,h,void 0,void 0,void 0),t=O-h[q[1]][q[1]]),t)throw Error();h[q[h[q[1]][q[1]]=O,1]].G=Q,D=L}if((((N+8^21)<N&&(N-q[0]^ +q[0])>=N&&p.call(this,C),(N-7|47)<N&&N-4<<2>=N&&(yE.call(this),this[q[1]]=C,K[26](q[2],oF,C,this.B,!1,this),K[26](9,PV,C,this.G,!1,this)),N)|72)==N)a:try{D=H[42](38,C).filter(function(u){return!u.startsWith(U[25](31,sY))}).length;break a}catch(u){D=-1;break a}return D},function(N,C,e,L,h,Q){if((N|((N+4&47)>=(((((N^(Q=[3,39,9],83))&15)==Q[0]&&e.u.length&&!e.O&&(e.O=!0,v[44](37,e,C)),N+Q[2])^17)<N&&(N+Q[0]^21)>=N&&p.call(this,C),(N-5|19)<N&&(N-4^5)>=N&&(this.request=C),N)&&(N-8|41)<N&&(h=P[18](27,W[Q[1]](24, +S[32](20,new b4,C),L),[y[38](16,e)])),6))>>4==4){if(fy)throw Error(C);f[21](2,L,e,X9,void 0,SB())}return h},function(N,C,e,L,h,Q){return(N+((N-4^(((N>>2&((N+7&45)>=(Q=[352,"Ub",1],N)&&(N-6|39)<N&&(YK.call(this,Q[0],19),this.R=this.hj=this.SW=this.Vk=this.JO=this.iI=this.T=this.Fd=this.J=this.iz=this.Z=this.lI=this.ZM=this.K=this.ks=this.wq=this.tu=this.Np=this.Gy=this.E_=this.jW=this.l=this.Y=this.o=this.X=this.mF=this.h=this.lz=this.Xe=this.O=-1,this[Q[1]]=-1,this.pR=C,this.hO=this.z$=this.S=this.bI= +this.rq=this.W=this.I=this.ZR=this.C=this.F=this.S_=this.u=this.Ku=this.G=this.Fe=this.ns=this.Nk=this.o6=this.vK=this.DM=this.W9=this.qp=this.B=this.PL=-1,this.Gm=I[21](71),this.rv=I[21](23),this.xN=I[21](7),this.E5=I[21](71),this.bp=I[21](84)),22))>=9&&((N^24)&12)<12&&p.call(this,C),(N^54)>>3)==Q[2]&&(this.i=this.G=this.B=C),16))>=N&&(N+5&43)<N&&(C=H[15](36,this),L=y[34](55,this),e=y[34](62,this),this.Pm[C]=L+e),Q)[2]^19)>=N&&N+8>>Q[2]<N&&(h=e.nodeType==C?e:e.ownerDocument||e.document),h},function(N, +C,e,L,h){return(((((L=[22,1,13],(N+3^30)>=N)&&(N-L[1]^7)<N&&!e.i&&(e.i=new Map,e.B=0,e.G&&T[L[0]](92,0,L[1],C,function(Q,m){e.add(decodeURIComponent(Q.replace(/\+/g,OY())),m)},e.G)),N<<2&11)||(h=e.firstElementChild!==void 0?e.firstElementChild:I[36](33,L[1],C,e.firstChild)),N>>L[1])&L[2])==L[1]&&p.call(this,C,0,WV.yl),N)-4<23&&N-2>=14&&p.call(this,C,0,HV.yl),h},function(N,C,e,L,h,Q,m){return((N|(Q=["",4,18],40))==N&&(C[0]=T[Q[2]](27,C[0]),C[1]=T[Q[2]](26,C[1]),m=C),(N-Q[1]|7)>=N&&(N+Q[1]^13)<N&&(eB.call(this, +kK.width,kK.height,"qr",rq),this.mobileToken=Q[0],this.url=Q[0],this.u=0),(N-Q[1]^5)<N)&&N+8>>1>=N&&(L=L===void 0?py:L,m=(h=W[33](13,C,e,void 0,void 0,P[0].bind(null,44)))!=null?h:L),m},function(N,C,e,L,h,Q,m,O,t,D){if(((((t=[8,1E6,"The 'this' value for String.prototype."],N)-7>>4||((O=Zf[h])||typeof document==="undefined"||(O=(new dq(document)).get(m)),D=O?W[6](2,C,e,L,O,Q):null),N-4<<1<N&&(N+3&30)>=N)&&(L%=t[1],Q=wq(Vn()*C),D=[Q].concat(T[5](25,h.map(function(q,u){return(q+h.length+(L+Q)*(u+Q))% +e})))),N-3)^t[0])>=N&&(N+7&46)<N){if(e==null)throw new TypeError(t[2]+h+" must not be null or undefined");if(L instanceof RegExp)throw new TypeError("First argument to String.prototype."+h+" must not be a regular expression");D=e+C}return D},function(N,C,e,L,h,Q){return(N&(((N^21)&(h=[0,"put",17],5))>=3&&(N>>1&8)<8&&C.v()&&H[7](h[2],C.v(),e,L),28))==N&&(e=H[2](28,C),L=C.Ql[y[1](35,1,e,C)],C.Ql[y[1](2,1,e,C)]=P[25](24,31,h[0],C),C[h[1]](h[0],L)),Q},function(N,C,e,L,h,Q,m,O,t,D,q){return(N+4^(((q=[27, +13,44],N^3)&7)==2&&Q!=null&&(m=I[4](17,2,h,L),e(Q,h),v[37](53,C,h,m)),10))>=N&&(N+5^q[0])<N&&(D=P[q[2]](q[1],function(u,B,G){B=[2,(G=["G",2,"i"],!1),7];switch(u.B){case h:m=null,t=0;case B[0]:if(!(t<3)){u.js(e);break}if(!(t>0)){u.js(L);break}return u[G[2]](W[44](51,1E3,null),L);case L:return u.K(B[G[1]]),u[G[2]](W[41](G[1],"script",B[1],C,0,Q),9);case 9:return u.return(u[G[0]]);case B[G[1]]:m=O=u.o();case 3:u.js((t++,B[0]));break;case e:throw m;}})),N+2>>3||(C=[!1,null,0],this.j=C[1],this.Y=C[0], +this.B=1,this.h=C[2],this.I=C[1],this.X=C[2],this.G=void 0,this.A=C[1]),D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y){if(N-8>>(X=[((N&90)==N&&(Y={send:function(k,E,J,r,z,d,x,w,a){return w=(a=[!0,"X",0],new xK(e)),w.j.add(String(aF),E,C,void 0,void 0),K[32](2,a[0],w,function(){w.dispose()},gq),d&&(w[a[1]]=vh(a[2],d)),x&&(w.K=x),w.send(k,J,r,z),w}}),27),1,4],X)[2]<X[1]&&(N|8)>=X[0]){if(t=(B=(F=(q=(U[21](31,(c=[0,!0,4096],e)),e).z2,S)[32](29,C,L,Q,e,void 0,q[Rw]|c[0],q,2,c[X[1]]),c[0]),c[0]), +Array.isArray(h))for(A=c[0],n=h.length;A<n;A++)m=l[5](X[2],h[A],Q),F.push(m),(O=U[22](X[1],m))&&!B++&&(F[Rw]&=-9),O||t++||v[22](66,c[2],F);else{D=P[X[2]](11,h),Z=D.next();try{for(;!Z.done;Z=D.next())G=l[5](2,Z.value,Q),F.push(G),(R=U[22](3,G))&&!B++&&(F[Rw]&=-9),R||t++||v[22](64,c[2],F)}finally{Z&&!Z.done&&(u=D.return)&&u.call(D)}}Y=(t&&l[X[1]](64,q),e)}if(!(N+6>>X[2]))K[5](35,[-107,-9],W[10].bind(null,8));return Y},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if(A=["S_","ik","i"],(N+9&13)>=10&&(N| +7)>>4<4){for(O=h=(Q=[],e);O<L.length;O++)m=L.charCodeAt(O),m>255&&(Q[h++]=m&255,m>>=C),Q[h++]=m;n=Q}if((N-9|14)>=N&&(N-9|39)<N){for(Q=(D=L[(m=(O=L[A[2]],O.push(new b5(e,h)),O.length-C),A)[2]],D[m]);m>0;)if(t=m-C>>C,D[t][A[2]]>Q[A[2]])D[m]=D[t],m=t;else break;D[m]=Q}if(N+4>>(N+2>>1<N&&(N-6^15)>=N&&(n=P[44](41,function(R,F,Z){F=[8,(Z=[5,33,10],16),500];switch(R.B){case e:O=l[36](77,W[Z[1]](21,Q,2)),c=l[36](75,W[Z[1]](25,Q,3)),G=l[36](77,W[Z[1]](Z[1],Q,e)),u=Array(O),D=0,q=typeof crypto!=="undefined"&& +typeof crypto.subtle!=="undefined";case 2:if((D++,D)>=5E6)throw Error(C);if(!(D>0&&D%F[2]===0)){R.js(Z[0]);break}return R.i(new Promise(function(X){setTimeout(X,0)}),Z[0]);case Z[0]:if(B=(t=Mw.encode(G+":"+D),void 0),!q){(B=T[7](25,F[1],e,t),R).js(h);break}return R.K(F[0]),R.i(l[8](1,L,0,e,2,t),Z[2]);case Z[2]:R.V((B=R.G,h));break;case F[0]:R.o(),q=L,B=T[7](24,F[1],e,t);case h:if((m=B%O,u[m]||(u[m]=[]),u[m].push(D),u[m]).length>=c)return R.return(u[m]);R.js(2)}})),1)<N&&(N+7&44)>=N)f[32](41,127,Q, +L,C,T[23](4,1,h,e));return(N>>2&15)==4&&C.G.push(C.mo,C.Ku,C[A[0]],C.KJ,C[A[1]],U[25](4,C,function(R,F){return!!R&&!!F})),n},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(N+(B=[16,"i",7],4)>>1<N&&N-B[2]<<2>=N)if(Array.isArray(Q))for(q=C;q<Q.length;q++)f[35](37,0,e,L,h,Q[q],m);else t=I[6](52,L)?!!L.capture:!!L,m=l[18](57,m),S[B[2]](3,h)?h.j.remove(String(Q),m,t,e):h&&(D=l[48](65,h))&&(O=H[25](B[0],Q,m,e,t,D))&&y[40](4,O);return N+1>=-65&&(N>>2&8)<2&&(m=[null,!1,0],TN.call(this),this.B=C,this.Xe=L,$K=e.R, +this[B[1]]=e,Q=this,N3=e.X,this.o6=K[B[2]](8,m[0],m[2],this.Xe),this.wq=h,this.uI=m[0],this.hO=m[0],this.s5=m[0],this.G=Cx,this.P=T[B[0]](19,80,this),this.o=m[0],this.Ku=m[0],H[3](26,m[2],U[25](27,eq))?O=m[1]:(U[10](18,U[25](29,eq),T[45](35),m[2]),O=!0),this.iI=m[0],this.O=m[0],this.JO=m[1],this.iz=O,this.W=y[3](5),this.j_=m[0],this.S_=[],this.Y=[],this.h=[],this.rq=m[0],this.PK=(t=l[27](4,22))!=m[0]?t:!1,this.S=m[0],this.T=m[0],this.I=m[0],this.F=m[0],this.Fd=Lx(Cx,Lx(h5,this.V,Qp,this.ZM,mG,this.j, +Ok,this.V,t5,this.vK,Uk,function(){return Q.B.Au()},DD,this.bI),q3,Lx(uj,this.lI,Bf,this.R,Uk,this.Hm,jq,this.Fe,Gz,this.u,cf,this.mC,Kx,this.mF),A5,Lx(yp,this.VM,h5,this.V,Ok,this.V,uj,this.C,Gz,this.u),ij,Lx(yp,this.VM,uj,this.C,Gz,this.u),vf,Lx(h5,this.V,Ok,this.V,uj,this.C,jq,this.Fe,Bf,this.R,Uk,this.Hm),RI,Lx(h5,this.V,Ok,this.V),FF,Lx(uj,this.lI,Bf,this.R,lj,this.E_,mG,this.j,h5,this.V),Tz,{}),this.K=Promise.resolve()),u},function(N,C,e,L,h,Q,m,O,t,D){if((N&(D=[22,"B","KI"],106))==N){for(m= +(Q=RegExp("([A-Z][\\w ]+)/([^\\s]+)\\s*(?:\\((.*?)\\))?","g"),[]);h=Q.exec(L);)m.push([h[1],h[e],h[C]||void 0]);t=m}if((N-1^1)<N&&(N+6&30)>=N)a:{for(L in e){t=!1;break a}t=C}if(!(N+9&3))a:{if(C[D[1]]!==0&&C[D[1]]!==2){t=!1;break a}t=!(h=W[18](95,128,e,e[Rw]|0,L),C[D[1]]==2?P[2](5,I[D[0]].bind(null,4),h,C):h.push(I[D[0]](4,C.i)),0)}return(N-7&7)==2&&(O=function(){return L.pu(h,Q,m)},L.response={},L.r0(C),l[49](18,L.P).width!=L[D[2]]().width||l[49](49,L.P).height!=L[D[2]]().height?(v[39](33,O,L),K[34](11, +e,L[D[2]](),L)):O()),t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if((N-8&11)==(c=["data",((N+4&67)<N&&(N+7&41)>=N&&(this.i=e,this.B=C),1),9],3))a:{if(u=(B=["-",0,4235],h)(L(e(),11),37))if(Q=u()||[],Q.length>B[c[1]]){t=(q=P[4](14,Q),q.next());try{for(;!t.done;t=q.next())if(O=t.value,S[36](41).test(O.name)){D=+!L(O,44),G=U[4](2,B[2])(L(O,27))+B[0]+D;break a}}finally{t&&!t.done&&(m=q.return)&&m.call(q)}G="";break a}G=ZD()}if((N+4&61)>=N&&(N+c[2]&30)<N)if(oI.call(this),C[Pf()]&&(this.headers=C[Pf()],this.statusCode= +C[sk()],delete C[Pf()],delete C[sk()]),L=C[fx()]){a:{for(h in L){e=h;break a}e=void 0}this[c[0]]=(this.o=e,this.o?U[39](8,L,this.o):L)}else this[c[0]]=C;return((N>>c[1]&15)==c[1]&&(L=typeof e,G=L!=C?L:e?Array.isArray(e)?XF():L:Sq()),N|c[2])>=27&&(N|6)<42&&(Q=L.c9,C[e]=h?function(A,n,R){return Q(A,n,R,h)}:Q),G},function(N,C,e,L,h,Q,m,O){if((m=[44,53,23],(N&110)==N&&(YK.call(this,1092,15),this.B=-1),(N+9^18)>=N)&&(N-2|4)<N&&L&&(H[41](m[2],L),h))if(typeof h==="string")K[18](m[1],h,L);else Q=function(t, +D){t&&(D=f[27](10,C,L),L.appendChild(typeof t==="string"?D.createTextNode(t):t))},Array.isArray(h)?h.forEach(Q):!l[22](49,e,h)||"nodeType"in h?Q(h):v[40](m[0],h).forEach(Q);return(N|80)==(N<<2>=((N&91)==N&&(O=function(t,D,q,u,B,G,c,A){for(D=(u=(t=(c=(G=new (A=[null,(q=new Y1,36),2],P[A[1]](A[2],500,0,y[31](1,A[2],T[25].bind(A[0],6),S[A[1]].bind(A[0],14),C,Wf),this.z2,q),T[7](33,q,q.i.end()),Uint8Array)(q.B),0),q).G,0),t.length);c<D;c++)B=t[c],G.set(B,u),u+=B.length;return q.G=[G],G}),-38)&&N+7>>5< +1&&(O=P[18](58,W[39](24,S[32](24,new b4,15),e),[y[38](8,C),y[38](48,L)])),N)&&(O=document.body),O},function(N,C,e,L,h,Q,m){return(N-2&16)<((N|7)>>((((N-(Q=["call",15,5],Q)[2]>>3==1&&(h=Error[Q[0]](this,e),this.message=h.message,"stack"in h&&(this.stack=h.stack),this.code=C,this.message=e,this.status=L,Object.setPrototypeOf(this,Hf.prototype),this.name="XhrError"),N)|56)==N&&(e<100||f[21](Q[1],1,1,k1)),N+8)>>3==1&&C.G.push(U[25](Q[2],C,function(O,t){return!!O||!!t}),C.Hm,C.pV,C.yd,C.Vd),3)==1&&(this.mj= +Array.from(C.entries()),this.CJ=Array.from(e)),Q)[2]&&(N>>2&23)>=6&&(m=(h=L(C(),32))?U[4](2,7799)(h)+","+U[4](2,4009)(h):""),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){if(((N+(c=[0,4,"i"],N-7<<1<N&&(N+7^23)>=N&&(this.width=C,this.height=e),8)^32)<N&&(N-8^20)>=N&&(L=L===void 0?null:L,e=e===void 0?null:e,h=h===void 0?!1:h,this.B=C,this.ep=h,this.R6=L,this[c[2]]=e),N+6>>2<N)&&(N-7^10)>=N)S[29](7,T[c[0]](61,"rc-imageselect-progress"),C,100-L/e*100+"%");if(((N|8)&3)==1){t=(u=(O=P[c[1]]((G=new (Q=C,Map), +14),e),O.next()),[]);try{for(;!u.done;u=O.next())h=u.value,h instanceof rw?G.set(h,Q):Q++}finally{u&&!u.done&&(B=O.return)&&B.call(O)}m=(L=P[c[1]]((Q=C,10),e),L.next());try{for(;!m.done;m=L.next())D=m.value,D instanceof b4?(t.push(D),Q++):D instanceof px&&(t.push(D[c[2]](Q,G)),Q++)}finally{m&&!m.done&&(q=L.return)&&q.call(L)}A=t}return A}]}(),I=function(){return[function(N,C,e,L,h){return(N^((N&(L=["h",92,1],L)[1])==N&&(J5.call(this,C,e),this.T=!1,this.iI=null,this[L[0]]=null),6))>>3==L[2]&&(e=H[2](56, +C)?0:1,U[29](5,e,C)),h},function(N,C,e,L,h){if(((((N|(((N&106)==(h=["l","A","h"],N)&&(e=[null,!1,""],eB.call(this,Ek.width,Ek.height,zz,dw,C===void 0?null:C),this.T=e[1],this[h[0]]=e[2],this.F=e[0],this.i=e[0],this[h[2]]=e[0],this.u=new ww,this.G=e[0]),N)-1&14||(this.V=3,this.G=this.P=this.K=-1,this.B=null,this.i=Vp,this.o=S[13](2,null,24,this),this[h[1]]=0),72))==N&&(L=y[48](52,C,S[16](15))),N)^5)>>3||(L=Object.values(window[Bh][GN()]).some(function(Q){return Q.Mz==C})),N|40)==N&&x1)try{x1(C)}catch(Q){throw Q.cause= +C,Q;}return L},function(N,C,e,L){return(((N|3)>=((L=[25,"G",7],(N^10)>>3)||p.call(this,C),L)[0]&&(N<<1&L[2])<6&&(this.o=null,this.i=0,this[L[1]]=new aI,this.B=new aI),N)-1|46)>=N&&(N-3^32)<N&&this.i.getValue().length>0&&this.Mp(!1),e},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(((N^22)&15)==(u=[5,188,"B"],N+8>>4<3&&(N<<2&11)>=u[0]&&(e=Math.random,this.K=500,C=C===void 0?2:C,this[u[2]]=512E3,this.P=e,this.o=C,this.reset()),3))a:{if((q=[!1,17,18],gw)&&Q){B=T[u[0]](33,q[0],O);break a}if(Q&&!t){B=q[0];break a}if(!bj&& +(typeof m==="number"&&(m=l[1](18,173,m)),D=m==q[1]||m==q[2]||gw&&m==e,(!h||gw)&&D||gw&&m==16&&(t||L))){B=q[0];break a}if(M3&&t&&h)switch(O){case 220:case 219:case 221:case 192:case 186:case 189:case 187:case u[1]:case 190:case 191:case 192:case 222:B=q[0];break a}switch(O){case C:B=bj?L||Q?!1:!(h&&t):!0;break a;case 27:B=!M3&&!bj;break a}B=bj&&(t||Q||L)?!1:T[u[0]](64,q[0],O)}return((N|24)==N&&(this[u[2]]=C,this.i=new $1,this.Oc=this.rz=!1,this.JE=new Nt),N)+8&u[0]||(m=m===void 0?C2:m,(O=Q.g$?void 0: +S[28](1))?K[19](1,C,2,L,u[0],O,m).then(function(G,c,A){return((c=(Q.B=L2((A=[65,!0,5],G!=L?G:"[]")),f[18](A[0],e,Q)),f)[A[2]](12,c,hC,9,Q.B),A)[1]}).catch(function(){return h}):Promise.resolve(h)),B},function(N,C,e,L,h,Q,m){if((N-4&((N-9&((((m=[1,8,20],(N^59)>>3)||(Q=QO[e]||(QO[e]=new mu(e<C?-1:0,e))),N-6)|m[2])>=N&&(N-m[0]^21)<N&&(v[22](m[1],e,L,C),h=e.i.end(),T[7](35,e,h),h.push(e.B),Q=h),15))==3&&p.call(this,C),32))<22&&((N|m[0])&15)>=14)W[36](80,T[11](4,0,null,Date.now(),(h=L.i)==null?void 0: +h.hG),function(){L.S.then(function(O,t,D,q,u){((u=(q=[!1,null,1],["J","i",15]),(D=L[u[1]])==q[1])?void 0:D.k_)!=q[1]&&((t=L[u[1]])==q[1]?void 0:t.hG)!=q[1]&&Date.now()>=L[u[1]].hG+24E4?(T[32](9,C,q[1],4,"POST",O.ey,L[u[1]].k_,L[u[1]].Iy).catch(function(){}),L[u[1]].hG=Date.now(),I[4](u[2],q[2],q[0],L)):L[u[0]]=e})});return N+m[0]>>2<N&&(N-6^13)>=N&&p.call(this,C),Q},function(N,C,e,L,h,Q,m,O,t,D,q){return(q=["Z","A2",2],(N^32)&14||(t={hp:!0,v3:"application/json+protobuf",yI:void 0,gI:Object.assign({}, +{gsessionid:m},Q.config.i.Jm()),pI:!Q.config.oM,oM:Q.config.oM,aF:Q.config.B,lJ:Q.config.i[q[1]](),hW:Q.config.i.eZ()},O=Q.Dp(S[22](24,"-",!0,10,Q.config).toString(),t),y[22](57,Q.i,O,"a",function(u,B,G){u=(B=Q[(G=[46,"B",null],G)[1]],B[G[1]](new OB),H)[36](G[0],G[2],new tC,0);try{B.A.next(u)}catch(c){}}),y[22](49,Q.i,O,L,function(u,B){(((u=(B=[18,"B",null],Q[B[1]]),u[B[1]](new UB),u).i=void 0,S[15](36,"",u),Q.state=2,y)[9](30,B[2],0,Q.channel),v)[B[0]](29,Q.i)}),y[22](39,Q.i,O,h,function(u,B,G,c, +A,n){(G=[null,(n=["o",8,2],2),0],u.data&&Array.isArray(u.data))&&u.data.length===1&&(u[n[0]]&&u[n[0]]==="status"?(B=T[44](10,G[0],32,u.data[G[n[2]]][G[n[2]]],tC),c=Q.B,T[n[1]](32,C,B)!==0&&(c.B(new DK(U[23](17,G[n[2]],!1,B))),U[10](1,G[0],G[1],c,B))):(A=T[44](11,G[0],32,u.data[G[n[2]]],qt),Q.G(A)))}),y[22](27,Q.i,O,e,function(u,B){(Q.B.onError(u,(B=["mF","i","state"],new ue(Q.channel[B[1]]))[B[1]][B[0]]),u.status!==0)&&(Q[B[2]]=2)}),D=O),(N>>q[2]&11)==q[2])&&(L=kW(K[34].bind(null,q[2]),e),C.J?L(): +(C[q[0]]||(C[q[0]]=[]),C[q[0]].push(L))),D},function(N,C,e,L,h,Q,m){return(N^42)>>((N+((N-((N|24)==(Q=["apply",34,null],N)&&(K[5](13,[-88,-93],W[35].bind(Q[2],61)),K[5](7,[-103],P[40].bind(Q[2],3)),K[5](7,[-81,-52],T[18].bind(Q[2],1)),K[5](39,[-64,-39],U[33].bind(Q[2],2)),K[5](21,[-19,-6],y[Q[1]].bind(Q[2],1)),K[5](17,[-118],W[9].bind(Q[2],65))),7)^10)>=N&&(N+2&40)<N&&(h=H[2](28,C),L=H[2](76,C),e=H[2](68,C),h=L==Q[2]?void 0:L[Q[0]](e,h),U[29](69,h,C)),9)&46)<N&&(N+9&58)>=N&&(e=typeof C,m=e=="object"&& +C!=Q[2]||e=="function"),4)||(m=(L=C.get(e))?L.toString():null),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(((u=[7,"isArray",0],N>>1)&u[0])>=4&&(N>>2&4)<1)if(Array[u[1]](m))for(q=C;q<m.length;q++)I[u[0]](9,u[2],!0,L,h,Q,m[q],O,t);else(D=P[8](31,e,O||L.handleEvent,Q,m,h,t||L.l||L))&&(L.X[D.key]=D);if(!(N>>2&u[0])){for(Array[u[1]](L)||(L&&(Bk[u[2]]=L.toString()),L=Bk),O=u[2];O<L.length;O++){if(m=K[26](11,L[O],C,Q||h.handleEvent,e||!1,h.l||h),!m)break;h.X[m.key]=m}B=h}return B},function(N,C,e,L,h,Q,m){return(((N& +126)==(m=["setProperty",null,8],N)&&(h=l[19](49,L,C))&&(jV.test(h)?C.style[m[0]](h,e):C.style[h]=e),(N<<2&m[2])<1)&&(N-7&7)>=0&&(this.B=m[1],this.i=m[1]),(N-2^13)>=N)&&(N-m[2]|13)<N&&(C.x*=e,C.y*=e,Q=C),Q},function(N,C,e,L,h,Q,m){if(!((Q=["call",null,"Np"],N|9)>>4))p[Q[0]](this,C);if((N|40)==N)a:{if(e==Q[1]||e==C){m=new L;break a}if(!(h=GH(e),Array.isArray(h)))throw Error(ck());m=new L(v[1](2,32,h))}return(N+5^((N|72)==N&&(K2[Q[0]](this),this.j=new AC(this),this[Q[2]]=this,this.Ku=Q[1]),6))>=N&&(N+ +5^14)<N&&(m=H[49](4,Q[1],document).y),m},function(N,C,e,L,h,Q,m){if(!(N>>(Q=["G","o","i"],1)&14))a:{for(;e[Q[0]][Q[2]].length!==0&&!e.V.has(I[10](9,C,e[Q[0]]));)e[Q[0]].remove();if(e[Q[0]][Q[2]].length===0)e[Q[1]]!=null&&(S[3](8,e[Q[1]].id),e[Q[1]]=void 0);else{if(e[h=T[17](1,C,e[Q[0]]),Q[1]]!=null){if(e[Q[1]].mH===h){m=void 0;break a}S[3](9,e[Q[1]].id)}(L=h-Date.now(),e)[Q[1]]={id:W[36](88,L,function(O,t,D){for(t=(D=["h",(e.o=void 0,9),"delete"],Date.now());e.G.i.length!==0&&T[17](3,C,e.G)<=t;)O= +e.G.remove(),e.V.has(O)&&(O.o=e[D[0]]++,e.V[D[2]](O),K[D[1]](13,e,O));I[10](2,0,e)}),mH:h}}}if(N-1>>3==1)a:if(L=e[Q[2]],L.length!=C){m=L[C].getValue();break a}return(N-4&7)==1&&(e=CB.get(),m=T[42](48,C,e)),m},function(N,C,e,L,h,Q,m,O){if(((O=[20,"i",9],(N+2^O[0])>=N&&(N+8&42)<N&&(C=C===void 0?f[0](14,0):C,e=e===void 0?{}:e,h=W[10](O[2],null,C,e).client,e&&(L=h[O[1]],yO(L[O[1]],e),L[O[1]]=P[19](26,null,L[O[1]])),P[1](5,!0,h)),N)|32)==N)a:{if(K[15](3,(Q=Q===void 0?Infinity:Q,h))){m=I[11](33,null,!1, +function(t,D,q){return(q=[1,2,12],T[q[0]](q[1],0,function(u,B){return h(t,u,D,B)}))(U[q[2]](23,"'",L(t,D)))},Q);break a}m=(typeof h==="number"&&(Q=h),l)[27](1,function(t,D){return I[35](1,C,0,!0,e,Q,t,L,D)})}return m},function(N,C,e,L,h,Q,m,O,t,D,q,u){if(q=[2,"B",67],!(N>>1&15)&&(h=[0,!1,null],this.G=h[q[0]],this.P=h[1],this[q[1]]=h[q[0]],this.K=h[1],this.o=h[q[0]],this.A=void 0,this.i=h[0],C!=U[22].bind(null,21)))try{L=this,C.call(e,function(B){v[45](7,null,2,B,L)},function(B){v[45](4,null,3,B,L)})}catch(B){v[45](1, +h[q[0]],3,B,this)}if((N+1^15)>=N&&(N+5^26)<N){if(e!=C&&typeof e!=="string")throw Error();u=e}if((N|88)==N)l[36](9,C,ie,vk,L,e);if((N^68)>>4==4)a:{if(t=((m=["string",(D=void 0,0),"bigint"],D)!=L||(D=1024),D!==0),!t&&!n2){u=Q;break a}if(!T[49](46,Q,t))throw P[22](11,Io());O=typeof Q;switch(D){case C:switch(O){case m[0]:u=W[q[0]](69,m[1],Q,!0);break a;case m[q[0]]:u=String(Ro(64,Q));break a;default:u=S[34](8,h,!0,Q);break a}case 1024:switch(O){case m[0]:u=T[9](3,e,m[1],Q);break a;case m[q[0]]:u=l[46](16, +Ro(64,Q));break a;default:u=v[0](1,m[1],!0,Q);break a}case m[1]:switch(O){case m[0]:u=W[q[0]](q[2],m[1],Q,e);break a;case m[q[0]]:u=l[46](40,Ro(64,Q));break a;default:u=y[49](8,m[1],e,Q);break a}default:u=v[24](62,"!",D);break a}}return(N+5&49)>=N&&(N+4&26)<N&&(u=l[43](47,C,e,void 0,FG)),u},function(N,C,e,L,h,Q,m,O,t){if(((N>>(O=["IX","i",36],1)&15)==4&&p.call(this,C),N|48)==N&&(L.IB=C,Q[O[1]][O[1]]&&Q.o||Q.uI.send(jq,L),Q.o&&Q.o.resolve(L),W[O[2]](74,L.timeout*e,function(){return Q.A(L.response, +lj)}),t=Q.j({id:null,timeout:null,K0:1E3,r$:h?1:null})),(N|80)==N)a:{if(W[27](3,(h=[7,1,5],e[O[1]]))){t=C;break a}if(Q=(L=(m=(e.K=e[O[1]][O[1]],y)[35](23,e[O[1]]),m>>>3),m&h[0]),!(Q>=0&&Q<=h[2]))throw Error();if(L<h[1])throw Error();(e.G=L,e.B=Q,e).o=(t=!0,m)}return((N-6<<1>=N&&(N-4|74)<N&&(C=C===void 0?1E3:C,e=new le,e[O[0]]=function(){return kW(function(D,q,u){return!(u=(q=P[35](35),q-D),q)||TH(u/C)?(e.IX=function(){return 0},e.IX()):C-u},P[35](36))}(),t=e),N)+8^28)>=N&&(N+1^7)<N&&(t=P[44](73,function(D, +q){if(D.B==(q=["G",1,"i"],q[1]))return D[q[2]](y[31](32,C,!1,q[1],new ZK(e,L,h)),C);Q[q[m=D[q[0]],2]].postMessage(m),D.P()})),t},function(N,C,e,L,h,Q,m,O,t){return N>>1&(((N&(((N^28)&(t=[2,"unsubscribe",21],7))==3&&(Q=(m=h!==void 0)?h.toString():"",O=y[27](1,!1,!0,function(D,q){for(q=0;q<D.length;++q)if(!m||D[q].type==Q)return C;return e},L.i)),t)[2])==N&&(O=C instanceof oo||C&&"closed"in C&&K[15](4,C.remove)&&K[15](1,C.add)&&K[15](4,C[t[1]])),(N>>t[0]&6)==t[0])&&(O=(h=L(e(),11,20))?L(h,Pk()):-1), +14)||(O=(new sB(K[43](26,C))).G),O},function(N,C,e,L,h,Q,m,O){return(((N|(((N^82)>>(O=[9,"G","i"],4)||(m=v[35](7,24,this[O[2]])),((N^50)&13)>=O[0]&&(N|5)<16&&(m=L(C(),42)),N)+1>>3==2&&p.call(this,C),40))==N&&(this.uri=L,this.BS=e,this.B=C,this[O[2]]=Q,this.oM=h),N)+7^12)<N&&N-5<<1>=N&&(this.j=this[O[2]][O[2]],this[O[2]][O[2]]=this[O[2]][O[1]]),m},function(N,C,e,L,h,Q){return(h=[2,15,'<noscript>Please enable JavaScript to get a reCAPTCHA challenge.<br></noscript><div class="if-js-enabled">Please upgrade to a <a href="https://support.google.com/recaptcha/?hl=en#6223828">supported browser</a> to get a reCAPTCHA challenge.</div><br><br><a href="https://support.google.com/recaptcha#6262736" target="_blank">Why is this happening to me?</a>'], +N<<1&4||(C=H[h[1]](4,this),this.Pm[C]=null),N-h[0]^18)>=N&&N-6<<1<N&&(e="",L=C.Pj,e=f[20](23,f2(),L,UY(),XG())?e+"<div>Could not connect to the reCAPTCHA service. Please check your internet connection and reload to get a reCAPTCHA challenge.</div>":e+h[2],Q=P8(e)),Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){return(((N-(((c=[7,2,5],N)+c[2]^c[0])<N&&(N+c[0]^c[1])>=N&&(G=typeof C==="string"?e.getElementById(C):C),c)[1]|36)<N&&(N+c[2]^3)>=N&&(SV.call(this,function(){return C}),this.G=C),N)<<c[1]&12)<c[0]&& +N<<1>=-46&&(G=P[44](13,function(A,n,R){n=[7,6,!1],R=[11,"could not contact reCAPTCHA.","i"];switch(A.B){case 1:if(!Q.G)throw Error(R[1]);if(!Q.B)return A.return(I[41](R[0],0,e));return A.K(e),A[R[2]](Q.G,C);case C:A.V((u=A.G,L));break;case e:throw A.o(),Error(R[1]);case L:return O={},m=(O[Yz]=Q[R[2]],O),A.K(h),A[R[2]](u.send(Wk,m,1E4),n[0]);case n[0]:return D=A.G,B=new Hk(D),t=B.kx(),q=B.hm(),Q[R[2]]=S[49](22,e,B),Q[R[2]]&&t!=e&&t!=n[1]&&t!=10&&q?Q.o=new kz(q):Q.B=n[2],A.return(I[41](28,0,t,B[R[2]]())); +case h:throw A.o(),Error("challengeAccount request failed.");}})),G},function(N,C,e,L,h,Q,m,O,t){return N+6&(t=[11,'<span class="',7],t)[2]||(m=m===void 0?{}:m,O=new ZE(function(D,q,u,B){return S[24]((u=(q=m.Ww)!=(B=Q.h++,e)?q:Q.K.H3,2),C,L,new ru(B,u,h,D),Q)})),(N+4&t[2])==1&&(C=['" tabIndex="0"></span><div class="',"rc-imageselect-payload","rc-imageselect-tabloop-end"],O=T[1](65,W[t[0]](74,T[1](80,fJ(),'<div id="rc-imageselect" aria-modal="true" role="dialog"><div class="'+H[t[2]](64,"rc-imageselect-response-field")+ +'"></div><span class="'+H[t[2]](1,"rc-imageselect-tabloop-begin")+C[0]+H[t[2]](65,C[1])+'"></div>'),l[t[0]](60," ")),t[1]+H[t[2]](65,C[2])+'" tabIndex="0"></span></div>')),O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if((n=[0,"X",18],(N<<2&6)>=3)&&N-8<20){if(L=L===void 0?!1:L,t=[1,100,0],L){if(Q&&Q.attributes&&(K[46](4,t[1],h,Q.tagName),Q.tagName!=xn))for(m=t[2];m<Q.attributes.length;m++)K[46](3,t[1],h,Q.attributes[m].name+":"+Q.attributes[m].value)}else for(O in Q)K[46](5,t[1],h,O);if((Q.nodeType== +C&&(D=Q,D.wholeText&&K[46](6,t[1],h,D.wholeText)),Q.nodeType)==e)for(Q=Q.firstChild;Q;)I[19](1,3,t[n[0]],L,h,Q),Q=Q.nextSibling}if(N-3>=((N>>1&7)==(N-5>>4||p.call(this,C),1)&&(e=[!1,0,""],yE.call(this),this.headers=new Map,this.V=null,this[n[1]]=e[1],this.o=e[2],this.G=e[n[0]],this.S=e[n[0]],this.K=e[n[0]],this.B=e[1],this.l=e[2],this.A=e[2],this.P=e[n[0]],this.h=e[n[0]],this.i=null,this.Y=e[n[0]],this.F=C||null),27)&&N+1<43)a:{if((q=[1,3,null],p2)(),O=q[2],L.i==h)I[37](n[2],q[2],L),U[44](21,q[2], +L),L.i=q[2],u=2;else if(U[24](5,h,L.G))O=h.Y,y[39](19,q[2],h,L.G),u=e;else{A=void 0;break a}if(L.B!=n[0])if(h.P)if(u==e)D=h.A?h.A.length:0,t=Date.now()-h.Z,c=L.Y,G=H[14](2),v[44](36,G,new JC(G,D,t,c)),f[n[2]](8,!0,L);else W[41](7,!0,n[0],L);else{if((B=(m=h.W,h.V),B==C)||B==n[0]&&m>n[0])EB(),m>200&&(L.mF=h.W);else{if(u==e&&y[36](12,2,!1,!0,q[n[0]],h,L)||u==2&&l[9](12,q[1],L)){A=void 0;break a}zH()}(O&&O.length>n[0]&&(Q=L.G,Q.G=Q.G.concat(O)),du)();switch(B){case e:S[39](2,2,L,5);break;case 4:S[39](1, +2,L,10);break;case C:S[39](2,2,L,6);break;default:S[39](3,2,L,2)}}}return A},function(N,C,e,L,h,Q,m,O,t){return N-((N|(O=['"',11,"i"],24))==N&&(t=new wu(function(D,q,u,B,G,c,A,n){if(B=(c=(G=function(R){q(R)},n=function(R,F){(c[R]=(B--,F),B==0)&&D(c)},[]),L.length))for(u=0;u<L.length;u++)A=L[u],U[28](1,e,C,!0,A,G,kW(n,u));else D(c)})),4)<O[1]&&(N+9&3)>=2&&(VO.call(this,C,L,h,Q,m),this[O[2]]=new xz,P[39](16,O[0],this[O[2]],ao),I[24](1,!0,this[O[2]],"rc-anchor-checkbox"),T[22](9,O[0],this,this[O[2]]), +this.X=e),t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC){if((((N|(((UC=[33,((N&109)==N&&(e.Rz=C),12),"i"],N)+6^32)>=N&&(N-9^26)<N&&(Df=new rw),8))==N&&(e=C[UC[2]],U[10](66,S[4](32,"_"),e,0)),N)-9|1)<N&&(N-5^6)>=N){Q=(B=(Y=(d=[null,1,!1],new gu),P[4](UC[1],L[UC[2]])),B.next());try{for(;!Q.done;Q=B.next())F=Q.value,k=new be,F.value===null?(n=k,z=new Mt,l[28](42,d[0],13,$z,z,n,Mt)):F.value instanceof mu?F[UC[2]]?(x=k,m=F.value.toString(),R=$z,I[UC[0]](20,m== +d[0]?m:U[45](1,"bigint",m),4,void 0,R,x)):(A=k,q=F.value.toString(),c=$z,I[UC[0]](36,q==d[0]?q:U[45](9,"bigint",q),C,void 0,c,A)):F.value instanceof N0?F[UC[2]]?(O=k,D=H[28](19,d[1],31,F.value.value),r=O,X=$z,I[UC[0]](4,H[0](15,d[2],D),6,void 0,X,r)):(w=k,J=H[28](17,d[1],31,F.value.value),mQ=$z,a=w,I[UC[0]](28,H[0](14,d[2],J),8,void 0,mQ,a)):typeof F.value==="string"?F[UC[2]]?P[36](32,d[0],e,$z,F.value,k):P[36](52,d[0],d[1],$z,F.value,k):F.value instanceof Uint8Array?F[UC[2]]?(G=$z,Z=k,I[UC[0]](36, +y[39](13,d[0],F.value,d[2]),5,void 0,G,Z)):(u=k,hA=$z,I[UC[0]](4,y[39](10,d[0],F.value,d[2]),7,void 0,hA,u)):F.value instanceof Cz?F[UC[2]]?(g=k,h=y[44](39,0,d[0],F.value),l[28](59,d[0],11,$z,h,g,eX)):(E=k,M=y[44](7,0,d[0],F.value),l[28](43,d[0],UC[1],$z,M,E,eX)):k=F.value[UC[2]],v[0](16,4096,k,be,Y)}finally{Q&&!Q.done&&(t=B.return)&&t.call(B)}Df=Y}return((N^87)&14)==4&&(this.B=C,this[UC[2]]=e),Df},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){if((Z=[0,14,"G2"],N&92)==N){if((m=(h=(e=(Q=(L=C.B, +[128,14,28]),C.i),L[e++]),h&127),h)&Q[Z[0]]&&(h=L[e++],m|=(h&127)<<7,h&Q[Z[0]]&&(h=L[e++],m|=(h&127)<<Q[1],h&Q[Z[0]]&&(h=L[e++],m|=(h&127)<<21,h&Q[Z[0]]&&(h=L[e++],m|=h<<Q[2],h&Q[Z[0]]&&L[e++]&Q[Z[0]]&&L[e++]&Q[Z[0]]&&L[e++]&Q[Z[0]]&&L[e++]&Q[Z[0]]&&L[e++]&Q[Z[0]])))))throw Error();f[20](26,e,C),F=m}if(N-5>>3==2){if(u=(D=(U[21](28,(A=[!0,1024,4],e)),W[45](2,A[2],L,C,Q,void 0,A[Z[0]],e)),n=I[32](33,A[1],A[2],D===Fq?7:D[Rw]|Z[0]))!=null?n:1024,t)if(Array.isArray(m))for(G=m.length,R=Z[0];R<G;R++)D.push(h(m[R], +u));else{q=(c=P[4](Z[1],m),c.next());try{for(;!q.done;q=c.next())D.push(h(q.value,u))}finally{q&&!q.done&&(B=c.return)&&B.call(c)}}else{if(O)throw Error();D.push(h(m,u))}F=e}return(N-4|6)<N&&(N-6^12)>=N&&(e.oz(),t=e.response,O=Lz(),q=e.Hm[Z[2]](),L=hS(),Q=l[23](4,C,6,q,L),t[O]=Q,m=e.response,f[36](12,!0,m)?D="":(h=QI(m),D=W[39](37,3,h)),F=D),F},function(N,C,e,L,h,Q){if((N|((Q=[4,6,2],N)<<1&Q[1]||(h=U[Q[0]](Q[2],8466)(L(C(),5))),40))==N)K[5](17,[-46],T[42].bind(null,19));return(N|Q[0])>>Q[0]||p.call(this, +C),h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F){return(R=["X",4,44],(N+R[1]^19)>=N&&(N-R[1]^24)<N&&L&&(e[R[0]]?S[9](R[2],e[R[0]],L)||e[R[0]].push(L):e[R[0]]=[L],K[46](15,e,L,C)),(N^31)>>R[1]<2)&&N-2>>3>=0&&(t=this,F=P[R[2]](73,function(Z,X,Y){Y=(X=[2,3,1],[0,36,1]);switch(Z.B){case X[2]:if(!(c=(D=(A=(B=Promise.resolve(null),Promise.resolve([null,null])),n=null),new m5),t.o)){Z.js(X[Y[0]]);break}return Z.K(X[Y[2]]),Z.i(Promise.race([t.o,Promise.resolve(null)]),5);case 5:if(O=Z.G)f[6](91,1024, +c,X[2],O.rt,T[45].bind(null,12)),K[23](61,X[Y[0]],O.op,c),H[38](8,c,K[24](Y[1],O.lY),4),O.OC!=null&&K[23](28,6,O.OC,c),y[44](13,X[Y[2]],c,O.Pc||X[2]);else y[44](8,X[Y[2]],c,X[Y[0]]);Z.V(X[Y[0]]);break;case X[Y[2]]:Z.o(),y[44](13,X[Y[2]],c,X[Y[2]]);case X[Y[0]]:return t.h&&(G=t.i.i.AK())&&(B=G.catch(function(){return null})),t.G!=null&&(A=H[27](26,X[Y[0]],!1,X[2],6,t).catch(function(){return[null,null]})),m=P[4].bind(null,10),Z.i(Promise.all([B,A]),6);case 6:Q=m(Z.G),u=Q.next().value,q=Q.next().value, +Array.isArray(q)&&q.length===2&&(h=P[4](14,q),n=h.next().value,D=h.next().value),T[Y[2]](24,4,n,C,u?u.request:null,e,D,L,t,t.G==null?null:U[Y[2]](47,X[Y[0]],4,H[10](49,X[Y[2]],new OA,v[28](Y[2],5,Y[0],tS.get(t.G)))),l[43](40,X[Y[2]],c,void 0,FG)?c:void 0),Z.P()}})),F},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){return(N>>((B=[8,2,null],N+1)&3||(G=W[B[0]](B[0],0,C,B[2],6,e,L).catch(function(){return K[18](90,e,L)})),B[1])&7)==1&&(G=P[44](45,function(c,A,n){n=(A=["none",6,0],[2,44,1]);switch(c.B){case n[2]:if(!(L instanceof +(c.K(n[0]),UA)))return v[n[1]](37,h,"n"),c.return();if((u=S[17](17,null,4,U[13](12,L,Dx,C,rY).S2()),u)===null)return v[n[1]](35,h,"n"),c.return();return Q=(h.h=(t=h.mF)==null?void 0:P[42](3,t),function(R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M){d=[2,16,(M=[4,9,1],10)];a:{r=(x=(X=(E=(J=new q0,w=R.getValue(),K[23](27,d[0],w,J)),S[49](30,3,R)),P[0](12,E,X,3)),T[8](49,M[0],R)),z=K[23](33,M[0],r,x);switch(W[M[0]](M[2],R,M[2])){case M[2]:I[46](M[2],z,M[2]);break;case d[0]:I[46](M[0],z,d[0]);break;case 5:I[46](2, +z,6);break;case 6:I[46](3,z,7);break;case 7:I[46](M[0],z,5);break;case 3:I[46](2,z,3);break;case M[0]:I[46](2,z,M[0]);break;case e:I[46](M[2],z,e);break;case M[1]:I[46](2,z,M[1]);break;case d[2]:I[46](M[2],z,d[2]);break;case C:I[46](M[0],z,C);break;case 12:I[46](3,z,12);break;case 18:I[46](M[0],z,13);break;case 13:I[46](3,z,14);break;case 14:I[46](3,z,15);break;case 15:I[46](2,z,d[M[2]]);break;case d[M[2]]:I[46](M[2],z,17);break;case 17:I[46](M[2],z,18);break;default:Promise.resolve();break a}F=(g= +(a=(Y=(Z=new u6,P[36](36,null,5,B7,h.l,Z,rY)),k=new jX,f)[5](16,k,q0,6,z),f[5](56,Y,jX,M[0],a,rY)),new Gk(g)),h.u.send(F,!0,!1)}}),O=function(R,F){h.h&&h.h.then(function(Z){Z({detail:[R,F]})}).catch(function(){})},c.K(4),c.i(S[39](6,A[n[0]],".",A[0],n[2],h.i,v[n[0]](n[2],n[2],U[13](18,L,Dx,C,rY)),u,Q,O),A[n[2]]);case A[n[2]]:((D=(m=v[31]((h.G=(q=c.G,q),n)[2],29))!=null?m:0,D)>A[n[0]]?setTimeout(function(){v[44](39,h,"r")},D):v[n[1]](33,h,"r"),c).V(5,n[0]);break;case 4:c.o(n[0]),v[n[1]](38,h,"n"); +case 5:c.V(A[n[0]]);break;case n[0]:c.o(),v[n[1]](33,h,"n"),c.P()}})),G},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k){if((N+1&(k=["apply",49,28],14)||(C=H[15](k[2],this),e=f[1](35,this),this.Pm[C]=e),N^53)<13&&((N|9)&7)>=4)a:{h=(D=(O=((B=(R=[!0,14,939],R[0]),B=B===void 0?!1:B,L=L===void 0?!1:L,(Z=c7.M()).o)[k[0]](Z,T[5](39,H[44](83))),c=c7.M(),Object.values(Kz)),P[4](10,O)),D.next());try{for(;!h.done;h=D.next())t=h.value,c.G.has(t)||(Q=P[4](15,y[41](9,c,e)).next().value,c.G.set(t,Q))}finally{h&& +!h.done&&(n=D.return)&&n.call(D)}try{Y=(F=(m=(A=U[2](8,R[2],3,586,R[1],L),new AS(S[k[1]](20,e,A.i),v[3](35,A.i,y[11](19),C).slice(),A.B)),null),B&&(q=U[30](20,12,C,e),u=U[30](18,12,C,C),F=new yI(u,q)),new i6(m,F));break a}finally{(X=c7.M()).i[k[0]](X,T[5](87,H[44](82))),G=c7.M(),G.i[k[0]](G,T[5](73,G.G.values())),G.G.clear()}}return N-((N&38)==N&&(Y=P[18](29,S[32](24,new b4,6),[W[0](3,C),W[0](18,e),y[38](16,L)])),6)>>4||(e=H[15](k[2],this),C=y[34](62,this),this.V&&Object.prototype.hasOwnProperty.call(this.V, +C)?this.Pm[e]=this.V[C]:this.Pm[e]=S[k[2]](57)[C]),Y},function(N,C,e,L,h,Q,m,O){if(O=[15,"platform",9],(N&59)==N)a:{if(typeof MessageChannel!=="undefined"){m=((L=(h=new MessageChannel,Q={}),h[v7()]).onmessage=function(t){Q.next!==void 0&&(Q=Q.next,t=Q.M4,Q.M4=C,t())},function(t){h[(L=(L.next={M4:t},L).next,nz)()].postMessage(e)});break a}m=function(t){Zf.setTimeout(t,e)}}return(N-O[2]^O[0])<N&&N-3<<1>=N&&(m=W[11](58)?Ie[O[1]]==="Windows":I[1](88,"Windows")),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(((N^ +(u=[14,"yl",2],27))&15)==1)P[44](41,function(G,c,A){c=(A=[2,"K",0],[!0,1,4]);switch(G.B){case c[1]:return O=!1,G[A[1]](C),G.i(Q.G,c[A[0]]);case c[A[0]]:return O=!(!L||h),t=G.G,G.i(t.send(Re),5);case 5:S[35](6,null,c[A[2]],(m=G.G,m.Mo),Q,m.E8,m.jx,O,m.t0),G.V(A[2]);break;case C:G.o(),S[35](7,null,c[A[2]],[],Q,null,[],O,e),G.P()}});if((N<<u[2]&15)>=11&&(N-8&16)<11)a:{if(D=(t=(m=T[39](18,C,Q),m[L]),m)[C].c9,t){q=(O=S[40](16,e,t),y[31](17,h,H[1].bind(null,44),f[37].bind(null,20),t,FN).LD),B=function(G, +c,A){return D(G,c,A,q,O)};break a}B=D}return((((N>>1&15)==u[2]&&p.call(this,C,0,l6[u[1]]),N)|u[2])&u[0])==u[2]&&(B=typeof BigInt==="function"),B},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(N>>1<((N+2&((N>>1&28)<((((G=[80,"Pm","i"],N^4)>>3==3&&YK.call(this,150,7,[2]),N)^G[0])&15||Tk.call(this),28)&&(N<<1&13)>=10&&(e=[],C.G.Ss.Jc.tc.forEach(function(c,A){c.selected&&Zx(this.T,A)==-1&&e.push(A)},C),B=e),30))==4&&(L?e.tabIndex=C:(e.tabIndex=-1,e.removeAttribute(oe()))),25)&&(N+7&31)>=12){if((q=(u=this[t= +(((m=H[15](4,(O=[0,(D=[],L=this,1),3],this)),e=y[34](60,this),T[0](1,O[1],this[G[2]]),f)[6](60,this[G[2]]),T)[0](64,O[1],this[G[2]]),I[22](20,this[G[2]])),T[0](67,O[1],this[G[2]]),f[6](61,this[G[2]]),G[2]][G[2]],T[0](64,O[1],this[G[2]]),I)[22](20,this[G[2]]),h=this[G[1]][q])&&h.length!==0)h.forEach(function(c,A){((L[(A=["G","Pm","i"],L)[A[1]][t]=c,A[2]][A[2]]=u,L)[A[0]][e].call(L,C-3),D).push(L[A[1]][q])});else for(Q=O[0];Q<C-O[2];Q++)y[34](63,this);this[G[1]][m]=D}return B},function(N,C,e,L,h,Q, +m,O,t,D,q,u,B,G,c){if(N-8<<1<(c=["","B","i"],N)&&(N-9|34)>=N)a:{if(!m[c[2]]){G=Q;break a}if(!Q){G=e;break a}try{if(t=GH(Q))for(q=0;q<t.length;q++)if(Array.isArray(t[q])&&(u=t[q],!(u.length<h||(O=u[C],!Array.isArray(O)||O.length<C||(B=O[0],B==L||B=="stop"||B=="close")))))for(D=C;D<O.length;D++)O[D]=c[0];G=(new P7).G2(t);break a}catch(A){G=(sA(),Q);break a}}return(N|24)==N&&(this[c[1]]=L,this[c[2]]=C,this.UK=e),G},function(N,C,e,L,h,Q,m,O){if((N&59)==((N<<(m=[13,4,23],1)&7)>=3&&N>>2<12&&(Q=["animation-play-state", +"display","running"],h.I6(L),S[29](71,h.h,Q[1],C),S[29](m[2],h.h,Q[0],Q[2]),S[29](39,h.h,"opacity",e),S[29](m[2],h.iI,Q[0],Q[2])),N))H[7](10,e.v(),C,"rc-response-input-field-error");return(N+m[1]&53)>=N&&(N-m[1]^m[0])<N&&(e=C.B,O=e.B.length+e.i.length),O},function(N,C,e,L,h,Q,m){if(((N-(Q=["add",((N-1|60)>=N&&N-4<<1<N&&(this.x=C!==void 0?C:0,this.y=e!==void 0?e:0),20),14],N-5<<2>=N&&(N+6^31)<N&&(m=P[0](Q[2],L,e,C)),9)|12)>=N&&N+4>>1<N&&(h=new fz,h[Q[0]](XN,I[6](32,L.i,SX)),h[Q[0]](YY,e),h[Q[0]](W7, +"8x-4t2pegToiW8KmThtO4AQt"),h[Q[0]](H7,Date.now()-L.h),window[Bh][kY()]&&h[Q[0]](rd,C),m=K[43](34,pz)+"?"+h.toString()),(N^11)>=Q[1])&&(N<<1&8)<8)a:if(e&L){m=512&L?512:C&L?1024:0;break a}return m},function(N,C,e,L,h,Q,m,O,t,D,q,u){if((N-3&7)==((q=[18,26,24],(N&106)==N)&&(u=H[2](q[0],C,function(B,G,c){return T[(G=(c=[6,18,0],U)[48](2,B),c)[1]](67,c[2],c[0],5,3,G(S[28](48)).concat(G(document)))})),1))a:{if(C==(D=(m=(U[21](31,(t=[0,null],Q)),Q).z2,m[Rw]|t[0]),t)[1])if(O=P[q[2]](8,t[1],m),P[49](9,t[1], +L,h,O,m,D)===e)O.set(h,t[0]);else{u=Q;break a}else D=H[4](12,t[1],D,h,L,e,m);W[q[1]](10,D,e,m,C,L),u=Q}return u},function(N,C,e,L,h,Q,m){return(m=[5,7,"https://chat.google.com/punctual/"],(N|1)>>m[0]<3&&(N<<1&m[1])>=1&&(e.G=h?U[31](8,L,C):L,Q=e),N&123)==N&&(Q={f0:new sB(m[2]+C),Y7:new sB(m[2]+C),BS:!1}),Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){return(N|7)>=(((A=["subscribe",.5,1],(N-4|75)<N)&&N-5<<2>=N&&(h=JS(e,L),c=h==void 0||h.get==void 0||H[39](16,"",!1,h.get,W[28](32,!1,function(n){return n.stringify}))? +e:new EA(W[28](A[2],!1,function(n){return n.stringify(C+h.get)}))),(N^95)>>4==4&&(C.keyCode==13?U[29](66,!1,this):this.l&&this.i&&f[22](5,"",this.i).length>0&&this.Mp(!1)),(N|4)>>3)||(G=function(n){U[12](24,"'",O(n,(D++,u++))).subscribe(new zk(t,function(R){t.next(R)},void 0,function(R){for(D--,R={};q.length&&D<Q;R={xL:void 0})R.xL=q.shift(),G(R.xL);!B||q.length||D||t.complete()}))},u=e,B=h,D=e,q=[],m[A[0]](new zk(t,function(n){return D<Q?G(n):q.push(n)},void 0,function(){(B=L,!B)||q.length||D||t.complete()})), +c=function(){q=C}),10)&&(N+9&8)<4&&(h?Q=h.K:Q=L.o6++,O=U[36](31,L.F),U[35](74,O,dd(),L.R),U[35](72,O,wd(),Q),U[35](75,O,VI(),L.T),W[24](9,O,L),L.A&&L.j&&W[41](82,C,L.A,L.j,O),t=new xY(Q,L,L.Y+A[2],L.K),L.A===null&&(t.l=L.j),h&&(L.o=h.Y.concat(L.o)),m=P[44](2,!1,"",L,L.JO,t),t.setTimeout(ae(L.Np*A[1])+ae(L.Np*A[1]*Vn())),U[10](60,t,L.G),W[33](2,e,m,O,t)),c},function(N,C,e,L,h,Q,m,O,t,D,q,u){if(!((q=[1,"cK","push"],N)>>2&7)){for(;L&&L.nodeType!=C;)L=e?L.nextSibling:L.previousSibling;u=L}if(N+4>>2<N&& +N+8>>q[0]>=N){for(Q=(D=C[O=C[q[1]](),q[1]](),m=[D],O!=D&&m[q[2]](O),L=[],e.Wm);Q;)h=Q&-Q,L[q[2]](v[9](8,h,C)),Q&=~h;(t=(m[q[2]].apply(m,L),e).X)&&m[q[2]].apply(m,t),u=m}return u},function(N,C,e,L,h,Q,m,O){if((((N|64)==N&&(e=e===void 0?null:e,m={then:function(t,D){return e&&e(t,D),I[37](71,C.then(t,D))},"catch":function(t){return I[37](67,C.then(void 0,t),e)}}),O=[32,"h",6],(N-7&O[2])==2&&e[O[1]]!=C&&(Zf.clearTimeout(e[O[1]]),e[O[1]]=C),N)|56)==N){if((h=S[41](40,(L=[".*","u",0],1),void 0,C),!h)||h.length=== +0)throw Error("Missing path");((this.B=new RegExp(h,"u"),this).i=(e=S[41](42,2,void 0,C))&&e.length>L[2]?new RegExp(e,"u"):RegExp(L[0],L[1]),this).action=S[41](O[0],3,void 0,C)}return N-1>>4||(this.op=h,this.rt=L,this.Pc=Q,this.OC=e,this.lY=C),m},function(N,C,e){return C=[1,7,11],e},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X){if(N+(X=["mid",2048,2],8)>>1>=N&&N-4<<X[2]<N)a:{if(L==(m=m===void 0?0:m,t=[64,1,1024],null))O=32,Q?(O|=C,L=[Q]):L=[],h&&(O=O&-16760833|(h&1023)<<14);else{if(!Array.isArray(L))throw Error("narr"); +if((O=L[Rw]|0,fy)&&t[1]&O)throw Error("rfarr");if(X[1]&O&&!(e&O)&&f[26](65,"carr",5,t[1]),O&256)throw Error("farr");if(O&t[0]){Z=((O|m)!==O&&W[32](8,O|m,L),L);break a}if(Q&&(O|=C,Q!==L[0]))throw Error(X[0]);b:{if(B=(c=O|t[u=L,0],u.length))if(q=B-t[1],n=u[q],n!=null&&typeof n==="object"&&n.constructor===Object){if(G=(R=c&C?0:-1,q-R),G>=t[X[2]])throw Error("pvtlmt");for(A in n)D=+A,D<G&&(u[D+R]=n[A],delete n[A]);O=c&-16760833|(G&1023)<<14;break b}if(h){if(F=vh(h,B-(c&C?0:-1)),F>t[X[2]])throw Error("spvt"); +O=c&-16760833|(F&1023)<<14}else O=c}}Z=(W[32](16,O|t[0]|m,L),L)}if(((N^38)&3)==1){for(Q=(e=(m=(O=(L=(h=[8,3,4],H)[X[2]](72,C),[]),H)[X[2]](56,C),H)[X[2]](76,C),0);Q<h[0];Q+=h[X[2]])O.push(m.charCodeAt(Q)<<24|m.charCodeAt(Q+1)<<16|m.charCodeAt(Q+X[2])<<h[0]|m.charCodeAt(Q+h[1]));for(Q=(m=[],m.length=e.length,0);Q<e.length;Q++)m[Q]=e.charCodeAt(Q);(L=(e=new gd(m),(new b6(O,L)).substring(e,0,e.length)),L=K[19](18,0,L),U)[29](68,L,C)}return Z},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if((B=[4,"B",1],((N^ +74)&5)==B[2]&&(G=U[38](16)?!1:I[B[2]](77,C)),(N&90)==N&&(G=U[13](16,e,M0,C,rY)),(N+2&46)<N)&&(N-B[0]|27)>=N)a:{if(!l[B[2]](80,(q=[0,4,null],"GET"),e,Q)){G=P[21](10,h,Q.i);break a}if(O=Q.i.getResponse(),O===""){G=h;break a}if(!(D=W[B[2]](14,(m=(u=h,O.length),Q.i))==q[B[2]],Q)[B[1]].G){if(typeof TextDecoder==="undefined"){G=($Y(),f[7](37,q[2],Q),l[14](26,q[0],Q),h);break a}Q[B[1]].G=new Zf.TextDecoder}for(t=q[0];t<m;t++)Q[B[1]][B[1]]=C,u+=Q[B[1]].G.decode(O[t],{stream:!(D&&t==m-L)});G=Q[Q[B[O.length= +q[0],1]].i+=u,Q.X=q[0],B[1]].i}return(N|16)==N&&(G=P[44](45,function(c,A){if(c.B==(A=[6,1,!1],A[1]))return c.i(K[49](11,22,A[1],A[2],A[0],e),C);((L=c.G,e).uI.send(NL,L),c).P()})),G},function(N,C,e,L,h,Q,m){if((Q=[6,25,9],(N-1^Q[2])>=N&&(N-2^Q[1])<N)&&(l[Q[2]](2,e),this.i=C,C!=null&&C.length===0))throw Error("ByteString should be constructed with non-empty values");return(N-3^13)<N&&(N-Q[0]|Q[2])>=N&&(h=new CN(L===void 0?"":L,e),m={isSuccess:function(){return h.i==C},getVerdictToken:function(){return h.B}, +getStatusCode:function(){return eW.has(h.i)?eW.get(h.i):LN()}}),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){return(N^35)>>(((((N^(((N^53)&15)==((B=[0,10,"aC"],(N>>2&15)==3)&&(this.G=[],e=e===void 0?!1:e,m=[0,!0,""],this.w$=C,u=this,this.V=h===void 0?null:h,D=m[1],D=D===void 0?!0:D,this.iI=L,this.HS=e,this.R=m[2],this.o6=[null].concat([this.UC,this.fV,this.nR,this[B[2]],this.qm,this.Ta].map(function(c){return c.bind(u)})),this.i=new hl,this.Pm=Array(2048).fill(void 0),this.l=K[29](1,m[B[0]],qY()),this.E5= +H[24](15,m[1],m[B[0]],this.iK.bind(this)),this.S=new Map,this.ZM=Q4.bind(null,this.A0.bind(this),72),this.K=[],this.B=[],this.h=S[2](25,1),this.j_=!(!D||!mX),Q=this.h.run.bind(this.h,this.Ju.bind(this,null)),this.j_?(O=this.wZ.bind(this),t=function(c){u.h.run(function(){return O(c)})},q=function(c){return mX(t,{timeout:c})}):q=function(c){return Q4(Q,RY(c,62))},this.JO=q,this.s5=function(){document[OR()]?tl.then(Q):Q4(Q,1)},this.rq=UR.bind(null,this.o5.bind(this),m[1]),this.qp=this.B.unshift.bind(this.B), +this.J=m[B[0]],this.X=null,this.P=m[B[0]],this.Z=m[B[0]],this.o=m[B[0]],this.W=qY(),this.Y=new DN,this.C=new DN,this.u=m[B[0]],this.T=m[B[0]],this.F=m[B[0]],this.j=null,this.A=m[B[0]],this.O=m[B[0]],P[26](32,this)),4)&&(e=H[2](28,C),L=H[2](56,C),e=W[7](33,7,B[1],e),L+=K[19](11,B[0],e),U[29](36,L,C)),34))&15)==2&&(m=m===void 0?qY()+3E3:m,O=O===void 0?qY()+3E3+250:O,D=D===void 0?H[40].bind(null,3):D,t=t===void 0?H[40].bind(null,56):t,this.TD=h,this.kO=t,this.QU=D,this.DM=L,this.H=C,this.T$=Q,this.Da= +O,this.TX=m,this.kZ=e),N-7)^8)>=N&&(N+4^32)<N&&(G=P[B[0]](76,e,L,C,rY)),4)||(G=P[4](40,2,K[44](44,1,new u4,C),qY())),G},function(N,C,e,L,h,Q,m,O,t){return(((N-((t=[52,1,"G"],((N^t[0])&7)==t[1]&&(e.o=!L,e[t[2]]=C,e.B=h,P[6](41,!1,!0,e)),N>>t[1]<27&&((N^20)&14)>=11)&&(m=L[t[2]],m||(e===h?e=h=qL(e):(e=qL(e),h=qL(h))),L.K.push([e,h,Q]),m&&P[6](33,!1,C,L)),t)[1]^19)<N&&(N+7^15)>=N&&(O=uw[C]),N)&76)==N&&p.call(this,C),O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return(N<<((N|((N&126)==(u=[84,28,26],(N+1&u[1])< +N&&(N+3&46)>=N&&(this.promise=new Promise(function(G,c){C=(e=G,c)}),this.resolve=e,this.reject=C),N)&&(D=O.i.h,Q=Q===void 0?!1:Q,q=I[20](24,!1,null,[(0,B8.tj)(O.E5.bind(O,m),C),O.P]).then(function(G,c,A,n){return(0,(c=(n=(A=P[4](12,G),A.next().value),A.next().value),B8).tj)(function(R,F,Z,X,Y,k){return(R=(X=(F=(Z=(k=[36,"call",25],c.send),W[k[0]](k[0],v[6](k[2],!0,L,n,O,t))),O.Ku),Y=B0.M().get(),T)[42](k[0],h,Y),Z)[k[1]](c,h5,new jW(F,X,!(!R||!O.i.i),Q))},12)}).V(function(){}),W[36](74,15E3*(e+D), +function(){(q.cancel(),O).A(t,yp)}),B=q),24))==N&&(B=T[16](31,e,GJ,U[u[2]](4,17,W[1](73,C,L),h.toString(),c0))),1)&11)>=6&&(N|9)>>4<3&&(YK.call(this,43,17,[2]),this.F=this.X=this.l=this.I=this.K=this.G=this.J=this.T=this.O=this.Z=this.R=this.H=this.u=this.o=this.S=this.Y=this.B=this.h=-1,this.W=I[21](23),this.C=I[21](u[0])),B},function(N,C,e,L,h,Q,m,O){return(N-2^15)<((O=["K","number",7],N)-O[2]<<2>=N&&(N-5|9)<N&&(typeof e==O[1]&&(e=ae(e)+C),m=e),N)&&(N+4&57)>=N&&(Q=I[49](35,!0,L,h),h[O[0]]=h[O[0]].then(Q, +Q).then(function(t){return S[11](49,e,t.D(),C)}),m=h[O[0]]),m},function(N,C,e,L,h,Q,m,O,t,D){if((N>>(D=[2,1,32],D[1])&15)==4&&(e=[],C.G.Ss.Jc.tc.forEach(function(q,u){q.selected&&e.push(u)}),t=e),N+4>>D[1]>=N&&N-5<<D[0]<N)y[44](16,D[1],C,e);if(((N|80)==N&&(t=P8('<div>This site is exceeding <a href="https://developers.google.com/recaptcha/docs/faq#are-there-any-qps-or-daily-limits-on-my-use-of-recaptcha" target="_blank">reCAPTCHA quota</a>.</div>')),(N|D[1])<39)&&N+6>=22){for(Q=(m=U[D[2]](24,C,L,255), +C),O=e;Q<h.length;Q++)O+=String.fromCharCode(h.charCodeAt(Q)^m());t=O}return(N-9|56)<N&&N-6<<D[1]>=N&&(KN.call(this,I[14](D[0],Al),function(){},y4()),H[47](13,14,H[49](18,D[1],v[9](12,0,!1,C))),I[21](D[2],C.D(),this),this.WL=iw),t},function(N,C,e,L,h,Q,m){if((N|(m=[18,105,14],(N&46)==N&&(v0.call(this,C),this.l=1,this.i=[[]]),2))>=17&&N>>1<m[0])a:{for(h=(L=nN(Date),0);h<L.length;h++)if(L[h].length==3&&L[h].charCodeAt(-1)==e){Q=L[h];break a}Q=C}return((N|1)&((N&((N|8)>>4||(Q=TH(Vn()*C)),m[1]))==N&& +(Q=P8('<div>This site is exceeding <a href="https://cloud.google.com/recaptcha/docs/billing-information" target="_blank">reCAPTCHA Enterprise free quota</a>.</div>')),15))==3&&(KN.call(this,I[m[2]](64,IE),U[5](21,RE),y4()),v[48](38,Fo,this,C),v[48](30,lw,this,QI(e))),Q},function(N,C,e,L,h,Q,m,O){if(!(N>>((m=["flush",56,"K"],(N&14)==N)&&(O=TJ[C]),2)&15)){if(e<C)throw Error();if((h=(Q=L.i,Q+e),h)>L.G)throw Error();O=Q,L.i=h}return((N|m[1])==N&&C.G.read().then(C.I.bind(C)).catch(C[m[2]].bind(C)),(N- +9^18)>=N)&&(N-2|11)<N&&(O=ZN.M()[m[0]]()),O},function(N,C,e,L,h,Q,m,O,t,D,q,u){if(((u=[28,19,7],N)-u[2]&15)==1)a:{if(P0((h=oE(Number(L)),h))){q=l[46](16,h);break a}q=((Q=L.indexOf(ZD()),Q)!==-1&&(L=L.substring(e,Q)),I[u[0]](3)?l[46](40,sR(C,BigInt(L))):l[46](56,f[24](15,"",0,L)))}if(N-1<<2>=N&&(N-2|u[0])<N)P[44](41,function(B,G,c,A,n,R){if(B[R=["B",0,"G"],R[0]]==e)return B.K(C),O=Q[R[0]][R[2]].value,G=new fN,A=P[R[1]](77,G,O,h,rY),t=new Xo(A),B.i(Q.i[R[0]].send(t),L);if(B[R[0]]!=C){if(D=(m=B[R[2]], +Q[R[0]][R[2]].value),m.Fa()==""||O!=D)return B.return();return(n=Q[R[0]],c=m.Fa(),n[R[2]]).value=c,B.V(R[1])}B.o(),B.P()});return N-((N>>1&15)>=9&&N+4<u[0]&&(L=e.style[v[49](16,"visibility")],q=typeof L!=="undefined"?L:e.style[l[u[1]](48,"visibility",e)]||C),u[2])>>3==3&&(q=function(){return(0,B8.tj)(L.E5.bind(L,new SW(e.p7)),2).then(function(B,G){return G=[6,11,26],H[G[1]](2,G[0],v[G[0]](G[2],C,8,B,L,e.lQ),YZ)})}),q}]}(),v=function(){return[function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return(N>>2&15)==(N- +2<<((N&((N+7&((N-3|(B=[32,1,35],B)[2])<N&&N-2<<2>=N&&(e=H[2](76,C),e=H[2](28,C)+e,U[29](5,e,C)),50))>=N&&(N+B[1]&49)<N&&H[47](55,64,C,e,L)&&K[47](74,B[1],C,e,L),107))==N&&(u=P0(L)?l[46](56,y[49](40,C,e,L)):l[46](16,S[34](4,16,e,L))),2)>=N&&(N+4^8)<N&&(L=e.tabIndex,u=typeof L==="number"&&L>=C&&L<32768),4)&&(q=[32,2,0],U[21](B[0],h),t=h.z2,O=S[B[0]](25,q[0],B[1],L,h,void 0,t[Rw]|q[2],t,q[B[1]],!0),e=e!=null?l[5](B[1],e,L):new L,O.push(e),D=Q=O===Fq?7:O[Rw]|q[2],(m=U[22](9,e))?(Q&=-9,O.length===1&&(Q&= +-4097)):Q|=C,Q!==D&&W[B[0]](8,Q,O),m||l[B[1]](72,t),u=e),u},function(N,C,e,L,h){return N<<(N<<1>=(L=[22,6,2],1)&&(N+4&L[1])<1&&(h=P8('Type your best guess of the text shown. To get a new challenge, click the reload icon. <a href="https://support.google.com/recaptcha" target="_blank">Learn more.</a>')),L[2])&L[1]||(v[L[0]](67,C,e),h=e),h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){if(!(N-((N|((N|40)==(Z=[1,2,16],N)&&p.call(this,C,0,W0.yl),6))>>3==Z[1]&&p.call(this,C),6)&14)){for(L=(O=(B=W[49]((h= +(G=["<table",(n=C.rowSpan,'"'),0],C.colSpan),29),n,4)&&W[49](26,h,4)?' class="'+H[7](32,"rc-imageselect-table-44")+G[Z[0]]:W[49](30,n,4)&&W[49](29,h,Z[1])?' class="'+H[7](33,"rc-imageselect-table-42")+G[Z[0]]:' class="'+H[7](Z[0],"rc-imageselect-table-33")+G[Z[0]],T)[Z[0]](81,fJ(),G[0]+B+"><tbody>"),vh(G[Z[1]],wq(n-G[Z[1]]))),m=G[Z[1]];m<L;m++){for(q=(A=(T[Z[0]](65,(D=m*Z[0],O),H0()),vh(G[Z[1]],wq(h-G[Z[1]]))),G)[Z[1]];q<A;q++){for(R in R=(u=(t=((T[Z[0]](80,O,(Q=q*Z[0],'<td role="button" id="'+H[7](32, +D*h+Q)+'" tabindex="0" class="'+H[7](64,"rc-imageselect-tile"))+"\" aria-label='"),W)[11](80,O,U[42](50,"Image challenge")),T)[Z[0]](Z[2],O,kZ()),{tW:D,JW:Q}),c=C,void 0),c)R in u||(u[R]=c[R]);T[Z[0]](80,W[11](14,t,S[48](80,u,e)),rH())}T[Z[0]](17,O,pN())}T[Z[0]](Z[2],O,Jl()),F=O}return(N+5&61)>=N&&N-4<<Z[0]<N&&(F=U[13](24,e,ER,C)),F},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){return(((N+(N+2>>(A=[1,4,6],A)[1]||(B=C.YU,u=C.uK,q=C.Sy,this.uK=u,m=C.w$,t=C.HS,G=C.z4,Q=C.gz,this.tE=e=C.tE,O=t===void 0? +!1:t,L=C.Q$,this.gz=Q,this.HS=O,D=C.d$,this.YU=B,this.w$=m,this.Q$=L,this.d$=D,this.Sy=q===void 0?null:q,this.OK=h=C.OK,this.z4=G),A[1])^26)>=N&&(N-2^7)<N&&(L=new zJ(e,C),c={challengeAccount:function(n){return(n=[2,17,4],I)[37](68,I[n[1]](n[2],n[2],n[0],3,5,L))},verifyAccount:function(n,R){return I[37](70,(R=[49,5,1],U[R[0]](16,6,R[1],10,R[2],L,n)))},getChallengeMetadata:function(){return y[0](1,L.o)},isValid:function(){return L.Qy()}}),N>>A[0])>=15&&(N-3&20)<7&&(c=W[45](A[2],A[1],l[36].bind(null, +73),e,L,h,void 0,C)),N-A[1]|47)>=N&&(N+7&63)<N&&p.call(this,C,0,u6.yl),(N^24)<38&&(N+A[1]&31)>=19&&(e=U[23](A[0],"goog.async.run",e),dH||y[26](28),wH||(dH(),wH=C),V4.add(e,L)),c},function(N,C,e,L,h){return((N-7|(h=[6,"B",62],h)[0])<N&&(N-3|13)>=N&&(e=this[h[1]],this[h[1]]=Array.isArray(e)?(e.push(C),e):e?[e,C]:C),(N-h[0]^24)<N&&N-1<<2>=N)&&(y[42](5,C.i),f[h[0]](h[2],C.i),y[42](1,C.i),L=C.qm()),L},function(N,C,e,L,h,Q,m,O){if(((O=[20,46,13],N>>1)&3)==1){for(Q=0,h=[];Q<L.length;Q+=C)h.push(new mu(L[Q], +L[Q+e]));m=h}if(!(N<<2&4))if(h=[1,null,4],l[43](O[1],h[2],C,rY)!=h[1])this.i.G=xZ,this.i.i.onError(C.kx());else if(e=T[22](2,h[0],C,rY),H[15](31,this,e),T[42](O[0],2,C)||T[42](16,11,C))K[22](O[0],h[1],C.m0()),L=new aE(e,60,null,null,T[22](1,9,C,rY),null,C.fP()?C.fP().G2():null,!!T[42](32,10,C)),this.i.i.m$(L),P[15](27,this,!1),this.i.G=gH;else W[43](1,h[2],U[O[2]](O[2],C,bw,7,rY),this,this.B.i.getName()!=ML);return m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z){if((r=[47,21,"R6"], +N&11)==N){for(h in L=[],Q=C,e)L[Q++]=h;z=L}if((N|24)==((N&60)==N&&(f[28](62,C,L),e=K[44](70,e,L),z=L.i.has(e)),N)){if(((k=((((((((t=((u=(((O=(Q=(c=(A=(B=(D=(F=[27,29,25],P[4](12,L)),D.next()).value,D).next().value,D.next().value),Y=D.next().value,Q===void 0?{}:Q),H)[r[0]](25,14,H[49](2,1,I[42](30,2,new kn,h.B.G.value))),B)&&P[0](76,O,B,5,rY),A)&&P[0](77,O,A,4,rY),c&&P[0](13,O,c,16,rY),Y&&P[0](13,O,Y,24,rY),H[3](28,1,U[25](31,$Z))))&&P[0](14,O,u,7,rY),H[3](31,0,U[25](24,N$))))&&P[0](77,O,t,r[1],rY), +Q[Cu[r[2]]])&&P[0](12,O,Q[Cu[r[2]]],e,rY),Q)[eH[r[2]]]&&P[0](77,O,Q[eH[r[2]]],9,rY),Q[Lu[r[2]]])&&P[0](13,O,Q[Lu[r[2]]],11,rY),Q[hE[r[2]]])&&P[0](12,O,Q[hE[r[2]]],10,rY),Q[Qe[r[2]]]&&P[0](14,O,Q[Qe[r[2]]],15,rY),Q)[mn[r[2]]]&&P[0](15,O,Q[mn[r[2]]],17,rY),Q[OO[r[2]]]&&T[r[1]](36,O,28,Q[OO[r[2]]],void 0,rY),Q[tE[r[2]]])&&T[r[1]](40,O,F[1],Q[tE[r[2]]],void 0,rY),h.j_&&(q=W[39](38,4,h.j_.G2()),P[0](15,O,q,F[2],rY)),h.h))==null?void 0:k.length)>0||((J=h.Y)==null?void 0:J.length)>0||h.rq||h.F)X=new OA, +R=f[33](r[1],32,X,1,h.h,UO),Z=f[33](19,32,R,2,h.Y,UO),E=H[10](48,3,Z,h.rq),n=f[5](44,E,Du,5,h.F),m=I[22](26,2,n,l[22].bind(null,13),K[27].bind(null,2),4,h.S_,void 0,C),G=U[1](46,2,4,m),P[0](13,O,G,20,rY),h.h=[],h.Y=[];z=(h.S&&P[0](79,O,h.S,F[0],rY),O)}return z},function(N,C,e,L,h,Q,m,O,t){return(((N|8)&7)==(O=[27,20,5],1)&&C.keyCode==O[0]&&(C.type==oF?this.O_=this.v().value:C.type==q$?this.v().value=this.O_:C.type==uA&&(this.O_=null),C.preventDefault()),N&110)==N&&(m=new fz,m.add(Be,h.toString()), +window[Bh][jH()]&&m.add(GM,e),window[ce][Ku()]&&m.add(AE,e),T[35](O[2],l[28](8,C,Q.i),m),t=l[28](O[1],L,e,ye,m)),t},function(N,C,e,L,h){return(N>>(N-((N^49)&(h=["v","i","S"],13)||(L=new Promise(function(Q,m,O){O=new iA({next:function(t){(Q(t),O).unsubscribe()},error:m,complete:function(){m(new ve)}}),C.subscribe(O)})),3)>>3==1&&!e[h[2]]&&e[h[1]]&&e[h[0]]().form&&(y[22](56,e[h[1]],e[h[0]]().form,nu,e.sG),e[h[2]]=C),2)&7)==2&&(this.T2=15E3),L},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(!((N^((N>>1&(u=[13, +21,46],15))==4&&(e.i||H[20](2,"-open","-hover",e),B=e.i[C]),(N|88)==N&&(B=C in Id?Id[C]:Id[C]=Rd+C),u)[0])&14))a:if(m=kn,t=rY,U[u[1]](32,L),D=L.z2,h=D[Rw]|C,O=l[14](u[2],t,D,1),q=void 0===Ff,Q=v[35](u[0],C,!q,h,m,O),!q||Q){B=(Q=T[34](3,e,Q),O!==Q&&(h=W[26](22,h,1,D,Q,t),l[1](97,D,h)),Q);break a}if(((N&54)==N&&(h=l[14](36,e,L,C),B=Array.isArray(h)?h:Fq),N&99)==N)H[22](30,null,this);return B},function(N,C,e,L,h,Q,m){if((N&(((N|(((Q=["backgroundColor",0,14],N)-2&Q[2])==4&&(m=I[39](1,128,2,e,L[Q[1]], +L[C])),6))<22&&(N<<2&7)>=4&&p.call(this,C),N<<1&7)||(C=lA,m=new C.constructor(C)),94))==N)a:{if(bj&&TM){m=(L=((h=Zu(C),h).style[Q[0]]="rgb(255, 255, 255)",document.body.appendChild(h),P[22](48,h,Q[0])),document.body.removeChild(h),L!=="rgb(255, 255, 255)");break a}m=e}return(N-9&Q[2])==2&&(m=U[13](31,e,M0,C,rY)),m},function(N,C,e,L,h,Q,m,O,t,D,q){return(N&((N|((q=[48,92,"K"],(N-9&7)==2)&&(m=L.length,Q=[4,0,2],h=m*C/Q[0],h%C?h=TH(h):y[q[0]](53,L[m-e],od)&&(h=y[q[0]](q[0],L[m-Q[2]],od)?h-Q[2]:h-e), +O=new Uint8Array(h),t=Q[1],y[28](20,6,L,function(u){O[t++]=u}),D=t!==h?O.subarray(Q[1],t):O),40))==N&&(K2.call(this),this[q[2]]=L,this.P=C,this.i=null,this.B=e||window,this.o=!1,this.G=Pe(this.V,this)),q[1]))==N&&(0,eval)(C),D},function(N,C,e,L,h,Q){return(((N-1|7)>=(((((Q=[37,46,33],N)|48)==N&&(h=l[Q[1]](48,I[28](17)?BigInt.asUintN(64,(BigInt(e>>>0)<<BigInt(32))+BigInt(C>>>0)):K[20](21,16,C,e))),N>>1)&7)==1&&(h=e&&L.IX()>C?e():null),N)&&(N+4&62)<N&&(h=l[36](74,W[Q[2]](Q[0],e,C,L,FG))),N)|8)==N&& +(this.i=C),h},function(N,C,e,L,h,Q,m,O,t,D){return((N&108)==(t=[1,0,27],N)&&(K2.call(this),this.K=e||5E3,this.o=C||t[1],this.B=L||new sO(this.o,lA,1,10,this.K),I[5](10,this,this.B),this.G=t[1]),N<<t[0]<20)&&(N<<t[0]&3)>=t[0]&&(h=[40,"",1],O=h[2],Q=K[29](3,t[1],h[t[1]]+L,C.l),m=f[7](t[2],h[t[0]],2),this.i=function(q,u,B,G){for(G=[5,1,29],B=83;B!=37;)B==20?(O=-1,e=void 0,B=37):B==8?(O=K[G[2]](G[0],0,G[1],Q),B=37):B==83?(u=K[G[2]](G[1],0,L,C.l),B=78):B==78&&(B=q===u&&O===1?8:20)},fu(this,Xf(),{get:function(q, +u,B,G,c,A,n,R,F,Z,X,Y,k,E){for(Z=(Y=(X=(F=undefined,47),85),E=[19,9,"call"],!1);;)try{if(Y==94)break;else if(Y==53)Y=44;else{if(Y==4)return O=n[2],e;if(Y==45)X=47,Y=E[0];else if(Y==34)m.has(c.value)&&B++,Y=13;else if(Y==13)Y=B===2?43:E[1];else if(Y==61)O=-1,e=void 0,Y=94;else if(Y==E[1])c=u.next(),Y=44;else if(Y==E[0])Y=B<2?61:52;else if(Y==32)Y=O===A?4:61;else if(Y==8)F!==undefined?(Y=F,F=undefined):Y=45;else if(Y==66)X=97,Y=53;else if(Y==52)A=K[29](2,n[0],n[2],Q),Y=32;else if(Y==44)Y=c.done?40: +34;else if(Y==85)n=[0,"",1],q=f[7](22,n[1],2),B=n[0],u=P[4](12,q),c=u.next(),Y=66;else if(Y==40)X=47,c&&!c.done&&(G=u.return)&&G[E[2]](u),Y=8;else if(Y==43)Y=40;else if(Y==92)throw k;}}catch(J){if(X==(k=J,47))throw J;X==97&&(F=92,Y=40)}}.bind(null)})),D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if((N>>(G=[15,1E6,0],1)&11)==1)if(Q=[4294967296,32,0],e.length<16)v[39](53,Q[2],Number(e));else if(I[28](16))D=BigInt(e),l5=Number(D&BigInt(4294967295))>>>Q[2],TU=Number(D>>BigInt(Q[1])&BigInt(4294967295));else{for(q= +(h=+(e[Q[2]]==="-"),l5=(TU=Q[2],u=e.length,Q)[2],t=Q[2]+h,(u-h)%C+h);q<=u;t=q,q+=C)l5=l5*G[1]+Number(e.slice(t,q)),TU*=G[1],l5>=Q[G[2]]&&(TU+=Math.trunc(l5/Q[G[2]]),l5>>>=Q[2],TU>>>=Q[2]);h&&(O=P[4](11,P[9](20,1,TU,l5)),L=O.next().value,m=O.next().value,l5=L,TU=m)}if((N-4&G[0])==2){if(e)throw Error("Invalid UTF8");C.push(65533)}if(((N^46)&G[0])==1)P[20](7,e,function(c,A){v[48](31,A,this,c)},C);return(N+9&7)==1&&(e=C.Lg(),U[29](37,e|G[2],C)),B},function(N,C,e,L){return(N&92)==N&&(L=new mu(C,e)),N- +5>>3||p.call(this,C),L},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(N+(B=["exec",49,47],2)>>5<2&&N-3>>4>=3){if(m=S[16]((Q=C,15)),I[27](7))q=/Windows (?:NT|Phone) ([0-9.]+)/,Q=(h=q[B[0]](m))?h[e]:SH();else if(P[35](8,"iPod"))q=/(?:iPhone|iPod|iPad|CPU)\s+OS\s+(\S+)/,Q=(L=q[B[0]](m))&&L[e].replace(/_/g,ZD());else if(S[22](13))q=/Mac OS X ([0-9_.]+)/,Q=(D=q[B[0]](m))?D[e].replace(/_/g,ZD()):Ys();else if(y[48](B[1],"kaios",S[16](14).toLowerCase()))q=/(?:KaiOS)\/(\S+)/i,Q=(u=q[B[0]](m))&&u[e];else if(S[B[2]](41))q= +/Android\s+([^\);]+)(\)|;)/,Q=(O=q[B[0]](m))&&O[e];else if(W[11](59)?Ie.platform==="Chrome OS":I[1](77,"CrOS"))q=/(?:CrOS\s+(?:i686|x86_64)\s+([0-9.]+))/,Q=(t=q[B[0]](m))&&t[e];G=Q||C}return((N-7&14)==(N-8&((N+8^13)<N&&(N+2^29)>=N&&(G=y[44](9,C,e,C)),14)||(G={L0:C.Jm(),bJ:C.A2(),withCredentials:C.eZ()}),2)&&(G=C.get(We)==He),(N|4)&11)||!e.i||(U[44](23,C,e),e.i.cancel(),e.i=C),G},function(N,C,e,L,h,Q,m){return((((Q=["i",!1,22],N|3)&7)>=0&&(N^29)<12&&(L=new ks,L.update((H[3](17,e,U[25](30,$Z))||"")+ +rZ),m=H[31](Q[2],C,L.digest())),N-9)&3)==1&&(L.G=Q[1],L[Q[0]]&&(L.P=C,L[Q[0]].abort(),L.P=Q[1]),L.B=e,L.o=h,l[38](15,!0,L),v[29](20,null,L)),m},function(N,C,e,L,h,Q,m,O,t,D,q,u){if(!(((q=[3,1,24],N)|6)>>4))try{(new PerformanceObserver(function(B){B.getEntries().filter(function(G){return G.name===pu||G.name===JE}).forEach(function(G,c,A,n,R,F,Z,X){Z=(n=(c=(R=(A=h[(X=["Y",22,3],X)[0]],A.push),F=new UO,y[44](10,C,F,G.name===pu?2:4)),H[38](X[2],c,K[24](6,G.duration),L)),H[38](7,n,K[24](X[1],G.startTime), +e)),R.call(A,Z)})})).observe({type:EO(),buffered:!0})}catch(B){}if((((N|((N+4^25)>=N&&(N-4^16)<N&&(P[20](8,C.X,function(B,G){this.X.hasOwnProperty(G)&&y[40](2,B)},C),C.X={}),48))==N&&(e=H[2](72,C),e=H[2](q[2],C)/e,U[29](7,e,C)),N>>q[1])>=14&&(N^77)>>5<q[1]&&(m=e.z2,u=W[14](67,null,m[Rw]|C,L,m,h,Q)!==void 0),N+4>>q[0])==q[0]){for(t=[1,(D=e,8),4],h=C;h<=L.length/t[2]-t[0];h++){for(O=(m=(h+(Q=C,t)[0])*t[2]-t[0],C);m>=h*t[2];m--)O+=L[m]<<Q,Q+=t[q[1]];D+=(O>>>C).toString(36)}u=D}return u},function(N,C, +e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){if((N+8^21)>=(F=[14,((N+9^24)>=N&&(N+2^28)<N&&(Q=h.style,"opacity"in Q?Q.opacity=L:"MozOpacity"in Q?Q.MozOpacity=L:"filter"in Q&&(Q.filter=L===""?"":"alpha(opacity="+Number(L)*C+e)),0),"line"],N)&&(N-2^6)<N)a:{if(((G=H[2](9,F[1],(c=["Not available","UnknownError",'Unknown Error of type "'],h),"window.location.href"),Q)==h&&(Q=zM()),typeof Q)==="string"){Z={message:Q,name:dZ(),lineNumber:wZ(),fileName:G,stack:wZ()};break a}m=e;try{t=Q.lineNumber||Q[F[2]]||c[F[1]]}catch(X){t= +wZ(),m=L}try{u=Q.fileName||Q.filename||Q.sourceURL||Zf[Ve()]||G}catch(X){u=wZ(),m=L}if(!((R=P[6](56,L,Q),!m&&Q.lineNumber&&Q.fileName)&&Q.stack&&Q.message&&Q.name)){n=Q.message,n==h&&(Q.constructor&&Q.constructor instanceof Function?(Q.constructor.name?A=Q.constructor.name:(O=Q.constructor,xs[O]?A=xs[O]:(q=String(O),xs[q]||(D=/function\s+([^\(]+)/m.exec(q),xs[q]=D?D[1]:ad()),A=xs[q])),B=c[2]+A+C):B=gZ(),n=B,typeof Q.toString==="function"&&Object.prototype.toString!==Q.toString&&(n+=": "+Q.toString())), +Z={message:n,name:Q.name||c[1],lineNumber:t,fileName:u,stack:R||c[F[1]]};break a}Z={message:Q.message,name:Q.name,lineNumber:Q.lineNumber,fileName:Q.fileName,stack:R}}if((N+9^((N|9)>=12&&((N^F[0])&16)<12&&(e=T[41](13,C),U[29](37,e,C)),26))<N&&(N-7|71)>=N)for(L in e)!isNaN(L)&&C(e,+L,e[L]);return Z},function(N,C,e,L,h,Q,m,O){if((((N&(m=[1,"S",5],60))==N&&p.call(this,C),N<<2)&29)==4)for(typeof L.X==="function"&&(e=L.X(e)),L.coords=Array(L.G.length),h=C;h<L.G.length;h++)L.coords[h]=(L[m[1]][h]-L.G[h])* +e+L.G[h];return((N+9&(N+m[0]&9||(this.value=C,this.i=!!e),47))<N&&(N+6&55)>=N&&(L=y[34](52,this),e=y[34](58,this),C=y[34](52,this),L[e]=C),N-m[2]|9)<N&&(N+9^28)>=N&&L.info(function(t,D){return(t=[" ","noop",null],D=[9,"XMLHTTP TEXT (",1],D[1]+h)+"): "+I[30](D[0],D[2],t[2],t[D[2]],C,e,L)+(Q?t[0]+Q:"")}),O},function(N,C,e,L,h,Q,m,O,t){return((N^53)&11)==((N^((((N^(O=[45,44,"i"],N-8&14||e&&U[34](41,null,".",C,e),81))&27||(C=I[22](20,this[O[2]]),t=W[41](11,1,!0,this[O[2]],!1,C)),N)&11)==N&&(L=L===void 0? +bA:L,t=new M$(L,e,C)),60))>>3||($s.call(this),K[15](2,C)||!C?h={next:C!=null?C:void 0,error:e!=null?e:void 0,complete:L!=null?L:void 0}:h=C,this.destination=new NI(h)),3)&&(t=P[O[1]](O[0],function(D,q,u,B,G,c){if((c=["o",(B=[0,10,4],1),"onError"],D.B)==C)return q=new CX,G=e.fu(),u=P[0](77,q,G,2),h=P[0](77,u,L,B[c[1]]),D.K(2),D.i(e.V.send(new eL(h)),B[2]);if(D.B!=2){if(!T[9](38,!(m=D.G,0),LX)(m))return e.B[c[2]](C),D.return();if(!m.fu())return e.B[c[2]](B[0]),D.return();return(e.P(m),D).V(B[0])}if((Q= +D[c[0]](),Q)instanceof hh)e.B[c[2]](B[2]);else e.B[c[2]](B[0]);D.P()})),t},function(N,C,e,L,h,Q,m,O){return(N|((N|56)!=((N-((N+2&15)==((N-(O=[0,1,"o"],6)|58)<N&&N-9<<2>=N&&(Jd||Rw in e||Qg(e,mf),e[Rw]|=C),3)&&(m=C==null?C:OP===2?th(C)?C|O[0]:void 0:C),6)&23)==4&&(UP.call(this),this[O[2]]=O[0]),N)||h.B||(h.G=Math.trunc(qY()),h[O[2]]||(h[O[2]]=S[13](3,C,L,h,e)||T[23](98,C)),h.B=h[O[2]].then(function(t,D,q){if(q=[98,"i","requestToken"],t&&typeof t[DW()]==="function")return D=Math.trunc(qY()),h.A++,T[23](q[0], +t[q[2]](Q)).then(function(u){h.P=Math.trunc(qY())-D,u&&(h.i=u)});t&&(h[q[1]]=qI)}).catch(function(){h.i=uH})),O[1]))>>4||(e>=O[1]&&TH(e),S[6](58,127,C.i,e*8+L)),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(N+7>>(G=["call","X-Recaptcha-Token",((N&45)==N&&(e=C.u,C.u=[],B=e),0)],3)>=2&&(N^5)>>5<2)a:if(L=[null,6,4],e=this,i5)try{if((u=Bj.get(this))&&u.url)if(u.EZ){h=(q=P[4](11,Aa),q.next());try{for(;!h.done;h=q.next())if(t=H[24](2,L[2],1,u.url,h.value)){B=(t.then(function(c){e.setRequestHeader("X-Recaptcha-Token", +c),jL.call(e,C)},function(){jL.call(e,C)}),void 0);break a}}finally{h&&!h.done&&(m=q.return)&&m[G[0]](q)}}else if(Q=Aa.find(function(c){return P[27](19,null,u.url,c)!==null}))O=f[4](3,L[2],P[16](25,10,P[3](27,11,P[30](83,L[1],P[34](44,1,L[1]),Q.i.iQ),Q.i.origin),(D=l[18](67,L[G[2]],u.url,Q))==L[G[2]]?void 0:D.substring(G[2],100)).G2(),Q.B),this.setRequestHeader(G[1],O);jL[G[0]](this,C)}catch(c){jL[G[0]](this,C)}else jL[G[0]](this,C);return B},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if((N-(n=["apply", +41,0],4)|66)>=N&&(N+5&60)<N)throw L=GC(),Error(L===void 0?"unexpected value "+e+C:L);return(N-1>>5<(((N^73)&11)==(N-6<n[1]&&N-7>=21&&(A=P[44](77,function(R,F,Z){Z=["i",(F=[7,3,6],0),1];switch(R.B){case Z[2]:if(!(h=(O=(m=(Q=S[28](57),Q.document),cj)(),KX()),m)[h]||!m[O]){R.js(e);break}return R.K(F[Z[2]]),R[Z[0]](m[h](),C);case C:if(L=R.G,!L){R.js(F[2]);break}return R[Z[0]](m[O]({localStorage:!0,sessionStorage:!0}),F[Z[1]]);case F[Z[1]]:(t=R.G)&&(Ah=t);case F[2]:R.V(e);break;case F[Z[2]]:R.o(),R.P()}})), +1)&&(A=C.B?!0:C.i?C.i.size>=C.o:!1),1)&&((N^69)&15)>=5&&(m=[1,7,!1],O=y[n[1]](72,c7.M(),C),u=P[4](10,O),Q=u.next().value,q=u.next().value,D=u.next().value,G=I[21](20),c=I[21](7),B=[y[36](1,e),K[n[2]](21,2,h,c,q,L),P[37](83,T[39](9,5),q,Q),T[30](36,G,W[n[2]](21,e),W[n[2]](1,Q)),yg(Q,T[39](6,4),Q),yg(D,T[39](4,m[1]),Q),T[30](51,c,W[n[2]](23,D),m[2]),P[37](87,h,L,e),T[30](59,c,m[n[2]],m[n[2]]),G,P[37](82,T[39](5,C),q,e),c,y[36](6,Q),y[36](3,q),y[36](5,D)],(t=c7.M()).i[n[0]](t,T[5](71,O)),A=B),N-5&7)|| +(C.o=e),A},function(N,C,e,L,h,Q,m){if((((Q=[34,"K","put"],N<<2&15)>=12&&N>>1<14&&p.call(this,C),N)-5|Q[0])<N&&(N+5&46)>=N){if(C&&!e.u)throw Error("Can't create secondary domain capable XhrIo object.");m=(h=e.z$&&!e.ZM?new xK(new iH({Jp:L})):new xK(e.ZM),h[Q[1]]=e.u,h)}return((N+2>>4==4&&p.call(this,C),N>>2)&11||(m=e?e.map(function(O,t,D){for(t=(D=[],0);t<O.length;t++)t!=1&&(D[t]=O[t]);return new u4((C&&(D[1]=C-vj+O[1]),D))}):[]),N-1|8)<N&&(N+9&69)>=N&&(L=T[41](2,C),e=C.Ql[y[1](3,1,L,C)],C.Ql[y[1](33, +1,L,C)]=P[25](16,31,0,C),C[Q[2]](0,e)),m},function(N,C,e,L,h){return L=[11,17,6],(N|3)>=23&&N-L[2]>>4<2&&(C=['" tabindex="-1"></div>','"><div class="',"recaptchaJavascriptChallengeLivenessContainer"],h=T[1](L[1],W[L[0]](52,T[1](81,fJ(),"<div id='rc-liveness' class=\""+H[7](33,"recaptchaJavascriptChallengeLivenessOuterContainer")+C[1]+H[7](65,C[2])+C[0]),l[L[0]](36," ")),jB())),(N<<1&L[2])<5&&(N>>1&L[2])>=2&&(e=['<div id="rc-prepositional"><span class="',"rc-prepositional-select-more","rc-prepositional-payload"], +C=T[1](16,fJ(),e[0]+H[7](32,"rc-prepositional-tabloop-begin")+'" tabIndex="0"></span><div class="'+H[7](32,e[1])+'" style="display:none" tabindex="0">'),W[L[0]](50,C,"Please fill in the answers to proceed"),T[1](81,C,'</div><div class="'+H[7](33,"rc-prepositional-verify-failed")+'" style="display:none" tabindex="0">'),W[L[0]](18,C,"Please try again"),T[1](L[1],W[L[0]](52,T[1](L[1],C,'</div><div class="'+H[7](64,e[2])+'"></div>'),l[L[0]](44," ")),'<span class="'+H[7](65,"rc-prepositional-tabloop-end")+ +'" tabIndex="0"></span></div>'),h=C),h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return N+((N&((N|88)==(((N^(B=[3,"jx",45],16))<5&&N-6>>B[0]>=1&&(e=Error.call(this,C.toString()),this.message=e.message,"stack"in e&&(this.stack=e.stack),nX(this,IH.prototype)),(N|40)==N)&&(u=P[44](B[2],function(G,c,A){c=[24,0,(A=[5,36,0],1E4)];switch(G.B){case C:t=c[1],q=l[A[1]](79,W[33](37,Q,h)),O=l[A[1]](79,W[33](21,Q,C));case h:if((t++,t)>=c[2])throw Error("");if(!(t>c[1]&&t%500===0)){G.js(A[0]);break}return G.i(new Promise(function(n){setTimeout(n, +0)}),A[0]);case A[0]:return G.i(l[A[1]](A[0],L,16,c[A[2]],255,O,t),L);case L:if((m=((D=G.G,D[c[1]]<<c[A[2]])|D[C]<<16|D[h]<<e|D[3])>>>c[1],m)%q===0)return G.return([t]);G.js(h)}})),N)&&(KN.call(this,K[43](2,RH),function(){},y4(),null,e),I[21](33,C.D(),this),this.WL=iw),105))==N&&(u=Array.prototype.slice.call(C)),8)>>4||(this[B[1]]=e,this.Mo=L,this.E8=h=vj,this.t0=C),u},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if((((((((A=[7,5,49],N+1&53)>=N&&N+1>>1<N&&(n=P[44](77,function(R,F){if(R.B==(F=["X", +"now","P"],L))return R.i(l[6](8,L,Q),h);for(t=(B=(c=(G=R.G,P)[4](14,G),c.next()).value,u=c.next().value,O=B,D=u,Date[F[1]]());Q[F[2]].length>0&&Q[F[2]][Q[F[2]].length-L]<=t-12E4;)Q[F[2]].pop();return q=Q[F[2]].length,q>L&&Q.B(new Fk(q)),R.return(H[23](16,e,0,5,C,m,W[3](34,3,L,O,D),q,Q[F[0]],Q.F))})),N)&107)==N&&(Q=[7,1,4],D=qY()-L.W,O=new lH,t=l[A[2]](15,e,Q[1],D,L.Y),h=f[A[1]](32,O,TC,Q[2],t),u=l[A[2]](13,e,Q[1],D,L.C),m=f[A[1]](12,h,TC,C,u),q=K[23](12,6,L.u,m),B=K[23](1,Q[0],L.F,q),n=K[23](65,8, +L.T,B)),N-3>>4||(n=new ZE(function(R,F){(F=[12,9,8],U[F[0]](64,3,F[2],4,F[1],C,R)).catch(function(Z){return R.error(Z)})})),N+A[1])&15)==1&&(ZW(C),oH(C),n=oH(C)?Number(C):String(C)),N-A[1])&A[0])==2)K[23](59,C,L,e);return n},function(N,C,e,L,h,Q,m){if(((m=[14,3,40],N-m[1])^15)>=N&&(N-8|m[0])<N&&e.i){(e.V&&(clearTimeout(e.V),e.V=C),h=e.i,e).i=C,L||v[44](39,e,gq);try{h.onreadystatechange=C}catch(O){}}return N+((N|m[2])==N&&(this.i=C),m[1])>>4||(L=function(){e.flush()},Q=e.S?C?function(){C().then(L)}: +L:function(){}),Q},function(N,C,e,L,h,Q,m,O,t,D,q){if(q=["i",43,23],(N>>1&15)==2&&(Q=new j8,Zf.Image?(m=new Image,m.onload=kW(P[15].bind(null,5),Q,"TestLoadImage: loaded",C,L,m),m.onerror=kW(P[15].bind(null,6),Q,"TestLoadImage: error",e,L,m),m.onabort=kW(P[15].bind(null,7),Q,"TestLoadImage: abort",e,L,m),m.ontimeout=kW(P[15].bind(null,16),Q,"TestLoadImage: timeout",e,L,m),Zf.setTimeout(function(){if(m.ontimeout)m.ontimeout()},1E4),m.src=h):L(e)),(N&89)==N){for(O=t=L;I[13](84,e,m)&&m.B!=C;)if(m.o!== +16||t)if(m.o!==26||O)T[q[1]](1,C,m);else t?(O=-1,f[25](17,L,Q,t,m)):(O=m.K,S[46](24,C,h,m));else t=y[35](4,m[q[0]]),O&&(m[q[0]][q[0]]=O,O=L);if(m.o!==12||!O||!t)throw Error();}if((N|48)==((N-4&15)>=7&&(N|5)<q[2]&&C.keyCode==13&&U[29](54,!1,this),N))a:{switch(Q){case h:D=m?Pj:sP;break a;case 2:D=m?fX:Xk;break a;case 4:D=m?SL:Yr;break a;case 8:D=m?Wj:Hj;break a;case e:D=m?kr:rm;break a;case C:D=m?pX:Jh;break a;case L:D=m?EP:zC;break a}throw Error(dm);}return D},function(N,C,e,L,h,Q,m,O,t,D){if((N-(((N- +(t=["V",28,7],(N+4&57)<N&&(N+2^12)>=N&&(this.B=!1,this.G=e,this.o=function(){return P[3](1)},this.aM=C,this.K=this.o()),1)|t[1])>=N&&(N+5&61)<N&&(D=P[18](25,W[39](20,S[32](24,new b4,17),e),[W[0](23,C)])),N&43)==N&&(e=B0.M().get(),D=v[12](65,C,e,rY)),t[2])|90)>=N&&(N-4|50)<N&&(Q&&(m=typeof Q==="string"?Q:P[9](11,e,Q),Q=h.K&&m?U[39](9,h.K,m)||C:null,m&&Q&&(O=h.K,m in O&&delete O[m],U[20](71,L,Q,h[t[0]]),Q.bz(),Q.B&&W[48](42,Q.B),l[48](25,C,Q,C))),!Q))throw Error(wm);return(N+8&t[2])==4&&(this.i=new Map, +this.B=C||null),D},function(N,C,e,L,h,Q,m,O,t,D,q,u){if((N>>(q=[1,73,2],q)[2]&7)==q[0]&&(e&&(e=U[23](5,"goog.Promise.then",e)),h&&(h=U[23](3,"goog.Promise.then",h)),m=f[17](q[1],C,C,C),m.i=new wu(function(B,G){(m.o=e?function(c,A){try{A=e.call(Q,c),B(A)}catch(n){G(n)}}:B,m).B=h?function(c,A){try{A=h.call(Q,c),A===void 0&&c instanceof Vg?G(c):B(A)}catch(n){G(n)}}:G}),m.i.G=L,T[34](24,3,q[2],L,m),u=m.i),(N&124)==N)a:if(D=[2,1,4],Array.isArray(L)){if(O=L[Rw]|0,O&D[q[2]]){u=L;break a}for(m=t=0;t<L.length;t++)Q= +e(L[t]),Q!=null&&(L[m++]=Q);u=(((h=O|D[q[m<t&&(L.length=m),0]],C&&(h=(h|D[q[2]])&-1537),h!==O)&&W[32](24,h,L),C)&&h&D[0]&&$4(L),L);break a}return u},function(N,C,e,L,h,Q,m,O,t){return N-((N|24)==(O=[7,"B",32],(N>>1&O[0])==2&&(e=[],y[28](O[2],6,C,function(D){e.push(D)}),t=e),N)&&(h=e.Vk+TH(Vn()*e.PL),e.isActive()||(xr(),h*=C),t=h*L),5)>=-53&&N+8>>4<1&&(this.G=C,this.o=L,this.K=1,this.P=e,this.A=h,this[O[1]]=Q,this.i=m,this.V=0),t},function(N,C,e,L,h,Q,m){return((N^30)&15)==((N-(((N&(m=[5,19,33],38))== +N&&(K[m[0]](m[0],[-40],U[37].bind(null,2)),K[m[0]](15,[-45],I[0].bind(null,9)),K[m[0]](m[0],[-14],v[14].bind(null,8)),K[m[0]](m[1],[-29,-56],l[45].bind(null,2))),(N^21)<11&&(N<<2&15)>=7)&&(gm=function(){return v[12](18,C,function(){return L.slice(e)},bH)},Q=L),1)|38)>=N&&(N-1|65)<N&&(h=T[m[2]](56,e,void 0,L,$z),Q=W[m[1]](27,C,e,h)),3)&&(Q=e==C?e:T[45](13,e)),Q},function(N,C,e,L,h,Q,m,O,t,D,q,u){if(!((N^77)&(q=[null,32,8],25)))a:{if(Q!=q[0]&&Q[MI]===$r){u=Q;break a}if(!Array.isArray(Q)){u=e?L&2?h[NM]|| +(h[NM]=y[23](9,h)):new h:void 0;break a}(O=(m=Q[Rw]|C,m|L&q[1]|L&2),O!==m)&&W[q[1]](16,O,Q),u=new h(Q)}return(N+3&((N+5^29)<((N|88)==N&&(C=Error.call(this,"object unsubscribed"),this.message=C.message,"stack"in C&&(this.stack=C.stack),Object.setPrototypeOf(this,this.constructor.prototype),this.name="ObjectUnsubscribedError"),(N-3&7)==4&&(D=e.B,t=[4,3,0],m=e.i,h=D[m+1],L=D[m+t[2]],Q=D[m+2],O=D[m+t[1]],T[0](19,t[0],e),u=L<<t[2]|h<<q[2]|Q<<16|O<<C),N)&&(N-2^19)>=N&&p.call(this,C),15))==1&&(this.i=T[26](22, +255,[])),u},function(N,C,e,L,h,Q,m,O,t,D){if(((((t=["xx",41,1],(N<<t[2]&7)>=0)&&N<<t[2]<9&&(D=C.classList?C.classList.contains(e):S[9](44,U[19](34,C),e)),(N^78)&15)==t[2]&&(D=I[t[2]](77,"Firefox")||I[t[2]](95,C)),N+2)&t[1])>=N&&(N+4^14)<N){for(O=(h=(m=(Q=(O=(this[t[0]]=((this.e_=-1,this).ez=e,L=[8,0,3],new gd(8)),C),new CM(8)),O[t[2]]|L[t[2]]),L[t[2]]),O[L[t[2]]])|L[t[2]];h<L[0];h++)Q[h]=O,m=(m>>>L[0]|m<<24)+O^h|L[t[2]],O=(O<<L[2]|O>>>29)^m|L[t[2]];this.U_=Q}return((N|2)&8)<7&&N+3>=27&&p.call(this, +C),D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(!(N>>(B=[2,"call",10],B)[0]&23))for(q=["px","fontSize",0],t=P[13](B[0],e,q[1]),h=(O=t.match(eP))&&O[q[B[0]]]||C,t&&q[0]==h?m=parseInt(t,B[2]):(D=LM(he,{style:"visibility:hidden;position:absolute;line-height:0;padding:0;margin:0;border:0;height:1em;"}),e.appendChild(D),t=D.offsetHeight,W[48](57,D),m=t),S[29](7,e,q[1],m+q[0]),Q=P[47](22,e).height;m>12&&!(L<=q[B[0]]&&Q<=B[0]*m)&&!(Q<=L);)m-=B[0],S[29](51,e,q[1],m+q[0]),Q=P[47](70,e).height;if((N+7^((N|7)>> +4==4&&(xW[B[1]](this,C,e),this.id=L,this.o7=h),B)[2])<N&&(N+5&61)>=N)p[B[1]](this,C);if(((N^54)&12)<1&&N>>B[0]>=-77){for(Q=(h=L.pop(),e.B)+e.i.length()-h;Q>C;)L.push(Q&C|128),Q>>>=7,e.B++;L.push(Q),e.B++}if(N-7<<1<N&&N-B[0]<<1>=N)a:{for(m=C;m<Q.length;++m)if(O=Q[m],!O.UV&&O.listener==e&&O.capture==!!h&&O.handler==L){u=m;break a}u=-1}return u},function(N,C,e,L,h,Q,m){return((N-6^((N-(m=["",16,3],m)[2]&13)==1&&(e=[],H[37](50,m[0],C,!1,e),Q=e.join(m[0])),12))<N&&(N-7^m[1])>=N&&(e=e===void 0?8:e,h=new ks, +h.update(C),L=h.digest(),Q=H[31](23,"0",L).slice(0,e)),N-5>>m[2])==2&&(QY.call(this,e),this.G=C||m[0]),Q},function(N,C,e,L,h,Q,m,O){if((((O=[46,12,4],N)-O[2]^30)>=N&&(N-2^O[1])<N&&(QY.call(this,C),this.i=null,this.G=I[17](42,mr,document)),N>>1&15)==2&&(Os[Os.length]=e,te))for(L=C;L<Us.length;L++)e(Pe(Us[L].i,Us[L]));if((N|48)==N)if(e<C)H[O[0]](8,C,C-e),Q=P[O[2]](11,P[9](O[2],1,TU,l5)),L=Q.next().value,h=Q.next().value,TU=h>>>C,l5=L>>>C;else H[O[0]](16,C,e);return(((N^51)&6)==2&&e.hO.push(C),(N&30)== +N)&&(m=v[O[1]](68,C,e,rY)),m},function(N,C,e,L,h,Q,m,O,t,D,q,u){if((u=["A","i",1],N|8)>=-73&&(N<<2&8)<5)a:{if((e=C.length,e)>0){for(L=(h=Array(e),0);L<e;L++)h[L]=C[L];q=h;break a}q=[]}if(N>>u[2]<18&&N+8>=u[2])a:{for(;e[u[1]].B;)try{if(L=e.B(e[u[1]])){e[u[q={value:L.value,done:!1},1]].Y=!1;break a}}catch(B){e[u[1]].G=void 0,y[37](14,B,e[u[1]])}if(e[u[e[u[1]].Y=!1,1]][u[0]]){if(e[u[1]][u[0]]=(h=e[u[1]][u[0]],C),h.W3)throw h.Fl;q={value:h.return,done:!0};break a}q={value:void 0,done:!0}}if(N<<2>=u[2]&& +(N<<2&16)<8)a:{if((t=(Q=e.X,L).indexOf(k4(),Q),t)==-1){q=D_;break a}if((O=(m=L.substring(Q,t),Number)(m),isNaN)(O)){q=qM;break a}if(h=t+C,h+O>L.length){q=D_;break a}q=(e.X=(D=L.slice(h,h+O),h+O),D)}return q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return(N^(((N|4)&11)>=(B=((N|8)==N&&(this.i=C),[0,77,null]),B)[0]&&(N+5&8)<4&&(this.gJ=e,this.G=C||"GET",this.o7=B[2],this.lp=h,this.P=!!D,q=[!1,"",0],this.B=m||B[2],this.uA=O!==void 0?O:1,this.oW=q[B[0]],this.dN=q[2],this.EC=q[B[0]],this.i=Q,this.o=t||q[1], +this.K=L),28))>>4||H[47](39,64,C,e,L)&&K[47](B[1],1,C,e,L),u},function(N,C,e,L,h,Q){if((N<<2&(Q=[9,5,"8x-4t2pegToiW8KmThtO4AQt"],15))>=Q[0]&&N+8>>Q[1]<1&&(KN.call(this,I[14](32,u1),U[Q[1]](37,LX),y4(),4),P[0](13,C,Q[2],1),e=H[13](17,B0.M().get()),P[0](79,C,e,3),this.Rz=C.D()),N-2<Q[1]&&N+4>=4)U[29](7,1,C);if((N>>2&15)>=1&&(N<<1&7)<2){if(L.S!=C)throw Error("WatchDog timer not null");L.S=y[Q[0]](19,Pe(L.hO,L),e)}return h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k){if(k=["isArray",((N+5& +61)>=N&&(N+4&78)<N&&(Y=C!=null&&C.sm===e),"explicit"),"concat"],N+1>>5<4&&(N+4&7)>=3){n=(Z=P[B=[!0,"reCAPTCHA couldn't find user-provided function: ","."],4](10,h),Z).next();try{for(;!n.done;n=Z.next())U[47](19,function(E){W[36](88,L,E)},n.value+e)}finally{n&&!n.done&&(R=Z.return)&&R.call(Z)}c=(Q=(((u=window[Bh][Bt()],window)[Bh][Bt()]=[],Array)[k[0]](u)||(u=[u]),P[4](15,u)),Q).next();try{for(;!c.done;c=Q.next())if(X=c.value,X==C)f[24](70,B[2],B[0]);else X!=k[1]&&(q=H[10](7,{sitekey:X,isolated:!0}), +Zf.window[Bh][jP()][X]=q,f[24](71,B[2],B[0],X))}finally{c&&!c.done&&(D=Q.return)&&D.call(Q)}O=(F=((t=((m=window[Bh][GY()],window[Bh])[GY()]=[],Array[k[0]](m)||(m=[m]),window)[Bh][ct()],window[Bh])[ct()]=[],t&&Array[k[0]](t)&&(m=m[k[2]](t)),P)[4](11,m),F.next());try{for(;!O.done;O=F.next())G=O.value,typeof window[G]==="function"?Promise.resolve().then(window[G]):typeof G==="function"?Promise.resolve().then(G):G&&console.warn(B[1]+G)}finally{O&&!O.done&&(A=F.return)&&A.call(F)}}return Y},function(N, +C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if((N|(A=["G",55,0],32))==N){if(B=(m=[1,!1,0],C).Ku)for(Q=[],O=m[A[2]];B;B=B.Ku)Q.push(B),++O;if(D=(u=C.Np,(L=e,G=Q,L.type)||L),typeof L==="string"?L=new xW(L,u):L instanceof xW?L.target=L.target||u:(t=L,L=new xW(D,u),yO(L,t)),h=!0,G)for(q=G.length-m[A[2]];!L[A[0]]&&q>=m[2];q--)c=L.B=G[q],h=l[24](23,m[2],!0,c,L,D)&&h;if(L[A[0]]||(c=L.B=u,h=l[24](75,m[2],!0,c,L,D)&&h,L[A[0]]||(h=l[24](51,m[2],m[1],c,L,D)&&h)),G)for(q=m[2];!L[A[0]]&&q<G.length;q++)c=L.B=G[q],h=l[24](A[1], +m[2],m[1],c,L,D)&&h;n=h}return(N-5&6)<4&&(N>>2&3)>=2&&(n=C.B?1:C.i?C.i.size:0),n},function(N,C,e,L,h,Q,m,O,t){return(N|24)==((O=[0,"X",1],N+6)>>4||(Q=[null,3,!0],h.i==O[0]&&(h===L&&(e=Q[O[2]],L=new TypeError("Promise cannot resolve to itself")),h.i=O[2],l[40](56,Q[2],!1,h.h,L,h[O[1]],h)||(h.A=L,h.G=C,h.i=e,U[43](10,Q[2],h),e!=Q[O[2]]||L instanceof Vg||U[16](8,Q[2],Q[O[0]],h,L)))),(N^50)>>4||(Q=[null,"object",0],l[9](O[2],KM),L=e.i,L==Q[O[0]]||Ae&&L!=Q[O[0]]&&L instanceof Uint8Array?h=L:typeof L=== +"string"?h=K[O[2]](17,C,Q[2],L):(f[37](66,Q[O[2]],L),h=Q[O[0]]),m=h,t=m==Q[O[0]]?m:e.i=m),N)&&C.onreadystatechange&&C.onreadystatechange.call(C),t},function(N,C,e,L){return N-2>>5<((N-4^(e=["K",6,"h"],31))>=N&&(N-9^8)<N&&C.G.push(C.lI,C.Hc,C.Zg,U[25](2,C,function(h,Q){return h+Q}),U[25](e[1],C,function(h,Q){return h-Q})),5)&&N-4>=10&&(YK.call(this,959,13,[2]),this.X=this.I=-1,this.Z=this.G=this.F=this.Y=this[e[0]]=-1,this.J=this.S=this.l=this.B=this.o=this[e[2]]=-1,this.u=I[21](7),this.T=I[21](7)), +L},function(N,C,e,L,h,Q,m,O,t){if((N>>2&7)==(O=[1,"call","Array.prototype."],O[0]))P[44](41,function(D,q){(L=(q=[36,"K",!0],I[49](q[0],q[2],new yY,e)),e[q[1]]=e[q[1]].then(L,L).then(function(u,B,G,c,A){(c=(G=new (A=(B=e.i.B,B.send),WV),f[5](56,G,kn,C,u,rY)),A).call(B,new i1(c))}),D).P()});if(N+3>>O[0]<N&&(N+O[0]&14)>=N&&Q)for(m=L;m<vt.length;m++)U[34](40,C,e,vt[m]+O[2]+h,Q);if((N|24)==N)U[29](71,-2,C);if((N|5)>>3==2)YK[O[1]](this,727,4,[2]);return t},function(N,C,e,L,h,Q,m,O,t){return((N^7)&3)==(((N| +2)<(t=["o","i",6],15)&&(N-8&11)>=7&&(Q=Q===void 0?null:Q,TN.call(this),this.K=Q,this[t[1]]=C||this.K.port1,m=this,this.G=new Map,e.forEach(function(D,q,u,B,G){B=(u=P[4](10,Array.isArray(q)?q:[q]),u.next());try{for(;!B.done;B=u.next())m.G.set(B.value,D)}finally{B&&!B.done&&(G=u.return)&&G.call(u)}}),this[t[0]]=L,new sB(h),this.B=new Map,y[22](40,this,this[t[1]],nM,function(D){return U[20](3,!1,2,m,D)}),this[t[1]].start()),(N^7)&t[2])<2&&(N^2)>=25&&(e[t[1]].remove(C),e[t[1]].add(C,L)),2)&&(YK.call(this, +2033,24,[2]),this.H=this.B=this.G=-1,this[t[0]]=-1,this.K=I[21](84)),O},function(N,C,e,L,h,Q,m,O,t){if(!(N+(O=["add",2,"classList"],(N|4)>>3==O[1]&&(t=String(C).replace(/\-([a-z])/g,function(D,q){return q.toUpperCase()})),(N>>1&11)==O[1]&&(e=e===void 0?!0:e,C.i&&e?(C.i[O[2]][O[0]]("recaptchaJavascriptChallengeQrButtonVisible"),C.i[O[2]].remove("recaptchaJavascriptChallengeQrButtonHidden")):C.i&&!e&&(C.i[O[2]][O[0]]("recaptchaJavascriptChallengeQrButtonHidden"),C.i[O[2]].remove("recaptchaJavascriptChallengeQrButtonVisible"))), +O[1])&11)){Q=(e=(L=H[h=[0,25,128],O[1]](60,C),m=H[O[1]](56,C),[]),L/4294967296|h[0]);for(L|=h[0];Q>h[0]||L<h[0]||L>=h[O[1]];)e.push(L&127|h[O[1]]),L=L>>>7|(Q&127)<<h[1],Q>>>=7;(e.push(L),m+=K[19](19,h[0],e),U)[29](5,m,C)}return t}]}(),W=function(){return[function(N,C,e,L,h,Q,m,O,t,D,q,u){return((N-8&((q=[24,2,"i"],(N-3&7)==1)&&(D=[4,"rc-imageselect-carousel-offscreen-right",null],t=y[14](33,D[q[1]],document),m.r0(h),O=Q.previousElementSibling!==void 0?Q.previousElementSibling:I[36](1,1,h,Q.previousSibling), +W[22](5,Q,D[1]),W[22](3,O,"rc-imageselect-carousel-leaving-left"),W[22](q[1],Q,m.G.Ss.Jc.rowSpan==D[0]&&m.G.Ss.Jc.colSpan==D[0]?"rc-imageselect-carousel-mock-margin-1":"rc-imageselect-carousel-mock-margin-2"),u=K[31](10,"*",Q).then(function(){W[36](80,100,function(B){(((B=[22,88,1],W)[16](66,Q,"rc-imageselect-carousel-offscreen-right"),W[16](43,O,"rc-imageselect-carousel-leaving-left"),W)[B[0]](B[2],Q,"rc-imageselect-carousel-entering-right"),W)[B[0]](6,O,"rc-imageselect-carousel-offscreen-left"), +W[36](B[1],C,function(G,c,A,n){for(G=(c=(((((W[n=[3,4,"G"],16](n[0],Q,"rc-imageselect-carousel-entering-right"),W)[16](2,Q,this[n[2]].Ss.Jc.rowSpan==n[1]&&this[n[2]].Ss.Jc.colSpan==n[1]?"rc-imageselect-carousel-mock-margin-1":"rc-imageselect-carousel-mock-margin-2"),W)[48](59,O),this).r0(e),t)&&t.focus(),this[n[2]].Ss.Jc),L),c.vS=L,A=c.tc;G<A.length;G++)A[G].selected=h,W[16](50,A[G].element,"rc-imageselect-tileselected")},this)},m)})),14))==q[1]&&(D=e[q[2]],O=[3,0,4],m=e.B,L=m[D+O[0]],Q=m[D+1],t= +m[D+O[1]],h=m[D+q[1]],T[0](3,O[q[1]],e),u=(t<<O[1]|Q<<8|h<<C|L<<q[0])>>>O[1]),(N&87)==N)&&(u=H[18](9,null,new IB,C)),u},function(N,C,e,L,h,Q,m,O,t,D){if(((t=[10,8,2],N-t[1])&15)==1){for(Q=(L=(O=[64512,1023,63],m=0,[]),0);Q<e.length;Q++)h=e.charCodeAt(Q),h<128?L[m++]=h:(h<2048?L[m++]=h>>C|192:((h&O[0])==55296&&Q+1<e.length&&(e.charCodeAt(Q+1)&O[0])==56320?(h=65536+((h&O[1])<<t[0])+(e.charCodeAt(++Q)&O[1]),L[m++]=h>>18|240,L[m++]=h>>12&O[t[2]]|128):L[m++]=h>>12|224,L[m++]=h>>C&O[t[2]]|128),L[m++]=h& +O[t[2]]|128);D=L}return(((N<<(N+1>>3==3&&(D=!!(t[2]&e)&&!!(C&e)||!!(256&e)),(N&60)==N&&(D=this.i[TH((C+7)/17)]),t[2])&15)>=6&&(N|3)<18&&(D=C.i?C.i.readyState:0),N)&120)==N&&(D=P8('<div>reCAPTCHA is changing its terms of service. <a class="migrate-link" href="https://google.com/recaptcha/admin/migrate" target="_blank">Take action.</a></div>')),D},function(N,C,e,L,h,Q,m,O,t){if(!(N-(O=[81,2,"hasAttribute"],8)&3))if(Array.isArray(L))for(Q=0;Q<L.length;Q++)W[O[1]](24,"=",e,String(L[Q]),h);else L!=null&& +e.push(h+(L===""?"":C+P[30](21,L)));if(((((N^66)>=27&&(N<<1&16)<13&&(t=e[O[2]](Nw())&&v[0](4,C,e)),(N<<1&15)==O[1]&&h!=null)&&(m=parseInt(h,e),TH(m),v[22](5,Q,L,0),W[23](3,C,Q.i,m)),N)<<1&16)<6&&N+6>>4>=3)a:{if((h=(T[49](39,e,L),oE(Number(e))),P0(h))&&(!L&&!n2||h>=C)){t=String(h);break a}t=((Q=e.indexOf(ZD()),Q)!==-1&&(e=e.substring(C,Q)),l[36](O[0],!1,16,e))}return t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){return(((N&90)==((Z=[1,47,24],N<<Z[0]>=14)&&(N|7)<20&&(F=I[Z[0]](88,"Android")&& +!(S[Z[0]](18,"CriOS")||v[36](15,C)||S[20](7,"Opera")||S[17](15,e))),N)&&(F=P[44](73,function(X,Y,k){if((k=["i",(Y=[1,255,0],2),52],X.B)==Y[0])return n=B0.M(),c=Q[k[0]].I,K[32](14,Y[1],RB.M(),c),D=L,q=new Fn(c,n.get().G2(),T[15](5,h,C,n)),A=Q.o6.then(function(E){return E.send(l1,q,5E3)}).catch(function(){return L}),X[k[0]]((0,B8.tj)(function(){return A},e),k[1]);if(!(O={w$:(G=(t=(((D=X.G)||(D=I[26](k[2],k[1],Y[0],h)),Q).s5=D[k[0]].B,decodeURIComponent)(escape(f[11](16,"",Q[k[0]].Y))),Q[k[0]].l),c), +YU:t,tE:G,uK:D[k[0]][k[0]],z4:D[k[0]].UK,gz:N3,Q$:v[39](6,19,n.get()),HS:y[29](8,h,n,TY),OK:null,d$:null,Sy:null},Q[k[0]]).G)l[39](k[1],L,(u=(m=D.B)==L?void 0:m[k[0]])!=L?u:null,Q,O);return X[k[0]](l[10](32,Y[k[1]],L,Q,O,(B=(R=D.B)==L?void 0:R.B)!=L?B:null),Y[k[1]])})),N<<Z[0]&7)||(h=h===void 0?new Map:h,Q=Q===void 0?null:Q,y[0](Z[2]),m=new MessageChannel,e.postMessage(Z_,H[7](41,C,L),[m.port2]),F=new oB(m.port1,h,Q,L,m)),(N^38)<9&&(N^68)>>4>=Z[0])&&(A=[null,!0,2],m=new Pt,Q=f[5](4,m,ss,4,fM),h instanceof +Xn?(q=new SP,L!=A[0]&&(u=W[21](14,e,A[0],L),f[5](Z[2],q,Yg,e,u)),B=h.B?T[Z[1]](26,A[Z[0]],A[0]):K[Z[1]](18,A[Z[0]],A[0]),R=f[5](36,q,Wt,A[2],B),c=I[21](21,A[2],C,h),f[5](40,R,gu,C,c),l[28](44,A[0],A[2],Ht,q,Q,SP)):(G=new kg,L!=A[0]&&(n=W[21](6,e,A[0],L),f[5](52,G,Yg,e,n)),O=h.i.B?T[Z[1]](25,A[Z[0]],A[0]):K[Z[1]](17,A[Z[0]],A[0]),t=f[5](40,G,Wt,A[2],O),D=I[21](22,A[2],C,h.i),f[5](48,t,gu,C,D),l[28](61,A[0],6,Ht,G,Q,kg)),F=Q),(N<<Z[0]&27)==2&&(e=Error.call(this,"["+T[8](17,Z[0],C)+"] "+S[49](28,3,C)), +this.message=e.message,"stack"in e&&(this.stack=e.stack),this.status=C),F},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if((N|40)==(A=[72,4,22],N))a:{if(h=(L=L===void 0?!1:L,C.get(e))){if(typeof h==="function"){n=h;break a}if(typeof window[h]==="function"){n=window[h];break a}L&&console.log("ReCAPTCHA couldn't find user-provided function: "+h)}n=function(){}}return((((N>>2&((N|7)>>A[1]||(L=L===void 0?0:L,n=(h=l[43](56,e,C))!=null?h:L),7))==1&&(n=new ve),(N^26)>>A[1])||(t=Q.kL,B=Q.onMessage,c=Q.Zp, +u=Q.origin,O=Q.destination,G=c===void 0?"ZNWN1d":c,m=Q.zk,D=B===void 0?void 0:B,q=m===void 0?void 0:m,H[44](17,e,C,0,{destination:O,rI:function(){return t.contentWindow},Hj:u instanceof rJ?u:typeof u==="function"?new rJ(u):new rJ(y[36](23,L,h,u)),Zp:G,onMessage:D,zk:q})),N)|A[0])==N&&(n=I[A[2]](A[1],C)),n},function(N,C,e,L,h,Q,m,O,t,D){return(N|4)<((N-7^22)>=((N&89)==(t=["Ku",21,2],N)&&(YK.call(this,41,16,[2]),this.W=this.o=this.Y=this.T=this.J=this.C=this.lI=this.H=this.O=this.hO=this.Fe=this.Z= +this.Xe=this.rq=this.R=this.K=this.I=this.X=this.l=this.h=this.F=this.S=this.B=this.iI=this.u=-1,this.o6=this.G=this[t[0]]=-1,this.E5=I[t[1]](87),this.S_=I[t[1]](71)),N)&&(N+3^32)<N&&(Q=["TileSelectionStreetSign","/m/0k4j","/m/04w67_"],O=["/m/0k4j","/m/04w67_","TileSelectionStreetSign"],h=K[13](15,C,L.metadata),T[22](3,C,h)=="/m/0k4j"&&(Q=O),m=T[0](6,"rc-imageselect-desc-wrapper"),H[41](19,m),y[10](50,T[t[2]].bind(null,16),m,{label:Q[L.i.length-C],PS:pM}),T[8](t[1],e,L)),N+1>=-53&&(N^79)>>5<t[2]&& +this.iI([this.R]),12)&&(N+t[2]&5)>=1&&(L=["",!1,!0],this.G=L[0],this.B=L[0],this.P=L[0],this.i=L[0],this.V=L[1],this.A=L[0],this.o=null,C instanceof sB?(this.V=C.V,S[20](68,L[0],this,C.B),this.P=C.P,S[42](1,L[t[2]],this,C.i),S[12](7,this,C.o),I[34](7,L[t[2]],this,C.G),l[3](18,null,this,y[23](5,C.K)),T[25](19,this,C.A)):C&&(e=l[34](1,0,String(C)))?(this.V=L[1],S[20](4,L[0],this,e[1]||L[0],L[t[2]]),this.P=U[31](12,e[t[2]]||L[0]),S[42](15,L[t[2]],this,e[3]||L[0],L[t[2]]),S[12](8,this,e[4]),I[34](13, +L[t[2]],this,e[5]||L[0],L[t[2]]),l[3](26,null,this,e[6]||L[0],L[t[2]]),T[25](27,this,e[7]||L[0],L[t[2]])):(this.V=L[1],this.K=new Je(null,this.V))),D},function(N,C,e,L,h,Q,m,O,t){if(!(N<<2&((N>>2&(t=[null,25,18],14))==2&&(e=H[2](76,C),e=H[2](60,C)||e?1:0,U[29](68,e,C)),13)))a:{if(!(e=C,Es)){O=e;break a}try{L=function(D){return D},e=Es.createPolicy("goog#html",{createHTML:L,createScript:L,createScriptURL:L})}catch(D){}O=e}return(N<<1&((N-7|t[1])>=N&&(N+5^14)<N&&(K[5](5,[-51],H[16].bind(t[0],2)),K[5](11, +[-8],v[t[2]].bind(t[0],48)),K[5](35,[-24,-16],W[t[2]].bind(t[0],17))),12))<7&&N<<2>=-82&&(O=(m=String(Zf.location.href))&&h&&Q?[Q,U[22](72,60,e,0,C,L||t[0],h,S[17](2,"",3,m))].join(OY()):null),O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){if(((A=[57,0,"charCodeAt"],N&23)==N&&(e=H[2](72,C),e=H[2](64,C)%e|A[1],U[29](37,e,C)),N)+9>>4>=2&&((N^4)&16)<7)a:switch(D=[63,127,65536],typeof L){case "number":for(G=(Q=(G=(Q=(G=null(L),G/4294967296|A[1]),m=B=G|A[1],Q),L<A[1]&&(m=-B|A[1],G=~Q+(m===0?1:0)|A[1]),L< +A[1]?-1:0),L=m<<1^Q,G<<1|m>>>31)^Q,m=[];G>A[1]||L<A[1]||L>=128;)m.push(L&D[1]|128),L=L>>>C|(G&D[1])<<25,G>>>=C;m.push(L),c=m;break a;case "string":b:{for(m=A[G=[],1];m<L.length;m++)if(Q=L[A[2]](m),G[m]=Q,Q>>C){for(q=(u=A[t=A[1],h=L,1],[]);u<h.length;u++)O=h[A[2]](u),O<128?q[t++]=O:(O<2048?q[t++]=O>>6|192:((O&64512)==55296&&u+1<h.length&&(h[A[2]](u+1)&64512)==56320?(O=D[2]+((O&1023)<<e)+(h[A[2]](++u)&1023),q[t++]=O>>18|240,q[t++]=O>>12&D[A[1]]|128):q[t++]=O>>12|224,q[t++]=O>>6&D[A[1]]|128),q[t++]= +O&D[A[1]]|128);L=q;break b}L=G}c=W[18](11,128,D[1],L.length).concat(L);break a;case "object":if(Array.isArray(L)){for(G=(m=A[1],[]);m<L.length;m++)Q=W[7](32,7,10,L[m]),G.push.apply(G,T[5](A[0],Q));c=W[18](12,128,D[1],G.length).concat(G);break a}c=[];break a;default:c=[];break a}return(N^3)>>4||(c=P[44](77,function(n,R){return(L=(R=[21,24,11],H)[3](R[1],C,U[25](R[1],zY)))?n.return(U[37](R[2],L,v[17](R[0],e,C)).then(function(F){return dJ(v[33](21,F))}).catch(function(){return null})):n.return(null)})), +c},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){if((N|(N>>(c=[6,"o","call"],2)<2&&((N^9)&3)>=0&&(K2[c[2]](this),this.B=C,I[5](26,this,this.B),this[c[1]]=e),48))==N)a:try{A=C();break a}catch(n){A=e;break a}if((N|((N+2&13)>=N&&(N+2&22)<N&&(A=T[c[0]](2,!1,L,function(n,R,F,Z,X,Y,k,E){return P[44](77,function(J,r,z,d,x,w,a){if(J.B==(a=["G",1,2],w=[4,!1,3],a[1])){if(!n)throw 1;return z=(d=new ((x=(r=(Z=new (k=W[a[1]](89,h,Q),Uint8Array)(12),R.getRandomValues(Z),J).i,new ks),x).update(m),Uint8Array)(x.digest()), +n.importKey(wJ(),d,{name:VY(),length:d.length},w[a[1]],[xg(),aB()])),r.call(J,z,a[2])}if(J.B!=w[a[2]])return E=J[a[0]],J.i(n.encrypt({name:VY(),iv:Z,additionalData:new Uint8Array(0),tagLength:128},E,new Uint8Array(k)),w[a[2]]);return X=(Y=J[a[0]],new Uint8Array(Y)),F=new Uint8Array(e+X.length),F.set(Z,C),F.set(X,e),J.return(T[16](28,w[0],gJ,F))})})),64))==N){O=(q=(G=W[41](36,(L.O=(t=[],C),4),h,e,rY),P)[4](12,G),q).next();try{for(;!O.done;O=q.next())u=O.value,m=T[22](2,5,h,rY),t.push(L.Ac(m,u))}finally{O&& +!O.done&&(B=q.return)&&B[c[2]](q)}(D=y[48](10,4,h,y[11](18),(Q=L.CR,UA),rY),Q[c[2]](L,t,D),f)[26](48,"j",L)}return A},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if(!(N-6>>((N|(n=[29,68,64],n[2]))==N&&(e=H[2](n[1],C),e=H[2](n[1],C)>>>e,U[n[0]](39,e,C)),4))){if(u=!(q=(G=L.length,Q&C?0:-1),!G))D=L[G-e],u=D!=null&&typeof D==="object"&&D.constructor===Object;for(t=(B=(O=u,G+(O?-1:0)),Q)&C?1:0;t<B;t++)h(t-q,L[t]);if(O)for(c in m=L[G-e],m)!isNaN(c)&&h(+c,m[c])}if(((N+3&5)==1&&(Q=S[0](4,C,"",L?b1:MM,e), +P[n[0]](43,y[10](17,e),Q,$g,Pe(function(){S[29](39,this.v(),"overflow","visible")},e)),P[n[0]](8,y[10](23,e),Q,Ny,Pe(function(){L||S[29](35,this.v(),"overflow",""),h&&h()},e)),A=Q),(N|9)>>4<1)&&(N-6&11)>=0)a:{if(h.length>L.length){A=e;break a}if(h.length<L.length||h===L){A=C;break a}for(O=0;O<h.length;O++){if(Q=L[O],m=h[O],m>Q){A=e;break a}if(m<Q){A=C;break a}}}return A},function(N,C,e,L,h,Q,m,O){if(!((O=[0,44,"test"],N)-5&4))U[29](7,7,C);if((N<<((N+9&O[1])>=N&&N+3>>1<N&&p.call(this,C),1)&3)==2){if(L= +(e=e===void 0?f[O[0]](11,O[0]):e,L===void 0)?{}:L,I[6](53,e))L=e,Q=f[O[0]](9,O[0]);else if(typeof e==="string"&&/[^0-9]/[O[2]](e)){if(Q=window[Bh][jP()][e],Q==C)throw Error("Invalid site key or not loaded in api.js: "+e);}else Q=e;if(h=window[Bh][GN()][Q],!h)throw Error("Invalid reCAPTCHA client id: "+Q);m={client:h,fI:L}}return m},function(N,C,e,L,h,Q){if((((N&(((N-((N<<(h=["push",56,0],2)&15)==4&&(L=[0,!1,2],this.B=128,this.o=Zf[CA()]?new Uint8Array(this.B):Array(this.B),this.G=L[h[2]],this.X=[], +this.i=[],this.K=L[h[2]],this.V=C,this.j=v[5](3,L[2],1,e),this.P=L[1],this.reset()),4)|54)<N&&(N-2|5)>=N&&(Q=eZ?!!Ie&&!!Ie.platform:!1),N-9>>5<2)&&(N<<1&14)>=13&&p.call(this,C),h)[1])==N&&(L=C,Q=function(){return L<e.length?{done:!1,value:e[L++]}:{done:!0}}),N+9)^27)<N&&(N-8^25)>=N){if(C.i!==void 0)C.i[h[0]](e);else e instanceof LA?e.B!==void 0?C.B+=e.U5():(C.i=[C.B,e],C.B=void 0):C.B+=e;Q=C}return Q},function(N,C,e,L,h){return((L=[7,8,3],N+L[1])&L[0]||(e[hw]||(e[hw]={}),e[hw].severity=C),N^35)&L[2]|| +p.call(this,C),h},function(N,C,e,L,h,Q,m,O,t,D,q){return((D=["o","i","init"],N-1>>3)||(QX.length?(Q=QX.pop(),Q[D[2]](e,C,h,L),m=Q):m=new hl(e,C,h,L),this[D[1]]=m,this.B=this.G=-1,this[D[0]]=-1,this.K=this[D[1]][D[1]],K[12](2,this,L)),N>>1)&5||(t=function(u){return C.next(u)},O=function(u){return C["throw"](u)},q=new Promise(function(u,B){function G(c){c.done?u(c.value):Promise.resolve(c.value).then(t,O).then(G,B)}G(C.next())})),q},function(N,C,e,L,h,Q,m,O,t,D,q){if((((N-(q=[64,1,3],7)^11)<N&&(N+q[1]& +15)>=N&&(D=new my(C&4294967295,TH(C/4294967296))),N^27)&7)==q[2])a:{if(h=["]",",",'"'],e==null){D=L;break a}if(m=typeof e,m===OF)L+=e;else if(Array.isArray(e)){Q=0;for(L+="[";Q<e.length-C;Q++)L=W[14](24,q[1],e[Q],L),L+=h[q[1]];L=W[14](16,q[1],e[e.length-C],L),L+=h[0]}else m===tw?(L=L+h[2]+e.replace(/"/g,UF()),L+=h[2]):m===Dj&&(L+=e?1:0);D=L}if(((N^47)>>4||(v[14](q[2],L,m),l[q[1]](2,e,h,function(u,B){y[49](4,u>>>C,B>>>C,Q)})),N|q[0])==N)a:if(t=!1,O=l[14](22,m,h,Q,function(u,B){return B=v[35](41,0, +!1,e,L,u),t=B!==u&&B!=C,B}),O!=C){D=(t&&!U[22](q[1],O)&&l[q[1]](73,h,e),O);break a}return D},function(N,C,e,L,h,Q,m,O){return(N|((N&(O=[24,"ownerDocument",4],47))==N&&p.call(this,C),O[0]))==N&&(L.src=H[41](O[0],h),(Q=T[18](O[2],"nonce","",e,L[O[1]]))&&L.setAttribute(C,Q)),m},function(N,C,e,L,h,Q,m,O){return(N+4^32)>=(N>>(N>>2<((N|(((m=[" ",6,1],N-7)&24)<7&&(N-9&15)>=m[1]&&(O=K[36](4,"",null,'"',m[2],function(){return C},String(e)).replace(qy,ut())),56))==N&&(C=1200,C=C===void 0?20:C,e=e===void 0? +Bz:e,this.i=(new Uint8Array(wq(2810))).fill(0),this.B=C,this.G=e),17)&&((N^28)&7)>=m[1]&&(C.classList?C.classList.remove(e):v[36](3,C,e)&&K[2](5,"string",Array.prototype.filter.call(U[19](2,C),function(t){return t!=e}).join(m[0]),C)),m[2])&15||(L=H[2](68,C),e=H[2](56,C),U[29](4,e===L||e==null&&L==null?1:0,C)),N)&&(N+8^31)<N&&(Q=jZ(),O=h.replace(new RegExp(L+(Q?C+Q+e:"")+")([a-z])","g"),function(t,D,q){return D+q.toUpperCase()})),O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if((N>>(G=[22,2,9],G)[1]&7)== +G[1]&&(t=[3,33,6],D=B0.M().get(),!(e===GS&&T[42](16,32,D)||e===cz&&T[42](20,t[1],D)))){if(e==KA||e==Aw)L.i.A=Date.now();if((L.i.V=Date.now(),S)[3](65,L.A),L.i.G==gH&&L.i.P!=null)W[43](5,4,L.i.P,L);else u=function(c,A){yX((A=["Nz","i",10],L[A[1]].B.send.bind(L[A[1]].B)),A[2],c).then(function(n){W[43](3,4,n,L,!1)},L[A[0]],L)},q=function(c){L.i.B.send(c).then(function(A,n,R,F){if((R=[null,(F=["kx",49,8],""),0],A[F[0]]())==R[0]||A[F[0]]()==R[2]||A[F[0]]()==10)n=A.hm(),H[15](7,this,S[F[1]](21,C,A)||R[1]), +this.lf(it,S[F[1]](29,C,A)||R[1],A,n?v[28](60,f[29](F[2],n,4))*60:60,!1)},L.Nz,L)},h?T[G[0]](1,11,h,rY)?(O={},q(new vz((O[Yz]=T[G[0]](3,11,h,rY),O)))):u(new nA(H[11](G[2],t[G[1]],h,e))):L.i.i.rJ()==Ip?L.i.i.Fq(function(c,A,n,R,F,Z){(R=I[42]((Z=[29,0,10],Z[0]),C,H[11](Z[2],6,new kn,e),L.i.fu()),F=P[Z[1]](15,R,A,13,rY),n=P[Z[1]](13,F,c,12,rY),u)(new nA(n))},L.i.fu(),!1):(m=function(c,A,n,R){A=I[42](28,C,(R=[4,11,"fu"],H[R[1]](3,6,new kn,e)),L.i[R[2]]()),n=P[0](14,A,c,R[0],rY),u(new nA(n))},((Q=L.i.o.i)== +null?0:T[G[0]](4,t[0],Q,rY))?L.i.o.execute().then(m,m):Promise.resolve().then(m))}if((N&14)==N)f[5](8,e,Rp,C,L);return N+1&6||(e=C.EK,Q=['"></div><div class="','"><div class="',"recaptchaJavascriptChallengeQrAdditionalInstructionsContainer"],L=f[20](18,Fj(),e,UY(),XG()),h=T[1](65,fJ(),"<div id='rc-qr'><div class=\""+H[7](1,"recaptchaJavascriptChallengeQrOuterContainer")+Q[1]+H[7](1,"recaptchaJavascriptChallengeQrContainer")+Q[1]+H[7](1,"recaptchaJavascriptChallengeQrBackground")+Q[0]+H[7](33,"recaptchaJavascriptChallengeQrInstructionsContainer")+ +Q[1]+H[7](32,"recaptchaJavascriptChallengeQrShortInstructionsContainer")+'"><h1 class="'+H[7](1,"recaptchaJavascriptChallengeQrShortInstructions")+'">'),L?W[11](84,h,"Mobile Verification"):W[11](82,h,"Scan to Verify You're Human"),T[1](1,h,'</h1></div><div class="'+H[7](1,Q[G[1]])+Q[1]+H[7](64,"recaptchaJavascriptChallengeQrCameraIcon")+Q[0]+H[7](1,"recaptchaJavascriptChallengeQrMobileIcon")+'"></div><h2 class="'+H[7](33,"recaptchaJavascriptChallengeQrAdditionalInstructions")+'">'),L?W[11](52,h,"Click below to verify you are human. reCAPTCHA protects your privacy and does not share your details with this website or app."): +W[11](10,h,"Scan this QR code with your mobile device to verify you are human. reCAPTCHA protects your privacy and does not share your details with this website or app."),T[1](81,h,'</h2></div></div><canvas class="'+H[7](32,"recaptchaJavascriptChallengeQrCanvas")+'" tabindex="-1" role="img" aria-label="'),W[11](80,h,U[42](49,"QR code")),T[1](65,h,'"><p class="'+H[7](32,"recaptchaJavascriptChallengeQrFallbackText")+'"></p></canvas><a class="'+H[7](1,"recaptchaJavascriptChallengeQrButton")+'" id=\'rc-mobile-verification-button\' target="_blank" role="button">'), +W[11](80,h,"Click to verify"),T[1](16,W[11](82,T[1](81,h,lt()),l[11](68," ")),W8()),B=h),B},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){if((N+5&(F=[56,3,26],44))>=N&&(N-F[1]^9)<N){Q=(h=P[4](15,e),h.next());try{for(;!Q.done&&C.add(Q.value);Q=h.next());}finally{Q&&!Q.done&&(L=h.return)&&L.call(h)}Z=C}if((N|5)>>((N+2&7)==F[1]&&(e=~H[2](F[0],C),U[29](4,e,C)),F[1])==1){for(Q=(h=(L|=0,L&e),[]);h!==L;)Q.push(h|C),L>>>=7,h=L&e;Z=(Q.push(h),Q)}if((N|88)==N){if(Q=[4,1,16],L&2)throw Error();if((O=(t=v[9](16, +h,(D=y[30](58,C,L),D),e),m=t===Fq?7:t[Rw]|0,P[47](40,Q[1],L,m)),2&O||W[1](30,Q[0],O))||Q[2]&O)O===m||W[1](29,Q[0],O)||W[32](16,O,t),t=v[27](33,t),m=0,O=P[30](68,2,O,L),W[F[2]](9,L,h,e,t,D);Z=((O&=-13,O)!==m&&W[32](8,O,t),t)}if(!((N^90)&13)){if(h[Q=[239,0,63],Q[1]]!==GJ)throw 1;for(A=(D=(t=(q=U[F[2]](21,17,v[33](37,h.slice(C)),L.toString(),c0),Q)[1],[]),Q[1]);t<q.length;)R=q[t++],R<e?D[A++]=String.fromCharCode(R):R>191&&R<224?(c=q[t++],D[A++]=String.fromCharCode((R&31)<<6|c&Q[2])):R>Q[0]&&R<365?(B= +q[t++],n=q[t++],O=q[t++],m=((R&7)<<18|(B&Q[2])<<12|(n&Q[2])<<6|O&Q[2])-65536,D[A++]=String.fromCharCode(55296+(m>>10)),D[A++]=String.fromCharCode(56320+(m&1023))):(G=q[t++],u=q[t++],D[A++]=String.fromCharCode((R&15)<<12|(G&Q[2])<<6|u&Q[2]));Z=D.join("")}return Z},function(N,C,e,L,h,Q,m,O){return((N|24)==(m=[6,"readyState","DOMContentLoaded"],N)&&(O=U[47](43,C,64,W[33](37,e,L,void 0,void 0,P[0].bind(null,43)))),(N+7&15)>=7&&(N>>1&8)<m[0]&&(Q=function(){h||(h=e,L())},document[m[1]]==="complete"||document[m[1]]=== +"interactive"?L():(h=!1,window.addEventListener(C,Q,!1),window.addEventListener(m[2],Q,!1))),N)-m[0]>=22&&(N<<1&8)<1&&p.call(this,C),O},function(N,C,e,L,h,Q,m,O){if(N+(O=["push",13,16],1)<29&&N<<1>=O[2]){for(Q=[],h=C;h<L.length;h++)Q[O[0]](L[h]^e[h]);m=Q}if((((N|9)>=15&&(N^48)>>4<1&&(m=v[43](O[1],C,TS)?C:C instanceof Zj?P8(W[36](23,"",C).toString()):P8(String(String(C)).replace(op,I[48].bind(null,4)),P[22](O[1],null,0,1,C))),N)+7^26)>=N&&(N+8^O[1])<N)K[23](65,C,L,e);return(N&89)==N&&(m=new ZE(function(t, +D,q,u){for(D=e[Pz]();!t.closed;)u=D.next(),q=u.value,u.done?t.complete():t.next(q);return function(){return K[15](1,D==C?void 0:D.return)&&D.return()}})),m},function(N,C,e,L,h,Q,m,O,t,D){if((N&35)==((N-5&(t=[!1,7,"defaultPrevented"],t)[1])==1&&(h=new Yg,D=P[36](16,e,C,sF,L,h)),N))P[44](73,function(q,u){(m=(u=[13,"startsWith",9],I[u[2]](43,L,Q,fA)),(O=m.getName())&&O[u[1]](Xj())&&SZ.set(O,S[49](23,e,m,void 0,rY),{T4:U[u[0]](25,m,Yl,h,rY)?v[28](28,U[u[0]](26,m,Yl,h,rY).getSeconds()):void 0,path:Wz(), +sameSite:Hz,secure:C==document.location.protocol?!0:!1}),q).P()});return(N&52)==N&&(this.type=C,this.B=this.target=e,this.G=t[0],this[t[2]]=t[0]),D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if((N-5|83)<((N-8&((N-4|43)<((N&((N+7^(G=[28,2,1],22))>=N&&N-5<<G[2]<N&&(C.classList?C.classList.add(e):v[36](4,C,e)||(L=l[19](89,"","string",C),K[G[1]](4,"string",L+(L.length>0?" "+e:e),C))),G[0]))==N&&p.call(this,C),N)&&N-3<<G[1]>=N&&(h=h===void 0?null:h,Q=Q===void 0?null:Q,O=O===void 0?null:O,m=m===void 0?null: +m,L=L===void 0?null:L,t=t===void 0?null:t,D=D===void 0?null:D,this.response=C,this.timeout=e,this.error=L,this.B=t,this.IB=D,this.G=m,this.JM=h,this.o=O,this.i=Q),23))==3&&(Q=[46,13,11],O=L(e(),Q[G[1]],10),t=new kl,m=L(O,Q[G[2]]),h=T[21](40,t,G[2],m),u=L(O,8),D=T[21](24,h,G[1],u),q=L(O,Q[0]),B=T[21](24,D,3,q).G2()),N)&&N-8<<G[2]>=N)a:{for(O=(m=[e==typeof globalThis&&globalThis,h,e==typeof window&&window,e==typeof self&&self,e==typeof global&&global],C);O<m.length;++O)if((Q=m[O])&&Q[L]==Math){B=Q; +break a}throw Error("Cannot find global object");}return B},function(N,C,e,L,h,Q,m,O){if(((N^19)&(m=["i","push",(N-6>>4||(this.H=e,this.B=C),62)],8))<7&&(N^34)>>3>=2)if(h=[0,127,128],TH(L),L>=h[0])S[6](m[2],h[1],e,L);else{for(Q=h[0];Q<9;Q++)e[m[0]][m[1]](L&h[1]|h[2]),L>>=C;e[m[0]][m[1]](1)}return(N^22)>>4||(C=new rr,e=f[33](19,32,C,1,pA,Jw),O=P[0](15,e,"c6",2).G2()),O},function(N,C,e,L,h){if((h=["removeItem",43,3],N)-h[2]<<1<N&&(N+8^32)>=N)try{l[38](h[1],1,C)[h[0]](e)}catch(Q){}return(N|8)==N&&(e.I&& +P[20](h[2],e.I,function(Q,m){U[35](72,C,m,Q)}),e.P&&P[20](h[2],{},function(Q,m){U[35](73,C,m,Q)})),L},function(N,C,e,L){return((e=[2,19,7],N)+e[0]^5)>=N&&(N-1|e[2])<N&&(EF.call(this,zS),this.l=[],this.F=0,this.W=!1,this.rq=[],this.i=[]),(N^e[1])&6||p.call(this,C),L},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if(((c=[22,2,null],N)>>c[1]&5)==1)a:{if(!L){G=C;break a}(Q=T[c[0]](1,e,L),Q)===null||Q===void 0?h=C:h=new dr(Q),G=h}if((N-3|23)>=N&&(N+4^15)<N)a:{if((m=L.length-(D=[(u=e+(Q?0:-1),14),1023,1],D)[c[1]], +m)>=D[c[1]]+(Q?0:-1)&&u>=m&&(t=L[m],t!=c[2]&&typeof t==="object"&&t.constructor===Object)){t[e]=h,G=C;break a}if(u<=m){L[G=C,u]=h;break a}h!==void 0&&(q=((O=C)!=c[2]?O:C=L[Rw]|0)>>D[0]&D[1]||536870912,e>=q?h!=c[2]&&(B={},L[q+(Q?0:-1)]=(B[e]=h,B)):L[u]=h),G=C}return G},function(N,C,e,L,h,Q,m,O,t,D){if(((t=["G",2,44],N)&29)==N)P[t[2]](77,function(q,u,B){for(u=[3,76,"i"],B=23;B!=83;)if(B==37)B=q.B!=u[0]?53:10;else if(B==23)B=q.B==L?90:37;else if(B==10)m=q.G,K[26](13,wr,S[28](40),function(G,c,A,n,R,F, +Z,X,Y,k,E,J,r,z,d){for(d=(z=["O5",74,18],32);d!=61;)d==32?(k=["",2,4],E=G[z[0]],d=1):d==1?d=E.key&&E.newValue&&E.key.match(U[25](24,sY)+"-\\d+$")?6:61:d==6&&(F=new VX,c=P[0](14,F,E.key,L),r=TH(performance.now()/6E4),R=K[23](26,k[1],r,c),Y=v[38](z[2],k[0]+Q||k[0],8),X=P[0](78,R,Y,3),n=f[5](24,X,SW,k[2],O.CD()),Z=m.cE(),J=P[0](79,n,Z,5),A=S[11](51,k[1],J.D()),U[10](2,E.key+C+v[38](15,H[3](23,L,U[25](26,zY))||k[0]),A,h),W[36](z[1],e,l[27].bind(null,3)),d=61)}),q.P(),B=83;else{if(B==90)return q[u[2]](xl(T[45](67), +I[13](u[1])),2);if(B==53)return O=q.G,q[u[2]](ap(O.cE()),u[0])}});return(N>>1&7)<4&&(N^t[1])>=-62&&(D=C.i==C[t[0]]),D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((N&43)==((N>>2&6)>=(u=[12,127,0],4)&&N-9>>4<1&&(L=e[gr],L||(h=y[31](8,C,T[25].bind(null,4),S[36].bind(null,u[0]),e,Wf),L=function(G,c){return P[36](1,500,0,h,G,c)},e[gr]=L),B=L),N)&&(B=T[14](2,C,u[2],!0)?e(bt):H[2](21,C,function(G,c,A,n){c=(A=(n=["toJSON","prototype","JSON"],Array[n[1]])[n[0]],Object[n[1]][n[0]]);try{return delete Array[n[1]][n[0]], +delete Object[n[1]][n[0]],e(G[n[2]])}finally{A&&(Array[n[1]][n[0]]=A),c&&(Object[n[1]][n[0]]=c)}})),N+8>>2<N&&(N+2&14)>=N)a:{D=(O=(Q=L.i,t=L.B,m=[0,128,3],q=m[u[2]],m[u[2]]),m[u[2]]);do h=t[Q++],D|=(h&u[1])<<O,O+=7;while(O<C&&h&m[1]);if(O>C)for(q|=(h&u[1])>>4,O=m[2];O<C&&h&m[1];O+=7)h=t[Q++],q|=(h&u[1])<<O;if(!(f[20](27,Q,L),h&m[1])){B=e(D>>>m[u[2]],q>>>m[u[2]]);break a}throw Error();}return B},function(N,C,e){return(N-((N-(e=[0,!1,1],5)&e[2])==e[2]&&(this.yy=e[0],this.i&&this.i.call(this.B)),8)^ +22)<N&&N-5<<e[2]>=N&&(this.B=[],this.closed=e[1],this.i=e[1],this.K=null,this.G=e[1]),C},function(N,C,e,L,h,Q,m,O,t){if((N+(O=[61,!1,"Tt"],(N-5^20)<N&&N+5>>1>=N&&(h=rY,t=T[22](1,T[33](58,e,h,C,L),e,h)),7)&70)>=N&&N+9>>2<N)a:{if(this.isVisible()&&this.isEnabled()&&this[O[2]](C)){C.preventDefault(),C.i(),t=!0;break a}t=O[1]}if((N|80)==((N-7>>3==2&&(C=H[15](1,this),Q=y[34](58,this),e=y[34](O[0],this),m=y[34](57,this),h=y[34](O[0],this),L=y[21](4,y[21](2,Q,e)+e,e),this.Pm[C]=function(D){return(L=y[21](6, +m*L+h,e),D)+L}),N>>1>=21)&&(N^10)<40&&(C=[null,549,18],YK.call(this,C[1],C[2]),this.G=C[0],this.S=C[0],this.iI=C[0],this.Ku=C[0],this.h=C[0],this.X=C[0],this.S_=C[0],this.T=C[0],this.Y=C[0],this.R=C[0],this.H=C[0],this.l=C[0],this.F=C[0],this.rq=C[0],this.K=C[0],this.o6=C[0],this.Xe=C[0],this.B=C[0],this.Z=C[0],this.I=C[0],this.o=C[0],this.O=C[0],this.hO=C[0],this.W=C[0],this.C=C[0],this.lI=C[0],this.J=C[0],this.u=C[0],this.Fe=I[21](20),this.JO=I[21](87),this.E5=I[21](71)),N))switch(typeof L){case C:S[30](60, +e,L)}return t},function(N,C,e,L,h,Q){return(Q=[2,"mozRequestAnimationFrame",40],N-4<<Q[0]>=N)&&(N+1^5)<N&&(L=e.B,h=L.requestAnimationFrame||L.webkitRequestAnimationFrame||L[Q[1]]||L.oRequestAnimationFrame||L.msRequestAnimationFrame||C),h},function(N,C,e,L,h){if(((N^24)&(h=[1,7,"call"],h[1]))==h[0])p[h[2]](this,C);return(N-h[1]&h[1])==h[0]&&(Jd||Rw in e||Qg(e,mf),e[Rw]=C),L},function(N,C,e,L,h,Q,m,O,t){if(((N+8>>(O=[1,23,36],O[0])>=N&&N-8<<O[0]<N&&(h.T=O[0],h.h=f[16](3,U[O[2]](O[1],L)),h.A=e,h.C=!0, +P[9](33,2,O[0],C,h)),N-2)|2)<N&&(N-O[0]^2)>=N)a:if(My(C),m=l[14](6,L,C.z2,e,Q),m!==null||h&&$l!==1&&C.G!==NR){t=m;break a}return t},function(N,C,e,L,h,Q,m,O,t,D,q){return(D=[12,7,4],N+D[1]>>3==1&&(O=H[D[0]](41,C),t=t===void 0?{}:t,q=new ZE(function(u,B,G,c,A,n,R,F){return(G=((c=new Co(O,(B=(R=Q.h++,F=["B",13,"i"],n=t.Ww)!=null?n:Q.K.H3,m),u,B,R,!1),T)[F[1]](3,C,Q),y[40](24,c,Q)))&&(G[F[0]]||O.compare(G[F[2]])<=C)?(A=e,W[36](72,6E4,function(){A&&c.B.complete()}),function(){A=L}):S[24](1,1,h,c,Q)})), +N)>>1&D[1]||(q=C&&K[15](D[2],C.jn)),q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA){return(((UC=[21,1,4],N-UC[2]^UC[0])<N&&(N+3&68)>=N&&(e=H[2](28,C),e=H[2](56,C)/e|0,U[29](7,e,C)),N+7>>3>=2)&&N+9>>UC[2]<2&&(tA=U[13](25,e,ej,C,rY)),N<<UC[1]&6)||(mQ=[0,18,2],w=mQ[0],r=mQ[0],r=r===void 0?0:r,m=m===void 0?null:m,O=O===void 0?0:O,Q=Q===void 0?0:Q,w=w===void 0?0:w,D.g$||(E=f[18](49,11,D),z=r,Df=w,g=O,u=new Lo,c=y[44](18,UC[1],u,D.o),R=W[42](7,D.G,mQ[2],c), +Y=K[23](58,h,g>mQ[0]?g:void 0,R),x=K[23](UC[1],UC[2],Df>mQ[0]?Df:void 0,Y),X=K[23](28,L,z>mQ[0]?z:void 0,x),q=U[23](19,mQ[0],e,X),f[5](32,E,Lo,10,q)),n=y[39](UC[2],34,D.i),k=Date.now().toString(),a=f[13](45,"bigint",n,k,UC[2]),G=l[36](11,mQ[2],a,hZ,t.slice(),h),m&&(Z=m,d=new QZ,F=K[23](27,13,Z,d),A=new mI,J=f[5](16,A,QZ,mQ[2],F),B=new OH,hA=f[5](24,B,mI,UC[1],J),M=y[44](14,mQ[2],hA,C),f[5](20,G,OH,mQ[UC[1]],M)),Q&&T[UC[0]](36,G,14,Q),tA=G),(N&59)==N&&(q=["0px","px",1],D=I[49](20,C,m.i)==="visible", +S[29](23,m.i,{visibility:O?"visible":"hidden",opacity:O?"1":"0",transition:O?"visibility 0s linear 0s, opacity 0.3s linear":"visibility 0s linear 0.3s, opacity 0.3s linear"}),D&&!O?m.R=W[36](74,e,function(){S[29](19,this.i,L,"-10000px")},m):O&&(S[3](72,m.R),S[29](39,m.i,L,q[0])),Q&&(t=S[28](33).innerHeight,U[34](5,q[UC[1]],P[25](UC[0],q[2],m),RY(Q.width,S[28](33).innerWidth),RY(Q.height,t)),U[34](8,q[UC[1]],f[28](28,h,P[25](17,q[2],m)),Q.width,Q.height),Q.height>t&&O&&S[29](71,P[25](29,q[2],m),{"overflow-y":"auto"}))), +tA},function(N,C,e,L,h,Q,m,O,t,D,q){if((N&90)==((q=["Invalid listener argument","handleEvent",6],N-4^19)>=N&&(N-q[2]^21)<N&&(D=S[31](12,C)),N)){if(typeof e==="function")L&&(e=Pe(e,L));else if(e&&typeof e[q[1]]=="function")e=Pe(e[q[1]],e);else throw Error(q[0]);D=Number(C)>2147483647?-1:Zf.setTimeout(e,C||0)}if((N&59)==N&&(KN.call(this,tZ(),U[5](69,Hk),y4()),v[14](15,this,C),this.ah=!0),(N+3^27)<N&&(N-9^13)>=N)a:{if((O=[1,"7.0",""],h=/rv: *([\d\.]*)/.exec(L))&&h[O[0]]){D=h[O[0]];break a}if((m=(Q=O[2], +/MSIE +([\d\.]+)/.exec(L)))&&m[O[0]])if(t=/Trident\/(\d.\d)/.exec(L),m[O[0]]==O[1])if(t&&t[O[0]])switch(t[O[0]]){case C:Q=UH();break;case "5.0":Q=DX();break;case e:Q=qR();break;case O[1]:Q=ui()}else Q=B9();else Q=m[O[0]];D=Q}if(!((N^q[2])&10))a:{if(e instanceof Zj){D=e.i;break a}throw Error(C);}return D},function(N,C,e,L,h,Q){return N-((N+((((N|48)==(h=[1,8,73],N)&&jj.call(this,C,e||G6.M(),L),N+3)&31)>=N&&N-4<<h[0]<N&&(Q=I[h[0]](h[2],e)&&!I[h[0]](89,C)&&!I[h[0]](75,"iPad")),h)[1]&62)<N&&(N+4^6)>= +N&&(this.G=C.mK||null,this.B=C.Jp||!1),h[1])<<2>=N&&(N-h[0]^10)<N&&(e=typeof H[2](24,C),U[29](69,e,C)),Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F){if(((N-(F=[30,"test",26],7)^15)>=N&&(N+9&34)<N&&(R=S[41](42,C,void 0,e)),N>>2<16)&&N>>2>=8)a:{try{R=Zf[c9()][Ko()](h);break a}catch(Z){}if((Q=String(h),/^\s*$/[F[1]](Q))?0:/^[\],:{}\s\u2028\u2029]*$/[F[1]](Q.replace(/\\["\\\/bfnrtu]/g,AZ()).replace(/(?:"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)[\s\u2028\u2029]*(?=:|,|]|}|$)/g, +yZ()).replace(/(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g,e)))try{R=eval(C+Q+L);break a}catch(Z){}throw Error("Invalid JSON string: "+Q);}return(N+8^14)<((N+4^5)<N&&(N+6&57)>=N&&(R=P[44](41,function(Z,X){X=["arrayBuffer","getWriter","i"];switch(Z.B){case L:return m=new CompressionStream("gzip"),t=(new Response(m.readable))[X[0]](),O=m.writable[X[1]](),Z[X[2]](O.write((new TextEncoder).encode(Q)),C);case C:return Z[X[2]](O.close(),e);case e:return D=Uint8Array,Z[X[2]](t,h);case h:return Z.return(new D(Z.G))}})), +N)&&(N-3^20)>=N&&(A=I[21](20),n=I[21](71),R=[y[36](3,L),y[15](72,C,h),v[31](71,h,Q),T[F[0]](59,A,W[0](6,Q),W[0](22,L)),P[37](87,D,Q,m),T[F[0]](38,A,W[0](23,m),W[0](18,L)),ii(q,O,t,m),U[0](75,u,e),P[37](81,u,q,B),T[F[0]](49,A,W[0](16,B),W[0](7,L)),P[37](32,W[0](7,B),B),U[0](90,u,c),I[F[2]](34,G,u,W[0](1,B)),T[F[0]](49,n,1,1),A,U[0](94,u,c),I[F[2]](38,G,u,0),n]),R},function(N,C,e,L,h,Q){return((((((N&60)==((Q=[2,15,9],N-Q[2])<<Q[0]<N&&(N-6|69)>=N&&(h=C.i?l[49](19,C.i.P):new B2(0,0)),N)&&(h=H[38](6, +C,P[44](30,null,e),Q[0])),N)>>Q[0]&Q[1])>=8&&N-8>>5<5&&(h=v9&&!C?Zf.btoa(e):S[11](50,Q[0],f[34](3,8,0,e),C)),N)^74)&Q[1])<7&&N+1>>4>=Q[0]&&(this.message=C,this.messageType=e,this.i=L),h},function(N,C,e,L,h,Q,m,O,t){if(((O=[1,8,15],N-7<<O[0])>=N&&(N-5^O[2])<N&&(t=P8("Scan the QR code with your phone's camera. This will initialize the verification process on the phone. After verification, you will pass the challenge.")),N+6)>>4>=O[0]&&(N<<2&O[1])<2)a:{m=["nanos must be less than 1000000000: ","nanos must be at least 0: ", +"seconds must be at least -62135596800: "];try{if((h=(Q=Number(L.getSeconds()),T[O[1]](48,C,L)),Q)<-62135596800)throw Error(m[2]+Q);if(253402300800<=Q)throw Error("seconds must be less than 253402300800: "+Q);if(h<0)throw Error(m[O[0]]+h);if(1E9<=h)throw Error(m[0]+h);if(!Number.isInteger(Q))throw Error("seconds must be integer: "+Q);if(!Number.isInteger(h))throw Error("nanos must be integer: "+h);t=new Cz(Q,h);break a}catch(D){t=e;break a}}return t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F, +Z,X,Y,k,E,J,r,z,d){if(((N^39)&7)==((N&(z=[22,"decode",null],14))==N&&(G={timeout:1E4},D=G.document||document,B=H[41](24,Q).toString(),t=(new no(D)).createElement(Iq),c={C7:t,VM:void 0},q=new Rq(FZ,c),u=z[2],O=G.timeout!=z[2]?G.timeout:5E3,O>h&&(u=window.setTimeout(function(x,w){(K[9](57,(w=[43,!0,24],null),w[1],t),x=new li(1,"Timeout reached for loading script "+B),H)[6](w[2],e,q),I[w[0]](5,w[1],q,e,x)},O),c.VM=u),t.onload=t.onreadystatechange=function(x){(x=[59,9,"complete"],t.readyState)&&t.readyState!= +"loaded"&&t.readyState!=x[2]||(K[x[1]](x[0],null,G.Ma||e,t,u),q.aM(null))},t.onerror=function(x,w){K[w=[9,58,22],w[0]](w[1],null,!0,t,u),x=new li(0,"Error while loading script "+B),H[6](w[2],e,q),I[43](21,!0,q,e,x)},m=G.attributes||{},yO(m,{type:"text/javascript",charset:"UTF-8"}),y[46](5,h,"aria-",m,t),W[15](24,L,C,t,Q),y[12](1,h,D).appendChild(t),d=q),4)){if(c=(F=(O=[55296,1023,63],I[48](1,0,Q,L)),L.B),T6){X=(m=(X=c,h?((R=ZX)||(R=ZX=new TextDecoder("utf-8",{fatal:!0})),D=R):((u=oq)||(u=oq=new TextDecoder("utf-8", +{fatal:!1})),D=u),F+Q),Z=D,F===0&&m===X.length?X:X.subarray(F,m));try{k=Z[z[1]](X)}catch(x){if(B=h){if(P9===void 0){try{Z[z[1]](new Uint8Array([128]))}catch(w){}try{Z[z[1]](new Uint8Array([97])),P9=e}catch(w){P9=!1}}B=!P9}B&&(ZX=void 0);throw x;}}else{for(r=(A=(q=F,z[G=[],2]),q+Q);q<r;){if(Y=c[q++],Y<128)G.push(Y);else if(Y<224)if(q>=r)v[14](6,G,h);else t=c[q++],Y<194||(t&192)!==128?(q--,v[14](38,G,h)):G.push((Y&31)<<6|t&O[2]);else if(Y<240)if(q>=r-C)v[14](70,G,h);else t=c[q++],(t&192)!==128||Y=== +224&&t<160||Y===237&&t>=160||((J=c[q++])&192)!==128?(q--,v[14](z[0],G,h)):G.push((Y&15)<<12|(t&O[2])<<6|J&O[2]);else if(Y<=244)if(q>=r-2)v[14](6,G,h);else t=c[q++],(t&192)!==128||(Y<<28)+(t-144)>>30!==0||((J=c[q++])&192)!==128||((n=c[q++])&192)!==128?(q--,v[14](54,G,h)):(E=(Y&7)<<18|(t&O[2])<<12|(J&O[2])<<6|n&O[2],E-=65536,G.push((E>>10&O[1])+O[0],(E&O[1])+56320));else v[14](z[0],G,h);G.length>=8192&&(A=y[40](81,z[2],G,A),G.length=0)}k=y[40](80,z[2],G,A)}d=k}if((N|(N>>1&13||(d=W[45](3,C,l[z[0]].bind(z[2], +11),y[11](3),L,h,void 0,e)),80))==N&&!f[36](6,!0,L))if(O=f[1](5,"\r\n",C,L),typeof h==="string")Q=P[30](16,e),m=O!=z[2]?"="+P[30](20,O):"",f[5](10,"?",h,Q+m);else U[35](73,h,e,O);return(N>>1&15)!=3||L.i||L.X||(L.Xe=1,v[3](19,C,L.bI,L),L.J=e),d},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){if(!((c=[": ",3,"call"],N<<1)&7))sH[c[2]](this);if(!((N^54)>>4)){if(h instanceof Map){G=(B=P[4](14,(t={},h)),B.next());try{for(;!G.done;G=B.next())u=P[4](10,G.value),m=u.next().value,Q=u.next().value,t[m]=Q}finally{G&& +!G.done&&(O=B.return)&&O[c[2]](B)}}else t=h;(q=new (D=t,xK),fo.push(q),K[32](10,!0,q,q.h0,gq),q).send(C,e,L,D)}return(N|c[1])>>4||(A=H[38](2,L,C==null?C:T[21](21,c[0],C),e)),A},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(!((N|((N&56)==((u=[10,43,"PL"],(N^91)&26)||(YK.call(this,659,12),this[u[2]]=T[15](5,!1,121,B0.M()),this.h=this.T=this.K=this.Ku=this.JO=this.Np=this.o=this.hO=this.qp=this.F=this.hj=this.rq=this.ZM=this.iI=this.wq=this.lI=this.bI=this.Vk=this.O=this.Fd=this.C=this.o6=this.W=this.R=this.Xe= +this.S=this.B=this.H=this.u=this.G=this.l=this.z$=this.Y=this.mF=this.Fe=this.iz=this.I=this.S_=this.X=this.J=this.Z=this.E5=-1,this.SW=I[21](84),this.lz=I[21](84),this.E_=I[21](7),this.ZR=I[21](84),this.vK=I[21](23),this.jW=I[21](20)),N)&&(B=P[0](78,e,L,C)),4))>>4)){if(v[18](68,(t=[7,0,9],t[1]),e,XZ,18,rY))try{Q=W[36](5,U[13](u[0],e,XZ,18,rY)),O=QI(Q),L.o=L.i.i.YN(new Sj(O),3E4),L.o&&typeof L.o.catch==="function"&&L.o.catch(H[37].bind(null,45))}catch(G){L.o=Promise.resolve(new Yv(0,[],void 0,8,0))}if(l[u[1]](47, +6,e,rY)!=null)L.i.i.onError(e.kx());else T[42](52,13,e)&&L.i.i.DD(),H[15](38,L,e.fu()),e.DS()&&(q=e.DS(),U[u[0]](18,U[25](28,$Z),q,1)),e.tG()&&(D=e.tG(),U[u[0]](32,U[25](27,N$),D,t[1])),(0,B8.tj)(L.lf.bind(L,T[22](3,5,e,rY),T[22](3,t[2],e,rY),U[13](15,e,UA,C,rY),K[22](19,null,e.m0()),!!h),8),U[13](8,e,W9,t[0],rY)&&(m=U[13](20,e,W9,t[0],rY),L.i.o.set(m),L.i.o.load())}if((N&78)==N&&(Q=[null,0,"bigint"],m=K[47](6,64,!1,e),m!=Q[0]&&(W[30](80,"string",Q[0],m),m!=Q[0])))switch(v[22](7,C,L,Q[1]),typeof m){case "number":(O= +C.i,TH)(m),v[39](54,Q[1],m),y[49](4,l5,TU,O);break;case Q[2]:(t=y[3](24,Q[1],H9,U[33].bind(null,22),m),y)[49](68,t.B,t.i,C.i);break;default:h=S[30](59,Q[0],m),y[49](36,h.B,h.i,C.i)}return(N|7)>>3==2&&(this.B=C>>>0,this.i=e>>>0),B},function(N,C,e,L,h,Q){return(N-3|(N+((h=["t2",16,14],(N|5)>=13)&&(N^42)<h[2]&&(e.VB&&(y[40](1,e.VB),y[40](3,e.Dq),y[40](1,e.B),e.VB=C,e.B=C,e.Dq=C),e[h[0]]=-1,e.BK=-1,e.i=C),9)>>3==1&&(Q=S[h[1]](19,W[33](29,e,C))),50))<N&&N-9<<2>=N&&(L=e,Q=(new wu(function(m,O){(L=W[36](64, +C,function(){m(void 0)}),L==-1)&&O(Error("Failed to schedule timer."))})).V(function(m){S[3](73,L);throw m;})),Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y){if(!((N|(X=["playbackRate",11,12],3))>>3)){if(G=(A=((m=(D=U[22](X[2],(u=(q=[2,(R=O.z2,16),0],R[Rw])|q[2],O),u)?1:L,!!m)||D===3,D===2&&S[45](25,!0,O))&&(R=O.z2,u=R[Rw]|q[2]),c=v[9](6,h,Q,R),c===Fq?7:c[Rw]|q[2]),n=P[47](8,1,u,A),C&n?!1:!0),G){for(F=(t=(C&n&&(c=v[27](97,c),A=q[2],n=P[30](65,q[0],n,u),u=W[26](8,u,h,R,c,Q)),q)[2],q[2]);F< +c.length;F++)B=e(c[F]),B!=null&&(c[t++]=B);n=(Z=(n|C)&(t<F&&(c.length=t),-513),Z&=-1025),n&=-4097}Y=c=(n!==A&&(W[32](32,n,c),q[0]&n&&$4(c)),K[8](4,q[1],Q,D,u,n,h,m,G,c,R))}return((N^39)&3)==(N-7>>4||p.call(this,C),2)&&this.h&&(e=this.h,C=B0.M().get(),L=l[0](X[1],null,C,6,1,rY),e[X[0]]=L,this.h.load(),this.h.play()),Y},function(N,C,e,L,h){return(L=[3,"B",2],N>>1&L[2]||(h=e?new no(f[27](34,C,e)):kv||(kv=new no)),((N|L[0])&7)>=0)&&((N^8)&L[2])<1&&(this.i=C,this[L[1]]=e),h},function(N,C,e,L,h,Q,m){if(N- +(Q=[3,!1,null],(N^2)>>Q[0]||p.call(this,C),8)>>Q[0]==1){for(h=(e=(L=new aI,H)[29](8,Q[1],Q[2],C(),function(O,t){return t=[6153,"","tagName"],(O[t[2]]==xn||O[t[2]]==aY)&&U[4](10,t[0])(O)!=t[1]}),0);h<e.length&&L.add(e[h].name);h++);m=L.toString()}return m},function(N,C,e,L,h,Q){return(N+(N-7>>(h=[31,"response",5],(N&109)==N&&(this[h[1]]=C),h[2])<1&&N+6>>4>=0&&(e=H[2](68,C),e=H[10](4,h[0],1,C,e),U[29](36,e,C)),h[2])^h[2])>=N&&(N-h[2]|46)<N&&(C.B&&W[44](42,null,C),C.i=e,C.VB=K[26](8,q$,C.i,C,L),C.Dq= +K[26](11,oF,C.i,C.G,L,C),C.B=K[26](10,uA,C.i,C.wo,L,C)),(N|40)==N&&C&&C.parentNode&&C.parentNode.removeChild(C),Q},function(N,C,e,L,h,Q,m,O,t){if(((t=[3,7,15],N)|48)==N){if(e.MW.length>7652)throw new IH(7);(((Q=(m=h!==0?e.MW[e.MW.length-C]:e.Ql.length,e).nI.xx,e.MW).push(h),e.MW).push(Q),e.MW.push(m),e.MW).push(e.Ql.length),e.nI.xx=L>>>t[0]}if(!(N>>1&t[2])){L=(e=(m=(h=[1,"Sources: ",'<div class="'],C.sources),h[2])+H[t[1]](65,"rc-prepositional-attribution")+'">',Q=0,m).length;for(e+=h[1];Q<L;Q++)e+= +'<a target="_blank" href="'+H[t[1]](65,S[6](t[2],m[Q]))+'">'+W[20](60,Q+h[0])+"</a>"+(Q!==m.length-h[0]?rX():"")+" ";O=P8(e+'(CC BY-SA)</div>For each phrase above, select it if it sounds somehow incorrect. Do not select phrases that have grammatical problems or seem nonsensical without other context. <a href="https://support.google.com/recaptcha" target="_blank">Learn more.</a>')}return(N|((N>>2&t[1])==2&&C.appendChild(e),t)[0])>>t[0]==t[0]&&(O=C&&e&&C.fJ&&e.fJ?C.sm!==e.sm?!1:C.toString()===e.toString(): +C instanceof Tk&&e instanceof Tk?C.sm!=e.sm?!1:C.toString()==e.toString():C==e),O}]}(),S=function(){return[function(N,C,e,L,h,Q,m,O){if(!((m=["V",12,null],N+1)&7))switch(C=C||new jW,this.S=C.XI,C.yM&&(this[m[0]]=C.yM),C.i!=m[2]&&(this.h=!!C.i),this.i.G){case gH:W[17](9,2,KA,this,new kn(C.B));break;case xZ:W[17](9,2,Aw,this);break;default:P[15](m[1],this,!0)}return(N&61)==N&&(Q=new po(P[43](2,L.i,h),L.size,L.box,L.time,void 0,!0),P[8](34,C,Pe(function(t,D){t=this[D=["backgroundPositionY","backgroundPositionX", +"V"],D[2]].style,t.backgroundPosition=e,typeof t[D[1]]!="undefined"&&(t[D[1]]=e,t[D[0]]=e)},Q),Q,JZ),O=Q),O},function(N,C,e,L,h,Q,m,O,t,D,q,u){if(!(N+((q=[1,0,88],N^21)<9&&(N>>2&7)>=4&&(u=U[38](8)?P[35](19,q[1],EH):(I[q[0]](q[2],"Chrome")||I[q[0]](91,C))&&!I[40](33,"Edge")||S[17](47,"Silk")),9)>>4))a:{if(typeof C!==(m=[2,null,34],"object")){u=C;break a}if(Array.isArray(C)){u=(h=C[Rw]|q[1],C.length===0&&h&q[0])?void 0:H[25](3,m[2],m[q[1]],e,h,C);break a}if(C!=m[q[0]]&&C[MI]===$r){u=T[27](17,q[1],m[2], +C);break a}if(C instanceof z6){if(L=C.Nd,L&m[q[1]]){u=C;break a}if(!C.size){u=void 0;break a}if((t=y[15](21,m[2],K[42](58,8192,C)),C).KD)for(O=q[1];O<t.length;O++)Q=t[O],D=Q[q[0]],D==m[q[0]]||typeof D!=="object"?D=void 0:D!=m[q[0]]&&D[MI]===$r?D=T[27](16,q[1],m[2],D):Array.isArray(D)?D=H[25](2,m[2],m[q[1]],!!(L&32),D[Rw]|q[1],D):D=void 0,Q[q[0]]=D;u=t;break a}if(C instanceof dX){u=C;break a}}return u},function(N,C,e,L,h,Q,m,O,t){if((N|(O=["K","j",56],O)[2])==N)a:{if(Q.B!==0){t=C;break a}t=(K[1](38, +l[21](32,Q.i),L,h,m),e)}if((N+7^31)>=N&&(N+4^10)<N)a:{if((L=wX(),typeof console!=="undefined")&&typeof console[VZ()]==="function")try{if(e=console[VZ()](L),typeof e==="object"&&e!==null&&typeof e[xv()]==="function"){t=e;break a}}catch(D){}t={run:function(D){return D.apply(void 0,aq.apply(C,arguments))}}}return((N^34)&22)==((N^96)>=-55&&(N-2&16)<7&&(L=[!1,0,null],this.i=L[2],this.A=L[1],this.S=L[0],this.B=void 0,this.o=L[0],this.G=L[0],this.P=L[1],this[O[0]]=[],this.J=C,this[O[1]]=L[0],this.V=L[0], +this.h=e||L[2]),(N-8^17)>=N&&(N-9|45)<N&&(h=C.DM&&((L=C.DM[0])==null?void 0:L.type))&&(Q=y[14](9,h)&65535,e=this.S.get(Q)||0,this.S.set(Q,e+1)),2)&&(C.iI=Date.now()+C.VM,v[42](8,null,C.VM,C)),t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(B=[1,0,6],!((N^52)>>4)&&(m=[0,1],this.i=[],C))a:{if(C instanceof gX){if(Q=C.e2(),O=C.lX(),this.i.length<=m[B[1]]){for(L=(h=m[B[1]],this).i;h<Q.length;h++)L.push(new b5(O[h],Q[h]));break a}}else{for(q in Q=v[B[2]](B[0],m[(D=m[B[1]],B)[1]],(e=[],C)),C)e[D++]=C[q];O=e}for(t= +m[B[1]];t<Q.length;t++)f[34](44,m[B[0]],O[t],this,Q[t])}return((N&121)==N&&Zf.clearTimeout(C),(N|2)>>3)==3&&((C==null?0:C.didTimeout)?this.Ju(null):this.Ju(C)),(N>>B[0]&15)==2&&(H[19](18,B[1],e,C),u=new bi(e)),u},function(N,C,e,L,h){return(N-9^((N+1&29)>=(((N|72)==((N+4&(L=["querySelectorAll",18,6],13))>=11&&((N|L[2])&20)<19&&new MR("/recaptcha/api2/jserrorlogging",C,void 0),N)&&(h=P8('<textarea id="'+H[7](1,C)+'" name="'+H[7](64,e)+'" class="g-recaptcha-response"></textarea>')),N)<<1&14||(h=C+$v+ +NP.split(C1())[0]),N)&&(N+1&L[1])<N&&(h=l[43](63,C,e,void 0,FG)),24))<N&&(N-L[2]^28)>=N&&(h=Array.prototype.filter.call(document[L[0]](".grecaptcha-badge"),function(Q){return S[9](42,et,Q.getAttribute("data-style"))}).length>C),h},function(N,C,e){return N+3>>2<((N|(e=[34,"from",32],e[2]))==N&&(this.R=y[e[0]](63,this)),N)&&N+6>>1>=N&&(C=Array[e[1]](X$,function(L,h,Q,m,O,t,D){return(t=(m=P[4](12,(D=[44,23,65],L)),h=m.next().value,O=m.next().value,Q=new L1,y)[D[0]](22,1,Q,h),K)[D[1]](D[2],2,O,t)})), +C},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F){if(!((N^59)>>((N-(R=[10,2,30],(N&45)==N&&(Array.isArray(L)||(L=[String(L)]),H[R[2]](11,0,null,C.K,L,e)),8)&15)==3&&(e&&l[5](3,C,h),O=v[35](9,0,L,m,h,C),Q&&(O=T[34](R[1],!1,O)),F=O),3))){for(TH(L);L>C;)e.i.push(L&C|128),L>>>=7;e.i.push(L)}if((N-6^13)>=N&&(N+3^12)<N&&(D=this[hG],B=this[FN],O=[0,1,2],Q=v[R[0]](39,O[1],void 0,B.LD),m=T[1](36,C))&&(A=B.iA,c=function(Z,X,Y,k,E,J,r,z){if((z=[!0,9,8],Y).length!==0)if(A[X]){E=(r=P[4](12,Y),r.next());try{for(;!E.done;E= +r.next()){J=l[26](23,E.value);try{G=z[0],D(Q,J)}finally{U[z[1]](z[2],100,J)}}}finally{E&&!E.done&&(k=r.return)&&k.call(r)}}else h==null||h(C,X,Y)},G=!1,A)){if(e==null)v[19](17,c,m);else m!=null&&(t=m[e])&&c(m,e,t);if(G){if((u=C[Rw]|(q=function(Z,X,Y){if(l[Y=[14,null,44],Y[0]](Y[2],n,C,Z)!=Y[1])switch(L==Y[1]?void 0:L.eo){case 1:return;default:throw Error();}delete (X!=Y[1]&&(u=W[26](22,u,Z,C,X,n)),m)[Z]},O[0]),u&O[R[1]])&&u&2048&&(L==null||!L.sZ))throw Error();(n=y[R[2]](26,128,u),e)==null?W[9](17, +128,O[1],Q,function(Z,X){q(Z,X)},Q[Rw]|O[0]):q(e,l[14](4,n,Q,e))}}return(N<<1&15)>=R[0]&&N>>1<19&&(v[43](R[2],C,QK)||v[43](12,C,qw)?e=String(C).replace(m7,I[43].bind(null,20)):(C instanceof O$?L=K[33](18,S[8](6,"",C)):(C instanceof u5?h=K[33](19,H[41](48,C).toString()):(Q=String(C),h=tG.test(Q)?Q.replace(m7,I[43].bind(null,28)):BV()),L=h),e=L),F=e),F},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if(!(N>>1&(n=[48,7,"ERROR for site owner:<br>Policy-based challenges cannot be rendered as a checkbox."], +15))){D='<div class="'+(O=(t=f[20](19,(m=(Q=(h=[3,(L=L||{},'"><div class="'),"Your session has expired."],L.errorCode),L).errorMessage,U$()),m,UY(),DJ()),f[20](23,qP(),Q,UY(),uM())),H[n[1]](64,"rc-inline-block"))+h[1]+H[n[1]](1,"rc-anchor-center-container")+h[1]+H[n[1]](1,"rc-anchor-center-item")+" "+H[n[1]](33,"rc-anchor-error-message")+'">';switch(O){case 1:D+="Invalid argument.";break;case 2:D+=h[2];break;case h[0]:D+="This site key is not enabled for the invisible captcha.";break;case 4:D+="Could not connect to the reCAPTCHA service. Please check your internet connection and reload."; +break;case 5:D+='Localhost is not in the list of <a href="https://cloud.google.com/recaptcha/docs/troubleshoot-recaptcha-issues#localhost-error" target="_blank">supported domains</a> for this site key.';break;case 6:D+="ERROR for site owner:<br>Invalid domain for site key";break;case n[1]:D+="ERROR for site owner: Invalid site key";break;case 8:D+="ERROR for site owner: Invalid key type";break;case 9:D+="ERROR for site owner: Invalid package name";break;case 10:D+="ERROR for site owner: Invalid action name goo.gle/recaptcha-action-name"; +break;case C:D+="ERROR for site owner:<br>Invalid endpoint for host domain. Please contact your assigned Security Sales Specialists if you have one or reach out to Google Cloud support through https://cloud.google.com/contact otherwise.";break;case 17:D+=n[2];break;default:D=D+"ERROR for site owner:<br>"+W[20](58,t!=e?t:"")}A=P8(D+"</div></div></div>")}return(((((N^17)>>((N&25)==N&&(A=Promise.resolve(l[23](14,4,6,C,e))),4)==4&&(KN.call(this,I[14](35,BX),U[5](77,Ky),y4(),9),v[n[0]](47,Fo,this,C),v[n[0]](54, +jt,this,e),S[n[1]](59,L,H7,this),S[n[1]](57,h,Gc,this),S[n[1]](55,Q,cX,this),S[n[1]](55,m,K1,this),S[n[1]](56,O,AG,this),S[n[1]](58,t,yK,this),S[n[1]](60,D,iM,this),S[n[1]](62,q,vX,this),S[n[1]](61,u,n1,this),B&&(c=B.D(),G=S[11](55,2,c,4),v[n[0]](39,Ii,this,G))),N)-n[1]|49)<N&&(N-n[1]|12)>=N&&C!=null&&v[n[0]](46,e,L,C),N>>1)&9)==1&&(A=!(!C||!C[Ri])),A},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y){if((Y=[1,7,'"'],N)+Y[1]>>Y[0]<N&&(N-8^14)>=N&&(Q!=null||(Q=!!(C&e)),m=f[8](21,!1,S[Y[0]].bind(null, +Y[0]),e,L,Q),O=32,h&&(O|=2),e=e&16769217|O,W[32](16,e,m),X=m),(N>>Y[0]&11)>=2&&N-4<20)a:{if(e instanceof O$){X=e.i;break a}throw Error(C);}return(N-2|5)<N&&(N-Y[1]^20)>=N&&(C=C||{},e=C.Uc,c=C.checked,u=C.disabled,t=C.FV,L=[" ",'" role="checkbox" aria-checked="',"recaptcha-checkbox-spinner"],q=C.sc,m=C.G4,Q=C.attributes,R=C.id,G=fJ(),F='<span class="'+H[Y[1]](33,"recaptcha-checkbox")+L[0]+H[Y[1]](33,"goog-inline-block")+(c?L[0]+H[Y[1]](33,"recaptcha-checkbox-checked"):L[0]+H[Y[1]](33,"recaptcha-checkbox-unchecked"))+ +(u?L[0]+H[Y[1]](33,"recaptcha-checkbox-disabled"):"")+(q?L[0]+H[Y[1]](Y[0],q):"")+L[Y[0]]+(c?FQ():lM())+Y[2]+(t?' aria-labelledby="'+H[Y[1]](Y[0],t)+Y[2]:"")+(R?' id="'+H[Y[1]](32,R)+Y[2]:"")+(u?Tc():' tabindex="'+(e?H[Y[1]](33,e):ZJ())+Y[2]),Q?(v[43](36,Q,oi)?A=Q.U5():(h=String(Q),A=PX.test(h)?h:s$()),n=A,v[43](22,n,oi)&&(n=n.U5()),D=(n&&!n.startsWith(OY())?OY():"")+n):D="",O=T[Y[0]](81,G,F+D+' dir="ltr">'),B=B={G4:m!=null?m:null},Z=P8((B.G4?'<div class="'+H[Y[1]](65,"recaptcha-checkbox-border")+ +'" role="presentation"></div><div class="'+H[Y[1]](32,"recaptcha-checkbox-borderAnimation")+'" role="presentation"></div><div class="'+H[Y[1]](64,L[2])+'" role="presentation"><div class="'+H[Y[1]](Y[0],"recaptcha-checkbox-spinner-overlay")+'"></div></div>':'<div class="'+H[Y[1]](64,"recaptcha-checkbox-spinner-gif")+'" role="presentation"></div>')+'<div class="'+H[Y[1]](Y[0],"recaptcha-checkbox-checkmark")+'" role="presentation"></div>'),X=T[Y[0]](80,W[11](46,O,Z),f1())),X},function(N,C,e,L,h,Q,m){return(N| +40)==((m=[9,7,32],N-5<<2>=N)&&(N-m[0]^29)<N&&(L=L||C,Q=function(){return e.apply(this,Array.prototype.slice.call(arguments,C,L))}),N)&&(Q=Zx(C,e)>=0),(N+5^m[2])>=N&&(N+m[1]^24)<N&&(L=(h=H[2](25,0,null,"CLOSURE_FLAGS"))&&h[C],Q=L!=null?L:e),Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((((((B=[14,78,"P"],N)&B[1])==N&&(L=L===void 0?new XQ(0,0,0,0):L,O.i||O.j(void 0,h===void 0?!1:h),O.V=L||new XQ(0,0,0,0),m[St()]=YJ(),m[WX()]=HX+O.F,O[B[2]]=U[40](4,C,Q,m),P[25](33,e,O).appendChild(O[B[2]])),((N^18)&15)== +2&&(e=U[27](32,e),u=S[B[0]](27,C,e)),(N|88)==N)&&kJ.call(this,C,e),(N|56)==N)&&(u=P[44](13,function(G,c,A,n,R,F,Z,X,Y,k){k=["G","call","m0"],Z=[2,4,0];switch(G.B){case L:return G.i(m.i.B.send(new nA(Q)),Z[0]);case Z[0]:if(t=G[k[0]],t.kx())return F=G.return,c=t.kx(),F[k[1]](G,new aE("",0,rj[c]||rj[Z[2]],!0));if((D=(((R=(S[47](1,L,t.DS()),t).tG())&&U[10](32,U[25](28,N$),R,Z[2]),m).j({id:null,timeout:null,K0:1E3,r$:T[42](48,h,t)?1:null}),t.fu()),!O)||!T[42](16,e,t)){G.js(Z[1]);break}return G.i(I[25](3, +12,Q.G2(),O),5);case 5:q=G[k[0]],D=K[14](3,Z[1],H[1](4,Z[0],U[13](1,L,C,new p1,t.fu()),q));case Z[1]:return Y=D,A=G.return,X=t[k[2]](),X==C||ZW(X),n=X!=C?v[28](44,X):void 0,A[k[1]](G,new aE(Y,n,null,null,t.qd(),t.jZ(),t.fP()?t.fP().G2():null))}})),(N^59)&11)==2){for(m=C;m<L.length;m++)h=m+TH(e()*(L.length-m)),Q=P[4](10,[L[h],L[m]]),L[m]=Q.next().value,L[h]=Q.next().value;u=L}return u},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y){if(((Y=[1,"V",2],(N+8&29)>=N&&(N-5|40)<N&&(e=T[41](Y[0],C), +U[29](39,P[25](36,31,e,C),C)),N)^79)>>4||(X=(h=(L=e.i)[JG])!=C?h:L[JG]=e.createElement(E$)),(N|48)==N){for(c=(Q=(F=(m=((l[22](41,(A=[3,0,4],"object"),e),L)===void 0&&(L=A[Y[0]]),y[Y[2]](65,"",A[Y[0]]),zc[L]),n=Array(TH(e.length/A[0])),m[64])||"",A[Y[0]]),A[Y[0]]);c<e.length-C;c+=A[0])O=e[c+C],D=e[c+Y[0]],t=e[c],B=m[(D&15)<<C|O>>6],R=m[t>>C],Z=m[O&63],h=m[(t&A[0])<<A[Y[2]]|D>>A[Y[2]]],n[Q++]=""+R+h+B+Z;G=A[Y[q=F,0]];switch(e.length-c){case C:G=e[c+Y[0]],q=m[(G&15)<<C]||F;case Y[0]:u=e[c],n[Q]=""+m[u>> +C]+m[(u&A[0])<<A[Y[2]]|G>>A[Y[2]]]+q+F}X=n.join("")}if((N|6)>>3>=Y[0]&&N>>Y[0]<14&&(Q=[6,1223,2],L.G&&typeof dj!="undefined"))if(L.h&&W[Y[0]](3,L)==4)setTimeout(L.T.bind(L),e);else if(v[44](33,L,wj),W[Y[0]](6,L)==4){L.G=!1;try{if(K[38](27,Q[Y[0]],L))v[44](33,L,aF),v[44](34,L,VK);else{L.B=Q[0];try{h=W[Y[0]](7,L)>Q[Y[2]]?L.i.statusText:""}catch(k){h=""}L.o=h+" ["+K[24](Y[0],Q[Y[2]],L)+"]",l[38](13,C,L)}}finally{v[29](22,null,L)}}if((N|72)==N){L=(m=(D=(u=(e=(C=C===void 0?f[0](10,0):C,e===void 0?{}:e), +O=W[10](11,null,C,e),O).fI,O).client,P[4](10,xJ(u))),m).next();try{for(;!L.done;L=m.next())if(B=L.value,![Cu.getName(),Lu.getName(),ai.getName()].includes(B))throw Error(gj());}finally{L&&!L.done&&(Q=m.return)&&Q.call(m)}if(h=u[ai.getName()]){if(!(t=U[3](18,null,h),t))throw Error(bM());D.B.A=t}X=(q=D[Y[1]](D.Xa.bind(D,Qp,u,9E5,!1)),I[37](64,q))}return X},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if(((G=[""",6,0],N^28)&27)==3)a:{if(L instanceof Zj){c=L;break a}c=(h=String(L).replace(/&/g,C).replace(/</g, +"<").replace(/>/g,">").replace(/"/g,G[0]).replace(/'/g,"'"),S)[14](35,e,h)}if((((N+8&13)==4&&(u=W[46](10,e,m),q=S[19](20,h,void 0,u.i,void 0,MP)[G[2]],q||(B=S[19](12,h,void 0,u.i,void 0,$J)[G[2]],q=u.ZS(MP),B.parentNode.insertBefore(q,B)),D=u.ZS(Nf),(t=T[18](5,"nonce",C,L,document))&&D.setAttribute(Cq(),t),O=P[39](43,C,Q),Zf.trustedTypes?K[18](50,O,D):D.innerHTML=O,u.B(q,D)),N+G[1])&7)==3&&(e=H[2](60,C),e=H[2](56,C)&e,U[29](68,e,C)),!(N-G[1]>>4))if(e){if(isNaN((e=Number(e),e))||e<G[2])throw Error("Bad port number "+ +e);C.o=e}else C.o=null;return(N<<1&15)==2&&p.call(this,C),c},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(B=[65,"call",96],(N&123)==N)a:{if(u=S[28]((h=h===void 0?!1:h,40))[e5()],!u){(G=C,L).i=Lq;break a}if(q=u[hM()],!q){L.i=QG,G=C;break a}if(!(t=q[ma()],t)){G=(L.i=O_,C);break a}for(O=(D=v[33](20,(L.V=h?5:4,"DkgVAkwBSVxebV5a")),Q=0,"");Q<D.length;Q++)O+=String.fromCharCode(D[Q]^"8x-4t2pegToiW8KmThtO4AQt".charCodeAt(Q%e));G=(m=Math.trunc(qY()),T[23](B[0],t[B[1]](q,{cloudProjectNumber:O}))).then(function(c){return L.K= +Math.trunc(qY())-m,c},function(){return L.i=tM,C})}if((N&125)==N){for(L=v[27](B[0],L),Q=0;Q<L.length;Q++)h=L[Q]=v[27](B[2],L[Q]),Array.isArray(h[e])&&(h[e]=y[15](17,C,h[e]));G=y[5](3,8192,L)}return G},function(N,C,e,L,h,Q,m,O){return(N^(N-8>>((m=[1,6,"i"],N-m[0]&7)>=m[1]&&N>>m[0]<19&&(O=I[22](16,this[m[2]])),4)||(e=(L=X$.get(C))!=null?L:0,X$.set(C,e+m[0])),27))&7||(h=e,Q=(L=K[40](m[0],C))?L.createHTML(h):h,O=new Zj(Q)),O},function(N,C,e,L,h,Q,m){return((((m=[44,51,"ix"],N)>>1&7)==2&&(L=S[23](m[1], +1,.2,!0,0,e.Y),S[26](16,L)[m[2]](U_(e.V$[m[2]](D6(function(O,t,D){return((D=["i",1,"T"],t=e[D[2]],t).update(),t[D[0]]<D[1])?O=!1:(t[D[0]]--,O=!0),O})))).subscribe(function(){e.S.then(function(O,t){(e.B((t=[19,1,28],new qf)),v)[t[2]](t[0],"POST",null,t[1],2,e,O.dI).then(function(D){e.B(new u9),e.F=D.N4,W[36](80,e.Z?0:D.wI,function(q){P[12](74,(e.Z=(q=[9,!0,null],q)[1],q[2]),.75,q[0],!1,O.Dp,D,e)})},function(D,q,u,B){if(D instanceof(q=H[36]((u=[2,null,400],B=[45,"","B"],B)[0],u[1],new tC,u[0]),Hf))H[26](10, +C,D.message,q),D.status&&H[36](44,u[1],q,f[9](8,403,u[2],D.status)),D.status===503&&e.X++;else H[26](9,C,D.toString(),q);e[B[2]](new Bv);try{e.A.next(q)}catch(G){}S[15](20,B[1],e)})},function(O,t,D,q){(t=(D=(q=[16,"toString",2],H[36](q[0],null,new tC,13)),H)[26](q[2],C,O[q[1]](),D),e.A).next(t)})})),N&13)==N&&(Q=j5(e.K,function(O){return typeof O[C]==="function"})),((N^34)&13)==1)&&(e=H[2](68,C),h=H[2](64,C),L=P[25](m[0],31,e,C),C.put(e,h),U[29](36,L,C)),Q},function(N,C,e,L,h,Q){if((N|6)>>(h=[null, +"",2],3)==h[2])a:{if(C==h[0]||typeof C==="boolean"){Q=C;break a}if(typeof C==="number"){Q=!!C;break a}}if((N-((N-6&7)==h[2]&&(Q=U[4](26,8458)(L(e(),0))),3)^31)>=N&&(N+h[2]^24)<N){a:{if(e=Zf.navigator)if(L=e.userAgent){C=L;break a}C=h[1]}Q=C}return Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((N|56)==(u=["substring",0,2],N))a:{if(e.B!=C){B=e.G.concat(e.B.Y);break a}if(e.i!=C&&e.i.size!==0){h=(L=P[4](10,(m=e.G,e).i.values()),L).next();try{for(;!h.done;h=L.next())m=m.concat(h.value.Y)}finally{h&&!h.done&& +(Q=L.return)&&Q.call(L)}B=m;break a}B=v[40](53,e.G)}if(!(N+5>>4))a:{if(!(t=["Invalid URI scheme in origin: ",0,"URI is missing protocol: "],L)){B=C;break a}if(/^about:(?:blank|srcdoc)$/.test(L)){B=window.origin||C;break a}if(m=((h=(O=(((L=(L.indexOf(GB())===0&&(L=L[u[0]](5)),L=L.split(NY())[t[1]].split(CJ())[t[1]],L).toLowerCase(),L.indexOf(cv()))==t[1]&&(L=window.location.protocol+L),/^[\w\-]*:\/\//.test(L))||(L=window.location.href),L[u[0]](L.indexOf(Kq())+e)),O.indexOf(Wz())),h!=-1)&&(O=O[u[0]](t[1], +h)),L)[u[0]](t[1],L.indexOf(Kq())),!m)throw Error(t[u[2]]+L);if(m!=="http"&&m!=="https"&&m!=="chrome-extension"&&m!=="moz-extension"&&m!=="file"&&m!=="android-app"&&m!=="chrome-search"&&m!=="chrome-untrusted"&&m!=="chrome"&&m!=="app"&&m!=="devtools")throw Error(t[u[1]]+m);Q=(q=C,O.indexOf(C1())),Q!=-1&&(D=O[u[0]](Q+1),O=O[u[0]](t[1],Q),m==="http"&&D!=="80"||m==="https"&&D!=="443")&&(q=":"+D),B=m+"://"+O+q}if((((N+((N-3&11)==1&&(B=y[48](16,L)?h.uI.send(AM,C,e).catch(function(){return C}):null),u[2])& +11)==1&&(B=I[1](75,C)),N)<<1&15)==u[2])a:{if(!L){B=C;break a}B=((h=T[22](u[2],e,L),h)===null||h===void 0?Q=C:Q=y[5](18,C,h),Q)}return B},function(N,C,e,L,h,Q,m,O,t){if((N+(t=[5,"-signaler-pa.googleapis.com/punctual","https://"],t[0])>>1<N&&(N+6&34)>=N&&(O={f0:new sB(t[2]+C+"-signaler-pa.clients6.google.com/punctual"),Y7:new sB(t[2]+C+t[1]),BS:!1}),N&45)==N){for(Q=(m=(L=(e=(h=H[15](4,this),f)[1](68,this),f[1](51,this)),[]),2);Q<C;Q++)m.push(f[1](19,this));this.Pm[h]=e[L].apply(e,T[t[0]](41,m))}return O}, +function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((u=["i","promise",2],(N<<1&5)>=1)&&N+3>>4<1)a:{if(e==(L[u[0]]==(t=[250,!1,!0],C))){B=T[23](98);break a}if(e){B=((((D=(O=L[u[0]],L.vL()),q=T[32](18,t[1],L),L.gq()?q.add(W[9](22,t[u[2]],L,t[1])):q.add(y[43](36,t[1],L,O,D,t[1])),I)[31](6,"block","1",t[1],L),h)&&h.resolve(),m=y[16](u[2]),P)[29](9,y[10](23,L),q,JZ,Pe(function(){m.resolve()},L)),L.Md(C),q.play(),m[u[1]]);break a}B=(H[47](1,t[0],t[u[2]],"none","0",Q,L),L.Md(1),T[23](66))}return(N&92)==N&&(m=h||L,B= +(O=Q&&Q!=C?String(Q).toUpperCase():"")||e?m.querySelectorAll(O+(e?"."+e:"")):m.getElementsByTagName(yG())),B},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){return(N&58)==((N|56)==((N-1^((N-5&(G=["B","G",14],G[2]))==2&&(c=U[38](17)?!1:I[1](78,C)),(N&76)==N&&(e[G[0]]=h?U[31](11,L,!0):L,e[G[0]]&&(e[G[0]]=e[G[0]].replace(/:$/,C)),c=e),21))>=N&&(N+3^32)<N&&(O=Q.w$.concat(v[3](43,m,y[11](27),2)).reduce(function(A,n){return A^n}),D=I[46](16,e,C,O,S[49](25,L,m)),t=v[11](11,h,L,D),T[10](1,h,t,Q.i)),N)&&(c=P[44](41, +function(A,n,R,F,Z,X,Y){if((X=[0,13,1],Y=[15,34,"P"],A.B)==X[2])return q=I[22](41,C,Q.i.i),A.K(2),O=new i9(Q.fu(),q,performance.now()-Q.j,performance.now()-Q.A),A.i(Q.V.send(O),C);if(A.B!=2){if(!T[9](Y[1],(D=A.G,e),Ky)(D))return Q.B.onError(X[2]),A.return();if(l[43](42,C,D,rY)!=h)return Q.B.onError(l[43](58,C,D,rY)),A.return();if(((u=S[41](10,X[2],rY,D),u!=h)&&(F=u,Q.K=F,Q.i.G.value=F),S[16](19,W[33](9,D,2,rY)))||S[16](21,W[33](9,D,11,rY)))R=(B=u)!=h?B:"",(Z=P[Y[1]](Y[0],null))==h||Z.zzsc(R),Q.G= +gH,P[1](Y[1],h,L,W[39](7,Q.i));else if(n=D.z2,t=W[14](66,h,n[Rw]|X[0],LX,n,X[1],rY))Q[Y[2]](t);else Q.B.onError(X[0]);return A.V(X[0])}if((m=A.o(),m)instanceof hh)Q.B.onError(C);else Q.B.onError(X[0]);A[Y[2]]()})),N)&&(eB.call(this,vv.width,vv.height,nq,I$),this.l=null,this[G[1]]=null,this.i=[],this.F=0,this.h=null),c},function(N,C,e,L,h){return N<<(((N^7)&(L=[1,!0,15],4))<L[0]&&N<<2>=-62&&(h=e.G==R$||e.G==Fc?f[28](9,C,e.i):null),L)[0]&5||(h=v[43](20,e,l9)?f[6](14,e.U5(),!1):e==null?"":e instanceof +dr?f[6](L[2],P[39](42,C,e),!1):f[6](22,String(e),L[1])),h},function(N,C,e,L,h,Q,m,O){return(N|2)>=((N+((O=[9,"i",19],N<<1&12)||(Q=U[36](39,h.uri),h.BS&&S[42](14,e,Q,TH(Vn()*L).toString()+C+Q[O[1]]),m=Q),2)&72)<N&&(N+8&O[2])>=N&&(m=W[11](2)?Ie.platform==="macOS":I[1](92,"Macintosh")),5)&&(N>>1&14)<5&&(kJ.call(this,C,e),this.T=L,this.S=!1,this.B=null,this.style=TB),(N-O[0]&10)==2&&(m=P[44](13,function(t,D){return(C=S[D=[42,4,18],D[0]](38,U[D[1]](D[2],7140),S[D[0]](38,U[D[1]](34,2981),S[D[0]](47,U[D[1]](26, +9365),S[D[0]](37,U[D[1]](26,7007),U[D[1]](2,1086))))),t).return(Promise.all(C.map(function(q){return H[4](10,q)()})).then(function(q){return q.map(function(u){return u.cE()}).reduce(function(u,B){return u+B.slice(0,2)},"")}))})),m},function(N,C,e,L,h,Q,m,O,t,D){if((N+1&78)>=(D=["i",33,"B"],N)&&(N-6|42)<N){if((this.buffer=C,L)&&!e)throw Error();this[D[0]]=e}return((((N^D[1])&7)>=6&&(N^9)>>5<4&&(t=/^[\s\xa0]*$/.test(C)),N)-3|50)<N&&(N-2|25)>=N&&(m=h,Q.G&&(O=Q.P()*e,m=wq((C-O)*Q[D[0]]),Q[D[0]]<Q[D[2]]&& +(Q[D[0]]*=Q.o,Q[D[0]]>Q[D[2]]&&(Q[D[0]]=Q[D[2]]))),Q.G=L,t=m),t},function(N,C,e,L,h,Q,m){return N<<(Q=[1,9,71],(N&Q[2])==N&&(K[Q[1]](12,h,L),m=function(O,t,D,q,u){h[u=["V","o","delete"],u[0]].has(L)?(h[u[0]][u[2]](L),I[10](1,0,h)):(h.i&&(O=new Z6,t=v[0](17,4096,void 0,o$,O),q=f[13](47,"bigint",t,L[u[1]].toString(),C),D=new Pv,l[28](60,null,e,s_,D,q,Pv),h.i.channel.send(O)),h.streams[u[2]](L[u[1]]))}),Q[0])&7||p.call(this,C),m},function(N,C,e,L,h,Q,m,O,t,D,q,u){if((N&(q=[6,((N&46)==N&&(this.iQ=L,this.B= +C,this.i=e),"G"),1],124))==N){if(this.kU=(this.id=(h=(this.i=(D=[0,null,!0],new fq(e)),window[Bh]),this.i).get(Xc)?1E5+h[S5()]++:h[jp()]++,this.Mz=L),this.F=C,this.i.has(Yq)){if(m=U[3](19,D[q[2]],this.i.get(Yq)),!m)throw Error(Wv());this.Mz=m}(this.X=(t=(this.A=(Q=(O=(this.j=((this.Y=((this.S=(((this.P=(this.K=new (this.J=D[q[2]],Hv),D[q[2]]),this).o=D[q[2]],this).B=D[q[2]],new kq),this[q[1]]=D[q[2]],this).h=D[0],U)[41](9),this).Z=!1,D[q[2]]),this.I=D[2],I[q[0]](34,this.i,SX))==="6LeYqFcqAAAAAD6iZesmNgVulsO4PkpBdr6NVG6M"|| +I[q[0]](34,this.i,SX)==="6Leb7KMpAAAAAAm20DGNdW_O7fuW4hECp4PpE6cI"||I[q[0]](32,this.i,SX)==="6LfwmQEoAAAAAOcMv1gEi85kHPcIZrCqpzoGBReE"||I[q[0]](34,this.i,SX)==="6LcHW9UZAAAAALttQz5oDW1vKH51s-8_gDOs-r4n"||I[q[0]](33,this.i,SX)==="6LfMsJ4kAAAAAOcuFSSja5TeRvoi26SexmG2o3L6"||I[q[0]](33,this.i,SX)==="6LcXU9cmAAAAAMXBihp92S7rVrcL--SgaL0yLCQG",Zf).window[Bh][OO.getName()],O?8E4:Q&&Q.length>D[0]?Q[D[0]]:2E4),this.i.set(OO,this.A),Zf.window[Bh])[tE.getName()],O)?6E4:t&&t.length>D[0]?t[D[0]]:3E4,this).i.set(tE, +this.X),y[7](32,!1,D[2],q[2],this)}return(N-9<<q[2]<N&&(N-8^31)>=N&&(C=H[15](28,this),this.Pm[C]=this.Z+(qY()-this.o)),N|72)==N&&(this.i=e,this[q[1]]=C,this.B=L),u},function(N,C,e,L,h,Q,m,O,t){return(N|((N|9)>>((N<<(O=["B",5,"i"],1)&7)>=3&&(N+O[1]&16)<8&&(t=function(){var D=aq.apply(h,arguments);return new Promise(function(q,u,B,G,c,A,n,R,F,Z,X){for(F=(c=(Z=(B=(G=(u=m>>(X=["QZ","e_","Jc"],3),L()),q=new rk(Q.WU,3E3+G,3250+G,u,D)),h),B).xx,B)[X[1]];Z<Q.Un.length;Z++){if((n=Q.Un[Z],n.xx>=c)&&n[X[1]]<= +F)break;(F=((c=vh(n.xx,c),n.xx)<c&&(Q.fs+=C,n.xx=c),RY(n[X[1]],F)),n)[X[1]]=F}Q[X[0]](B)&&Q[X[2]](B)&&(R=Q.Un[Q.Un.length-C],A=L(),R[X[1]]<=A&&(Q.fs+=C,R.xx=e),Q.T_&&Q.T_>=R.xx||(R.xx===1?(R=R[X[1]]-A,Q.T_=C,Q.Jv(R)):(Q.T_=e,f[12](1,null,0,Q))))})}),4)||(this[O[0]]=e,this[O[2]]=C),16))==N&&(t=new ZE(function(D,q){return q=W[36](74,C,function(){D.next({}),D.complete()}),function(){S[3](16,q)}})),t},function(N,C,e,L,h,Q){return((Q=["tO",1,28],N-8>>4)||(h=RY(vh(C,e),L)),N-6<<Q[1]<N)&&(N+7^4)>=N&&(e= +~C[Q[0]]+Q[1]|0,h=v[15](Q[2],~C.m+!e|0,e)),h},function(N,C,e,L,h,Q){return(N-9<<(h=["rc-image-tile-overlay",3,((N&57)==N&&(Q=C?C.defaultView:window),!1)],1)<N&&(N-2^11)>=N&&(S[29](51,T[0](14,h[0],L.element),{opacity:"0.5",display:"block",top:"0px"}),W[36](64,e,function(m){S[29]((m=["opacity",0,35],m[2]),T[m[1]](28,"rc-image-tile-overlay",L.element),m[0],C)})),N)-8>>h[1]==2&&(Q=H[38](4,e,H[0](6,h[2],L),C)),Q},function(N,C,e,L,h,Q,m,O){if((((O=[1,15,72],N+9&O[1])==O[0]&&(Q=Q===void 0?1:Q,h=h===void 0? +U[32](21,L,pq(),e):h,m=Array.from({length:Q},function(){return C+h()})),N-5<<2)<N&&(N+3^O[0])>=N&&(this.i=e,this.G=h,this.o=C,this.B=L),N-O[0]&11)==2)if(typeof e==="string")I[8](10,C,L,e);else for(h in e)I[8](14,C,e[h],h);return m},function(N,C,e,L,h){if(((N^48)&((N&84)==(L=[13,0,14],N)&&(KN.call(this,I[L[2]](33,JM),U[5](53,E_),y4()),P[L[1]](76,C,"8x-4t2pegToiW8KmThtO4AQt",2,rY),e=H[L[0]](15,B0.M().get()),P[L[1]](12,C,e,1,rY),this.Rz=C.D()),L[0]))>=L[1]&&(N^48)>>4<1)a:{if(!e){h=zB||(zB=new H9(0,0)); +break a}if(!/^\d+$/.test(e)){h=C;break a}h=(v[L[2]](11,6,e),new H9(l5,TU))}if((N|72)==N)a:{if(!e){h=dk||(dk=new my(0,0));break a}if(!/^-?\d+$/.test(e)){h=null;break a}h=new (v[L[2]](10,C,e),my)(l5,TU)}return N>>1<29&&N-5>=19&&(h=P[44](73,function(Q){return(C=T[45](98),Q).return({Ss:wk+C,YL:l[42](4,0,C)})})),h},function(N,C,e,L,h,Q,m,O,t,D,q,u){if(((N-(u=[7,!1,30],u)[0]<<1>=N&&(N-6|49)<N&&(O=[0,1,2147483648],T[49](36,L,e),L=oE(L),!e&&!n2||P0(L)?Q=L:(v[39](55,O[0],L),D=TU,m=D&O[2],h=l5,m&&(h=~h+O[1]>>> +O[0],D=~D>>>O[0],h==O[0]&&(D=D+O[1]>>>O[0])),t=l[8](17,O[0],h,D),Q=typeof t==="number"?m?-t:t:m?C+t:t),q=Q),N-2)&u[0])==2)a:{if(e){zQ=e==null||e===l[u[2]].bind(null,6)||e[VG]!==xq?l[u[2]].bind(null,10):e;try{q=T[0](34,u[1],C);break a}finally{zQ=void 0}}q=T[0](33,u[1],C)}return N-u[0]<<2<N&&(N-2|52)>=N&&(L=y[41](75,c7.M(),C),e.PK.push.apply(e.PK,T[5](89,L)),q=L),q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df){if(((((N|(Df=(N-4>>4||(mQ=new a$(e,L,C)),[2,47,30]), +80))==N&&(e.P&&(W[48](46,e.P),e.P=C),e.i&&(e.G=C,S[3](17,e.h),e.h=C,v[18](28,e),W[48](60,e.i),e.i=C)),N&92)==N&&(mQ=y[44](22,1,C,e)),N)|Df[0])>=27&&N+1<42){if(hA=(M=(J=(D=(r=(c=(Y=U[22](6,(a=[4,!0,0],h),m),q&&!Y),Y?1:t),!!D)||r===3,(r===2||c)&&S[45](17,a[1],h)&&(O=h.z2,m=O[Rw]|a[Df[0]]),v)[9](4,e,Q,O),J===Fq?7:J[Rw]|a[Df[0]]),k=P[Df[1]](24,1,m,M),!(a[0]&k))){for(d=(G=((B=(w=a[Df[0]],!!(E=a[Df[0]],(R=(n=(x=J,m),k),Df)[0]&R)))&&(n|=Df[0]),a[1]),!B);w<x.length;w++)F=v[35](11,a[Df[0]],!1,n,L,x[w]),F instanceof +L&&(B||(u=U[22](4,F),d&&(d=!u),G&&(G=u)),x[E++]=F);R=((R|=a[0],E<w)&&(x.length=E),G?R&-4097:R|4096),k=d?R|8:R&-9}if(k!==M&&(W[32](32,k,J),Df[0]&k&&$4(J)),c&&!(8&k||!J.length&&(r===1||(r!==4?0:Df[0]&k||!(16&k)&&C&m)))){for(z=(A=(W[1](26,a[0],k)&&(J=v[27](8,J),k=P[Df[2]](69,Df[0],k,m),m=W[26](9,m,e,O,J,Q)),Z=k,J),a[Df[0]]);z<A.length;z++)g=A[z],X=T[34](4,!1,g),g!==X&&(A[z]=X);W[32]((k=Z=(Z|=8,A.length?Z|4096:Z&-4097),24),k,J)}mQ=J=K[8](1,16,Q,r,m,k,e,D,hA,J,O)}return N-5<<Df[0]>=N&&(N-1^32)<N&&(h=l[36](78, +e),h!=null&&h!=null&&(TH(h),v[22](13,C,L,0),W[23](48,7,C.i,h))),mQ},function(N,C,e,L,h){return((((L=[19,8,29],N)+4&51)<N&&(N-2|L[2])>=N&&(this.i=C),N)|L[1])>>3==1&&(e=new V$,v[L[0]](10,function(Q,m,O){e[m]=v[27](72,O)},C),e.Dn=C.Dn,h=e),h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E){if((((N|((k=[57,1,39],N&76)==N&&(T[49](29,L,e),L=oE(L),L>=0&&P0(L)?h=String(L):(v[k[2]](58,0,L),h=K[20](16,C,l5,TU)),E=h),40))==N&&(E=P[44](77,function(J,r,z){z=["B",(r=[11,0,2],"i"),7];switch(J[z[0]]){case 1:B= +((n=new B0,n).init(gk(m[z[1]])),v[39](2,19,n.get()));try{q=(0,B8.tj)(Q.o[z[1]].bind(Q.o,B),6)}catch(d){F=Q.G.then(function(x){return x.send(b9,new Mf([]))}),F.catch(l[2].bind(null,8))}for(R=(Z={p0:(X=((G=(t=(A=(U[30](17,W[4](43,Q[z[1]],Q[z[1]].has($q)?$q:NB),Q.kU,n),function(d){return d.J2(R),d.cE()}),C5).slice(),e3).slice(),y)[19](4,25,n.get())&&(t.push(T[13].bind(null,15)),G.push(C)),u=I[13](97,B),Promise).resolve(U[41](33)),pA=[],0)},[]);Z.p0<t.length;Z={p0:Z.p0},Z.p0++)X=X.then(function(d){return function(x){return H[4](11, +t[d.p0],G[d.p0]).call(Q,x,u,d.p0)}}(Z)).then(A);return(X=X.then(function(d){return L5(d,I[13](79,100))}).then(A).then(function(d){return h3(d,I[13](76,100))}).then(A),J)[z[1]]((0,B8.tj)(function(){return X},r[0]),r[2]);case r[2]:J.js(3);break;case 3:if(!(D=(c=(Y=new Qj(R),UR(function(d,x,w,a,g,M,hA,mQ,Df){for(M=(a=new (hA=(Df=[6,29,(w=[1847,!1,17],38)],H[Df[1]](10,w[1],null,P[48](Df[2],MP)[0],U[4](18,w[0]))),aI)(240,7,25),0);M<hA.length&&(d=a,g=d.add,mQ=new me,I[19](21,3,1,L,mQ,hA[M]),x=y[14](7,P[20](17, +"[",mQ.i)),g.call(d,h+x));M++);f[Df[0]](90,e,Y,w[2],[a.toString()],K[27].bind(null,1))},null),O=S[41](53,r[1],Q[z[0]]),[]),[]),Q.o)||!q){J.js(5);break}return J.K(6),J[z[1]](q,8);case 8:J.V(z[2]);break;case 6:J.o();case z[2]:c=W[36](37,v[28](2,5,r[1],tS.get(Q.o))),D=W[36](4,f[2](8,1,r[2],4096,tS.get(Q.o)));case 5:return J.return(new OV(O,c,D,S[31](12,Y)))}})),(N^k[1])&15)==k[1]&&(sH.call(this,C),this.B=!1),(N+8^9)<N&&(N+6&27)>=N&&(this.i=C[Zf.Symbol.iterator](),this.B=e),N<<k[1]&7)==4){c=U[22](14, +(O=(D=(h=L.z2,[34,!0,8192]),h[Rw]|0),L),O);a:{if((q=(G=(!(B=(t=O,h),c)&&S[45](9,D[k[1]],L)&&(B=L.z2,t=B[Rw]|0),l)[14](38,void 0,B,3),e),G)==null){if(c){u=U[33](17,D[0]);break a}G=[]}else if(G.constructor===z6)if(Q=G,Q.Nd&C&&!c)G=K[42](k[0],D[2],Q);else{u=Q;break a}else Array.isArray(G)?q=!!((G[Rw]|0)&C):G=[];if(c){if(!G.length){u=U[33](21,D[0]);break a}q||(q=D[k[1]],y[15](20,D[0],G))}else q&&(q=e,y[5](2,D[2],G),G=S[13](4,D[0],k[1],G));u=(t=(m=(!q&&t&32&&v[k[1]](8,32,G),new z6(G,t3,H[45].bind(null, +2),void 0)),W)[26](27,t,3,B,m),q||l[k[1]](64,B,t),m)}(E=u,!c&&t3)&&(u.KV=D[k[1]])}return E},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB,R6,LB,sC,Sp,ur,g8,$W,q4){if(N<<1>=(q4=[4,"KR","oCancelRequestAnimationFrame"],11)&&N-1<29){if((OC=((0,(R6=(Df=(tA=(LB=(KB=(M=(hA=(k=(g=(0,(z=(O=(A=(0,B8.oB)().slice(),O)===void 0?!0:O,[3,9,7]),X=(0,B8.xg)().slice(),B8)[q4[1]])(L,Q),v[16](26,h.i)?2:1),new jX),E=W[42](9,O,z[0],hA),y)[44](15,z[2],E,k),K[23](27,8,h.A, +M)),K)[23](59,z[1],h.X,KB),new UV),f[33](22,32,tA,1,A.concat(g),u4)),D=f[33](23,32,Df,2,X.concat(m),L1),f[5](32,LB,UV,5,D)),B8).Ls)(),U)[13](27,R6,UV,5),DL).size===0)q=[];else{F=[];try{r=(R=P[q4[0]](12,performance.getEntriesByType(qB())),R.next());try{for(;!r.done;r=R.next()){G=P[q4[0]]((a=r.value,11),DL),u=G.next();try{for(;!u.done;u=G.next())mQ=P[q4[0]](12,u.value),c=mQ.next().value,n=mQ.next().value,a.name.includes(c)&&(g8=P[q4[0]](57,2,S[28](28,z[0],K[44](40,1,new u4,n),ae(a.duration)),ae(a.startTime)), +a.responseStatus&&a.responseStatus>=400&&(W[42](3,e,q4[0],g8),sC=new us,x=T[21](40,sC,1,a.responseStatus),f[5](12,g8,us,5,x)),F.push(g8),DL["delete"](c))}finally{u&&!u.done&&(w=G.return)&&w.call(G)}}}finally{r&&!r.done&&(ur=R.return)&&ur.call(R)}}catch(br){}q=F}(Z=new (Y=(J=(Sp=(UC=(B=(f[33](20,32,OC,1,q,u4),d=new u6,P[36](40,C,2,B7,t,d,rY)),I[6](35,h.i,SX)),P[0](13,B,UC,1,rY)),P)[0](14,Sp,"8x-4t2pegToiW8KmThtO4AQt",z[0],rY),f)[5](q4[0],J,jX,q4[0],R6,rY),Gk)(Y,I[6](35,h.i,SX)),h.F).send(Z,e,!1)}return(N- +((N|48)==N&&(L=[null,0,"lang"],this.g$=e=e===void 0?!1:e,this.locale=L[0],this.o=L[1],this.B=L[0],this.G=!1,this.i=new BL,Number.isInteger(C)&&this.i.a7(C),e||(this.locale=document.documentElement.getAttribute(L[2])),l[12](57,5,new pP,this)),q4[0])|16)<N&&(N+6^28)>=N&&(L=e.B,$W=L.cancelAnimationFrame||L.cancelRequestAnimationFrame||L.webkitCancelRequestAnimationFrame||L.mozCancelRequestAnimationFrame||L[q4[2]]||L.msCancelRequestAnimationFrame||C),$W},function(N,C,e,L,h,Q,m,O,t){if(O=["call",3,"JG"], +(N|64)==N)p[O[0]](this,C);if(N-O[1]>>O[1]==1&&(C[e]=L[O[2]]),((N^66)&8)<5&&(N^13)>>O[1]>=1)a:{if(m=(S[43](18,C,Q.i),Q).i.j){t=H[33](40,L,"return"in m?m[e]:function(D){return{value:D,done:!0}},Q,Q.i.return,h);break a}Q.i.return(h),t=v[40](22,L,Q)}return(N|32)==N&&(t=RegExp("^https://www.gstatic.c..?/recaptcha/releases/8x-4t2pegToiW8KmThtO4AQt/recaptcha__.*")),t},function(N,C,e,L,h,Q){if((N-2|36)<((N<<(Q=[39,7,41],1)&12)<6&&(N-Q[1]&5)>=3&&(h=W[Q[0]](16,S[32](72,new b4,C),e)),N)&&(N+3^9)>=N)for(e=T[Q[2]](8, +C),L=0;L<e;L++)U[29](37,null,C);return(N-Q[1]|14)>=N&&(N-5^23)<N&&(j3==C&&(j3="placeholder"in y[Q[2]](13,document,xn)),h=j3),h},function(N,C,e,L,h,Q,m,O,t,D,q){if(!(N+2&(D=['"></div>',20,"rc-anchor-pt"],3))){if(!L.B){for(Q in O=(L.i||H[D[1]](3,"-open",e,L),L.i),t={},O)t[O[Q]]=Q;L.B=t}q=(m=parseInt(L.B[h],C),isNaN(m))?0:m}return(N^3)>>3||(L=e.x7,h=e.qW,Q=f[D[1]](16,Gt(),h,UY(),XG()),m=f[D[1]](19,cL(),L,UY(),XG()),q=P8('<div class="'+H[7](64,D[2])+(Q||m?C+H[7](64,"rc-anchor-over-quota-pt")+C:"")+D[0])), +q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R){if(((R=["location","B",8],N+R[2])&46)>=N&&N-4<<2<N){if((Q=[!0,"",!1],e.K.info("Error code "+L),L)==C)O=Pe(e.ks,e),t=e.vK,m=!t,h=new sB(t||"//www.google.com/images/cleardot.gif"),Zf[R[0]]&&Zf[R[0]].protocol=="http"||S[20](4,Q[1],h,K5()),f[16](1,h),m?v[30](4,Q[0],Q[2],O,h.toString()):U[49](2,Q[2],Q[0],O,h.toString());else H[R[2]](7,C);(e[R[1]]=0,e).P&&e.P.G(L),y[27](16,null,0,e),l[16](7,null,e)}return((N|32)==N&&(this.i=e,this.G=C,this[R[1]]=!0,this.o= +null),(N+6&27)>=N)&&N+5>>1<N&&(n=P[44](13,function(F,Z,X){return(((((u=(B=new (G=(c=U[23](13,(Z=["hidden",null,"100%"],q=window.origin,X=[18,"0","iframe"],2),h,"#",C,O,new Map([["d",m.G2()],["origin",q]])),new URL(H[41](40,c).toString(),document.baseURI)).origin,Promise)(function(Y){A=Y}),Zu)(X[2]),T[35](X[0],!1,e,!0,Z[1],function(Y,k,E,J,r,z,d,x){return P[44](73,function(w,a,g,M){a=[5,3,(M=[40,"contentWindow",49],6)];switch(W[4](8,Y,h)){case a[1]:A(H[19](28,null,4,A3,Y,yj));break;case 4:t&&t(H[19](M[0], +null,a[0],is,Y,yj));break;case a[0]:D&&(g=H[19](39,null,a[2],vL,Y,yj),r=S[M[2]](31,h,g),(k=u[M[1]][r])&&typeof k==="function"&&(z=P[4](10,k.call(u[M[1]])),E=z.next().value,J=z.next().value,d=E,x=J,D(d,x)))}w.P()})},u,G),u).src=H[41](44,c).toString(),u.width=Z[2],u.height=Z[2],u).allow=[99,97,109,101,114,97].map(function(Y){return String.fromCharCode(Y)}).join(""),u.scrolling="no",u.style.overflow=Z[0],u.style).border=L,u.style).margin=X[1],Q).appendChild(u),F.return(B)})),n},function(N,C,e,L,h,Q, +m){if(m=[116,"tK",2],(N&m[0])==N)a:{if((h=e[hG],h)!=C){Q=h;break a}Q=(e[h=(L=y[31](16,m[2],H[1].bind(null,35),f[37].bind(null,19),e,FN),L)[m[1]]?function(O,t){return n5(O,t,L)}:function(O,t,D,q,u,B,G,c,A,n,R){u=[(R=[2,1,0],0),100,null];a:{H[34](R[1],u[R[1]]);try{for(;I[13](86,!1,t)&&t.B!=4;)c=t.G,n=L[c],n==C&&(D=L.iA)&&(A=D[c])&&(B=I[28](11,u[R[2]],u[R[0]],R[1],R[0],A),B!=C&&(n=L[c]=B)),n!=C&&n(t,O,c)||H[17](4,C,O,c,U[10](11,4,u[R[2]],t));if(q=T[R[1]](32,O))q.Dn=L.VU[If];G=!0;break a}catch(F){if(F instanceof +RangeError)throw new SyntaxError;throw F;}finally{Rf>u[R[2]]&&Rf--}G=void 0}return G},hG]=h,e[If]=Fp.bind(e),h)}return(N^7)&3||p.call(this,C),Q},function(N,C,e,L,h,Q,m){if(((N&(Q=[28,106,32],Q)[1])==N&&(m=l[22](18,W[33](17,L,C,e,h))),N+9>>4>=3)&&((N^59)&16)<14)a:{if(e.A){m=P[47](54,e.A);break a}m=new ((h=S[L=f[14](21,window).width,Q[0]](Q[2]).innerWidth)&&h<L&&(L=h),B2)(L,vh(f[14](Q[2],window).height,S[Q[0]](17).innerHeight||C))}return m},function(N,C,e,L,h,Q,m,O,t){return(N|((N|80)==((N|((N&((O= +[1,"concat",32],N+2^13)<N&&(N-8|23)>=N&&(Q=e=U[27](O[0],e),L=(h=K[40](2,C))?h.createScript(Q):Q,t=new ls(L)),70))==N&&p.call(this,C),5))<23&&((N|4)&13)>=5&&(e.i=h?U[31](9,L,C):L),N)&&(C.M=function(){return C.kg?C.kg:C.kg=new C},C.kg=void 0),O[2]))==N&&(t=[][O[1]](e,C,L||[],L+h/7||[],L+Q/5||[],L+m/O[0]||[])),t},function(N,C,e,L,h,Q,m,O,t,D,q,u){if((((q=[2,null,31],N<<q[0])&7)>=1&&N>>1<18&&(K[5](11,[-60,-109],H[42].bind(q[1],8)),K[5](13,[-85,-48],l[q[2]].bind(q[1],19)),K[5](37,[-120,-90],I[6].bind(q[1], +23)),K[5](3,[-97,-82],H[34].bind(q[1],q[0])),K[5](3,[-87],W[37].bind(q[1],11)),K[5](37,[-113],H[1].bind(q[1],25))),(N|3)>>3>=q[0]&&(N<<q[0]&10)<5)&&(h==C?e.o.call(e.G,L):e.B&&e.B.call(e.G,L)),(N+4&46)<N&&(N+4&26)>=N){if(e.Y)throw new TypeError("Generator is already running");e.Y=C}return(N<<q[0]&16)<12&&(N^26)>=13&&(m=[4,null,3],O=C.U5(),Q=(L==m[1]?0:L.kx)?L.kx():void 0,t=(L==m[1]?0:L.y7)?L.y7():void 0,h=new us,D=K[23](60,q[0],O?O.length:0,h),Q&&(T[21](36,D,1,Q),W[42](1,!0,m[0],e)),t&&(T[21](88,D, +m[q[0]],t),W[42](13,!0,m[0],e)),f[5](16,e,us,5,D),(0,B8.h2)(e)),u},function(N,C,e,L,h){return(((N&(h=["children","i","call"],118))==N&&(K2[h[2]](this),this.B={},this[h[1]]={}),N)^14)>>4||(L=e[h[0]]!=void 0?e[h[0]]:Array.prototype.filter[h[2]](e.childNodes,function(Q){return Q.nodeType==C})),L},function(N,C,e,L,h,Q,m){if(!((m=[0,69,8],N+m[2])&6))a:{if(e.B!==NR){Q=!1;break a}e.B=(L=h=S[m[2]](10,(h=e.z2,34),h[Rw]|m[0],h),v[22](m[1],2048,L),void 0),e.G=void 0,e.z2=L,Q=C}return N-m[2]<<2<N&&(N-4^13)>= +N&&(h=h===void 0?Tt:h,H[11](4,C,e,tS.get(L),h)),Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k){if((Y=[3,37,"i"],N-1<<2>=N&&N-7<<2<N)&&(u=["px",.5,0],I[49](19,e,L[Y[2]])=="visible")){R=P[47](6,P[25](25,1,L));a:{if(A=u[G=window,Q=G.document,2],Q){if(F=(B=Q.body,Q.documentElement),!F||!B){m=u[2];break a}(t=f[14](20,G).height,Q.compatMode)=="CSS1Compat"&&F.scrollHeight?A=F.scrollHeight!=t?F.scrollHeight:F.offsetHeight:(O=F.offsetHeight,X=F.scrollHeight,F.clientHeight!=O&&(X=B.scrollHeight, +O=B.offsetHeight),A=X>t?X>O?X:O:X<O?X:O)}m=A}if((D=(c=(q=(Z=vh(m,S[41](54,u[2],L).height),h=K[4](4,null,L),S)[27](16,h.y-R.height*u[1],H[49](9,null,document).y+10,H[49](12,null,document).y+S[41](51,u[2],L).height-R.height-10),S[27](13,q,h.y-R.height*C,h.y-R.height*.1)),S)[27](15,c,10,vh(10,Z-R.height-10)),L.G)==R$)n=h.x>S[41](48,u[2],L).width*u[1],S[29](67,L[Y[2]],{left:K[4](9,null,L,n).x+(n?-R.width:0)+u[0],top:D+u[0]}),l[12](9,null,u[2],u[0],".",n,L,D);else S[29](7,L[Y[2]],{left:H[49](20,null,document).x+ +u[0],top:D+u[0],width:S[41](52,u[2],L).width+u[0]})}if((N|1)>>((N+1^22)>=(((N^68)&Y[0])==2&&(t=[0,8,1],L[Y[2]]&&(O=W[Y[0]](Y[1],e,t[2],h.G,h[Y[2]]),h instanceof Co&&(Q=f[13](56,"bigint",O,h.P.toString(),t[2]),W[42](11,h.A,t[1],Q)),y[44](10,9,O,h.K),h.K=t[0],u=new Z6,D=v[0](18,4096,void 0,o$,u),q=f[13](46,"bigint",D,h.o.toString(),t[2]),m=l[28](58,null,2,s_,O,q,Pt),y[44](15,C,m,L[Y[2]].K7),L[Y[2]].channel.send(u))),N)&&(N+5&13)<N&&(this[Y[2]]=[]),Y[0])==Y[0])if(L.B!=e)T[43](29,C,L);else h=y[35](5, +L[Y[2]]),T[0](Y[0],h,L[Y[2]]);return k},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){return((((N^(((N>>((((A=[15,13,26],N)^A[2])&A[0])==1&&(u=C===void 0?{}:C,t=u.XI,D=u.AE,G=u.T2,L=u.yM,Q=u.lQ,h=u.p7,m=Q===void 0?{}:Q,this.AE=D===void 0?!1:D,O=h===void 0?null:h,e=L===void 0?null:L,q=G===void 0?void 0:G,B=t===void 0?!1:t,this.p7=O,this.XI=B,this.lQ=m,this.T2=q,this.yM=e),1)&A[1])==1&&p.call(this,C),(N+3^19)>=N&&N-5<<1<N&&e)&&U[10](16,U[25](28,$Z),e,C),40))&A[0])==1&&(c=W[11](3)?Ie.platform==="Android": +I[1](76,"Android")),N|4)&11)==3&&(c=new ZL(function(n){return n.substr(C,e.length+1).toLowerCase()===e+":"})),c},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return(N&76)==((N|(N-(((u=[2,39,21],(N>>u[0]&23)==4&&(C=H[15](28,this),e=y[34](53,this),this.Pm[C]=e),N-3)|68)<N&&(N-4|59)>=N&&(q=C.Ze,h=['"><img','"',"rc-image-tile-target"],Q=C.rowSpan,L=C.JW,D=C.iJ,t=C.f7,m=C.tW,O=C.colSpan,e=W[49](26,Q,4)&&W[49](31,O,4)?' class="'+H[7](33,"rc-image-tile-44")+h[1]:W[49](25,Q,4)&&W[49](27,O,u[0])?' class="'+H[7](64, +"rc-image-tile-42")+h[1]:W[49](24,Q,1)&&W[49](25,O,1)?' class="'+H[7](1,"rc-image-tile-11")+h[1]:' class="'+H[7](1,"rc-image-tile-33")+h[1],B=P8('<div class="'+H[7](1,h[u[0]])+'"><div class="'+H[7](64,"rc-image-tile-wrapper")+'" style="width: '+H[7](32,S[u[2]](1,"",q))+"; height: "+H[7](33,S[u[2]](8,"",D))+h[0]+e+" src='"+H[7](32,P[11](1,t))+'\' alt="" style="top:'+H[7](64,S[u[2]](16,"",m*-100))+"%; left: "+H[7](32,S[u[2]](9,"",L*-100))+'%"><div class="'+H[7](1,"rc-image-tile-overlay")+'"></div></div><div class="'+ +H[7](1,"rc-imageselect-checkbox")+'"></div></div>')),1)&23||(B=P[18](28,W[u[1]](24,S[32](76,new b4,12),C),[y[38](32,e),y[38](48,L)])),72))==N&&(L instanceof O$?Q=S[8](5,C,L):Q=of.test(L)?L:void 0,h=Q,h!==void 0&&(e.href=h)),N)&&(this.Za=1024),B},function(N,C,e,L,h,Q,m,O,t){if((N+(O=[49,9,"i"],3)^19)<N&&(N-4^19)>=N)P[0](78,e,L,C);return(N|7)>>3==((N^26)<17&&(N>>2&7)>=3&&(L=L===void 0?"":L,t=(Q=S[41](8,C,h,e))!=null?Q:L),1)&&(this[O[2]].G=PL,T[O[0]](1,'"',")",this.B,C,this.P),m=this.B[O[2]],m.X=this.V, +f[36](O[1],!0,"h",m,e,L,Q),this.A=W[36](64,h*1E3,this.en,this)),t}]}(),y=function(){return[function(N,C,e,L,h){return(((((N^(h=[7,22,20],h[1]))>>4<2&&(N+9&13)>=9&&(sV||(f5?sV=new Xp(function(Q){K[31](45,Q)},f5):sV=new S3(function(){K[31](29,P[3](7))},20)),C=sV,C.isActive()||C.start()),N-5<<1)>=N&&(N-8|62)<N&&(L=l[43](40,C,e,void 0,FG)),(N+h[0]^12)>=N&&(N-2|13)<N)&&(L=C?{getEndpointIdentifier:function(){return C.B},getEndpointType:function(){return C.G},getExpirationTime:function(){return new Date(C.i.getTime())}}: +null),(N&108)==N&&(e=H[2](60,C),U[29](71,S[26](34,1,2,null,0,C,e),C)),N)|24)!=N||Yd||(P[44](h[2],function(Q){return Q.O5.origin},function(Q){return WL.add(Q)}),Yd=new TN,y[h[1]](39,Yd,S[28](17),nM,function(Q,m,O,t,D,q){O=P[4](15,HL.values()),m=O.next();try{for(;!m.done;m=O.next())D=m.value,(t=D.filter(Q))&&D.aM(t)}finally{m&&!m.done&&(q=O.return)&&q.call(O)}})),L},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R){return N-7>>(((N>>2&23)>=(((R=[22,38,8],(N^72)<R[2])&&(N>>1&7)>=5&&(u=[!1,2,null],c=K[0](9, +1,P[34](14,1,0,""+h),Q.h),Q.j&&P[30](81,e,c,Q.j),T[21](88,c,7,Q.A,void 0,rY),T[21](56,c,R[2],Q.X,void 0,rY),q=L&&L[Cu.getName()]?L[Cu.getName()]:I[6](36,Q.i,Cu),P[16](26,10,c,q==u[2]?void 0:q.substring(0,100)),P[3](26,C,c,(m=I[6](36,Q.i,kd))!=u[2]?m:""),window[Bh][r3()]?(B=I[6](R[1],Q.i,SX)||U[41](33),T[R[0]](2,e,c,rY)||(G=(Vn()*p5+J3)/u[1],O=T[45](99,EV),A=W[39](33,4,zt+O.substring(0,G)),H[R[1]](6,c,y[39](12,u[2],A,u[0]),9,rY)),t=T[46](1,0,3,c.G2(),B),D=T[16](60,4,zt,t)):D=f[4](2,4,c.G2(),I[6](R[1], +Q.i,SX)||U[41](1)),n=D),(N&35)==N)&&(n=L.MW[L.MW.length-2]+e-C),7)&&(N<<1&16)<11&&(C=U[13].bind(null,R[2]),this.ctor=d3,this.i=C,this.defaultValue=void 0,this.B=w3.yl!=null?rY:void 0),(N>>1&16)<14)&&((N^71)&7)>=6&&(n=P[18](24,W[39](12,S[32](76,new b4,C),e),[y[R[1]](48,L),y[R[1]](32,h)])),3)||(this.i=new Vj),n},function(N,C,e,L,h,Q,m,O,t,D,q){if((N|3)>=(q=[0,"B",15],25)&&((N|1)&11)<9&&!xd)for(xd={},t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split(""),L=["+/=","+/","-_=","-_.", +"-_"],h=e;h<5;h++)for(O=t.concat(L[h].split(C)),zc[h]=O,m=e;m<O.length;m++)Q=O[m],xd[Q]===void 0&&(xd[Q]=m);if((N+7&q[2])>=4&&N-8<6){for(e=(C=(Q=(L=(h=H[q[2]](1,this),m=U[42](6),[]),y[34](54,this)),q[0]),Q?Q+af:af);C<e.length;C++)L[C]=m.call(e,C);this.Pm[h]=L}if((N|32)==N)a:{if(L==C){D=T[33](41);break a}D=(O=((t=I[48](3,C,L,e),e).eR&&e.K?Q=e[q[1]].subarray(t,t+L):(h=t+L,m=e[q[1]],Q=t===h?new Uint8Array(0):g3?m.slice(t,h):new Uint8Array(m.subarray(t,h))),Q),O).length==C?T[33](40):new dX(O,KM)}if((N- +7&13)==1){if(e=(C=C===void 0?f[q[0]](13,q[0]):C,window)[Bh][GN()][C],!e)throw Error("Invalid reCAPTCHA client id: "+C);D=l[23](16,e.id).value}return D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J){if((J=[61,14,1],N-7)<<2>=N&&(N+5&62)<N){if(m=[3,"[",(this.B=!1,null)],R=m[2],C)L=bs(C),R=y[48](26,J[2],L,y[11](59),MB)[0];else if(this.B=!0,Y=window,Q=Y=Y===void 0?window:Y,Q=Q===void 0?window:Q,A=(e=Q[$d])&&"TSDtV"in e?e.TSDtV:null,h=typeof A!=="string"?null:A)u=m[J[2]]+h.substring(4),t= +N1(u),R=y[48](2,J[2],t,y[11](27),MB)[0];if(R){F=(X=P[4](J[1],y[48](34,2,R,y[11](10),CC)),X.next());try{for(;!F.done;F=X.next())if(K[38](16,0,6,eY,LC,F.value))throw Error();}finally{F&&!F.done&&(Z=X.return)&&Z.call(X)}}if(R){n=(D=P[4](10,y[48](26,2,R,y[11](2),(q={},CC))),D).next();try{for(;!n.done;n=D.next())switch(c=n.value,G=f[29](3,c,J[2]).toString(),T[J[1]](44,m[2],c,LC)){case m[0]:q[G]=T[29](13,m[2],c,T[33](J[0],c,void 0,m[0],LC));break;case 2:q[G]=v[28](60,f[29](3,c,T[33](57,c,void 0,2,LC))); +break;case 4:q[G]=l[0](3,m[2],c,T[33](62,c,void 0,4,LC));break;case 5:q[G]=S[49](29,T[33](62,c,void 0,5,LC),c);break;case 6:q[G]=l[41](62,6,c,eY,LC);break;case 8:k=H[19](26,m[2],8,hp,c,LC);switch(T[J[1]](32,m[2],k,QL)){case J[2]:q[G]=S[49](23,T[33](57,k,void 0,J[2],QL),k);break;default:throw Error("case "+T[J[1]](40,m[2],k,QL));}break;default:throw Error("case "+T[J[1]](48,m[2],c,LC));}}finally{n&&!n.done&&(O=D.return)&&O.call(D)}B=q}else B={};this.i=B,this.Tm=R?R.H2():null}if((N|((N+3&8)<3&&N+8>> +4>=0&&sH.call(this),24))==N)a:{if(typeof BigInt64Array!=="undefined"){E=new (Q=(ml||(ml=new BigInt64Array(1),O6=new Uint32Array(ml.buffer),ml[C]=BigInt(J[2]),tp=O6[C]===1),ml[C]=h,tp?0:1),e)(O6[Q],O6[J[2]-Q]);break a}if((U6||(Dy=BigInt(Number.MIN_SAFE_INTEGER),q1=BigInt(Number.MAX_SAFE_INTEGER),ud=BigInt(4294967295),U6=BigInt(32)),h)>=Dy&&h<=q1){E=L(Number(h));break a}E=new e(Number((m=BigInt.asUintN(64,h),m)&ud),Number(m>>U6))}return N-5<9&&(N>>2&7)>=0&&(C=K[43](18,ye),E=new Map([["recaptcha/"+(C.includes(Bi())? +jY():Gw()),3],["recaptcha/releases/8x-4t2pegToiW8KmThtO4AQt",1],[C,2],[K[43](10,ci),4]])),E},function(N,C,e,L,h,Q,m,O,t,D,q,u){return(N>>2&((q=["rO","GD",13],N-7>>4||(L.i=W[36](64,L.K,function(B){L[(B=[13,"o","i"],B)[2]]=e,L.G&&!L[B[1]]&&(L.G=C,y[4](B[0],!1,null,L))}),h=L.B,L.B=e,L.P.apply(e,h)),(N-4^4)<N)&&(N+8^28)>=N&&($s.call(this,C),this.K=Q,e&&(this[q[0]]=function(B){try{e(B)}catch(G){this.destination.error(G)}}),L&&(this.x_=function(B){try{L(B)}catch(G){this.destination.error(G)}this.unsubscribe()}), +h&&(this[q[1]]=function(){try{h()}catch(B){this.destination.error(B)}this.unsubscribe()})),7))>=3&&((N^42)&15)<7&&(u=P[44](q[2],function(B,G){if((G=["B",1,"onError"],B)[G[0]]==G[1])return O=Q.i.i,m=v[23](G[1],O),B.K(e),B.i(Q.V.send(new KC(Q.fu(),m)),C);if(B[G[0]]!=e)return D=B.G,W[8](64,h,e,O,D),B.V(L);if(t=B.o(),t instanceof hh)Q[G[0]][G[2]](C);else Q[G[0]][G[2]](L);B.P()})),u},function(N,C,e,L,h,Q,m,O,t,D,q){if((N-7^17)>=(N>>((q=[19,39,1],N-4|75)<N&&(N+9^24)>=N&&(v[22](66,C,e),D=e),2)<12&&(N>>q[2]& +11)>=8&&(h=e,L=(Q=K[40](4,C))?Q.createScriptURL(h):h,D=new u5(L)),N)&&(N-9^q[0])<N)a:if(t=T[0](60,dY),Q=!U[5](26,C,t),h==null||h==Q){if(Q){if(L.rr(t),!S[44](q[2],q[2],t)){D=void 0;break a}m=(P[49](6,t,!0),P)[47](6,t).height,v[q[1]](q[2],function(u){((u=[1,2,"focus"],TH)(10),K[u[1]](8,u[0],"4.0",e,"")>=10)||t[u[2]]()},L)}else m=-1*P[47](6,t).height,H[41](22,t),P[49](4,t,!1);K[34](43,((O=l[49](20,L.P),O).height+=m,"h"),O,L)}return D},function(N,C,e,L,h,Q,m,O,t,D,q,u){return((N&84)==((q=[33,24,"B"], +N|3)<29&&(N|1)>=20&&p.call(this,C),N)&&(u=function(B,G,c,A,n){if(n=[0,"",127],h)return h;for(B=(A=n[1],n[0]),c=e;B<C;B++)G=("ibUis8)z\f\r#l`eu-q\"2^wb\bp1m\f =HFIp\t1ADbJ~/aVKP:+N~\n_O$+Pyil\b1ED+Wr+450]Sv:LXCk\nb\t%{b\n1]r~P\\}g.</]l\v 5X}d9e2_~p/N?UH|a7E@bvYDh?P\\?^GbBibOW/mH;H]Hd'\b~*v)m>Ze&eEl\x00|\b=5$Hp\v2_z$Vs\b1#HKRc=\bFg#Kr\x00\td\x00()n|o\f|p\v0B_~lBjx0`4!Hn\v!so9]=\r$/]yq!VR`/@lu%$Oa\tAv}1V_qJEkM.bK\fi<1+FDx,w\\S\"|P9]u=`6j \t[.\rV%eEx.u:\bG\vc^LW_,g+\x00;} v]S?dt}yZ\\u12`#k8\tY`WKH_-c/ZG[xF^\fx8e9-|FSN\\GDi9p/c n=tZ\b\v[(bK?\vGw5d:*g4WJ)\fsV5[!wJn7k&]S.oY$j'_\f=6Sv8_o{`/.?F\"]za9-Hq\n$Uym\b<'B\"NKkQ]q|\f uk\x00(9\"Pqn- \b\\-82U= TyWDeHs>,I?VLi+:HI5VY71XP}\n/Ndm29L[Bh-4h=SOh(:7EL}/Igf0%P~o}d*fc\n(Il'Co$%xVZ!z9:-FFzm6FTw`6K<yf~G7EFlcU^I{\f)BWH9![tc\bFJs\n3;WFqm;m&!_{lsb73rj7i7[V}\t;+b'q\x001^Y\r,ZC9q3GOj56\b+/=.DK=3V{,8#KjBy\x007YQ7~\n%(Iyh7\v|eGR*7YQ82U%,Mp5Q@,S\r#OLe4<pi8,Sj^;3\\P`Z?NE@y\t\b5=R()Ru:TE+Pzk>J#L9MDyk0^2RMt$-^Py\v.!8!Dv\t%T8'Kz;m>\"D}2@A~n-^N}u80K!*@G9\"Ctm8l\x00=5ZFsOK&:[of\tRQ{q?XTqe^l\vLu\r80]po)\"j;7X\b{j\t?Kv\x00\x007^MhSz\bgu3e\t0/[VyKcq7i:&Lu,}\twI &Zr!1(aL YSgnPy\vYCg<MA$UmVdgtz<#Sgd3(Y|N^,?KV{\n0}?PGyq?z6c#f)m\r\b-4ZGt\t2-C\r\t-r|\t0Q}';,U7\tp)/Vk>%KgN>XKj(: Kk::\b{\tN$W)x\v?SHf8U\r>/_zj%i84]{f()Ce.!bnk XC2#Vvr\t\"4Qui4/\rHg.|/=O@j}/]De\b:NMytM,Ip\b?VOa2\r84UDh2ql=^S\x002GPq\vpO[%!?M'YFg>#W%fW.}0K2v:X'u+\nUN>HUyhn?MP=O\\6Y&@q1,@{f)Jo\x00+=5)@v?Q9Bx0/$f:\n[/{2J2_zpy\r\f)\"%AA1BEk(9CV|\\I#82U6Zo|gIfm?VM#|gBjxq,5fm+6VEl<%Vhg=.TK#JxaLj5LI81Z] x\v0Wgs6'\t&'N=-Dssb12]~)](<%Fi-.XyVBs\b9^R{\vpm4#Em\"_sb73dsm#*Nbq~oRc)\fvv8JWs[>3'(4]=\\>XMc=3>-OjFd)q.n$j73'Bj6gbb5 If9NYcq7i3$]Mh\\Pbm\n6CM?~nF\vl$>KA@^?O %k95l?QI%\bBUA%\rU\v_H\b\\j(Ni<wL4sLl\n|2(j4u_r\bZ07W^Lk*\"^I3Zd[4h;/K+>5TE~I\bK\nNaSx9$qIXU\x00so'e~c2:<$RxNJa_\f\r3U#]\fTa-8`yW?[k=8`G./D@E6F4KI?yn%v*3J2NOXSu@;L[A-%BMU/-Gx~0&{1{Wa\\$3v4M!\"\r@H\x00]3ZUS7\r O.hFJK?FbTra\vI}MN~(8&wJ\t\"0[Ny\n\tFi\n8)FvL?]Saj\x00yu\x00;OZEi_o}n\v}L;/[J[0[sQ0I]rb\t\b|T;,7\v>mt5*ZQ;,@Sz\n}0\"_sY83FM~t !\\{l[\"'\"OzvV\f~7\tR}No.dPYNM<\\Ua}wv\nGxhYEd3*@m0HExg\t!(F[,Et?QYDa6<Eaf&ft4\"O}x\n-\"9\"Eu\n$U; J{:l3_vm/tmq\f&)&&Umxca\r0:-\rTp\v .m,I\v=QZN\v 6YK`c5!@d(AuH&%7YF`-|:-\"HQ3\r(#O@0>[@g#(FwYs8]oi;\"JqBxr8MJwf(~t,AZhc\x00p{j;/Jgt%8TL~2eie/^rk\b?X\bw3.CWv\n)Apg\t!\x00|f\tWef\fuy\f\x00?KFIe[Saj\x00yJ6\\Ef\\Lut(+<\rgbMe`,>WT97RyP'(BKE\f H\b)[il>L_k|,GNbg\v6KXA0(BMxMAx,\".Ovdd('E]|\f)ai\f S_fhm!P@v%0i?QYh>Q[5#IxeDefL\f\"'Dk/,Z{UZsr*S}b\f#I+*KvVIcn'Ial\"+X{E;^ET#$NOPN|e)Ymn93EHy;K_0/A~h%f\b\t.U;0Y\\$l?U\t4>Q,;IH~%Ig)\"UAV4%\\A\r8C_pi[t\x00i?QYh>QYK*9TI{W&Rvc}\n =OAxfFc/ L3\\FcKm\f?0%mb1(Ap()@Wrb&2Jg(8WC)~t9!P\\3?^Bn\vm->4[\r#&Kj(3[zR~\f2QZ3>.ZGu$!Zh@\t'PM$>[Q/o\n&4WUIdj<'Kv/.R~E4sJKir2O\\D},n7)RyeEb4-]x,S|oumVdgC3\\Ke\r\b \t~v:-Coj\v<4]P}a)gGY)\vN{as9k6%]hsq}\x00*=o<6DMl\bZCwb'SzQMh!..?FWel\r0BVu\x00l\f+e4+C|pZRs??R\\}\v! Il*1]|QGv<!W~pKr-Bn!MLit{Y%c)q4BK&\\yc?07z&T}1EF`\fti4RMc-A@e\f`\v% ALl9p9e2_~p/N?UH|a7E@bvYDh?P\\?^GbBibOW%ko}nBky\v UKtZu{\"Z6DAp-L ]~t+6;SBj)w/,Wya\x00<'ii;moO[ue0)<,Cx\f19.)<LUyd*Jb,?VLS7&Q~p=DZMvVe<[MeL ZM@R}uJbw<IP~P\\na\tNC.<HYN%&@B6MHaqWd96]v*9$Um-Lb\b\t0Vo/Fv&Vdg,5F[M95E7Ro\x00/*5A\t}M}~KS3_zr3Bf3Z1-Hp}&e7ELm\"6Uq`Lcl\vEpo7Roj&\\$XEk?>J\t'D^lef5*ZQA\x00>[p7\"O{#Qp<NZAm\fa>_lq 4\x00.Oc\"]D)\\sj\v6KN|0\"S>Y@U8:N\x00/ G\rCe+L^qyn^lu9I]~h\tg'5VO}`Ok )2_}tpyX\x006Sx/; NoAnVGi0/]?^GbBvi3v9^Aq\t'\"On\x007_~/Ex\f\"'UprIt/@l?ONwry_,j;$'CD4?VZ#0it\x00:U@v)%)PkT6'^LcL\\3,w\b<4\vRxu)\t:6^$xIi,Ia?XNz8m=\rH)z9Xf4WWFTwsDjo\f3CWtm1/FtaGD%oj0-_8#Ixv3e8.\x00()9\\m?ls<me|m~thz2b;/QwL`m)S|v</?P\\S/;GUv|Ekn2DP{j9(Oa\t_O\b<!Up;X}d*Od1x5)TxcGt\n74_\v{>E\"U$-]xc#c~\f+<l\x00; Ronrz\b/ >[@i\r4UmE<PXS=xi\n)zKe\r\";OM{x\n-\"&+_1AgS/=.DKC:Vlm+vz\r k2ZLu>`/Atu\"v\f H\"'VmhN\\O{l\\Rw;K_|j\ve0!TxpVk5*F_V0SYpk6'Y/=.DK=3V{,8#KjBwh1-H<r\b]xu:SG{f\v?VGy@$_vf\vJui%)ZSIw\f)DE<{1b\"g&u-!.^mt8%HwJn;\"\t5Px\tuv]?MTu*>]IhDkd]E`\f1DJfe0^ro:!>-Li\nKrh>$6Sx/; No@ti>3Pdazg.\\pm<'\b2_yd73+Ux/My6*Wyb\t\f`&q_f+tc0H`<HQn/=V)\rD\b?LA\f>_xj6NKTp-,?ZFsO|m\bW;^Cb +CrZQz}SCr!Haq\fk(D8JOl#7TrcLx+2GDx!f3\"H|(S4\"S}e)BPmK{2.Ip\t$-(!D\fI\v_zp1/[Fz\f=^\fq<{!+@a:]0.Gdk\t!\\z?'2Yc6Zsm0BM<M*Fd&Igj=\v\n84QkeeP\f3\\O$!\t~s\f<3VE!3\\Vy+A@i\f>JQ}po2!Gc%ts2f,/Gv<UVhd,~t1XnoTt(jc6TMiRn])3=O@j}/XO}d\n7DYB3/]NyL@y\x00-!-Lwkg4VCj=4Bf+VjX9,Ait5VFp|\n7VlmCK\"c\b)HA+COf;,[unPdkSa`,)i9v[ +%lZ2gSr7CJ!]x`>m6u'U|\x002FEa|suh;SL`*BCda&)Gj*?^Gb$[Ok*\t;^Cb +Cr[Il6[iduh;SL`+CBc~\rc!pC7ELm\"6Uq`Lu\r\b1@^{#L|lEr6;,;OG7^Nxm\t+Gr\\nk0w'XgIT{VI|\v$Yud\n>[Mvpc$2\v2Vs'.]xfK|wz*QN\\O{l\\Pek\"?^L\"JXs@S\t'R\v#\"Pp.~-%k1PEg86UqNj'&1\\|uqzY1Py.:!Ml@o`YFi!,]\"I]ix\t\b>[@r3-BPj?P@o/]De\b:NMyuc\"+X}s,8o\f:[wk6!H=\"Ek\b9.^huFefKQ35X}n9i:T\be%r3U[~a*ZNw<YQb*Xo73T/&JOc Dh*%PFY9 [D\n7N\\sl\\w?|n2R^W\t3TJv %Pm#|\f\n#ULUe}&Sz\nth9-Td; M`2Wl/6DGcdTBs\bd4'#TM}Ly8,DMyxTJe\bDnk\f(]~a<QCh\n9(^g9-L`\"_kfz,|f9TC%pl-\bdm/\vr\x00\t\tPyC\x00#i)w5\t[#skya\n7Vh|7&;,P}\f`,)CP\f%Ml.Uzv0[6[z\f+J!POn2\v>4@GyQ_zg8LOgwf1r[Bg%L@hs:PDq\x00+~D\x00ZL!fi\x00\t%Vy/Cf)Pfg4Py\r\fc:&S|/\\Mh7e>#Bt\x00\v#R:1Z]3*By\n&h\"I?\\No<]v+%PLw(v\r.Qau0!:[mp:SSg(Wyf\x00?M1V}SXqt<tAyb! Iyn7CNdm\x00?\x007$Kg\"Ctm_l}xTLm\x00l#\"J{\"7SO%=XFT=N_jfe\fQ|[ho\t0LQ}\b$d,>K@R1Pib\t\x00#~r\"{\b$x \f\t\\z[iY3z2\rN\f+!,@{\n0,DA{7_p{q=^Lc\b\v7Z))Dk0k&s4Py\r\fc:&S|/\\Mh7e>#Bt\x00\v#R:1Z]3*By\n&h\"I?SD}n<]oh()Ru:TE*^\t%*^wwD{\n$[Q:4UrO|m\bPn'e`d3f/;7XH9)Ft`\r?\f5LZKgYMylt|\x0098_y`9^R{\v]Ndk;7E@p4)[Pdk,>QYN>N[Mr\x00<R(:U]r\"uk0YiR<]slGUv|E~o\x009)T8-Coj\b5Y&\\yo\n893$D}%1JXAut~OE{\b5fa6#O@+'e?QY$'CD4?VZ#0it\x00:U@v)%)PkT6'^LcL@=%Py\t8^D=_~c\bMz\t?u7\"6:SDc)$tHc\x00 L p\f>WC+\b-Rw De8.Rg`ChaK'\"On\x007_~.]Ni'Tvo\n:6/Jw\x00+K?^L`;Xu)[~c4@Kc{i\f8%V{\t&2\n QDh\x00Gt*ZVI0%Fc:<25MAa3KDsm1@BGN\\O{l\\W~r;&[hQ\f XR}h]qh<2^\v4&Sz\f)\rh$+C`\n;^NzK%_p ro\" ]Y5RPww5UP\v\r%-d%\r0Vu8+_2NXA{3X+-iQ!Uzi9$)Gp'7Sz\b&<]o{]y`7\x00-OzcFkdN !Jm)2\\}SXqt(]pk\f7DOc7Trc#^Nita?XC[:EYNqu/N`t?^%Xlq5PRf)Vpa\r!\\pkwn<Y@y+Pb%POn2OJxe<25MGe#/Fwd3_sn9 #/@i{o\x00?[5GB}kAG|l(8o<LIz:]q`\b\tz\v9Dbb\x00\v'3WBG2E\b{#Qp\t2\"IH2FCsw`gJu\x00'XEa>ROad6&BXsgM>4'2L\\sxg4j95G^\x004\\y!N`e\vUe;tP!g(a0`A\rk!MI 1Ykdsy$Vbi40JKh\v\x00Vw<6Y\v! Il*1]|POc'C\vNt\n)U@80u9/[j</]Lo\n#U<]ncj]o`\nO}d(Znm8\v'^EkIV7(]Ho;*A|\r+Cg<]y`\b;,@OjH~\rPy\r\fc\v5%K\"u|uI~eEd=>5GU|\f5e,-_kz\rq\r( !Xoju<%Uu!EFd>+>#Bt\x00\v#R9 Ls484T}\t%Tzn\v=&MY\b'Rs~t9(Dmyd\nxRP#{j<QXV60e}d\x00#IHbc\"/hz2b\b\t2Ueq4%\v0ZKn*|C/F}]Nw\f=2fc48HQwd7(Xi\"+OnVC\b<\t>5A+Cz\fl&h910, !Svz2!IFvc--o;}PPul{\r\"Kzc66)NuZCbaw+.R6<|{'.^j!wVdgt?SNcp)4X@z\x006iei+Zvg\f#\\\fmyd6'KG=XQah'9KDnaS[ib\bm?]Sz\"B\f4_L#}d7EH~4UahGs7P38QTAw?^Pdg.->9&UqnL`a-2*DAbm#^\x002Wt+?\\JkDpe:OL`m)~a,Zu{TZ{i.j;_=n$\bUCQzpIgb.@Tw>n4(EydHZ7^Vs8QAu`\t9(EwB\"]Hd\rLwk'-?PZM?MTu*>]IhDK -~p6QGn'\b`i<ZG=O@j}/XO}d\n7DYB3/]NyL@y\x00-!-Lwkg&'D~>M~v)?VLic$\nw\"@l;0Ec\x003AJ`gYWr>0DGo~\r$Su}S{\t\b\"-BMyh7&DW6H\\p+R`i\v/NdeHv9HU45VQ|r4[k\n+*#B-R|s{;&93^RD\r?VNwV-\"HQNPbg+[ol;\x005CJ=MY1_|j+d\n\v,W96W^n<sQa:}dWWr2+F}u\v!Ae2[6,Isb\x00'j6DMn!5VpaO|m\bDy\"]S=1Pupm6)z\b%0Ir,^{`7CHfxl'&[x\f)=\r#XviHfg\x00+;:Do-9[WH!PZug2>?SYxc>`7YAl!x\n-\"\b8YMhVvb3\"PG\v2Mr|\t0.Az*q\t!-Dw-i&'7V56QUp\x003[}u(<NGyq$6O.Wv;,7T{\v<*K%Zpa80$Ml\r>.|e#.CW1-\f19.)<LUyd*Jb,?VLS7&Q~p=DZMvVb<)YN`C/F}Fp'(BE70WU|<1ju5VAu*$(QhU5$_sdOA81AJm\x00\nB}u\nyh!Ix!|;,l3aWl~~\f6Yi}\b)#<-Wv/ L\nEF^?\\Vyw4RCo>.Ip7\"XAe2[s4$]~o\n&4AWef\fu{\"T`k2)XOL>WBb&Sz\x00!H~Pm9(Sgnzl+2@A~nYkdsn\b=OFu`,?/ J]\f~\"Nk\v>2[vm/~y\n5QX6vC%Fx\n),\\Tm_:*S~i0{m0XEav#$6:_sn\tTx`5 VI\t0Ktz>,C|,`l\r4l-]tc-xbs4+ALti4)[W\b2SU'k<&Oy;mb\fL`;7T{6#OE*<^S#0Wp,\\t)FNk2Xa!$_AL\b1{8\t-LzcNt;NW:7X_\"~\f6Yi}\b)$%@\r\"XAbJ\t'%,Mp5Q@-[z\n %[rt\x00Gt/C~n\t09!HiBqf=^=.I[9WuCQp\f;7gf('YBXVd}!;^DG+\\Luu7XDgv\r7Rngl.!EL*Wcn'\"H0QCp\")E5AF8TK}fEej\f%[D+x5)Txcp2ZA`:'C+It&ShkKcVCb-\"_pc\v2HU\"JkN~\n91Y9Z}0^>QC;Xqc\n:65VFbk:+E~ sV8kgz\r6*3_hwCq.;1[7E\\{-AlNiKdc\tWOn\x00)[Wrsh38WCn#0!S~f7$Wex\n1I8Yo`\r2{d3AJ`gYU`d/:%I?O]Ndk]v-.XJ>5Piyn-0m{b\v?^\r(@VywZGf8\"C`\rF{Mg7W'wGg7\tJQ#bYCih4FRyi&/Mp6WRr~\b+\"Rc:HExc,c1#O]N|Wxj\n1Zte\v4_Ykdsy$Vbi4\t>\"Kgr]$~3\ba0Yixrm4-}';,Sw9XAd\")Et[U|\f?F2HDK}4#DAqu0*]6WcjA}\x001^\r>/VGu= Rfe0<;+.@O|k6'YDj\\Hm)i>#Bt\x00\v#R;)Lxe;IDfrUJd9-H|gczt;TYtr\f<!M#HAd,e1WU_v{/Crp<]slp\b\"-BMyh74NO}u19MDs_'c?\tBT$sHU,{6\t_.eOj>4Qtt=TIYCg<O<%]l~7Ryo\v\\Am*]sk*%MB2:OA~t\b&&)AF6a<'t-'\"^L&8WIfm\\\t%P:TGc+M~u};\f]5\tLd c5-B+x7CG/\f;U]xp|[7AEaQ|2*U@R}uJ`a\n-]ir=\b\"SFfDM7ah\x00\r+J~&)[Ps,XTdwM;,>2W{f(L`=(NQ1(S|r?FTKtTl\t\"/[LbQ0HZKh\v e;-El\x00:-BP{wHfc\b/_kp?<U@d\fB\\=/[Ffmcl\x000WLw.6~K}\x00*=o=$Jw]so9]B\f\x009@mam\f7+\\E's?\\GT./[Vk6fX\n>QC|\"Qah\t&H:Y*)'(Dk>[30Uvf*X\ba\f~POf\n\t8.O}!Sv;1Ptk~P\".]C3$[\x00%Pno\v2@Il oQcl\t{q9\\nza\r,\x00F\f\"i},H}' '\n6C_k|l]q`\r#^S`+\\L=Y@p.\\OP1@=,GdoD'p,F;EE.Uf|\t\x00wwe*&)[1DBcO`A},;dx\vky<XAu{g.[D'DE`/m+J|\b;Z29RU\v:QHm%,B5Q@n?QJqWN}9 m\n(\"'Dk/,Z{T@u\n?\\P}\rNs:PDq\x00+\v&Y~e=QLmJ}\v,Wdo>#W96W^m%g\f1GF{,9I]'pYO}n\x00#Mt-\"+ID8 Mu8$M{#JhM=\"\t0\\Ck(a\f&/\\Ki<Pp-,r(4[Tt%BM8#\tsz-EW)jx0`\v0Wgs6'\tAe`9ICJb.FCy<Y2[on]yd=Z\t\"+JKy$Vbi48?/*DK`o\n#UHfXTu\f5(N.\\Ef\t9MNxvb%(Y~r+?\r9Xvj9\"I>.B59KN`o\v?VGyd\n|sa&{Y}D]i;&j=Ou:]KYrxoAoj6H\\f8!]j{q-Hfg*XA0Sz\r9$'CD4?VZ#0it\x00:U@v)%)PkT6'^LcLWfL)BO{l!Ix19\bd1(#O@0;*^{o\n'4ex\f>QDr%)%ToP2+RHH^-rk! Ymb8\v65PM_m~tMat3NQ}S[ib\bq@/#OFO$'O]5IFvuAu0n&Wya4%Nu{3k2fM)Pp5)Tr%\v0Wgs6'\n'\"XUeKYrxoAj}\n8%VkT\v%]o`Zvg?OCz76HI{\n;\\J~=-DsHr*%MB2:OA~t\b&\r#OJfh9o=$U`|c&Zhc\t=\\g{l7FQDj{o@R}uJe`\x00%Pi~_>.J`k8oc%\nDHq\b9\"Ir.+@Vyk\x00j\x00\t ^m()ZKtT[o}t->n>QBpUEJ6\\Ef/o28`7[Fi9%N`p5&I}\t;l\nG`yrQO`\fp\r8,S|f/\t%Td{idrM5t Kg'Wv\n\v&]it{\b90VB*HiQp@o\r;^Cw<S=XDm;;\tTfivq=QL}r+2ZFt4kco)Xte2%^kH\"SFf#]GhXq\n\t#c>Jq\b/AiY0,DW9u4,m?ip\b6'Y5#\r0:--4Ux\n=)H$[wn;7,Cz~l\t2@A~n#^Tu8NO2/X}\f;O,@Ah;'*)IJi<QC;O]Xsmx\f{38_sg.!;\"PyTBo\r$!\x00)\"E\bPfc\b/_kp?6f1 Nb1*Q75\\re>wd7g<]@r!P=+Jzc5KBdpWDb?SN~\x00e4%I}\f7R29RUm)kV1/HzgGOn<9/[JxyWs=&\b<S\v9XVdq!f-y->4[\r#&Kj(3[zRGxd=X\ffi:%\\\rto6#{%9.Quz\b/ .'ALm\bD{,)I]3.H\\ys\x00.\x00Ymh\x00\n3_LCs\n\"]R:\v*$YuF$]xl4FIcb=Yl?OFva>[S&A|8#}d\x00#IHq-~e,[om1THr74Yoj7 2]Uz*BWyf)0^0<NAi~.a5,MeL*`e\v4_6'M;;OJzq1#7T7&Fu\"o60UVqc*\t&NKa(Zu3_\f5-YUeHu\"+v\x00'DC|l9*@\b)_~i4Ttas:RYip2/K#\fG5z93AJ`gYWr>0DGo~\r$Su}S{;&{\b:IEzp<UCm2[Me`,?mez5+W7GFz6-YDtXup\tAch\t'2PM`19a\"b\v/95Phm\b%W)ZP8K^P`o0^>I]tjw5$FI{f\"j f\b;7>.*]Bq%M0Sx\v\f:;~r\x00\v!->4[\r#&Kj(3[zRIa)A@Y2 TAj!z\"[wKV;FmUx\v:S+$O]Ba9KDnaSYxa6BIexg\v:YO{-~b=NSr\x00\r)r=QEp*gn9$Ja>AdVh:Ccq7i/N`t?^-]tc-c5,ZUvz5Phj>!OlK&go<!\npI0CWxq8\vE)sT9XAp\b\t|Ma@[\bg3\x00=5Z\n !Jm)2\\}S{=5@Kg'&QMb9/7wh, WIzsIl=3=\\js^Da\v>'\n'(ON|e)Ymn950l?\\Je\vEih\r4\n=3^Am2l; Gw\b&W8,Qgf8LYi}RMc6)G\b&'@k]R{zF[9$Ibt`8K@\v2AMdkk9=aKkA@R}uJ`a\n-]ir=\b\"SFfD\\3([Nu2Xs;-P~\r\rL~Wh:jO6DGcdTZ3GDb}b\b9\\px.g<LQr\x00'\"~&)[Ps\r0:-(?MTzg)Mc->)MR0)P}q<G[LuWd5)Tu\r+\\PP=_js-J{lx`>h8'\rTx`5Ughwe,+FI{qY5Ml=[Bg,bO%Hd93Wv\f\r`;!P},]Ni4d?\\Cs\"S=2[Z2+Ez\v!k#N>]Il\r:^quM\"PLi\"Jv:#A`\t'\"On\x007_~/Ex\f\"'UprIt/@l?ONwry_-b3W/?ZGsd)ZHu8d3O(YQ9-k+#m@['t?k]xo\r4DFy\x00=5Z\n !Jm)2\\}SFwe\x00>[\rqo4!{\f#ZxR7DZugXqc\b1,C~s\x00 KIXwb5Tbod'#\vu77[BpQt0/Ai/=.DK=6QSv:Opo93\\Ko0>RKr[?^YujuL66Sid&BcJ\vVE(gAsg#\x00)L~\n=\\0?PW\t6Ywq-\r9(Yxn\v0Bb;3}n4_p~\r7[@j8UHA@x\v&]ol1>5GBS4/]S|p+\fQzj37hILR)u7*V!97Vz9%El]?S_m3Za/\nU|?HQkb3 Gs\v=T{h\v=]o`\nOxo*Wdy\"=SO}n=bl` \rAMl\v<%\x00Gya/<i?QYh>Qmx\f'~\v![z\"+Yib^'m(ZG'd +^EZsg*Wov\r;&FbG8\"_sn5M]r~\n! Kg)njUJaz(@MR}r38[W{r\f=5\"-^\x00!Cl\x00=Yi&'\n UxgUp\t<;^DW#9HQa|\f^w`9e1KBut7&Jf?.k2p=o'5V\\s%KNs$0[sbJq\b/Ai?jd`\t=X`92OJfB+_~R7F]xqj2PMDKz;1QvD <Lo\x000\"_|v0 (9TCd`!e5|!l \tPr?{=O@j}/]De\b:NMyte/C~.a90INq\x00.c\b%YDU0%Gvj }]pQ2+A@i\f>JQ}^Fa8)]H{a`\t,^jq<.c(&2UGBd;VMi'x(*8S_p NKp'3XvgIv\r(\\T:\vd\t(DMc&V@c2@KghXSrv7\"_lM<$Vyl\n\rAMl86ZCz0 W@\\4CNcwNe}\f%Vs\n=2@Xwn*7EJm)$4]?M^T{-ATxg.1]3;IBhQze:Tv(>QChk]b\f-C|g%H~\t2H_to%Fwq2#W4)@Yxn\v2BOFTwsDjo\f3CWtm8)L`\b^S>_|O*@Im\f:#Au0kz:![;X2X\x004[L2Wv\n/6yJ\x00m?Wm's4T5'CN~\n>QLj3#,FI;4SQp8Mnq;1ZMi. ,MtY9 [whsF9Z_3\"Qws2*Twnc56Y*8S_p LYOl:P&4WSt$hz6[o!=TP<UA4d9\v%ZtkH{6;RFjzg\v2GTs`Kdk3\"ZE+F}o\x00);c0;:Y0#^Af\r>%It-`=&MyJKl?VLi9]N\rqgd~+&;dE&4WSt$OFjo>3@yd\b0JEpf95Y@{$*&Wn|\f|N+Rfd%@y3;x6VRS\r7X\bGf8Eq-:H_oK!,XA{2*TwI{X|)0;&JK`i\fS\t?ZGf,/GvVUvq/Fud(A@f8JQ}2&Sun{n8T\b:_|c'$Bs\\Hm7Thevk2XLi8#3.Qv.5YDere$O|g\v6[o!N_f\"c3x\n-\"9\"Eu\n$U;._}h3$YGn9k.WSaj\x00yo&'\t6WJ:%Fw`?2_qyh'yg\b'i\"+Mx<J[td\v)0^wsZJk=ZAz\b2O;1T{fF[<NGt\t(DMc+R`ic6TMiQR<I_to\vs! Ymb872OJay)Br~\r%h&4Ywt7!Gt\r$XCu8+A@y\n#2{7Y{:oP#~S\x00g k,_8JEmbRHc\b#*^z,t:UVqn\n@Al@P\t;\\Gt8![hg\bZyeI q+Onh3YhuTUvq<7T{\v<*K%JCb:#V|\n7_~l\x00=SLwYPt{\x00?ME@nN|e)Ymn93EHy;K_0-Yx\n7YBi^At3,\x007Srk]R{zF[99N@B,[uf;*I}1M'5V\\s%KNs$0[sbJA+\"ZE[>'Ncw.tZ?XO|v)x`\r5s2A\b?]@n1)Pfg:PXpaIf\b\t*Eap?\n]kwj2Y .I>KS [nuvc1Taal8SS6DGcdTMuu(%XGirz\b/ %Q|\t/F}Di\n'Pl\nb:!u8NO\"XEg;n\f+v*Xyb5AJd{ppm/@}i\b&ZGi9o>9UJur{m2-I1CFk\n<HS{sa -^Cq.:m<]qe4/J;\"Q}\tze>WH87X_%l=c1CLfi[Sal&Q,]O{fzg+6JDyKV $![uhTqw;Bw\b -UQzpk-B$XEk?#O`po9\"J}s(:SMe%]~e\x00.KwWze}\r/Jf&Is[ih1$UTFtX7y:IXhiEWxrGel\r0BVu\x00l?VMcA_0:%\\\rx#1ZPw)BEgb\x00=NC|c\r5GH<2^''+Rmaa>,Ip\x002H|\f5\\lB*[Wr?P@zk\fzp=\\js]q$\r{f\"|7.^y1Q\"H@s,C*6\f=mEE! +GH86Sx/; NoApe2(U;\b5Yb\v?SNs?Q}';,Swt#Oc1EMAJM-Sz8f\f#3Q\b\rqi|\r8UIxG7D\n&_qh!eU;pE5ZTu15L~P,r7)P{\t}D\b@-%WA82U%,Mp5Q@,S\r#O\rLi\tCz\f7(BYO\n$+AQ'\"8+(b5.+p7gSV'/Nc#Bh&Lu%Gb\t?-4X@m: \b!_?K[rwWr\r _qy7Rzm=SGxg^JbYkdsn\b=OFu`,?0NKaj!?Z\no?RI\v:XS5;^Scl:JWM=.HKn\x00=RB:JKy7 +K[~c2X\x00\nY},\"#Z<Iy\v8]Ds/o28`*yg&U|+v\n3909`(oJ,})(:_1*[Lu\x00+[rwYFgKI_6]<*Ke &Gyq08m98JOg%/3Ae\f<}/[+k~\f)Pv) \tcn4]of']rxaU<\\Kb\x00=NUgT?SNsCo4=dv6f\r.Qau0!,^wb.`=SHfN~\vKo$%\b6Sy\btu\\<2Wt+?\\JkEjcZCv5*W\f ]slyg($+]b\v=5GHz\"Pq=MYBl\rb1\\mr?K-Lb%^E*U`n8i#/Fw)FGn*xE0T[nbg[0;0MCph4g0,_%;\v>\"Gc.R~v#$*#EHiHw\b -UQ7\"TP}<Real/CK9XSfmxh\x00\r51p0U*{1V.v3Xh*zM^R`e\rHGuJ~;$a#9rA\t`>{GT#TXy!Dh8\"OF6/[n&;Z{f Ut?MB&Ch:7R<ZCp\"S}e0!JiQx\tM~ewYNev>!Ol;?^TuXG*/K>#Bh>_|i3>#Kx\n!1$+6[z\f+J\"Yq`917E@di8`,]R@<'IV0!Ma0+VJ>5Piy(:U]r\"MXhi81Fwf2HCr`77[B}\", Y`~\nzC3Cv\v\n+V)9ujVs,?K\\\f'.BGk+8a|\b\"-X~!-!XcL/VD{dDZ31Qjc\r#Of\x00#3Pbap%{l 9RYUd,c!H~rh7BK>3\\[&z\b\t2Ueq4%\v )L\x00?SBquj1Zwe ~1.XwuYkn2DP{k<HUfk46B:PAtwd?ZJfY Uv*L)\"EWyi4=4TKqOj?vF_f7EHg%+[rc?VOgV75\\}`&%Ap-0BK!\v[)#$OLz1)82U%,Mp5Q@,S\r#ON}0?KR`a=!Lm4(Q}}\x00*=o%Hz\r9X4|o)4X@\\./Lwc>rIh6#G:k9/[\x00R}g<Yk>#Qzh>_m?M^T{-CFk\n<HS{rX)?o}n%(G^>KG2/@xG&[~srS=_z`\r)nv\t$S()[hk6/\\V\v5Sbda6-_m~rHo\x000?Kv)FXyYuVK`r*%PLda*/oyw/?#Yxa6BIexa#.BR`mIi5 \n8YUg~ Rw81A\t=UDrZspVw0[Xkh3_jxegz2N>aP+{$I?~Y{:REw~m)\"3$O\\GB:'Ia*SgfEq<5R1:SRCq9\\nza\r,\x00?WBo8SS\r2[Me`,?-4Ux\n=)H%SBr(-CJ|\b_~n\r9VZ5*Dq7%F`>M^Y#f9\bF2}Sw'#,FI;$Evo>n32@I}\b/ZJy-?}h9KRb6T@{=s;NBG*5t&\\+o?k(/=HV\r9Xvj9\"I<JSq?O>[Dc1ZJt=ONr;O]Ndk]Qdh#>!M#KYrxoAJ!*DF8NAsxMC;BZA/L`}\rq+`)z<\t$#\\LO>Z}`1PMyyIKr\x00\v'(26Swb,\rP|d9,JM\r,Wxv:PGpPh\v=$b<)YN`C/F}FpRalf!)]zk|'VzuP?;IBhQ_zg8LOgve<[Me+a`9$BX90GB\vI[t~Cih4FRyh$![}n.^}d4]n\n,c&/La*%MB2+Ixqt{\f*[~.f9!n&<ICF[>1DCe9NKal\b-`)%1VF;+Dvb=\t[;k\r7Q;7X\b&#Ho+0^Q@uk8%\vPw+~\f Yq+'XGc?ZGf,/GvB\b^xeLR-c?q\f&)0Y|-L _sb73$CGcb ]~t7Vh|7&e./Kr\x00\t^)g3Ae\f<}.Jse<\\UrQZsr9c0Y|-L O@g9$Hw0<n?XC%O'SzM~h)5ZSu^3]Hd\x00,5Vy\t>(I&RCu).BK{@8WU68Y~eK`i\fTj%ka51\\jw.'XH4@A|\f'3)(Sp;'\t(S\r!\\hu9.^jB0Ek=ndv1*`g$>LEF|\t,o4$]\x00+0^sd\f\bD\b})]jC);T^q#L[ih;0Evi3IBua68TE|!-!Xc\t{H/Fwt9Q@wLvq\f&) YV66DGcdT_vz3.CP8%Kw1%\v#/Ni'GKr\r6/\nQ{7(QN*&%LM>5[Wr0'X\\\r=OJ96JK{6QMK2GSXs\v=(My\rvU-z?(BCd!Yp7ySO~\v0BOkS}t X<^kg'@a\tQ4EC&[5.<%@c!6YIx\v\"U\t;^c\"t \vC4W{j\t?K@#SJ\v]n\v5VZ =)Lm9%U/}@J\v\bc(&2UG:6SGNdh>m\f _whEeqys0!U5Pvc=S_?K\\&Ch/.DAlbk;NDPwi#1ZPw)GBo 4WNc\b%YD(w\n)_kZ2,_'E'.4;T\v5PLq10\x00h<)(e;V9+Tno\tZhc\x00p{j;/Jgt%8TL~2eie/^rk\b?X\bGf8Eq-:H_oL>WBb'YCdTe5v[zr\x00#b'6Sx/; No%Xlq5PRfE!P~!ZAE<HQwb,zj.^{qky<m<yFT1AEa\f-^Da{w\n h. 0_me`n\f)i5,]#Qzs\b\v!k)Gc8\f1CQtm_/r\x00\v'(3X\x00.O!^Le4<+_kal\f%1PM~0@X8\n_ow{f\t*XI1i+h*w1zL_f;\r^0aS\x00r/r$\rwf\n)It;+B~8,_o~r,83CJVg5\nXc<zCq7(B\n8YUg~i0:7R<H_?ZVdgI}yl/^&ciM_pzm_mt8J^}i\bd7.U{wYc\n?Kv\x006MYDR5\"QwUmh/;&L,Fey{\b&DuKCBo\t4CGc&JO|r<'72PDh~\v'Ue`d9'N~cq7i'\"@}<#Mu\b?[|r?Fggk-!VO!nu2+]{\f>\"C`\re'EFM-;Zoj&#_mhN+_~y45^e#QpBqZ-=E()r5eQT%5Y@a\x00\"]Mi$h\r!\\sn*r*'39X#M1Tzg\n1WS;TX<UA99\vkRK}h\r0FIg%=YOj\f9\"P}Ao\b<*3_jq/?GeyQ\"4L\f>YGf@ lL<H8D4P=\\&&#Hzgk* -C|\"@q\rMjwRo5iL}/}\x006W: Mof\v#n2@Aj\r=IR|sxH`\b5Vlc\tCkj\t>!E%Wr>0DGo\b<!Rw\x00\"6 Q}\f [F'C\\Mw;O@l?KDE7XT65VQj9c5TbkF|6_2?PWFt>!Qef\x001,=8\t<ZKd5$J~\r6]3&YplPbg+[ol;\x005CJ=MY3[z1W@k\\Cv5*1]ti[Py|DSDk\x00YxV>WTS|7 ]u.]Qshz2b\r()]xq7&Fr\b2 ww=bl` >QJ:d\r#&On\r\"Rg(1Ut\vsvAcl\x00&p\v2XLuG+\\AnE\\uw=YXY<RFsVdgdv6f7V6%Fu+Tuf3.7#N~\n/6f7693Zzk\b/[Jc-8#Of\fK{2.Ip\t$-^(FGjwU<MDJfG1\\wk6ZGB:'IaM,ZC<D!*@G97R$'On^}m3U]3~b/Jgt<'GWs(5St\t#m?M`2(<ZFt.#x*P8LC;KBzeIn0)YD(Wxk\t\f:'Db=&M->4[\r&!CFd*?`\t#,[ .\"[bK.IEzcESul\v=5|\n=o)YTea8TNaQ\f~2PC.t+@$Gc<\fO<V*e5I2<]ip_{f\n?X\v )LI&Xlo661o5$Ah\x00&Sx\n=\\rf5.U;7Rd`&_q~t8J[td\v\"Y@e\fDj4N<%Fi-.XyVBs\b9^R{\vpm8VJw)\t$Wp3WBoLq<RFs5j`mwtX)g%X|S!*CBzf3VEj\rkkkkkkkk:YXoS];TD}PDm`93T]=(\\Ed3-V8VC|\"j*\"q\b:7C]Hy\b?;,APhi.&#Yt`6Ymd\v +GH84AGt(.</[L<\rxn\vCw2q\n3%JI?|n.5r$K\t4>Q)(Qt9UD(W{j\t?K#Qzs\b\v!\x00|e\v'jo-CLeznkPRw3Zhqd\b|\nb.+AUgnz7_zg8LOgvuOa.@Tw>n:UK\n1RAm`A<nGc79WS~r;\"R\b\\Rw5.^w}dj=3\\P4Wxb.DE(P}(YKBFc>q\",YUq1Ew\f [zQ\rl,|9r7q8Qd/|] p1fW0pI`7ZA$6YQv&DMn!5VpaOY\x008OFwi>sd;/6%[~m\b<4Uye2[Saj\x00yw?^Pdg.=-DssH!PZo{b1.^]\t(Fzg\t2Y\f}l+'\"o6THu/},ZKd K@Cdo\x00J<2Wv3&L,AxRv+?W+Zq`H:l-4Q,-Oc##\t]-g.q=rK_yqXDmCj\bm/]B)P|c\v$H/~b3Z-`\t >ZMff[T{\t2*U;`O>vFI?^Vs-?PZM?MTu*>]IhD{5[W9\nv)\"'F|z6Zvc[&{/\f].{2Zo.r>{G'c*By:'CQzpIgb.@Tw>n\r=TCe\rCK\"+ZrG2HQu\"+ss;OJpX]1,C~nB`-m\n;7rU\tlO(8JEmym8#\v9XCg'&\\yb\f-C|gIX\v! Il*1]|SIx`*W:%Wef{\t(?:'Fx\f'V6%E|\r%k7N^6{,8#Kj!\\js6LMy)&KB`a+]ED%Pna_m~tM{*3+^)ZKte#EmdMs}w.'Qte\b>WHxw<RCg~.Fw.Uf|\t;= OjZa(Wr\r)t\x00\t?Kw,-.ygG5Y@{\n5Cd\b%[3.^kz\b8!Mh>\"Mis)<[Pb*Ib5 ^{]Dg5'Cm3_?WSoEGpBl~#+Dj'Ukd\r;\r51\\p9t\n\v&]_0<$A{4YyQt\t!&44]ql\vRzf7.TK.Ivx<RE~.i\v4VCC</JW;*I\v:RLih=NDw(-Jq8Y~e+Z&c/k\f8-Ju\x00=/o`\n,Scw2#$+X{mg\t:*KFwr([Qxo\n _{+FD`a4(Qc(qd=Og93\"ioOFf=ONr;T'}\x00*=o%Hz\r9X4+G~e\v'i4XGo\x00,Wn|r\x00\v'(3X\x00.O!^Le4<+^Dm~p/N]86Ws(1:]CbL=\r]1i[+{WvHt$z6u)&QO{f_/a+J8uA\fQ>\tMLo\v6VAyiW&\r&#Hk*7S;LSgd6YB,XId4?K6NK}!U} \"'Vmhy\n5Q|Bq\x00\t.Uf{:.Wh\f-Y@/Kv/(9<Yoj6H\\f!-GF{UJm-0Al\x00/;1@Iyh74()Ru:TE*^\t%*^wwDy*^{m=.^huGt5?^S=2[Z&g?-=Eeu\rM82J\n-CB}pi/&[V6JK9}4(S+Oj?YLkG|\tAacg -k6O_k)Ht<WIf|1%EWxkHW8\x00GbT<6Y\v! Il*1]|Po2!GcG6LI\tHbmk63VF~ M>p\x00x\v6/K3GUx+*^{mjxg7+wWel*1JX\x00&Gn9%sh?L]Tdkp*l5=<HU|\v)A|^qk5,@y,>QYN>LUv)=^HiGt*ZV8qm\b@f8J[td5 ^0Y2Vw\na8 Q~-^Ov5g<]@r!P<3\\[5(D{\f j$O!MY~ Rw;K_|j\vd3Zol\x00\r=I/Lztz<'\t&'N\n^.w%88\nr\x00\v'(3X\x00.O!k~I'D^lef5*Z\f\x00As9g/<#Do\n&4WUr<U@|gI,@\bp\f)CCg8%F|\n:b?RIc-n</Fvc~0dKYjE\t|Ou\b S\\L0u6:5/:*Ysd\r\v\n9l7\vv9)@d1X7#Nr\x00c\b$k1GBo 4WN}n\tGs'Rp|7&Dxe\v4_1 [rjR`a\n-]ir=7AL}b?O[\f1]|3UNuZ@m\v2AEa&\\yg=Q]B7&Dxe\v4_1>/V[9 2]Uz*@Aj\r=IR|s\\%_vm Myd=TI{@)[E`;O]HiLa?VF;4RGiXAw*a3$C}o4S~T<YLkk1!Xnk\bUv}El]?MEI3\b\rm:Q(:U]r\"HIr%1ZteKp\v.^j<t4#b'3\n3?P\x00.+Pw8VG)Vtm\b<42]Md wi\v$6Ok4%\\M3_RSkkv\n7$Kg#,FI;1Py.:!Ml@1WS5\r3U`)GJu\x00=/Qdr\n-]tr7.JOi;KDt{Ma8YMO]Ndk]Qdh#>!M#KYrxoAR$]~t=Yq.Gon\v2BO[,\f|\b%5VGpPKv\f!JKQ@q\n$1IU|\v?V^{)98VC.+Pw8VG)FGn>]@l4\v*Blq,I}\rKDhx1G6\rPMkG7Vk+Nqe>!e\x00,Qdj+Vkx8#!JZo\n'4[|g3BDA=[f\vi{1c\f)(^{p6)Gs\t5!vx<ama#?PI;g22_Z,)CJa0831\\yP3-Eo]X$\rLwOicq7i'\"@}<#Mu\b?[|r?Fggk-!VO!dswn;7~n\b;k?}H\rX|#n\"Np=y1L2*FCy295)-;,Sw?ME4UahGs7P38QTAw?^Pdg.->9%,^q~i4)[Bh^sj;c0Y|-L!WF~,1GN`t[@n#WBbi`5ZW~t2\"[w)FGn*s!!`+P55GHbeWU|\x002FEa|H)Gs<'Tn{qBxr8Mt\x00\t?Kw,-\n MHfc\fM-7O_~n\n7Sm.o*cN}F[e4bCW|E\f@e7}st3k'3KYxs\r>47Vth3P}/=.DK=3V{,8#KjBy\x007YQ7lh% h1:7RnJ3GFZ?LBM\fJQ:ElVz\b/  %YQ`y\t2hi\v&:YxW%%ew5!]sh97s+F'd!MH=<g_)fO\vVBA\b5=R-8HI}&Ff(#R@W;\"]B\f\x009@^qjZn:xs\t5w,/G~n\t|\t8IYhl\v=\\my4%Kt0(ib~;.Qap\"^w\v:RCgn=T\\Ea91V$-Nq6PA/Bsi:'\tqz?P\\E@$_vf\vJui%hs\vXR^{p\t;0S6!_ozpUIp1Uew5g\f-Pbv1 \f3_vm/a+>z\r0^m.R!yR~s.+`r)92gNQ\b5=R()Ru:TE+Pzk>J(IgGt0wb%Dr}d(Znm843m1)Pq[RfN+_o+ALi0a\r6)E)x6/Q%]7^Rkya4*3Rr\fF_sn#+Nu9KDna[#;\n3?P\x00;,]Fdwn*7EGvJ{:*FO{zRYta>$Kf|0]3=p\\s;-Tr5<Jaq.+\n3?P\x00.+Pw8VG)Vtm\b<4!Ix19\rd*+YdZ\v-Tbc\f`\rWUdo)iH8NOv\\46YQmaLw.Jse<\\UrQZsr9c0Y|-L O@g9$Hw0<n?XC%UJs:U[o}`\v?`>LUv)=^HiFrc8INbk/`1.XwuVXyk\x00\t,t;\rCo\x00?[Pbe\t4>c_m!uUo7&WmxNbqGs,Cz!l?Q^IfE*g/@pxe\v'.^xkm%(XxC+Jb\r!tg\rTbx\x009w5$E}\t;`/+=l\r9Xvj9\"I<VCg[ih9KNcp?wn8`,_o`\t?K:RNk\vKdClx5<PHcsm$]y!b\f9/DGOnh5Q~eg&|=q@qi\t<]Up~\t&<]sh\v<$\bm@b#k\f=5p\tC!Ed;\f)SfoBo`J$-Nq6PA/Lz<)O`XIp5i>#Bt\x00\v#R;)Lxe;IDfrUHd3,@\v0^{`\r3\\Z4;TSe7JXs@kz\v?ZWdU\b$\\naYud\x00NB{(*Wv\n\b5l\n8/_\\'Rr~7)St$of%NCg:+Hk:RL=S@xkx=O]Nb\"MwWcrty[u|yp\f)W~n\v7D/c>W73T/&JOc Dh*%PFY9 [D\n7N\\sl\\qNu$Ewa1H@Eq\r?6<S)<PO{v5k:0W\tMyb\f{p\t;0S5hq.Oc\b\v3yO{'(E@fo\x00091Ut|,m.|9*[Lu\x00Yvx\r/ J]=$Eh.-YxTKg+G\tF`7Vlitm\b<4gn9$Ja\":e|\f\r#\\$amQLF~.c(+@UpmrE1as^Bw0 >,Hu(%Pt|)8UGt-V}M6--o9}EU%u +GH84AGt(.</[L<\rxn\vCw2q\b:7Ci\f:!M>\"Hi h\"d\n=5<JWeh\b ]3Rm}a/j7c^?[Bpgl\b1ED+Wr+450]Sv:LXCk\nb\t%{j8]Du2/Lfe0^ro:!>-LiG{fHz<#Sgd3\b-[Bw(%EQ6+Cr\f)_xcDsn6]nu%]2%XCd<'Kv/a&b#qGEze;^Dm:'S4AI6\x00Bf3@O\t0x?\\]D7G?Kcj=q\v4Ra`*7E\t,\\R}s'5V\\s%I\\po9U\v#1ZPw)bm,~&)[PsUh8%Kp=POb;1=QY4$]iejOg\n6Sim3wbr'!\\k|vM<Sgb HQkbGD'Vmi5*Du\r(\\GbA|\f\r#n81FIn*<^W\t!,\\Nop@3?jgb)I]xl\n#Uz\x00+_;l1K_vg Xnapxe9 ^>{{\v84]o&Hg<NAi~.\\Ef\t9MNxws\f&KNO,Qzq\rTda.Gt\n74_Vl'wu \\t\b+]Om6#i096]oA|RI\n7EGo#\x00i2R^~^}`\"_{#Tsw6&Fa[(n=-Bh0GN|Hi\"-TU9KNdq\vy\r*1GT?Z#D5>)S5$Uz-(\\T9\"K}r9$T}Lf%$Pi}cg7xU\r\r?ZWgh28!UtVdm$&St!R[MS:RKy\"\"@Kgsrw$ -Chg\b's3c&+Ytv1+\\Ls c*MD`\t=\\3/Jv\f\fg5KNs$0[sbJaj\rCri5\\mt$^}i\b&ZGi9o04\v%JXRgd7(XW7ELm\"6Uq`M{*3@E{ g2#Oc)P5 _~g?ZHu,c6'K\n5\\A\t.:l\f+q3J{5,@{f;-Eyd\x00-XNzK%JXAo\f7-4E@hiL^qyn^lu9I]~h\tg\r7V{\x00,~?\\Aj#\bf;/Jze\fEv\b96]8r34]neh0JFyd:HC|p*?/ J](YJsb\r% Xrkyl\n7YQpvAny+Wxs7CN>HKW2^kt5?ZVda0I<0]ip8%7J0,DA{8_qn96#Ym\r\b<!,]L [L}f14Qws!!o\x008UCb6LEzj#*@qu\f@te\v7P{p-4E1ON}LX9WCL7D^ka`@~2)t\x00\t?K\t4@Ev>(Ig;Q=iXg405!Dzpk:TKa(Qy`&!R96Yke\f7g&w!\b5=R26[O!nq2tp\tS|v<q4fOk/'5V\\s%NYkn92Gxg\t1KDsg86ZCz#+'Va}\v}O*@_p|k(Ase=5\\qc2*Tw)SewWk!*YD+FFbx\t=Yt%WB{.DEgJde)ZVba70^wh1 Nb1*Q4/Andv\b:+Dt{6WcjAx)8UG!lZ#a)t)}?lF4mNq+C5Ply9.BKn*3GN^z3XGb\x004u=THsJ%uji@x\t6&\n!X}dK|l]y`?O_c3gNQ<_to,@K`u*)CJm08YSP9(BCq->.]b\v>0Qel\f<YK\n\"U^N.H{q7%,_jq\n!\t=DFC+M~rR{k'Jq\r4/Jxd6Sh{o)^C'XTq{,-A(y\"k#IX&yCQa|e)Ymn950l2(QrZO`\t%PR+C$-n1aUP!1]|.Aqm\b d%Pwb.n.#75\\>[N`t\r[9ML#]@qQ8b);,F.Oy`JkKI,Mz?WFf%0IY@`\b9JDq*'uIchz2b\r()]xq7&Fr\b2 ww=bl` >QJ:jI!PGi \\Fi:0W\t'\"On\x007_~.M}%Mqc\b-J]iy:NKw2>WFd6KN~\n'._qQvk\r(\\TY4Qt$%U@^?LY$Xua\n)]q\n7Vh|7&9(\\Ek+8\t86BEwR9M:#WvUAl\f%\"*#B\tSa`\t,^jq<07i8'O`\f^no\b3\x00<6_l{1,b?`>LUv)=^HiFrc8INbk/`1.XwuVXyk\x00\t,t:\vY?mt4)[+ADk3r/.)(:_;._it]mdDdk,Qc8%IxGab\b#&Dq(?M5\\ro+V{C8XpmMynPcf|\f\r?ZJf&Ef:*Wyq@\r$Su}\v.+P~1*Q}$ci&'\n$6Swh3zr'~e\t4Um~t'3]o`\nO\n1LOcUYkdsY8$Z\foj=S_vi&\x009IQr?V(xTvFz\"c3N(o=rFSWc{AKd}vVQ.~8iDf!~x9-y._s5\\6_zw099[kj?S!H~rh7BK>3\\[&z\b\t2Ueq4%\v )L\x00?SBqu`?L[y\f`3(FywWel\r0BVu\x00m:JS`e24@4VOjyf=XLd[\n\"LYje;&%&A\vSKYrxoAhfouZ(1EPi]/ J]N8Yui8#N0Um}=YRam9h\x00:LCuz\bji\b\"6_p`\\zpp97@O}e&@q1(^X\b%6PEa*Ma&K`)u|\f\r.\\yFw9I^Rs?~c\x00#Xmjo4+O\"^kgsum0,IcG93Zpau7*DK}d\b h/.DA%b>\vw%B7yZ%w%\bS$D{tu)%5}'B~\rhi/*GW7*UrLl-\"R?PB~(ZSg4\tZf5Wh'pK\v[#L^qyn^re}q\f&)31Pvc-*@KzN~\v2j/VD{dDO\n6{f=QF,<!Qbl/7XH`F7ZAZPu=uZ/v3i$~*v[j37^Am@H\t\"4[Mba`/iPX:}?YM:7The2XB{XEi%V_De)\"PDq\v\b&Wyb\t;7X\b&#Ho+0^Q`\r(^X(^ka`\t&-Nq 8Y%3^Ba\r,@ro3T\\Ew$/C~c>/A~h\t'P{kl~~\f6Yi}\b)4VOjxV3HAh`gys6:WFf<sn?\\Q3$VRss\vL}nyv\f+0BY3te8b/Fv&Ehx\t!i\v.7ELo:.&Wy%Hs\v#M1Tnm&2SL| Ol 8NKwK]Rq\x00)YKfz/&WIv/Hs73rj#u\v!Kr\rTda.w\f)U}`/@yw+T5ZyrGc>WBhPdkSp\v'\"Bn.J}b4#Em]NgT*+E7uO2Cv=XPgX9PU\t:7R8\"Ke(5&;}m=IdT/% RVw\f/c&\\}PNk -->9Tjo\f3CWtm\v*b5$J~\r6]3(As\r\f<]sn|\v0Wgs6'\b<!Wv\v\b<)Ym\"_wf8%Ktpm8VJw),=8\x00C\t^?VDq}-A9MB<se!<Rb*y`?lfg>k\n\"]Db5?K]|!fG?LBM\fvl](8 QmdLx\f5k5FHl\\eyd5QDc]Ndk+\\T}&^lq;hi5EQzj\x004&Gdfo/+H#qHx(N=(Fs10b5KDhi5PEaE5Pe)Lo /Fvr-4XP}\f\rqza\v>4]q'_k~lBnww/a.1Wr)#/\r;el\f&/Jc.-<5A]rbWOj}wc\n>U/NdeHfg \\Da*%MB28YBe!*Du[@j>.Z\fV}.WrRs\vpGf31\x00S$o!Dcuc\x004<MEL`Ce*j=6,#.#&\b8JEmbOfFr,&56)1+GsBe=\bDg.SRY.\\ys\"Uynp4O[F%XQke&)JXs@nk7GSxi82ULm\"6Uq`5X|T;(K}L`\b')TzA*YQp\x00\r>/AI\b?vf3q}\t5'(@M<#Wt H\tyNY/ J]=$Eh.-YxTKg+G\twj-,ZKd+Cr\f)_xcET&WU`Q=\\rf5.U%c)FMo37(#O@0>[@g#(FwYH}c\n ]3we\x00>[l2O\\Ad?[u(%Tt^;%L|r3,3@%Hd>,Ius\b2[un#&Zlu].[Qdr\n#I_zg1XnoBxe2[#,KJx%Uaj59<8 Mn\v!k(D8JOl#7TrcLx+2GDx!f3\"H|(S4>IZBk\b:-C\f&1RJs\"%K*#BYIl\x00, Y`fn:#C)~s$!AUn*{\b,My`Ok:OH;0Y\\#y\n7Vh|7&%&A;,AFi-.XyWJu0l; Gw\b&W8,Qgf8LYi}ROg4(U{d`\r\"'Fx\f'V7#Din!5VpaO|m\bPHa;y\x006Si BM|Nu\r(GNWIil8QO+=Q[~a<}n-%7BO{f\fHz)=Xi\b+'F|pn\v1@M<M^Y$t\n,Scw2#\r\"+J9Q@wwu-!.^mtVdm1AUvn;MPaf33G\b5ULkzg\v:YO{-BKj6q_$Qz\b1d/'XB*Dws[h{s\f 0]y\n[Gz\x00<4QkN>JWeo3^D$B$-Br*HyuUrZW-qTe'\n\f0;O]Hd#.>ZGa8!M#~TM'2YR`(\\uh34?KN\\O{l\\Rw;K_|j\ve0!TxpVe49Ndejf3Z1:H_to^P`l6Ymd\v|zWWef\f9HT~jEe5-3Txu7Y\rm_*a%g2\t]=\fG^Tu\f8!GcKYrxoAoj6H\\f5,K}u[q6)Tr()BT{m}\b?,c\vm\v!7XTP/Kv;1P{&x\v$ek0/Nda\"qD'`\t;7Vqo\n&f\v&;O-T6Wy%@f6-Co/@l0Y}Sjj=n|o\f|r4[k\n+4)W~l\t2#YtjLb\b.|e#.CW\r\"]y`\x00+AQ\t(^rY-,Mx/]S#1ZPw)BEgb\x00=NC|c\r5GH<2^''+Rmaa?M^Wdo(D~H!5T#>\"M}SB`m>4[Q5\\m1_pz\"Fc\r8TMi_gh>%@d9%2*DIe:b\r!$Ty\r9+9!7)AAK7~OHyjug(~&>L}0-Jq\v6h!uU|LyrI3|FNOc8#[\vVk/&VA^7AH`>*;VMb\tk6)G$'CD48MCx\n$ +GH8o\x001>%v/9 XN\v\"1\\meF9\rO\n@-E g'\vR\x00msX/~;tYN'dCje\f$![t\vcw9^E;,-EBy`0\"Ol('XH@?Zg<]qf#Sco;Zhyv,=5ZI1TdzNU>A`RIY0hIc4?S<]@r!P<3\\[5(_{j8VGk:*U|PDqtx>KGStd;TDl~{\t(?\b*:_mx\"N]?M^T{-r\t,@hV:#D$kn\v*@q{fiOc,P%KH#Ziu1.Xy\t4XCn]oj8(GB!_vm=jMT5pFu)Pm=$Eh.-YxT[ts-Xwf*GB`>4W\f ]slyl\x000!_zL)]mm2.Oc/'^S`=~l0T\\1I{M]/ J]BkK@CF9I7#OJ?}BaQ>,q4fOk/&)AF64]~a%&@q_|n2R^0\rc->)MH$-CoF6 C|e$HIp! ]Ope\f+\\T}+Sf\t:(Ut;/Cgbb;%@|eml3Sgu\f7^F^l\n&2CP~1*Q\v0Wgs6'\t&'N?QNxww?Z\n?^Ig\f6Yi}\b)$%@!On\t%&@q1,@{fF~?LUv)=^HiDce2a.$0WI\x005GB}6MIxD&3Xj{+hx>4Q}]rn=^T4Vc_xiI,]{^S=|TRgd!YHdb\v?lbc\r`,)CSaliO{k.q%\rbp8h&#Gr= Lt\t<Z}q<Ghfj* W@ lm8[Wcj/Cra#zd)BBi8Rno/*Fy7G@|a \n>VC+Cr5Q@i\br\x008OJgs[o`^_}`.S{2$]q'yj\x007.^jw\n-]idt.HX}1]=I^\x00%]tu\rWbq^q+ADa\b<4Qkh\"r@}jx>2F_@\n;Opyl6Kv\v!Aqh)T{\\\f?Klgt\x00T[ki@ith\x00\t1l\n+_2!L]U8 A$YUa`62'C\r,IpUCcf4Ws\n5Y8!Dv\t%T;1Pvi2<JFI{X/a2m\v=$Hq\nrn#$T=R@|eF\b5=XAq:73T*/Ls4RC-Rxi\f HVw\bJk\x00.]~8+Ex\vhk$K\n\fy$XY[7(Urw@Oic3+\x00<4^>ZMff/.Tq\\\ngUb(o9q;rP~N}WT1|!c \vR\x00k#B=j)ZVs+'eW/`\b\t2Ueq4%\b !Zlc9O`?\\VU1 L~xr7.T4GSz\b{,Z`\v&&Rsmwn;7el\r%]Ut\x00)EzjXvv?\b&'Dc](b+T#e,C.}'xgYNt+m\r^0_vf=fcWj5kDp\b;0_q%H\"\x00Q,bZ(y4B0\\2jZ4|U3?ZVR5*YLkxl;KYtupf7,Wybi&<UI?WSvdZVoyQ+>3GBh\"'Tu|\f6m;IBh\f;/[J|\rjzv2)Bp=5AEp1 S,j:y\n#VXta3U]|\f\tuVzw7t-V}'YQ|2R_=Gh ]B\v0Wgs6'xe<[Me-w>I\n`Q1t)V?qJg#n#;MTdz>#Kj'[JxyVuTD}\t\n:o*]@fK|l]y`?=l: A~c\v*@ta0[ ,Mt+Q`~\n\"k3}nXOh4(S\\yg>WSrkA@i\f>JQ}sc446LXOa9P2b*}!wXi~e#\"BO};'_*'3TGR.</]0A_~m5JK[~U'+_\fbm4<YSW81S{)9 Vs*Bj\veL\rE0hI\b9VAe`<ZW{o7RyoWIyh=++{K[ib\bq&Xlo66Sik9 Ls@~\f:OYxn\v0B:1UQpr;]h?},=-XVs4FOyd?$_q*w0{Mb_c'KKm;WRnkS;UF8\\}\t{9/p&;&Ztilb`,M~h+D~B;MTd(Kg1,].EW7Ux6+Cr\f5Y(Y=PC`u\f7 D\b!U(pd9&@\r\\wi'.R~N\t(a\b0:#{vi[Q|\vbw.:+Dt(No4!MK[c3@IyhnMrEF9Z-R9\f^%&\\}PIl6$Ij +GH86Sx/; NoA~l0T\\2wjLv:%Qpmz\b/  %YCe\fUlb]Ndk8jOz\t<Q\x008IEQvf[Kd/]=.^{Vs\b\v'ag$$!Jxei>4F_?MTgr h\"d4RGc\f)U;u8NO\"XEg;n\f+v*Xyb5AJd{ppo>HUf&Ux?L !Jm)2\\}RFw\f=\"VLq<RFs5&F`mOl=7Vk%JCb.y')\\p|\t=KAQ.FOl:+GN2^Wl;oO:tX\x00uE\tq@\v&Swk\x00;^Ek>_qj8} KGC>\fD <L~!,]UO+sHz?JYlw,:+G9-YLbT\\ee`sX?Y@B&+_O$+~y9KY'B@le9I]~h\tvz'$?LBGi\nqDj7n\r\"7XTqf?]o`2O\\@e>X/n\"Ic.qd=Ol#7B^{~\v0BOkSr9@0A]=ZKg'?Y<Mi7^NZ=\\r*_qh\n?\\Vsq?\x00x\v6/K3GUx+*^{m/q:\nU&k>T?LFSih7YA|o?P[SC@+Q`~\nb\t;,0 \r,\\Kq\r\v^{A-o-)_ze<js\x00\r{'.JO9KDnaSL}n;&&4WSthi! _zw\n!I\"oCl_'a}cz#^Gf\v2\ngj3Ib=5GN~L`\b'd)]dT4+P}n:-C\r:'D~SDtm3Vi|\"qf3?\v1`kG\"f3x*S4XGo\x00,};T^j}l?YQL?Vdg\"Ga.+Zrz=O]Nb\"KeYi{; RCe0/[JcSlc\n&#Y~a,W{M#MP~k:NOb0H_?K\\%[~c4@Kczg:'Rhu[{KiTn7SJxi:d(RSVuu!&}Saw!3FNh+Nj_,7Ez\r(QaD!VQ;uM\b#OGQ%,]Q~nk:*Weh;'%P(_om(^RO`+G\n6_qi4/}:HIuU}-q>LUt#s00Q}c.vSY|?(_~d-IpwI,c+~E.r1cWVF+En_6Sx/; NoB}\b?P9HFRugGXDb4N-^UyeEkv=.$6_qj;*IuKN-V#\t*XI\x00-^Cf2[u}\x009PCg".codePointAt(L+ +B)^c)&n[2],A+=String.fromCodePoint(G),c+=G;return h=A}),(N+2&31)<N&&(N-7^29)>=N&&(u=l[27](q[0],function(B,G,c){B.subscribe(new zk((c=e,G),function(A){++c<=C&&(G.next(A),C<=c&&G.complete())}))})),N>>2<18&&(N>>2&15)>=9)&&(D=[32,"k",null],y[22](59,Q,Q[q[2]],"g",function(){return P[15](28,Q,!0)}),y[22](25,Q,Q[q[2]],"h",function(B){B=["i",10,"L6"],Q[B[0]][B[0]][B[2]](W[39](B[1],Q.B))}),y[22](36,Q,Q[q[2]],"i",function(){return Q.Mm()}),y[22](35,Q,Q[q[2]],D[1],function(){return W[17](41,2,Ap,Q)}),y[22](41, +Q,Q[q[2]],"l",function(B){((B=[26,"i",15],P)[B[2]](B[0],Q,!1),Q[B[1]])[B[1]].XG()}),t=B0.M().get(),T[42](32,h,t)||y[22](59,Q,Q[q[2]],"n",function(){return W[17](42,2,cz,Q)}),T[42](64,D[0],t)||y[22](55,Q,Q[q[2]],"m",function(){return W[17](11,2,GS,Q)}),(O=P[39](12,q[1],t))!=D[2]&&O&&y[22](25,Q,Q[q[2]],"o",function(){return W[17](43,2,yL,Q)}),(m=T[42](16,L,t))!=D[2]&&m&&y[22](43,Q,Q[q[2]],e,function(){return W[17](11,2,id,Q)}),y[22](61,Q,Q[q[2]],"j",function(B){return l[14](8,function(G,c,A){if(l[43](43, +C,(A=[30,22,"Nz"],G),rY)!=null)Q[A[2]]();else(c=T[A[1]](3,1,G,rY))&&H[15](A[0],Q,c),W[8](65,!1,2,Q.B.i,G)},new KC(Q[B=["i","fu","B"],B[0]][B[1]](),v[23](4,Q[B[2]][B[0]])),Q)}),I[7](1,Q[q[2]],void 0,"r",Q,Q.C8),I[7](2,Q[q[2]],void 0,"t",Q,Q.IG),I[7](32,Q[q[2]],void 0,"s",Q,Q.iY)),u},function(N,C,e,L,h,Q,m,O,t){if((N-(O=[null,"i","B"],(N|5)>>3==1&&p.call(this,C),4)&15)==2)a:{if([(L=C.outerHTML.toLowerCase(),vi),nC].some(function(D){return L.includes(D)})){t=!1;break a}t=(e=[IG,RG,Fy,ld,Tw],[Fy,Zy].includes(C.autocomplete)|| +e.some(function(D){return L.includes(D)})?!0:!1)}return(N+((N&106)==N&&(Q=[!0,2,"-"],h.h=Date.now(),oG=h.kU,h[O[2]]=v[16](10,h[O[1]])?new Pi(h.kU,h.Y,I[6](33,h[O[1]],s6)):new fC(h.kU,h.Y),h[O[2]].V=T[12](53,9,h.Mz),window[Bh][kY()]?h[O[2]].I(I[32](9,Q[0],"en",h),T[3](5,Q[2],h.id),C):(h.G=K[42](32,1,0,L,h),h.G.catch(l[2].bind(O[0],56)),L===1&&window[Bh][Xy()]&&window[Bh][Xy()].includes(SY)&&v[16](10,h[O[1]])&&P[30](10,Q[1],h),v[16](74,h[O[1]])&&h.Mz!=h.kU&&(m=function(){return y[46](12,0,h.Mz,C)}, +h.J=new YU(h.Mz,function(D,q){(((q=["Xa",46,"V"],D).preventDefault(),y)[q[1]](13,0,h.Mz,e),h[q[2]](h[q[0]].bind(h,h5))).then(m,m)}),m()))),5)&78)<N&&(N-8^12)>=N&&p.call(this,C),t},function(N,C,e,L,h,Q,m,O,t,D,q,u){return(N+2&(u=[32,26,1],(N+9&20)>=N&&(N+4^u[1])<N&&(D=[2147483648,32,16],L&D[0]?(I[28](u[0])?h=C+(BigInt(L|0)<<BigInt(D[u[2]])|BigInt(e>>>0)):(O=P[4](11,P[9](8,u[2],L,e)),t=O.next().value,m=O.next().value,h="-"+K[20](17,D[2],t,m)),Q=h):Q=K[20](24,D[2],e,L),q=Q),44))>=N&&N+5>>u[2]<N&&p.call(this, +C),q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z){if(r=[3,2,15],(N&r[2])==N){for((((m=((q=(L=(h=h===(D=[1,!0,0],void 0)?f[7].bind(null,64):h,L===void 0)?f[7].bind(null,65):L,Wi).call(this)||this,q).Nd=C[Rw]|D[r[1]],D)[r[1]],q).KD=e,q).Zs=L,q).Wn=q.KD?S[6].bind(null,11):h;m<C.length;m++)Q=C[m],O=L(Q[D[r[1]]],!1,D[1]),t=Q[D[0]],e?t===void 0&&(t=null):t=h(Q[D[0]],!1,D[1],void 0,void 0,q.Nd),Wi.prototype.set.call(q,O,t);z=q}if((N&91)==((N|80)==N&&(B=[4,1789,452],u=y[41](8,c7.M(),7), +t=P[4](11,u),J=t.next().value,c=t.next().value,X=t.next().value,O=t.next().value,G=t.next().value,R=t.next().value,A=t.next().value,m=T[39](4,1),Z=T[39](6,r[1]),Y=T[39](7,8),D=T[39](8,6),q=T[39](8,9),n=T[39](r[0],7),E=T[39](9,11),Q=I[21](71),k=[y[r[2]](72,B[r[1]],X),v[31](75,X,X),y[r[2]](70,1449,J),y[r[2]](45,L,c),ii(O,X,J,c),y[r[2]](44,e,A),P[37](81,A,O,A),y[r[2]](70,1719,J),y[r[2]](77,1502,c),I[26](r[1],A,J,W[0](6,c)),y[r[2]](70,181,G),P[37](80,G,X,G),y[r[2]](77,255,J),ii(c,G,J,O),y[r[2]](43,1522, +R),P[37](86,R,O,R),y[36](r[1],X),y[36](5,A),y[r[2]](74,271,m),P[37](80,m,R,m),y[r[2]](70,B[1],J),P[37](82,J,m,m),y[r[2]](74,1409,Z),P[37](81,Z,R,Z),y[r[2]](70,C,J),P[37](83,J,Z,Z),y[r[2]](70,362,T[39](4,r[0])),y[r[2]](76,1518,Y),y[r[2]](43,265,c),P[37](80,c,R,c),P[37](81,Y,c,c),y[r[2]](43,1372,J),P[37](86,J,c,D),y[r[2]](70,578,q),y[r[2]](43,265,c),P[37](82,c,R,c),P[37](84,Y,c,c),y[r[2]](45,884,J),P[37](81,J,c,c),ii(T[39](r[0],B[0]),D,q,c),y[r[2]](73,105,T[39](5,5)),y[r[2]](71,999,c),P[22](78,c,W[0](17, +c),""),y[r[2]](72,h,J),P[37](86,J,c,n),ii(n,n,q,c),y[r[2]](74,766,T[39](r[0],10)),y[r[2]](73,1585,c),P[37](85,c,R,c),y[r[2]](45,1501,J),y[36](1,E),T[23](28,7,9,J,c,E,Q),Q,y[r[2]](76,1316,J),ii(c,G,J,O),y[36](5,G),y[36](6,O),y[36](r[1],R),y[36](r[1],J),y[36](5,c)],(F=c7.M()).i.apply(F,T[5](39,u)),z=k),N)){if(typeof C!=="function")throw Error("Fn must not be null and must be a function");z=Zf.setTimeout(function(){C()},e)}if((N+6^16)>=N&&(N-6^10)<N&&L.j)for(h in t=e,m=L.j,m.i){for(Q=(O=m.i[h],e);Q< +O.length;Q++)++t,l[38](r[1],C,O[Q]);m.B--,delete m.i[h]}return(N&121)==N&&p.call(this,C),z},function(N,C,e,L,h,Q,m,O){return((((N+4>>4<(O=[6,1,0],3)&&(N-O[1]&15)>=14&&(this.o=e,this.B=Q,this.K=h,this.G=C,this.i=L),N-O[0]<<O[1]<N&&(N-4|53)>=N)&&p.call(this,C,O[2],Hi.yl),N)+8&7)==2&&((h=C(L||JA,void 0))&&h.G&&e?h.G(e):(Q=U[40](17,null,h),e.innerHTML=W[36](O[0],"",Q))),N)-O[1]>>3==2&&(C.Y||(C.Y=new TN(C)),m=C.Y),m},function(N,C,e,L,h,Q,m,O,t){if((t=[0,!1,44],(N-9|39)<N)&&(N+4&41)>=N){if(Q=H[2](24,C), +h=kU,Q!==""){e=(L=P[4](12,Q.split(".")),L.next());try{for(;!e.done&&h!=null;e=L.next())h=h[e.value]}finally{e&&!e.done&&(m=L.return)&&m.call(L)}}U[29](69,h,C)}return(N&t[2])==((N>>1&3)==1&&(O=C===ri?2:4),N)&&(this.o=t[0],this.i=t[0],this.B=null,this.K=t[1],this.G=t[0],this.init(C,e,L,h)),O},function(N,C,e,L,h,Q,m,O,t,D,q,u){if((N+3&(q=["i",21,11],7))==2){if(e.size!=e[q[0]].length){for(D=m=0;m<e[q[0]].length;)Q=e[q[0]][m],U[22](32,Q,e.B)&&(e[q[0]][D++]=Q),m++;e[q[0]].length=D}if(e.size!=e[q[0]].length){for(h= +(L=0,t={},0);L<e[q[0]].length;)O=e[q[0]][L],U[22](24,O,t)||(e[q[0]][h++]=O,t[O]=C),L++;e[q[0]].length=h}}return((N-5&7)==1&&(L=f[18](60,e),delete pC[L],f[36](4,C,pC)&&sV&&sV.HL()),(N^37)>=q[2]&&N<<1<q[1])&&(u=(L=P[48](q[1],MP,e))&&L.length!==0?L[C]:e.documentElement),u},function(N,C,e,L){return(N^11)&3||(L=P8("<center>Your browser doesn't support audio. Please update or upgrade your browser.</center>")),(N&57)==N&&(L=C===e),L},function(N,C,e,L,h,Q,m,O,t){if(O=[0,1,6],!(N>>O[1]&13))a:try{t=(L=e&&e.activeElement)&& +L.nodeName?L:null;break a}catch(D){t=C;break a}if((((N+8&13||(L=[3884,1,0],t=U[28](48,128,L[O[1]],gm().slice(U[4](10,L[O[0]])[e],U[4](10,6005)[e+L[O[1]]]),U[4](34,693)+v[12](3,L[2],function(){return gm().slice(0,U[4](10,C)[e])},bH))),N)|5)&15)>=3&&N-O[2]<4)a:{if(!(m=U[42]((L=e===void 0?0:e,64)),C)){t=L;break a}for(Q=O[0];Q<C.length;Q++)h=m.call(C,Q),L=(L<<5)-L+h,L&=L;t=L}return N-O[2]>>3==2&&p.call(this,C,8),(N^64)>>3==O[1]&&p.call(this,C,O[0],bw.yl),t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if((N>> +2&15)>=(c=[0,1,54],6)&&(N+5&16)<12)a:{if(Q==h){G=Q;break a}if(typeof Q==="bigint"){oH(Q)?q=Number(Q):(t=sR(L,Q),q=oH(t)?Number(t):String(t)),G=q;break a}if(!n2){G=Q;break a}if(T[49](38,Q,C)){if(typeof Q==="number"){G=S[31](55,e,C,Q);break a}G=(Jp?(T[49](45,Q,C),u=oE(Number(Q)),P0(u)?O=u:(D=l[24](42,c[0],C,Q),m=Number(D),O=P0(m)?m:D)):O=l[24](46,c[0],C,Q),O);break a}}return((N-6|((N>>2&11)>=c[0]&&N<<c[1]<20&&(L==e?h=L:(Q=L.i||C,h=typeof Q==="string"?Q:new Uint8Array(Q)),G=h),13))>=N&&(N+c[1]&15)<N&& +(h=[null,278,36],L=L===void 0?null:L,D=T[14](64,21,e,W[c[0]](6,C)),Q=U[26](9,e,W[c[0]](2,e),W[c[0]](22,341)),m=f[38](15,W[c[0]](3,e),e,W[c[0]](7,438)),u=W[c[0]](19,h[c[1]]),B=P[18](57,W[39](4,S[32](68,new b4,h[2]),e),[y[38](48,u),W[c[0]](6,e)]),t=[D,Q,m,B],L!=h[c[0]]&&(q=I[21](71),O=I[21](84),t=[T[30](c[2],q,W[c[0]](23,C),W[c[0]](21,c[0]))].concat(t,[T[30](c[2],O,c[1],c[1]),q,U[c[0]](88,e,L),O])),G=t),N|16)==N&&(v[22](68,C,e),G=e),G},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return(N<<1&3)>=((((u=[2,6, +22],N)|48)==N&&O.info(function(){return"XMLHTTP RESP ("+h+") [ attempt "+Q+L+m+e+q+e+D+C+t}),N+u[1]^u[2])>=N&&N+u[1]>>u[0]<N&&p.call(this,C,0,W9.yl),0)&&(N<<u[0]&7)<3&&(L=new wu(function(G,c){C=(e=c,G)}),B=new E6(C,e,L)),B},function(N,C,e,L,h,Q,m,O,t,D,q,u){return N-8>>(((q=[!0,21,60],N-6)^27)<N&&(N+7&63)>=N&&(u=v[12](70,C,e)),3)||(O=[0,!1,1],Q=O[1],m=[],h=h===void 0?1:h,e||(e=y[41](8,c7.M(),O[2])[O[0]],m.push(U[0](93,e,O[0])),Q=q[0]),D=I[q[1]](20),t=I[q[1]](71),m.push(D,T[30](58,t,W[0](q[1],C),W[0](18, +e)),L,l[44](20,e,W[0](17,e),h),T[30](41,D,O[2],O[2]),t),Q&&c7.M().i(e),u=m),u},function(N,C,e,L,h,Q,m,O,t,D){if(N<<(t=[4,25,1],t[2])>=-78&&(N<<t[2]&t[0])<2)a:{if(C instanceof SV||C instanceof zw||C instanceof di){D=C;break a}if(typeof C.next=="function"){D=new SV(function(){return C});break a}if(typeof C[Symbol.iterator]=="function"){D=new SV(function(){return C[Symbol.iterator]()});break a}if(typeof C.qz=="function"){D=new SV(function(){return C.qz()});break a}throw Error("Not an iterator or iterable."); +}if((N+5&t[1])<N&&N-t[2]<<t[2]>=N){L=(e=(Q=(O=(m=(h=H[15](36,this),y)[34](57,this),f)[t[2]](51,this),""),P[t[0]](15,O)),e).next();try{for(;!L.done;L=e.next())Q+=m[L.value]}finally{L&&!L.done&&(C=e.return)&&C.call(e)}this.Pm[h]=Q}return D},function(N,C,e,L,h,Q,m){return((Q=[21,5,6],N-4<<2>=N&&N-Q[2]<<1<N&&(h=["m","k",0],TN.call(this),this.V=L,this.o=null,this.A=h[2],this.j=h[2],this.K=null,this.i=C,this.B=e,this.G=gH,y[28](22,h[1],!1,h[0],"r",this)),N+2>>2<N&&(N+Q[1]&Q[0])>=N&&p.call(this,C,0,UA.yl), +(N>>2&15)<12&&(N-Q[2]&15)>=14&&(m=T[42](48,C,e)),N>>1&15)||L&&fu(L,h,{get:function(O,t,D,q,u,B){return(t=(q=(O=(B=(D=e.Hm,[17,0,38]),u=new wi,v)[B[2]](13,h),P[B[1]](13,u,O,C)),I[22](22,2,q,v[22].bind(null,B[0]),l[26].bind(null,4),2,2)),v[B[1]](80,4096,t,wi,D),L.attributes[h]).value}}),N>>2>=7&&(N^34)<15)&&(y[22](31,e,e.B,C,function(){return e.A(new yY,Ok)}),L=e.B.v(),y[22](51,e,L,VL,function(O){(O=["classList","remove","uI"],L[O[0]]).contains(xU())&&(L[O[0]][O[1]](xU()),L[O[0]].add(aG()),this[O[2]].send(gi))}), +y[22](39,e,L,bd,function(O){O=["classList","uI","remove"],L[O[0]].contains(aG())&&(L[O[0]][O[2]](aG()),L[O[0]].add(xU()),this[O[1]].send(gi))})),m},function(N,C,e,L,h,Q){return((N+5^((N>>2&15)==(Q=["defaultValue",25,0],3)&&p.call(this,C),Q[1]))<N&&(N-3^15)>=N&&(e=2,e=e===void 0?2:e,this.key=C,this[Q[0]]=!1,this.phase=e,this.flagNameForDebugging=void 0),N<<1)&29||(e=[],v[6](3,Q[2],M1).forEach(function(m){M1[m].ep&&!this.has(M1[m])&&e.push(M1[m].getName())},C),h=e),(N|56)==N&&(h=U[4](18,2115)(L($U, +36),10)),h},function(N,C,e,L,h){if((((N&102)==(h=[2,5,1],N)&&(L=C%e),N>>h[2])&6)>=4&&(N>>h[0]&h[1])<h[0]&&this.closed)throw new Nc;return L},function(N,C,e,L,h,Q,m,O){return N+((N>>2&15)>=((N-(O=[6,3,"On"],9)<16&&N>>2>=O[1]&&C.G.push(C.LV,U[25](O[1],C,function(t,D){return t||D}),C.Pw,C.OG),N<<1&O[0])==4&&this.i.G==PL&&(this.i.G=xZ,this.i.i[O[2]](),this.B.i.s_(!1)),(N|72)==N&&p.call(this,C),O[0])&&(N>>1&32)<24&&(m=I[7](O[1],e,Q,L,C,h)),7)>>4||(this.i=[]),m},function(N,C,e,L,h){return(N&((N>>2&((N& +121)==(L=[0,"i",78],N)&&(e=new C,y[15](19,34,e.z2),h=e),7))==1&&(e=new Je,e.G=C.G,C[L[1]]&&(e[L[1]]=new Map(C[L[1]]),e.B=C.B),h=e),L[2]))==N&&p.call(this,C,L[0],p1.yl),(N|48)==N&&(this[L[1]]=new Ca,this.B=C),h},function(N,C,e,L,h,Q,m){return N+9>>((((m=["constructor",2,"call"],N)-7>>4||(C=Error[m[2]](this,"no elements in sequence"),this.message=C.message,"stack"in C&&(this.stack=C.stack),Object.setPrototypeOf(this,this[m[0]].prototype),this.name="EmptyError"),N)|8)>>4||(Q=!!h.relatedTarget&&l[33](1, +C,1,e,h.relatedTarget,L)),3)>=1&&(N-3&7)<1&&(e=H[m[1]](64,C),L=H[m[1]](68,C),C=P[25](20,31,0,C),C.splice(e>=0?e:C.length+e+1,0,L)),Q},function(N,C,e,L,h,Q,m){return((((((N&(Q=["nu",18,1],13))==N&&(e=[null,!1,9],yE.call(this),this.A=C||W[46](Q[1],e[2]),this[Q[0]]=e[Q[2]],this.Y=void 0,this.I=e[0],this.K=e[0],this.B=e[0],this.E5=es,this.V=e[0],this.o=e[0]),N)-3&7)==Q[2]&&(h=[null,"recaptcha-checkbox",0],L=P[36](73,La,h[Q[2]]),jj.call(this,h[0],L,e),this.i=Q[2],this.P=h[0],this.tabIndex=C&&isFinite(C)&& +C%Q[2]==h[2]&&C>h[2]?C:0),N>>Q[2]&7)==Q[2]&&(m=C),N-6)^Q[1])<N&&(N-7|14)>=N&&(m=T[42](20,C,e)),m},function(N,C,e,L,h,Q,m,O,t,D,q){if((D=[2,3,15],N>>D[0]&D[1])==1){for(h=(L=(Q=H[D[2]](36,this),f[1](35,this)),e=[],1);h<C;h++)e.push(f[1](19,this));this.Pm[Q]=L.apply(null,T[5](73,e))}return(N<<(N+D[0]>=23&&N-D[0]>>5<5&&(C=Promise.resolve(void 0),dH=function(){C.then(P[43].bind(null,22))}),1)&8)<4&&N+7>=-53&&(t=O.then(function(u,B,G,c,A){A=[33,18,(B=h,34)];switch(u.LP()){case 2:case e:c=(B=m.BS,m).f0; +break;case L:c=m.Y7;break;default:c=new sB}return G=I[A[2]](21,!0,U[36](39,c),T[40](20,e,L,c.G,"/multi-watch/channel")),{dI:new ht(f[A[0]](10,h,Q.Xl),c,u),ey:new Qc(c,f[A[0]](A[1],h,Q.Xl),u),Dp:function(n,R,F,Z,X,Y,k){return(Z=(k=new mP(Q.Xl!==void 0,u,G,B,(Y=(X=Q.JE)==C?void 0:X.oM)!=C?Y:!1),new OL(k,R,function(E,J){return new tt,new UL(E,J)},F,n)),Z.state)===0&&(Z.state=L,U[8](24,!0,Z.channel)),Z}}}),q=new Dk(t,Q)),q},function(N,C,e,L,h,Q,m,O){if(((m=["G",17,1],N)>>m[2]&11)==2)H[2](76,C);if(!((N| +m[2])>>4))a:{for(Q in h)if(L.call(void 0,h[Q],Q,h)){O=e;break a}O=C}if((N&92)==N&&(L.B=e,L.s5=[],L.P)){if(h=S[m[1]](59,C,L[m[0]]),h.length!=e||L.o.length!=e)qc(L.s5,h),qc(L.s5,L.o),L[m[0]][m[0]].length=e,v[40](44,L.o),L.o.length=e;L.P.B()}if((N|m[2])>>5<4&&(N<<2&14)>=12){for(h=0;h<e.length;h++)L=(L<<C)-L+e.charCodeAt(h)|0;O=L}return O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((N+7>>3>=(((u=[63,5,"h"],N-9)&15)==4&&(B=[C,this.get(C)]),0)&&(N|4)<12&&(K[u[1]](9,[-12],l[7].bind(null,4)),K[u[1]](17,[-94, +-23],l[13].bind(null,7)),K[u[1]](19,[-7,-33],U[u[1]].bind(null,80)),K[u[1]](11,[-2,-69],P[28].bind(null,49)),K[u[1]](u[1],[-38],T[14].bind(null,17))),N&52)==N)for(q=function(G,c,A){for(;O<e.length;){if((A=e.charAt(O++),c=xd[A],c)!=null)return c;if(!S[23](14,A))throw Error("Unknown base64 encoding at char: "+A);}return G},Q=[0,240,""],y[2](64,Q[2],Q[0]),O=Q[0];;){if((D=(t=q(-1),h=q(Q[0]),q(64)),m=q(64),m===64)&&t===-1)break;L(t<<2|h>>4),D!=64&&(L(h<<4&Q[1]|D>>2),m!=64&&L(D<<C&192|m))}if((((N+1&30)>= +N&&(N-2|20)<N&&(y[22](45,Q,Q.i,"g",function(G){P[1]((G=[null,"i",6],35),G[0],!0,W[39](G[2],Q[G[1]]))}),y[22](u[0],Q,Q.i,u[2],function(){Q.resize()}),y[22](37,Q,Q.i,"i",function(G){P[G=[1,39,null],G[0]](38,G[2],e,W[G[1]](6,Q.i))}),y[22](53,Q,Q.i,C,function(){return v[21](18,1,Q,Ap)}),y[22](53,Q,Q.i,"n",function(){return v[21](22,1,Q,cz)}),y[22](27,Q,Q.i,L,function(){return v[21](6,1,Q,GS)}),y[22](43,Q,Q.i,"j",function(G){return y[G=[4,2,!1],G[0]](28,G[0],G[1],0,G[2],Q)}),y[22](57,Q,Q.i,h,function(G){return S[G= +[20,null,4],G[0]](57,G[2],!0,!1,G[1],Q)})),N^25)&27)==2){for(L=(h=(O=(e.i.cookie||"").split(u0()),[]),t=[],C);L<O.length;L++)Q=By(O[L]),m=Q.indexOf(js()),m==-1?(t.push(""),h.push(Q)):(t.push(Q.substring(C,m)),h.push(Q.substring(m+1)));B={keys:t,values:h}}return B},function(N,C,e,L,h,Q,m,O,t,D,q){return(((((q=[69,6,"innerHeight"],N&11)==N&&(e.B?(h=e.B,Q=L.phase===1||h.B&&!(L.key in h.i)?L.defaultValue:L.ctor(h.i[L.key])):Q=C,D=Q),(N-8|39)>=N)&&(N-3^16)<N&&(h=h===void 0?!1:h,m=this,Q=Q===void 0?!0: +Q,D=P[44](13,function(u){return(t=m.G.then(function(B,G,c){return cy(U[c=this,41](40),I[13](99),void 0,B).then(function(A,n,R,F,Z,X,Y,k){return((n=l[28](7,0,(Y=(k=[36E5,"i",49],G.send),c[k[1]]),e),Z=S[41](k[2],0,c.B),R=S[31](52,A.CD()),e&&Ka.getName()in e)?F=!!e[Ka.getName()]:F=(X=c[k[1]].get(Ka))?!(X==="0"||X===0||X===!1||X==="false"):!1,Y).call(G,C,new yY({lQ:n,yM:Z,p7:R,AE:F,T2:L||c.X,XI:h}),k[0])})}.bind(m,(O=function(B,G){m[(G=[44,"i",!0],G)[1]].has(G_)?W[4](G[0],m[G[1]],G_,G[2])(B):B&&Q&&console.error(B)}, +S[28](57).Error()))),u).return(t.then(function(B,G){if(G=[!1,"JM","l"],B){if(B.error)throw B[G[1]]&&O(B.error),B.error;return(m[B.IB=G[0],G[2]](B),B).response}return null},function(B,G,c){if((G=(c=[11,.001,1],B&&B instanceof Error)&&!B.message.includes(eN()))&&Vn()<c[1])return y[c[2]](74,c[0],6,e,B,m);if(G)throw O(B),B;return y[c[2]](75,c[0],6,e,B,m)}))})),N>>1<26&&(N-8&14)>=11)&&(At||yc?(L=screen.availHeight,e=screen.availWidth):i0||vy?(L=window.outerHeight||screen.availHeight||screen.height,e=window.outerWidth|| +screen.availWidth||screen.width,na||(L-=C)):(L=window.outerHeight||window[q[2]],e=window.outerWidth||window.innerWidth),D=new B2(e||0,L||0)),N+2)&19)<N&&(N+q[1]&q[0])>=N&&(C=Ig,D=e=function(u){return C.call(e.src,e.listener,u)}),D},function(N,C,e,L,h,Q,m,O){if(((((((N>>(O=[17,38,75],1)&15)==2&&(C.v().disabled=!e,L=C.v(),H[7](13,L,!e,"label-input-label-disabled")),N-3)|69)>=N&&(N+6^12)<N&&(e=[6,2,null],B0.M().init(I[40](8,e[1],C)),L=e[2],S[4](10,function(t,D,q,u,B,G){D.k=(B=I[G=[40,2,41],G[0]](10, +G[1],C),u=S[G[2]](10,G[1],rY,B),u),L&&(q=L.fu())&&(D.t=q)}),L=new Rg,L.render(f[O[1]](86)),h=new F1(l[36](73,W[33](9,C,e[0],rY))||0,l[36](O[2],W[33](O[0],C,7,rY))||1E4),this.controller=new l0(L,new T_,h)),(N|7)>>3==1)&&(m=function(t){t.forEach(function(D,q){(q=["B","G","target"],D.type==="attributes")&&(Vn()<C&&e.i++,D.attributeName&&e[q[1]].add(D.attributeName),D[q[2]]&&D[q[2]].tagName&&e[q[0]].add(D[q[2]].tagName))})}),(N|24)==N)&&(m=e&C?rY:void 0),N+6&29)<N&&(N-7^21)>=N)a:{if(h.B!==0){m=e;break a}m= +(H[33](26,L,l[21](33,h.i),Q),C)}return m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E){if(((N-8<(E=["tK",5,"i"],25)&&(N<<1&15)>=9&&(QY.call(this),this.G=C,this.X=Zk[e]||Zk[1],this[E[2]]=L,this.P=h),N)&25)==N)a:{if(m=(G=[null,1,0],q=h[Q],{}),q){k=q;break a}for((Y=(B=(m.LD=K[40](15,"object","number","string",(m.VU=(t={},h),G[2]),h[G[2]]),G[1]),h[G[1]]))&&Y.constructor===Object&&(m.iA=Y,Y=h[++B],typeof Y==="function"&&(m[E[0]]=!0,n5!=G[0]||(n5=Y),og!=G[0]||(og=h[B+G[1]]),Y=h[B+=C]));Y&& +Array.isArray(Y)&&Y.length&&typeof Y[G[2]]==="number"&&Y[G[2]]>G[2];){for(A=G[2];A<Y.length;A++)t[Y[A]]=Y;Y=h[++B]}for(O=G[1];Y!==void 0;){if((F=void 0,typeof Y)===(D=void 0,"number")&&(O+=Y,Y=h[++B]),Y instanceof M$?R=Y:(R=Py,B--),(F=R)==G[0]?0:F[E[2]])Y=h[++B],u=B,X=Y,c=h,typeof X==="function"&&(X=X(),c[u]=X),D=X;for((Y=(Z=O+G[1],h)[++B],typeof Y==="number")&&Y<G[2]&&(Z-=Y,Y=h[++B]);O<Z;O++)n=t[O],D?e(m,O,R,D,n):L(m,O,R,n)}k=h[Q]=m}return((N|40)==((N|72)==N&&(this[E[2]]=C),N)&&(Q=C,k=function(){return(Q= +(L*Q+e)%h,Q)/h}),N-E[1])>>3==3&&(k=P[44](13,function(J,r){if(r=["i",33,18],J.B==L)return J[r[0]](K[r[2]](84,W[28](2,e,function(z){return z.stringify(h.message)}),h.messageType+h[r[0]]),C);return J.return(W[28]((Q=J.G,r[1]),e,function(z){return z.stringify([Q,h.messageType,h.i])}))})),k},function(N,C,e,L,h,Q,m){return((((N+6>>1<(Q=[68,"M",3],N)&&(N-2^Q[2])>=N&&(this.next=function(O,t,D){return(D=[null,33,"j"],S[43](12,!0,C.i),C.i)[D[2]]?t=H[D[1]](41,D[0],C.i[D[2]].next,C,C.i.l,O):(C.i.l(O),t=v[40](14, +D[0],C)),t},this["throw"]=function(O,t,D,q,u,B,G){if((S[G=[33,(D=[null,"throw","return"],"i"),0],43](14,!0,C[G[1]]),C)[G[1]].j)if(q=C[G[1]].j[D[1]])t=H[G[0]](56,D[G[2]],q,C,C[G[1]].l,O);else{C[G[1]].j=(B=C[G[1]].j,D[G[2]]);try{B[D[2]]&&(u=B[D[2]](),H[12](55,u)),y[37](28,new TypeError("The iterator does not provide a 'throw' method."),C[G[1]])}catch(c){y[37](30,c,C[G[1]])}t=v[40](15,D[G[2]],C)}else y[37](16,O,C[G[1]]),t=v[40](23,D[G[2]],C);return t},this.return=function(O){return S[36](1,!0,"return", +null,O,C)},this[Symbol.iterator]=function(){return this}),N)-2|4)>=N&&(N-5^28)<N&&(B0[Q[1]]().init(I[40](2,2,C)),L=new Rg,L.render(f[38](85)),e=new F1,h=new sL(e,C,new fa,new X1),this.i=new Ss(L,h),this.i.init(T[22](Q[2],1,C,rY))),N+Q[2]&7)||(m=P8('<div class="'+H[7](64,"rc-anchor-error-msg-container")+'" style="display:none"><span class="'+H[7](32,"rc-anchor-error-msg")+'" aria-hidden="true"></span></div>')),(N>>2&7)==2)&&(h=H[2](64,C),L=H[2](24,C),e=H[2](Q[0],C),h=(h>>31&e.length)+h,h>=0&&h<e.length&& +(L=e[h]),U[29](4,L,C)),m},function(N,C,e,L,h,Q,m,O,t){return((O=[1,"setFullYear",26],N-8)&6||Array.from(C).reverse().some(e),N)-9<<O[0]>=N&&(N+5&O[2])<N&&(m=new Date(h,L,Q),h>=e&&h<100&&m[O[1]](m.getFullYear()-C),t=m),t},function(N,C,e,L,h,Q,m){return(N|((N&((N<<2>=(m=[12,"i",29],8)&&((N^66)&m[0])<1&&(Q=new wu(function(O,t){t(C)})),N>>2&7)==1&&(Yj.call(this),this.G=[]),73))==N&&(e=H[2](68,C),H[2](24,C)!==0&&H[23](8,3,e,C)),(N^7)>=26&&N-8>>5<1&&(U[21](m[2],L),h=L.z2,H[4](20,C,h[Rw]|0,e,void 0,0,h), +Q=L),48))==N&&(y[42](7,C[m[1]]),f[6](59,C[m[1]]),e=y[42](4,C[m[1]])>>3,Q=C.o6[e]()),Q},function(N,C,e,L){return(N-3&((N<<(L=["IX",16,11],1)&L[2])>=3&&N-4>>4<2&&(e=I[22](L[1],C)>>>0),(N&26)==N&&(this[L[0]]=function(){return 0}),4))<3&&(N>>1&7)>=5&&p.call(this,C),e},function(N,C,e,L,h,Q,m,O,t,D){if(((N|48)==(N+(N+7>>(t=[33,"Y","V"],3)==1&&(D=W[39](28,S[32](20,new b4,9),C)),9)&14||(h=Wy(e),(typeof L==="string"?[L]:L).forEach(function(q){if(q==="null")throw Error("Receiving from null origin not allowed without token verification. Please use NullOriginConnector."); +h[q]=C}),D=function(q){return h[q]===!0}),N)&&(O=f[20](18,Gt(),e.qW,UY(),XG()),h=f[20](7,cL(),e.x7,UY(),XG()),m=f[20](16,Hy(),e.QM,UY(),XG()),L=f[20](19,kj(),e.es,UY(),XG()),Q=T[1](65,fJ(),'<div class="'+H[7](t[0],"rc-anchor-invisible-text")+'"><span>'),W[11](22,Q,"protected by <strong>reCAPTCHA</strong>"),T[1](65,W[11](22,W[11](14,W[11](84,W[11](46,W[11](74,T[1](16,Q,f1()),m?T[1](65,W[11](79,T[1](17,fJ(),r7()),W[1](64)),jB()):""),L?T[1](65,W[11](54,T[1](16,fJ(),pa()),P[34](1)),jB()):""),O?T[1](80, +W[11](20,T[1](16,fJ(),Jt()),I[46](82)),jB()):""),h?T[1](1,W[11](78,T[1](80,fJ(),Jt()),I[47](64)),jB()):""),S[38](1,C,e)),jB()),D=Q),(N^31)&7)==3)a:{if(v[44](13,m.G)>=m.G.o-(m[t[2]]?1:0)){EL(),D=e;break a}if(m[t[2]]){D=((z_(),m).o=Q[t[1]].concat(m.o),L);break a}if(m.B==h||m.B==C||m[t[1]]>=(m.lz?0:m.E_)){D=e;break a}D=(d7(),m[t[2]]=y[9](27,Pe(m.iz,m,Q),v[t[0]](25,C,m,m[t[1]])),m[t[1]]++,L)}return D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){return N+6&(((n=[30,"X",85],N)<<1&7)>=2&&((N^19)&4)<1&&(this.i.G= +gH,this.i.i.onError(2)),(N-6^12)>=N&&N+7>>2<N&&(h=h===void 0?w7:h,B=[2,0,!1],D=y[41](9,c7.M(),B[0]),t=P[4](14,D),q=t.next().value,O=t.next().value,c=T[39](4,10),m=I[21](87),u=I[21](87),Q=[yg(O,T[39](3,1),L,c),y[36](2,q),T[n[0]](37,m,W[0](6,O),W[0](1,q)),P[37](n[2],T[39](8,C),O,q),f[9](18,q,W[0](1,q),B[1]),T[n[0]](37,m,W[0](5,q),B[1]),yg(O,T[39](8,7),q),T[n[0]](56,m,W[0](16,O),B[2]),P[37](81,c,L,O),T[n[0]](53,m,W[0](18,O),B[2]),yg(O,T[39](8,B[0]),L),T[n[0]](36,u,W[0](23,O),W[0](1,e)),m,y[36](3,L), +y[36](1,q),y[36](2,O),T[n[0]](42,h,1,1),u,y[36](5,q),y[36](6,O)],(G=c7.M()).i.apply(G,T[5](57,D)),A=Q),9)||(e.A={Fl:C,W3:!0},e.B=e.h||e[n[1]]),A},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((N&56)==(((N+((N|(N-(u=[0,12,2],4)&15||(B=P8('Tap the center of the objects in the image according to the instructions above. If not clear, or to get a new challenge, reload the challenge.<a href="https://support.google.com/recaptcha" target="_blank">Learn more.</a>')),80))==N&&(this.i=C,this.size=e,this.box=h,this.time= +L*17,Vc(h.bottom-h.top)),7)<14&&(N<<u[2]&15)>=3&&p.call(this,C,u[0],kn.yl),N>>u[2])&16)<9&&(N>>1&15)>=11&&(m.Zt=Q===void 0?!0:Q,m.DR=P[4](14,K[21](37,m,1)).next().value,q=m.i().flat(Infinity),D=q.findIndex(function(G){return G instanceof b4&&W[4](3,G,1)==7}),O=y[48](42,C,q[D],y[11](43),IB),t=[S[37](19,e,m.DR),y[36](u[2],T[15](10,h,1,O[1])),P[28](8,1,u[1],m,q,m.K8)],K[26](18,L,m),B=t),N))a:switch(e=[2,null,1],typeof C){case "string":B=(L=new IB,P[36](20,e[1],4,xj,C,L));break a;case "number":B=(Number.isInteger(C)&& +C<2147483648&&C>=-2147483648?(m=new IB,h=U[44](u[2],e[1],C,3,m)):(t=new IB,q=xj,h=I[33](u[1],K[24](20,C),6,void 0,q,t)),h);break a;case "boolean":B=(Q=new IB,H[6](38,e[1],C,xj,e[u[0]],Q));break a;default:C==e[1]?O=u[0]:(D=T[33](55,C,void 0,e[u[2]],xj),O=P[17](40,W[33](33,C,D))!=e[1]),B=O?C:new IB;break a}return B},function(N,C,e,L,h,Q,m,O,t,D){if(D=[24,8,0],(N^9)>>3==1&&(h=e.z2,L=h[Rw]|D[2],t=l[33](D[0],!1,e,L,h)?H[40](16,e,h,!0):new e.constructor(S[D[1]](D[0],C,L,h,!1))),N<<1>=-69&&(N+9&D[1])<4){if(e== +C)O=e;else{if(typeof e==="string")Q=e?new dX(e,KM):T[33](42);else{if(e.constructor===dX)h=e;else{if(Ae&&e!=C&&e instanceof Uint8Array)m=e.length?new dX(new Uint8Array(e),KM):T[33](46);else{if(!L)throw Error();m=void 0}h=m}Q=h}O=Q}t=O}return(N<<2&14)>=9&&(N<<2&6)<6&&(L.B&&L.B==e?L.B=C:L.i&&L.i.has(e)&&L.i["delete"](e)),t},function(N,C,e,L,h,Q,m,O,t){if(N-6>>3==(O=[0,"string",8],(N|80)==N&&(h=String.fromCharCode.apply(C,e),t=L==C?h:L+h),3))if(C.classList)Array.prototype.forEach.call(e,function(D){W[22](5, +C,D)});else{for(h in Array.prototype.forEach.call((L={},U[19](33,C)),function(D){L[D]=!0}),Array.prototype.forEach.call(e,function(D){L[D]=!0}),Q="",L)Q+=Q.length>O[0]?" "+h:h;K[2](20,O[1],Q,C)}if(N-7<<1<N&&N+4>>1>=N&&(h=[null,0],typeof C!=="number"&&C&&!C.UV))if(m=C.src,S[7](2,m))y[42](32,h[1],m.j,C);else if(e=C.type,Q=C.proxy,m.removeEventListener?m.removeEventListener(e,Q,C.capture):m.detachEvent?m.detachEvent(v[9](89,e),Q):m.addListener&&m.removeListener&&m.removeListener(Q),ag--,L=l[48](68,m))y[42](34, +h[1],L,C),L.B==h[1]&&(L.src=h[O[0]],m[g7]=h[O[0]]);else l[38](O[2],h[O[0]],C);return(N|24)==((N-5&27)==3&&(t=40+4*C),N)&&(t=e.j.find(function(D,q,u,B,G){if(B=(G=["G","i","o"],D.K===C[G[0]]))q=D[G[2]],u=C[G[1]],B=q instanceof Xn&&u instanceof Xn?q.equals(u):q instanceof b0&&u instanceof b0?q.equals(u):!1;return B})),t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(((N+3&22)>=(G=[35,2,"pow"],N)&&N+4>>1<N&&(e=String(e),C.contentType==="application/xhtml+xml"&&(e=e.toLowerCase()),B=C.createElement(e)),N+6>> +1)>=N&&N+G[1]>>G[1]<N)a:{if(m!=C)for(O=m.firstChild;O;){if(L(O)&&(h.push(O),Q)){B=!0;break a}if(y[41](G[1],null,!1,L,h,Q,O)){B=!0;break a}O=O.nextSibling}B=e}if((N<<((N>>G[1]&15)==G[1]&&(B=Array.from({length:e===void 0?1:e},function(c,A,n){if(c=(n=[2048,"B","add"],n[0]),C[n[1]].size<n[0]){do c=TH(Vn()*n[0]);while(C[n[1]].has(c))}return C[n[A=c,1]][n[2]](A),A})),G[1])&13)>=4&&(N^G[0])>>4<G[1]){for(D=[].concat(T[5](39,(t=(q=(m===void 0?0:m)%Mc.length,O=U[42](22),Mc.slice()),Q))),u=h;u<D.length;u++)t[q]= +((t[q]<<L^Math[G[2]](O.call(D[u],h)-Mc[q],e))+(t[q]>>e))/Mc[q]|h,q=(q+C)%Mc.length;B=Vc(t.reduce(function(c,A){return c^A},h))}return B},function(N,C,e,L,h,Q,m){return N+2>>3==(((N^100)&(((m=[1,0,27],N>>2<2)&&(N^2)>=m[0]&&(e=C.B[C.i+m[1]],T[m[1]](m[0],m[0],C),Q=e),(N+3^13)<N)&&(N+m[0]^29)>=N&&(L=L===void 0?W[4].bind(null,36):L,Q=l[m[2]](9,function(O,t,D){O.subscribe(new zk(t,function(q){D=e,t.next(q)},void 0,(D=C,function(){return D?t.complete():t.error(L())})))})),N-7<<m[0]>=N&&(N-7|45)<N&&p.call(this, +C),16))<13&&(N>>2&15)>=4&&(h=L.type,h in e.i&&U[20](46,C,L,e.i[h])&&(l[38](6,null,L),e.i[h].length==C&&(delete e.i[h],e.B--))),3)&&p.call(this,C),Q},function(N,C,e,L,h,Q,m,O,t,D,q){return((N+(D=['"></div>','<span class="',7],4)&15)==1&&(this.src=C,this.i={},this.B=0),(N^48)>>3==2&&(t=L==2,O=S[0](1,!0,"",Q?t?NX:h?Cm:eJ:t?Lm:h?h4:QM,e),m=P[43](11,"recaptcha-checkbox-border",e),P[29](40,y[10](19,e),O,$g,Pe(function(){P[49](2,m,C)},e)),P[29](8,y[10](17,e),O,Ny,Pe(function(){Q&&P[49](14,m,!0)},e)),q=O), +(N-D[2]|51)<N&&(N+4&57)>=N&&(L=C.Wj,e=['"></div><div class="',"rc-response-input-label",'" id="'],q=T[1](81,W[11](14,T[1](81,fJ(),'<div id="rc-audio" aria-modal="true" role="dialog"><span class="'+H[D[2]](1,"rc-audiochallenge-tabloop-begin")+'" tabIndex="0"></span><div class="'+H[D[2]](64,"rc-audiochallenge-error-message")+'" style="display:none" tabIndex="0"></div><div class="'+H[D[2]](64,"rc-audiochallenge-instructions")+e[2]+H[D[2]](32,L)+'" aria-hidden="true"></div><div class="'+H[D[2]](32,"rc-audiochallenge-control")+ +'"></div><div id="'+H[D[2]](65,"rc-response-label")+'" style="display:none"></div><div class="'+H[D[2]](65,"rc-audiochallenge-input-label")+e[2]+H[D[2]](65,e[1])+e[0]+H[D[2]](64,"rc-audiochallenge-response-field")+e[0]+H[D[2]](33,"rc-audiochallenge-tdownload")+D[0]),l[11](28," ")),D[1]+H[D[2]](64,"rc-audiochallenge-tabloop-end")+'" tabIndex="0"></span></div>')),N-3&3)==3&&YK.call(this,1310,27),q},function(N,C,e,L,h,Q,m,O,t){if(!((N^85)&(N-(O=[2,9,46],7)&15||(h=new eX,h.setSeconds(L.i),l[8](O[2],C, +O[0],v[34](13,e,L.B),h,C),t=h),11)))T[34](25,e,O[0],Q,f[17](72,h||C,L||U[22].bind(null,23),m));return(N|88)==(N-((N+3^6)<N&&(N-O[1]|26)>=N&&p.call(this,C),8)>>4||(t=H[38](7,e,L==null?L:l[26](68,L),C,h)),N)&&(t=C.displayName||C.name||"unknown type name"),t},function(N,C,e,L,h,Q,m,O,t,D){return((N+(t=[!1,"i","K"],(N|32)==N&&(this.o=e,this[t[2]]=L,this.G=h,this.B=C),4)>>4<3&&(N<<2&14)>=9&&(this.JG=e,this.c9=C,h=P[18](14,bA),this[t[1]]=!!h&&L===h||t[0]),N)|1)>>3||(O=T[0](54,"rc-prepositional-target"), +m=[],Array.prototype.forEach.call(S[19](28,h,null,document,O,L),function(q,u,B,G,c){(G={selected:!((c=["push","i",13],B=this,this)[c[1]][c[0]](u),1),element:q,index:u},m[c[0]](G),y[22](57,y[10](22,this),new mT(q),O5,function(A,n){(A=!(B.Mp((n=[16,"i",13],C)),G).selected)?(W[22](6,G.element,"rc-prepositional-selected"),U[20](78,e,G.index,B[n[1]])):(W[n[0]](42,G.element,"rc-prepositional-selected"),B[n[1]].push(G.index)),G.selected=A,K[n[2]](37,t4,G.element,G.selected?U5:DO)}),K)[c[2]](36,t4,q,DO)}, +Q)),D},function(N,C,e,L,h,Q,m,O){if((m=[1,2,0],N)-8<<m[1]>=N&&(N+7^23)<N)if(e.tagName==qX)for(Q=C,h=e.elements;e=h.item(Q);Q++)y[46](14,m[2],e,L);else L==1&&e.blur(),e.disabled=L;if(N+4>>3==m[0])P[20](5,L,function(t,D,q){q=["setAttribute","className","htmlFor"],D=="style"?h.style.cssText=t:D=="class"?h[q[1]]=t:D=="for"?h[q[2]]=t:uR.hasOwnProperty(D)?h[q[0]](uR[D],t):D.lastIndexOf(e,C)==C||D.lastIndexOf("data-",C)==C?h[q[0]](D,t):h[D]=t});return O},function(N,C,e,L,h,Q){if(!(N<<2&((Q=["lastElementChild", +40,21],N&87)==N&&(h=L[Q[0]]!==void 0?L[Q[0]]:I[36](32,C,e,L.lastChild)),7)))a:{if(B_){L=BigInt(e),h=v[15](20,Number(BigInt.asIntN(C,L>>BigInt(C))),Number(BigInt.asIntN(C,L)));break a}h=K[Q[2]](9,0,String(e))}return(N^46)>>4<2&&N>>2>=-79&&(h=P[18](57,W[39](16,S[32](68,new b4,27),e),[y[38](Q[1],C)])),h},function(N,C,e,L,h,Q,m,O,t){return(N|((N|48)==((O=[32,0,8],((N|O[2])&7)==2)&&(m=e.z2,t=S[O[0]](27,O[0],C,h,e,Q,m[Rw]|O[1],m,L,!1,!0)),N)&&(t=e.indexOf(C)!=-1),6))>>3==2&&(e=B0.M().get(),t=T[42](O[0], +C,e)),t},function(N,C,e,L,h,Q,m,O){if((((N-7&15)==(m=["i",9,null],1)&&(T[49](31,L,e),L=oE(L),!e&&!n2||L>=C&&P0(L)?h=L:(v[39](52,C,L),h=l[8](19,C,l5,TU)),O=h),N-2)|m[1])>=N&&(N-3^11)<N)f[32](25,127,Q,L,C,T[23](5,1,h,e));if((N-1&30)==2){TH((h=[0,127,25],C));for(TH(e);e>h[0]||C>h[1];)L[m[0]].push(C&h[1]|128),C=(C>>>7|e<<h[2])>>>h[0],e>>>=7;L[m[0]].push(C)}if((((N>>1&15||(L=[10,0,"navigation"],this.K=C||L[0],Zf.PerformanceNavigationTiming?(e=Zf.performance.getEntriesByType(L[2]),h=e.length>L[1]&&(e[L[1]].nextHopProtocol== +"hq"||e[L[1]].nextHopProtocol=="h2")):h=!!(Zf.chrome&&Zf.chrome.loadTimes&&Zf.chrome.loadTimes()&&Zf.chrome.loadTimes().wasFetchedViaSpdy),this.o=h?this.K:1,this[m[0]]=m[2],this.o>1&&(this[m[0]]=new Set),this.B=m[2],this.G=[]),N)^91)&15)==4)a:{if(C==m[2]||typeof C==="number"){O=C;break a}if(C==="NaN"||C==="Infinity"||C==="-Infinity"){O=Number(C);break a}}return O}]}(),K=function(){return[function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){return(N-(N-9<<(((N^9)&7)==(((N&(n=[5,13,10],44))==N&&p.call(this, +C),(N^n[2])>>3)||(A=T[21](56,e,C,L,void 0,rY)),3)&&C.keyCode==n[1]&&this.i.getValue().length==6&&(this.G.I6(!1),U[29](34,!1,this,"t")),2)>=N&&(N-4|64)<N&&(this.G=C,h=h===void 0?!1:h,Q=Q===void 0?!1:Q,this.version=e,this.B=h,this.Ss=L,this.i=Q),4)^14)>=N&&(N+1^21)<N&&(m=y[41](73,c7.M(),C),B=P[4](12,m),c=B.next().value,D=B.next().value,G=I[21](20),u=I[21](71),q=I[21](7),O=[y[36](n[0],D),U[27](99,Q,c),G,yg(h,T[39](9,1),c,e),T[30](53,u,W[0](21,D),W[0](22,h)),T[30](41,q,0,0),u,yg(c,T[39](9,C),c),T[30](49, +L,W[0](n[0],D),W[0](2,c)),T[30](39,G,0,0),q,y[36](6,c)],(t=c7.M()).i.apply(t,T[n[0]](57,m)),A=O),A},function(N,C,e,L,h,Q,m,O,t,D){if(!(((N+5&(D=[24,4,0],21))==1&&(Q=L[Rw]|D[2],m=y[30](27,128,Q),Q=H[D[1]](28,null,Q,e,m,h,L),W[26](8,Q,h,L,C,m)),N^D[0])>>D[1]))a:{if(!jJ){t=v[11](3,C,1,L);break a}for(Q=new (O=(m=Gb.test(L)?L.replace(Gb,l[23].bind(null,5)):L,atob)(m),Uint8Array)(O.length),h=e;h<O.length;h++)Q[h]=O.charCodeAt(h);t=Q}return(((N&73)==N&&(this.i=C),N)|80)==N&&p.call(this,C),(N+3&13)==1&&(c_= +C),t},function(N,C,e,L,h,Q,m,O,t,D){if(D=[7,65,"i"],(N-6&15)==2)a:{if(U[38](25)&&Km!==A4){if((O=Ie.brands.find(function(q){return q.brand===Km}),!O)||!O.version){t=NaN;break a}m=O.version.split(ZD())}else{if(Q=l[48](40,h,"FxiOS",C,e),Q===""){t=NaN;break a}m=Q.split(ZD())}t=m.length===0?NaN:Number(m[L])}return N>>(((N<<1&D[0])>=2&&((N|9)&D[0])<4&&(e=C.f7,L=['"></canvas><img class="','" src="','"></div>'],t=P8('<div id="rc-canvas"><canvas class="'+H[D[0]](D[1],"rc-canvas-canvas")+L[0]+H[D[0]](D[1], +"rc-canvas-image")+L[1]+H[D[0]](1,P[11](32,e))+L[2])),(N>>1&D[0])==2)&&(typeof L.className==C?L.className=e:L.setAttribute&&L.setAttribute(yM(),e)),2)<22&&((N^80)&11)>=10&&(e=[500,2,"visible"],C&&C[D[2]]&&(0,B8.En)(C.errorCode),L=C&&C.errorCode==e[1],this[D[2]].has(G_)?W[4](41,this[D[2]],G_,!0)():!L||document.visibilityState&&document.visibilityState!=e[2]||alert("Cannot contact reCAPTCHA. Check your connection and try again."),L&&P[23](6,e[0],0,this.B,!1)),t},function(N,C,e,L,h,Q){return((N-1|(Q= +[6,"K","h"],4))>=N&&(N-Q[0]^22)<N&&(YK.call(this,619,29,[1]),this.o=this.H=this.B=-1,this.X=this[Q[2]]=-1,this.G=this[Q[1]]=-1,this.J=I[21](87)),(N+3^18)>=N&&(N+8&77)<N)&&(h=typeof Symbol==="function"&&typeof Symbol()==="symbol"?(L===void 0?0:L)&&Symbol["for"]&&C?Symbol["for"](C):C!=null?Symbol(C):Symbol():e),h},function(N,C,e,L,h,Q,m,O,t){if((N|(t=["v",0,59],(N>>2&15)==3&&(h=H[15](4,this),e=y[34](52,this),C=y[34](t[2],this),L=H[40](13,C,e),this.Pm[h]=L),24))==N)a:switch(m=[224,61,189],Q){case m[1]:O= +187;break a;case t[2]:O=C;break a;case h:O=m[2];break a;case m[t[1]]:O=L;break a;case e:O=m[t[1]];break a;default:O=Q;break a}return(((N&61)==N&&(m=L?e.V.left-10:e.V.left+e.V.width+10,h=K[42](6,9,C,e.u()),Q=e.V.top+e.V.height*.5,m instanceof aw?(h.x+=m.x,h.y+=m.y):(h.x+=Number(m),typeof Q==="number"&&(h.y+=Q)),O=h),(N>>1&15)==1)&&(e=C().querySelectorAll(y[14](88,8105,1)),O=e.length==t[1]?"":U[4](34,6140)(e[e.length-1])),N-5<<2)>=N&&(N-8|78)<N&&(O=!!e[t[0]]()&&e[t[0]]().value!=C&&e[t[0]]().value!= +e.G),O},function(N,C,e,L,h,Q,m){if(!(((Q=[3,0,1],(N-Q[0]|24)>=N)&&N+2>>Q[2]<N&&iR.set(e,C),N)<<Q[2]&Q[0])){for(h=((this.o=(L=(e=e===void 0?2:e,this.i=C===void 0?60:C,L)===void 0?20:L,TH)(this.i/6),this).K=e,this.B=[],Q)[1];h<this.o;h++)this.B.push(l[39](17,Q[1],6));this.G=L}return m},function(N,C,e,L,h){if(N-6>>3==(L=[0,14,42],3))for(e=this.o;e.i.length>L[0];)if(C=this.xZ())e.remove().apply(this,[C]);else break;return(((N-9&L[1]||(e=this.B,e===C?this.B=null:Array.isArray(e)&&K[45](64,1,e,C)),N)|24)== +N&&(this.i=[],this.B=[]),(N^L[2])>>4)>=3&&N-8>>5<1&&p.call(this,C),h},function(N,C,e,L,h,Q,m,O){return((N-(m=[1,2,14],m)[0]&7)==m[0]&&(L=new SW,O=K[23](62,C,e,L)),N)+9>=m[2]&&(N<<m[0]&6)<m[1]&&(h=new Map,Q=Q===void 0?5E3:Q,O=new Promise(function(t,D,q,u){u=(u=C,q=function(B,G){(G=["removeEventListener","location","ports"],B.data===Z_)&&B[G[2]].length>e&&(S[3](33,u),L[G[0]](v_(),q),t(new oB(B[G[2]][e],h,null,Zf[G[1]].origin)))},L.addEventListener(v_(),q),W[36](72,Q,function(){L.removeEventListener("message", +q),D(Error("Timed out."))}))})),O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){return(N+(((N>>1&(c=[8,20,2],7))==1&&eB.call(this,nm.width,nm.height,IM),(N-c[0]^9)>=N)&&N+c[2]>>1<N&&(h=S[16](c[1],e),h!=null&&(v[22](12,C,L,0),C.i.i.push(h?1:0))),c[0])&79)>=N&&N-c[0]<<c[2]<N&&(u=Q,B=[2,4096,0],L===1||(L!==4?0:B[0]&Q||!(C&Q)&&32&h)?W[1](26,4,Q)||(Q|=!D.length||t&&!(B[1]&Q)||32&h&&!(B[1]&Q||C&Q)?2:256,Q!==u&&W[32](c[0],Q,D),$4(D)):(L===2&&W[1](23,4,Q)&&(D=v[27](73,D),u=B[c[2]],Q=P[30](66,B[0],Q,h),h=W[26](11, +h,m,q,D,e)),W[1](27,4,Q)||(O||(Q|=C),Q!==u&&W[32](24,Q,D))),B[0]&Q||!(B[1]&Q||C&Q)||l[1](65,q,h),G=D),G},function(N,C,e,L,h,Q,m){if((N&89)==((N+5&28)>=((N|56)==(m=[10,"o",90],(N&m[2])==N&&(Q=new M$(C,e,L)),N)&&(h!=C&&Zf.clearTimeout(h),L.onload=function(){},L.onerror=function(){},L.onreadystatechange=function(){},e&&window.setTimeout(function(){W[48](43,L)},0)),N)&&(N+4^22)<N&&(C.streams.set(e[m[1]],e),C.l.next({}),S[46](18,4,3,C,e)),N)){if(this.j=(this.G=(K2.call(this),e)||m[0],C||0),this.j>this.G)throw Error(RM); +(this.delay=(this.i=(this.B=new FA,new Set),0),this.P=null,this).wN()}return(N|1)>>3||(L=W[m[0]](3,null,C).client,Q=v[3](29,e,L.G)),Q},function(N,C,e,L,h){return(N|16)==((h=["G",64,"i"],N+3>>2)<N&&(N+7^24)>=N&&(this.B=h[1],this.o=Zf[CA()]?new Uint8Array(this.B):Array(this.B),this.V=C,this.P=e,this[h[0]]=0,this[h[2]]=[],this.K=0,this.A=Zf[lR()]?new Int32Array(64):Array(h[1]),Tb===void 0&&(Zf[lR()]?Tb=new Int32Array(ZO):Tb=ZO),this.reset()),N)&&p.call(this,C),L},function(N,C,e,L,h,Q,m,O,t,D,q){return(((((N^ +7)&(q=[72,1048575,32],8))<7&&((N^58)&12)>=11&&(D=W[39](4,S[q[2]](q[0],new b4,28),C)),N)+4^4)>=N&&(N+4&45)<N&&(h=[4294967296,2047,2],Q=W[0](10,16,e),t=W[0](58,16,e),m=(t>>31)*h[2]+1,L=t>>>C&h[1],O=h[0]*(t&q[1])+Q,D=L==h[1]?O?NaN:m*Infinity:L==0?m*oM(h[2],-1074)*O:m*oM(h[2],L-1075)*(O+4503599627370496)),(N<<1&7)==2)&&(L=["-signaler-pa.googleapis.com/punctual","-dynamite-","-signaler-pa.clients6.google.com/punctual"],D={f0:new sB("https://"+e+L[1]+C+L[2]),Y7:new sB("https://"+e+L[1]+C+L[0]),BS:!0}), +D},function(N,C,e,L,h,Q,m,O,t,D){if((N+((t=["B",92,73],N&t[2])==N&&(O=["goog-inline-block",null,"rc-button-default"],m=P[36](74,G6,C||O[2]),P_.call(this,e,m,h),this.h=Q||O[1],this.P=C||O[2],this.i=L||0,I[24](33,!0,this,O[0])),1)&15)>=N&&(N+6&74)<N)switch(typeof e){case "string":S[30](t[2],C,e)}if(N+6>>3==3){for(Q=((this.G=Array((h=e,this[t[this.o=(this[this[t[this.i=C,0]]=-1,t[0]]=L||C[t[0]]||16,Array(this[t[0]])),0]])),h).length>this[t[0]]&&(this.i.update(h),h=this.i.digest(),this.i.reset()),0);Q< +this[t[0]];Q++)m=Q<h.length?h[Q]:0,this.o[Q]=m^t[1],this.G[Q]=m^54;this.i.update(this.G)}return N+8>>4||(L=(e===void 0?{}:e).c2,C.c2=L===void 0?!1:L),D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return(((((B=[1,17,"i"],(N>>B[0]&15)>=7&&(N+5&7)<7)&&(u=U[13](16,e,s5,C,rY)),N-4)&8)<6&&(N>>2&15)>=4&&(O=["none",!1,"false"],Array.isArray(L)&&(L=L.join(OY())),h=fm+C,L===""||L==void 0?(XA||(m={},XA=(m[SJ]=O[B[0]],m[YE]=O[0],m[W_]=O[0],m[H_]=O[B[0]],m[kE]="off",m[rL]=O[B[0]],m[pm]=O[B[0]],m[J4]="vertical",m[E5]= +O[B[0]],m[zb]="additions text",m[dL]=O[B[0]],m[wL]=O[0],m[VM]=O[B[0]],m[xE]=O[B[0]],m[aM]=O[B[0]],m[gL]=O[2],m)),Q=XA,C in Q?e.setAttribute(h,Q[C]):e.removeAttribute(h)):e.setAttribute(h,L)),N)&93)==N&&(t=RB.M()[B[2]](),q=t.UK,D=I[46](B[1],e,L,t.QI,Q),O=U[21](5,C,P[27](10,h,new bR,D),q),u=new MX(m,O)),u},function(N,C,e,L,h,Q,m,O,t,D){return(N-(((((((t=['Draw a box around the object by clicking on its corners as in the animation above. If not clear, or to get a new challenge, reload the challenge. <a href="https://support.google.com/recaptcha" target="_blank">Learn more.</a>', +44,71],N)^11)&14||p.call(this,C),N)&29)==N&&(D=P[t[1]](13,function(q,u,B){if((B=[0,"B",(u=[7,6,null],1)],q)[B[1]]==B[2]){if(K[38](4,C,B[2],$E,N9,Q))return m=H[19](27,u[2],B[2],$E,Q,N9),q.i(v[27](42,B[2],8,u[B[0]],e,m),u[B[2]]);if(!K[38](20,C,e,CS,N9,Q))return q.js(C);return(O=H[19](41,u[2],e,CS,Q,N9),q).i(f[34](9,L,B[2],h,u[B[0]],O),5)}return q.return(q.G)})),N+1)&14)==2&&(sH.call(this,e6+(C&&C.message?String(C.message):String(C)),C),(e=C&&C.stack)&&typeof e==="string"&&(this.stack=e)),(N^t[1])<18&& +(N^t[2])>=5&&(D=P8(t[0])),3)^19)>=N&&(N-8^17)<N&&(D=LS+W[39](35,C,e.G2())),D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){return(((N|24)==(c=[20,"rc-2fa-response-field-error-override",7],N-4<<1<N&&(N+3&69)>=N&&(A=typeof C==="function"),N)&&(sH.call(this),this.request=C,this.errorCode=(this.i=e)?K[24](2,2,this.i):-1,this.G=(h=(L=this.i)==null?void 0:L.B)!=null?h:null),N-6)|11)>=N&&(N+5&30)<N&&(q=["<p>To make sure this is really you, we sent a verification code to ",'">',"rc-2fa-header"],Q=C.RF,B=C.cj, +L=C.identifier,u=C.De,t=f[c[0]](c[0],hF(),L,UY(),QR()),O=f[c[0]](18,mN(),B,UY(),XG()),m=f[c[0]](c[0],O1(),Q,UY(),tF()),h=f[c[0]](c[2],U1(),u,UY(),QR()),G='<div class="'+H[c[2]](33,"rc-2fa-background")+" "+H[c[2]](64,"rc-2fa-background-override")+'"><div class="'+H[c[2]](65,"rc-2fa-container")+" "+H[c[2]](65,"rc-2fa-container-override")+'"><div class="'+H[c[2]](32,q[2])+" "+H[c[2]](1,"rc-2fa-header-override")+q[1],G=(h==="phone"?G+"Verify your phone":G+"Verify your email")+('</div><div class="'+H[c[2]](64, +"rc-2fa-instructions")+" "+H[c[2]](1,"rc-2fa-instructions-override")+q[1]),h==="phone"?(e="<p>To make sure this is really you, we sent a verification code to your phone at "+W[c[0]](59,t)+".</p><p>Enter the code below. It will expire in "+W[c[0]](49,m)+" minutes.</p>",G+=e):(D=q[0]+W[c[0]](51,t)+".</p><p>Enter the code below. It will expire in "+W[c[0]](57,m)+" minutes.</p>",W[c[0]](55,t),W[c[0]](53,m),G+=D),G+='</div><div class="'+H[c[2]](33,"rc-2fa-response-field")+" "+H[c[2]](65,"rc-2fa-response-field-override")+ +" "+(O?H[c[2]](33,"rc-2fa-response-field-error")+" "+H[c[2]](64,c[1]):"")+'"></div><div class="'+H[c[2]](65,"rc-2fa-error-message")+" "+H[c[2]](64,"rc-2fa-error-message-override")+q[1],O&&(G+="Incorrect code."),G+='</div><div class="'+H[c[2]](33,"rc-2fa-submit-button-holder")+" "+H[c[2]](32,"rc-2fa-submit-button-holder-override")+'"></div><div class="'+H[c[2]](65,"rc-2fa-cancel-button-holder")+" "+H[c[2]](65,"rc-2fa-cancel-button-holder-override")+'"></div></div></div>',A=P8(G)),A},function(N,C,e, +L,h,Q,m,O,t,D,q,u,B,G,c,A){return(N&60)==((((((N|(A=[0,36,1],72))==N&&p.call(this,C),N-8)>>4||(D=[!1,2,0],O=y[41](73,c7.M(),D[A[2]]),B=P[4](10,O),m=B.next().value,t=B.next().value,G=I[21](84),q=I[21](84),Q=[y[A[1]](6,h),K[A[0]](22,D[A[2]],C,q,m,L),P[37](83,T[39](7,5),m,t),T[30](37,e,W[A[0]](5,t),W[A[0]](16,h)),yg(m,T[39](7,7),t),T[30](40,e,W[A[0]](7,m),D[A[0]]),ii(h,T[39](3,6),T[39](6,9),t),y[A[1]](5,m),y[A[1]](2,t),T[30](51,G,D[2],D[2]),q,y[A[1]](2,C),y[A[1]](2,m),y[A[1]](A[2],t),T[30](39,e,D[2], +D[2]),G],(u=c7.M()).i.apply(u,T[5](25,O)),c=Q),N-A[2]>>3>=A[0])&&N<<A[2]<19&&(Q=["",null,5],K2.call(this),this.jP=C.jP||function(){},this.B=[],this.SP=A[0],this.V=Q[A[2]],this.I=A[2],this.j=A[0],this.A=Q[A[2]],this.Y=Q[A[0]],this.X=this.l=-1,this.WS=C.WS,h=this,this.K=A[0],this.o=new Dg(C.g$,C.WS),this.BE=C.BE||Q[A[2]],this.RM=C.RM||Q[A[2]],this.hc=C.hc||Q[A[2]],this.P=C.Gk||Q[A[2]],this.B3=C.B3||!1,this.withCredentials=!C.Ec,this.g$=C.g$||!1,this.S=typeof URLSearchParams!=="undefined"&&!!(new URL(f[2](48))).searchParams&& +!!(new URL(f[2](47))).searchParams.set,O=v[16](6,A[2],new pP),l[12](54,Q[2],O,this.o),this.G=new q9(1E4),m=v[29](A[2],C.lK,this),this.i=new BQ(m,this.G.getValue()),this.h=new BQ(m,6E5),this.B3||this.h.start(),this.g$||(document.addEventListener(j6,function(n,R){R=["flush",null,"visibilityState"],document[R[2]]==="hidden"&&(T[35](33,!0,h),(n=h.A)==R[1]||n[R[0]]())}),(e=S[28](40))==Q[A[2]]||(L=e.addEventListener)==Q[A[2]]||L.call(e,GA,function(n,R){(n=(T[R=[35,"flush",32],R[0]](R[2],!0,h),h).A)==null|| +n[R[1]]()}))),N)|40)==N&&p.call(this,C),N)&&(c=P[48](37,xn)),c},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){if(!(N>>(c=[39,2,21],c[1])&13))a:{for(Q=(O=C,e instanceof String&&(e=String(e)),e).length;O<Q;O++)if(m=e[O],L.call(h,m,O,e)){A={MW:O,P3:m};break a}A={MW:-1,P3:void 0}}return(((N-c[1]|50)<N&&N-8<<c[1]>=N&&(A=P[0](79,e,L,C)),N|64)==N&&(B=y[41](10,c7.M(),c[1]),q=P[4](15,B),u=q.next().value,t=q.next().value,G=I[c[2]](23),O=I[c[2]](71),D=[y[36](6,h),v[31](70,Q,u),yg(t,T[c[0]](3,4),u),yg(t,T[c[0]](5, +7),t),T[30](37,G,W[0](3,t),e),P[37](87,T[c[0]](5,8),u,h),T[30](36,O,C,C),G,y[36](3,Q),y[36](1,u),y[36](5,t),T[30](58,L,C,C),O,y[36](5,t),y[36](6,u)],(m=c7.M()).i.apply(m,T[5](87,B)),A=D),(N^27)>>4)||p.call(this,C),A},function(N,C,e,L,h,Q,m,O,t,D){if((N|48)==(((N&(t=[1,"nodeType",0],104))==N&&(O=function(){var q=["B","apply","indexOf"];if(m.J)return Q[q[1]](this,arguments);try{return Q[q[1]](this,arguments)}catch(B){var u=B;if(!(u&&typeof u==="object"&&typeof u.message==="string"&&u.message[q[2]](e6)== +C||typeof u==="string"&&u[q[2]](e6)==C))throw m[q[0]](u),new cQ(u);}},m=h,O[K[44](23,L,h,e)]=Q,D=O),N-7&15)>=t[2]&&N-5<10&&(h=new Rq,L.then(function(q){h.aM(q)},function(q){H[6](23,C,h),I[43](13,e,h,C,q)}),D=h),N))if("textContent"in e)e.textContent=C;else if(e[t[1]]==3)e.data=String(C);else if(e.firstChild&&e.firstChild[t[1]]==3){for(;e.lastChild!=e.firstChild;)e.removeChild(e.lastChild);e.firstChild.data=String(C)}else H[41](18,e),e.appendChild(f[27](35,9,e).createTextNode(String(C)));return(N>> +(N+t[0]&5||p.call(this,C,t[2],S8.yl),2)&23)>=21&&(N-3&15)<8&&(D=Promise.resolve(I[44](25,6,4,C,e))),D},function(N,C,e,L,h,Q,m,O,t,D,q,u){if(u=["brands","getHighEntropyValues","mobile"],((N|6)&1)>=0&&N-2<6)a:{if(!(m=m===void 0?C2:m,KS)){if(!(D=(O=Q.navigator)==L?void 0:O.userAgentData,D)||typeof D[u[1]]!=="function"||D[u[0]]&&typeof D[u[0]].map!=="function"){q=Promise.reject(Error("UACH unavailable"));break a}KS=((I[12](88,e,1,(D[u[0]]||[]).map(function(B,G,c,A){return c=(G=(A=["version",15,0],new vk), +P)[A[2]](A[1],G,B.brand,1),P[A[2]](78,c,B[A[0]],e)})),typeof D[u[2]]==="boolean")&&W[42](10,D[u[2]],e,ie),D)[u[1]](m)}q=(t=new Set(m),KS).then(function(B,G,c,A){return((c=y[39](1,(G=[4,"platform",34],A=["has",12,77],G[2]),ie),t[A[0]](G[1])&&P[0](15,c,B.platform,3),t[A[0]]("platformVersion")&&P[0](A[1],c,B.platformVersion,G[0]),t[A[0]]("architecture")&&P[0](76,c,B.architecture,h),t[A[0]](C))&&P[0](A[2],c,B.model,6),t)[A[0]]("uaFullVersion")&&P[0](A[1],c,B.uaFullVersion,7),c.G2()}).catch(function(){return ie.G2()})}if(((N| +((N|48)==N&&(this.H=L,this.B=e,this.G=C),1))&6)==2){for(m=(L=C,"");L<e.length;L++)Q=e[L],h=AF.get(Q),h===void 0&&(h=null.apply(null,[Q]),AF.set(Q,h)),m+=h;q=m}return q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){return(((N|(B=[16777215,1E7,4],B)[2])&7)>=6&&N+1>>B[2]<2&&(L="Jsloader error (code #"+C+")",e&&(L+=": "+e),sH.call(this,L),this.code=C),N+2^25)<N&&(N-2|25)>=N&&(m=[0,32,4294967296],L>>>=m[0],e>>>=m[0],L<=2097151?Q=""+(m[2]*L+e):(I[28](2)?t=""+(BigInt(L)<<BigInt(m[1])|BigInt(e)):(q=(e>>>24|L<<8)& +B[0],u=L>>C&65535,O=u*2,D=q+u*8147497,h=(e&B[0])+q*6777216+u*6710656,h>=B[1]&&(D+=h/B[1]>>>m[0],h%=B[1]),D>=B[1]&&(O+=D/B[1]>>>m[0],D%=B[1]),t=O+P[0](32,D)+P[0](33,h)),Q=t),G=Q),G},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if((N^28)>>(G=[32,4,"multiply"],((N^22)&7)==2&&(O=B0.M().get(),T[42](36,12,O)||m.JO?m.iI=P[5](8,e,C,3,L,Q,m):T[42](64,h,O)&&(m.O=I[45](1,G[1],e,Q,m))),3)==2)a:{if((u=[8,9007199254740991,"number format error: empty string"],e).charAt(C)=="-"){c=S[27](2,K[21](8,0,e.substring(1),L)); +break a}if(t=parseInt(e,L||10),t<=u[1]){c=new mu(t/4294967296|C,t%4294967296|C);break a}if(e.length==C)throw Error(u[2]);if(e.indexOf(yR())>=C)throw Error('number format error: interior "-" character: '+e);if((h=L||10,h)<2||36<h)throw Error("radix out of range: "+h);for(D=(B=H[12](40,oM(h,u[0])),q=C,iC);q<e.length;q+=u[0])m=RY(u[0],e.length-q),Q=parseInt(e.substring(q,q+m),h),m<u[0]?(O=H[12](G[0],oM(h,m)),D=D[G[2]](O).add(H[12](33,Q))):(D=D[G[2]](B),D=D.add(H[12](38,Q)));c=D}return(N+2^15)>=N&&(N+ +G[1]^19)<N&&(c=U[38](1)?P[35](20,C,vQ):I[1](95,"Edg/")),(N^58)>>3==3&&(L=y[41](11,c7.M(),e),C.s5.push.apply(C.s5,T[5](87,L)),c=L),c},function(N,C,e,L,h,Q){return(N-9^19)>=((N&((h=["call","prototype","join"],N)+8>>3==1&&(e=[RG,Fy],Q=(L=Array.from(nS(Ij)).find(function(m){return e.includes(m.autocomplete)&&m.type!=vi&&m.value}))==C?void 0:L.value),42))==N&&(C.classList?Array[h[1]].forEach[h[0]](e,function(m){W[16](51,C,m)}):K[2](36,"string",Array[h[1]].filter[h[0]](U[19](3,C),function(m){return!S[9](46, +e,m)})[h[2]](" "),C)),N)&&(N-9^27)<N&&(e==C||ZW(e),Q=e==C?null:v[28](44,e)),Q},function(N,C,e,L,h,Q,m,O,t,D){if((N+2&(D=[3,"K",9],(N&84)==N&&(h=h===void 0?!1:h,P[44](77,function(q,u){if((u=[17,"i","G"],q.B)==1)return q[u[1]](cy(T[45](35),I[13](77),void 0,S[28](u[0]).Error()),C);e.K=(m=q[u[Q=function(B){return(B=["CD",44,2],I)[B[1]](8,B[2],1,8,16,h,m[B[0]](),e,L)},2]],e.K.then(Q,Q)),q.P()})),7))==1){if(Q==D[0]&&m.B&&!m[D[1]])for(O=h;O&&O[D[1]];O=O.G)O[D[1]]=!1;if(m.i)m.i.G=e,S[43](36,C,m,L,Q);else try{m[D[1]]? +m.o.call(m.G):S[43](28,C,m,L,Q)}catch(q){Rj.call(e,q)}P2.put(m)}return(N+D[0]&58)<N&&(N+6^D[2])>=N&&(t=H[38](8,L,v[34](29,null,e),C)),(N-D[2]&16)<10&&N-D[0]>=27&&(this.listener=Q,this.proxy=null,this.src=C,this.type=L,this.capture=!!e,this.handler=h,this.key=++FW,this.bx=this.UV=!1),t},function(N,C,e,L,h){if(((N^(L=[0,4,"Value of float/double field must be a number, found "],L[1]))&5)>=L[0]&&(N-3&8)<6){if(C==null)e=C;else{if(typeof C!=="number")throw Error(L[2]+typeof C+": "+C);e=C}h=e}if((N+7&5)>= +L[0]&&(N<<1&8)<3)a:try{h=W[1](10,e)>C?e.i.status:-1;break a}catch(Q){h=-1;break a}return h},function(N,C,e,L,h,Q,m){if(((Q=[1,3,null],N>>2)&10)==2){for(h in L=[],e)W[2](8,C,L,e[h],h);m=L.join(lC())}return(N<<((N+4&54)<N&&N-9<<2>=N&&(m=T[30](48,w7,Q[0],Q[0])),Q)[0]&12)<Q[1]&&N+Q[1]>>Q[1]>=2&&(m=Q[2]),m},function(N,C,e,L,h,Q,m,O,t,D){if((N+(D=[42,4,0],5)^11)>=N&&(N-9|35)<N&&e.Nd&C)throw Error("Cannot mutate an immutable Map");if(!(N+1>>D[1]))a:{if(O=[null,!1,0],h&&h.once){t=P[8](35,!0,L,e,C,h,Q);break a}if(Array.isArray(C)){for(m= +O[2];m<C.length;m++)K[26](9,C[m],e,L,h,Q);t=O[D[2]];break a}t=(L=l[18](58,L),S)[7](6,e)?e.j.add(String(C),L,O[1],I[6](54,h)?!!h.capture:!!h,Q):H[6](8,O[1],e,L,Q,O[1],h,C)}return(N|3)>=-(N-2>>D[1]>=2&&(N-7&16)<12&&(e='<img src="'+H[7](64,P[11](33,C.Ac))+'" alt="',e+=U[D[0]](48,"reCAPTCHA challenge image"),t=P8(e+'"/>')),74)&&((N|3)&10)<9&&((L=c7.M()).i.apply(L,T[5](41,e.s5)),e.s5.length=C),t},function(N,C,e,L,h,Q){if(!(((N+(h=[41,9,2],h[1])&28)>=N&&(N+7^17)<N&&(L=L===void 0?null:L,Q=l[27](h[0],function(m, +O,t){m.subscribe(new zk(O,function(D){O.next((t=e,D))},void 0,(t=C,function(){t||O.next(L),O.complete()})))})),N>>h[2])&7)){if(typeof C!=="string")throw Error();Q=C}return Q},function(N,C,e,L){return(L=[14,28,21],(N^L[0])>=25&&(N^L[1])<34)&&(this.handler=C),e},function(N,C,e,L,h,Q,m){return(N&108)==((((Q=[14,"G",7],N+Q[2]>>3)==1&&(L=L===void 0?0:L,h=(typeof e==="string"?y[Q[0]](2,e,L):e+L)|C,h=(h>>16^h)*2642172555,h=(h>>16^h)*2642172555,m=h>>16^h),N-4)&Q[2])==2&&(this.i=Zf.setTimeout(Pe(this[Q[1]], +this),0),this.B=C),N)&&p.call(this,C),m},function(N,C,e,L,h,Q){return((h=["i","isEnabled","o"],N+7>=19)&&(N<<2&8)<6&&(C[h[0]](),this[h[1]]()&&this[h[0]]!=3&&!C.target.href&&(e=!this.gq(),v[44](35,this,e?TA:Zg)&&(C.preventDefault(),this.Iz(e)))),(N|2)>>3)||(yE.call(this),this.G=-1,this[h[0]]=C,this[h[2]]=new oj(this[h[0]]),I[5](8,this,this[h[2]]),(vy&&na||yc||At)&&K[26](11,[PQ,s1],this[h[0]],this.K,!1,this),e||(K[26](8,fS,this[h[2]],this.B,!1,this),K[26](10,uA,this[h[0]],this.P,!1,this)),this.V=L), +Q},function(N,C,e,L,h,Q,m,O,t,D,q){return(((((N|6)&(N-9&(N+(D=[15,4,14],3)&D[0]||(P[20](9,pC,function(u){T[11](14,!0,1,C,u)}),f[36](16,!0,pC)||y[0](2)),13)||(q=l[27](1,function(u,B,G,c,A){(G=u.subscribe(new zk(B,void 0,(A=!1,G=e,function(n,R){c=U[12](19,C,L(n,(R=[null,31,"unsubscribe"],K)[R[1]](25,"'",R[0],L)(u))),G?(G[R[2]](),G=e,c.subscribe(B)):A=!0}))),A)&&(G.unsubscribe(),G=e,c.subscribe(B))})),24))<6&&N+D[1]>=12&&(O=C.hE,Q=C.n7,e=C.style,m=f[20](23,XW(),O,UY(),QR()),h=f[20](7,S6(),Q,UY(),QR()), +L=f[20](7,St(),e,UY(),QR()),q=T[1](17,W[11](10,T[1](80,fJ(),'<div class="grecaptcha-badge" data-style="'+H[7](33,L)+'"><div class="grecaptcha-logo"></div><div class="grecaptcha-error"></div>'),S[D[1]](77,m,h)),jB())),N-9<<1)<N&&N-6<<2>=N&&(q=new wu(function(u,B,G){(B=S[19](4,C,(G=[0,null,14],G[1]),document,e,"img"),B.length)==G[0]?u():K[26](G[2],Y3,B[G[0]],function(){u()})})),N+5)&27)>=N&&N-D[1]<<2<N&&(m=[0,17,11],Q=L(e(),m[2]),h(Q,m[1])&&(O=h(Q,m[1])(y[D[2]](40,8105,20)))&&O[m[0]]&&(t=L(O[m[0]], +27)||""),q=U[D[1]](18,2120)(t)),q},function(N,C,e,L,h,Q,m,O,t){if((N+2&(t=[27,92,"call"],11))==3)p[t[2]](this,C,0,fN.yl);return(N&106)==((N|1)<((N|((N&t[1])==N&&(L=[820,148,17],O=C==0?0:9*vh(1<<32-WQ(C+C/2-1),4)<=e?C==0?0:C<4?100+(C-1)*16:C<6?L[1]+(C-4)*16:C<12?244+(C-6)*16:C<22?436+(C-12)*19:C<44?L[0]+(C-22)*L[2]:52+32*C:40+4*e),80))==N&&(O=P[44](73,function(D){return D.return((e=String(C.G++),e))})),32)&&(N<<1&t[0])>=23&&(e.i=T[26](23,C,L)),N)&&(O=e.j.add(String(h),L,C,Q,m)),O},function(N,C,e,L, +h,Q,m,O){return(N|24)==(N-1<<((((O=[7,16,5],(N^13)<36)&&(N^11)>=24&&(m=String(C).replace(m7,I[43].bind(null,19))),N)|32)==N&&(Q=C.S,h=e||"Verify",f[38](30,9,"object",Q.v(),h),Q.RX=h,H[O[0]](O[1],C.S.v(),!!L,HQ)),1)>=N&&N-O[0]<<2<N&&(e=e===void 0?"0":e,K2.call(this),this.hc=this.BE=null,this.WS=C,this.RM=e),N)&&(K[O[2]](15,[-99,-92],f[19].bind(null,22)),K[O[2]](9,[-84],S[11].bind(null,1)),K[O[2]](17,[-15,-65],U[23].bind(null,8)),K[O[2]](37,[-27],l[23].bind(null,58))),m},function(N,C,e,L,h,Q,m){return(N<< +((N|((Q=[20,1,2],(N|Q[1])&6||(this.r0(!1),this.Mp(!1),v[44](35,this,"k")),(N^91)&15||L.P.width==e.width&&L.P.height==e.height)||(L.P=e,h&&v[39](25,K[25].bind(null,16),L),v[44](35,L,C)),7))>=7&&(N|Q[2])<8&&C&&typeof C.dispose=="function"&&C.dispose(),Q)[2]>=0&&(N^23)<17&&YK.call(this,360,Q[0],[2]),N+5&41)>=N&&N+8>>Q[1]<N&&k3.call(this,8,r5),m},function(N,C,e,L,h,Q,m,O){return((((N^36)&3)==((N-2&(O=[15,null,1],O[0]))==O[2]&&(this.i=C),O[2])&&(h=H[O[0]](36,this),e=this.Pm,L=y[34](55,this),C=W[14](8, +O[2],L,""),e[h]=C),N-4|62)>=N&&(N+O[2]&62)<N&&(Q=U[48].bind(O[1],12),m=W[28](5,C,function(t,D,q,u){return(q=((u=(q=t,-(q&e)),q>>>e)|D<<L)^u,Q)(q,D>>>e^u)},h)),N&117)==N&&p.call(this,C),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r){if((N<<(J=["i",2,"o"],(N&42)==N&&(r=U[4](10,11)(L(C(),43))),J)[1]&19)>=12&&N>>1<18)a:{for(c=(G=[(A=m.length,u=[],0),">","'"],F=[],t=G[0],G[0]);t<A;){switch(c){case G[0]:if(D=m.indexOf(pS(),t),D<G[0]){if(u.length===0){r=m;break a}t=(u.push(m.substring(t)), +A)}else u.push(m.substring(t,D)),O=D,t=D+h,JF?(E1.lastIndex=t,R=E1.exec(m)):(E1.lastIndex=G[0],R=E1.exec(m.substring(t))),R?(q=R[h],c=h,t+=R[G[0]].length,F=["<",R[G[0]]]):u.push(pS());break;case h:B=m.charAt(t++);switch(B){case G[J[1]]:case L:(n=m.indexOf(B,t),n<G[0])?t=A:(F.push(B,m.substring(t,n+h)),t=n+h);break;case G[1]:F=(c=(q=O=((F.push(B),u).push(Q(F.join(C),q)),e),G)[0],[]);break;default:F.push(B)}break;default:throw Error();}c===1&&t>=A&&(t=O+h,u.push(pS()),F=[],q=O=e,c=G[0])}r=u.join(C)}if((N| +72)==N){D=["backChannelRequestTimeoutMs_=",6E3,0];try{if(Q=e[J[2]],Q.B!=D[J[1]]&&(Q[J[0]]==e||U[24](6,e,Q.G)))if(!e.F&&U[24](21,e,Q.G)&&Q.B==3){try{R=Q.mC[J[0]].parse(L)}catch(z){R=null}if(Array.isArray(R)&&R.length==3){if((A=R,A[D[J[1]]])==D[J[1]])a:if(zA(),Q.X)d5();else{if(Q[J[0]])if(Q[J[0]].Z+3E3<e.Z)I[37](25,null,Q),v[16](20,null,Q);else break a;else w5();(l[9](4,3,Q),H)[8](6,18)}else Q.PK=A[1],D[J[1]]<Q.PK-Q.T&&A[J[1]]<37500&&Q.l&&Q.J==D[J[1]]&&!Q.h&&(Q.h=y[9](26,Pe(Q.Fd,Q),D[1]));if(v[44](8, +Q.G)<=1&&Q.lI){try{Q.lI()}catch(z){VR()}Q.lI=void 0}}else x3(),S[39](1,J[1],Q,11)}else if((e.F||Q[J[0]]==e)&&I[37](17,null,Q),!S[23](30,L))for(E=Q.mC[J[0]].parse(L),Z=D[J[1]];Z<E.length;Z++)if(c=E[Z],G=c[D[J[1]]],!(G<=Q.T))if(c=c[1],Q.T=G,Q.B==J[1])if(c[D[J[1]]]=="c"){if(O=e[((k=((Q.E5=(Q.R=c[1],c)[J[t=c[3],1]],t)!=null&&(Q.S_=t,Q.K.info("VER="+Q.S_)),c)[4],k)!=null&&(Q.DR=k,Q.K.info("SVER="+Q.DR)),m=c[5],m!=null&&typeof m==="number")&&m>D[J[1]]&&(n=1.5*m,Q.C=n,Q.K.info(D[0]+n)),J[0]],F=Q,O){if(B= +O[J[0]]?O[J[0]].getResponseHeader(aj):null)h=F.G,!h[J[0]]&&(y[48](54,"spdy",B)||y[48](51,"quic",B)||y[48](56,"h2",B))&&(h[J[2]]=h.K,h[J[0]]=new Set,h.B&&(U[10](58,h.B,h),h.B=null));F.Z&&((u=O[J[0]]?O[J[0]].getResponseHeader(g5):null)?(F.wq=u,U[35](73,F.F,F.Z,u)):bC())}if((X=(((Q.B=3,Q).P&&Q.P.K(),Q).j_=Date.now()-e.Z,Q.Hm&&Q.K.info("Handshake RTT: "+Q.j_+C),q=e,Q),X).qp=U[30](48,".","",X,X.Ku,X.u?X.E5:null),q.F)M9(),y[39](15,null,q,X.G),(Y=X.C)&&q.setTimeout(Y),q.S&&(l[5](21,null,q),S[J[1]](32,q)), +X[J[0]]=q;else W[41](38,!0,D[J[1]],X);Q[J[2]].length>D[J[1]]&&f[18](J[1],!0,Q)}else c[D[J[1]]]!="stop"&&c[D[J[1]]]!="close"||S[39](4,J[1],Q,7);else Q.B==3&&(c[D[J[1]]]=="stop"||c[D[J[1]]]=="close"?c[D[J[1]]]=="stop"?S[39](5,J[1],Q,7):l[24](17,null,Q):c[D[J[1]]]!="noop"&&Q.P&&Q.P[J[2]](c),Q.J=D[J[1]]);l[47](19,4)}catch(z){$3()}}if((N+J[1]&57)>=N&&N+3>>J[1]<N)P[44](45,function(z,d){if((d=["P","G","uI"],z.B)==L)return(O=h.W)!=C&&O.size?z.i(h[d[2]].send(NQ,new Cc(h.W)),e):z.return();(((Array.from((m= +new Map((Q=z[d[1]],Q.mj)),m).keys()).forEach(function(x){return h.W["delete"](x)}),h).h=h.h.concat(Array.from(m.values()).map(function(x){return new UO(x)})),h).S_=Q.CJ,z)[d[0]]()});return(N^77)>>4||(eb.call(this,[L.left,L.top],[L.right,L.bottom],h,Q),this.h=!!m,this.V=C,this[J[2]]=e),r},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if((N+8&14)==(N-4>>(G=["focus","call","keyCode"],3)==1&&(this.G=[],this.B=0,this.i=new Lc),2))a:if(m=[1,38,39],L[G[2]]==37||L[G[2]]==m[2]||L[G[2]]==m[1]||L[G[2]]==40||L[G[2]]== +C)if(O=[],L[G[2]]!=C){if((t=(Array.prototype.forEach[G[1]](P[48](22,hI),function(A){P[22](54,A,"display")!=="none"&&QU((A||document).querySelectorAll(".rc-imageselect-tile"),function(n){O.push(n)})}),O).length-m[0],h.Xe>=e)&&O[h.Xe]==y[14](36,null,document))switch(t=h.Xe,L[G[2]]){case 37:t--;break;case m[1]:t-=Q;break;case m[2]:t++;break;case 40:t+=Q;break;default:c=void 0;break a}(t>=e&&t<O.length?O[t][G[0]]():t>=O.length&&I[17](18,mc,document)[G[0]](),L.preventDefault(),L).i()}if(((((N^66)&3)<2&& +(N-7&15)>=12&&(this.B=C,this.i=e),N)-3|27)>=N&&N-7<<2<N)a:{if(W[3](9,L,h)||I[40](11,e)){c=new OZ("",0,0);break a}B=(D=(u=(O=(q=qY(),I[33](2,C)),new tI),P)[4](15,O),D.next());try{for(;!B.done&&u.add(B.value);B=D.next());}finally{B&&!B.done&&(Q=D.return)&&Q[G[1]](D)}c=(m=(t=u.toString(),qY()-q),new OZ(t,m,O.length))}return c},function(N,C,e,L,h,Q,m,O,t,D,q){if((N|24)==(q=[5,13,40],N)){h=K[24](32,2,(m=[304,!0,201],e));a:switch(h){case 200:case m[2]:case 202:case 204:case 206:case m[0]:case C:L=m[1]; +break a;default:L=!1}if(!(Q=L)){if(O=h===0)t=l[24](9,1,null,String(e.l)),O=!UZ.test(t);Q=O}D=Q}return N+6&((N&(((N^76)&14)>=q[1]&&(N>>1&15)<4&&p.call(this,C),116))==N&&(m=Q.z2,D=W[14](65,null,m[Rw]|C,L,m,T[33](58,Q,void 0,e,h))!==void 0),11)||(K[q[0]](39,[-70,-98],y[32].bind(null,8)),K[q[0]](39,[-28,-32],v[19].bind(null,4)),K[q[0]](7,[-26,-22],U[33].bind(null,q[2]))),D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r){return(N|32)==((r=[1,7,80],N+9)>>3==r[0]&&(E=["rc-anchor-logo-portrait", +'">'," "],X=f[20](16,Db(),C.size,UY(),tF()),qQ(),UY(),QR(),uo(),UY(),QR(),Gt(),UY(),XG(),cL(),UY(),XG(),Hy(),UY(),XG(),kj(),UY(),XG(),U$(),UY(),DJ(),qP(),UY(),uM(),X===1?(D=f[20](18,qQ(),C.cS,UY(),QR()),uo(),UY(),QR(),m=f[20](20,Gt(),C.qW,UY(),XG()),L=f[20](16,cL(),C.x7,UY(),XG()),t=f[20](20,Hy(),C.QM,UY(),XG()),k=f[20](22,kj(),C.es,UY(),XG()),Z=f[20](19,U$(),C.errorMessage,UY(),DJ()),A=f[20](22,qP(),C.errorCode,UY(),uM()),u=T[r[0]](65,W[11](10,W[11](74,W[11](78,W[11](86,W[11](18,T[r[0]](r[0],W[11](84, +W[11](42,T[r[0]](16,fJ(),'<div id="'+H[r[1]](33,"rc-anchor-container")+'" class="'+H[r[1]](64,"rc-anchor")+E[2]+H[r[1]](32,"rc-anchor-normal")+E[2]+H[r[1]](65,D)+E[r[0]]),H[43](89,C.FI)),y[32](13)),'<div class="'+H[r[1]](32,"rc-anchor-content")+E[r[0]]),Z||(A!=null?A:null)>0?S[r[1]](33,15,null,C):H[31](5,E[2])),m?T[r[0]](r[2],W[11](50,T[r[0]](r[0],fJ(),Bc()),I[46](r[2])),jB()):""),L?T[r[0]](81,W[11](10,T[r[0]](65,fJ(),Bc()),I[47](41)),jB()):""),t?T[r[0]](r[0],W[11](54,T[r[0]](r[0],fJ(),jb()),W[r[0]](r[2])), +jB()):""),k?T[r[0]](r[0],W[11](78,T[r[0]](81,fJ(),GW()),P[34](2)),jB()):""),'</div><div class="'+H[r[1]](r[0],"rc-anchor-normal-footer")+E[r[0]]),O=C.x7,q=C.qW,n=f[20](16,Gt(),q,UY(),XG()),c=f[20](18,cL(),O,UY(),XG()),B=P8('<div class="'+H[r[1]](32,E[0])+(n||c?E[2]+H[r[1]](64,"rc-anchor-over-quota-logo"):"")+'" aria-hidden="true" role="presentation"><div class="'+H[r[1]](65,"rc-anchor-logo-img")+E[2]+H[r[1]](65,"rc-anchor-logo-img-portrait")+'"></div><div class="'+H[r[1]](32,"rc-anchor-logo-text")+ +'">reCAPTCHA</div></div>'),Y=T[r[0]](r[0],W[11](50,W[11](46,u,B),S[38](4,E[2],C)),W8())):X===2?(F=f[20](r[1],qQ(),C.cS,UY(),QR()),uo(),UY(),QR(),Q=f[20](23,Gt(),C.qW,UY(),XG()),h=f[20](22,cL(),C.x7,UY(),XG()),R=f[20](18,Hy(),C.QM,UY(),XG()),G=f[20](23,kj(),C.es,UY(),XG()),e=f[20](19,U$(),C.errorMessage,UY(),DJ()),qP(),UY(),uM(),Y=T[r[0]](r[2],W[11](74,W[11](82,T[r[0]](17,W[11](42,W[11](22,W[11](18,W[11](79,W[11](46,T[r[0]](r[2],W[11](78,W[11](14,T[r[0]](17,fJ(),'<div id="'+H[r[1]](33,"rc-anchor-container")+ +'" class="'+H[r[1]](64,"rc-anchor")+E[2]+H[r[1]](64,"rc-anchor-compact")+E[2]+H[r[1]](r[0],F)+E[r[0]]),H[43](90,C.FI)),y[32](5)),'<div class="'+H[r[1]](33,"rc-anchor-content")+E[r[0]]),e?S[r[1]](32,15,null,C):H[31](4,E[2])),Q?T[r[0]](17,W[11](18,T[r[0]](r[2],fJ(),Bc()),I[46](81)),jB()):""),h?T[r[0]](65,W[11](74,T[r[0]](17,fJ(),Bc()),I[47](65)),jB()):""),R?T[r[0]](r[0],W[11](52,T[r[0]](16,fJ(),jb()),W[r[0]](72)),jB()):""),G?T[r[0]](r[2],W[11](14,T[r[0]](16,fJ(),GW()),P[34](3)),jB()):""),'</div><div class="'+ +H[r[1]](r[0],"rc-anchor-compact-footer")+E[r[0]]),P8('<div class="'+H[r[1]](32,"rc-anchor-logo-landscape")+'" aria-hidden="true" role="presentation" dir="ltr"><div class="'+H[r[1]](33,"rc-anchor-logo-img")+E[2]+H[r[1]](65,"rc-anchor-logo-img-landscape")+'"></div><div class="'+H[r[1]](65,"rc-anchor-logo-landscape-text-holder")+'"><div class="'+H[r[1]](r[0],"rc-anchor-center-container")+'"><div class="'+H[r[1]](r[0],"rc-anchor-center-item")+E[2]+H[r[1]](32,"rc-anchor-logo-text")+'">reCAPTCHA</div></div></div></div>')), +S[38](5,E[2],C)),W8())):Y="",J=W[11](20,fJ(),Y)),N)&&(J=P[18](27,S[32](76,new b4,C),e.map(function(z){return W[0](1,z)}))),J},function(N,C,e,L,h,Q,m,O){if((((O=[2,11,5],N-6^31)<N&&N+O[2]>>1>=N&&(cc===void 0&&(cc=W[6](4,C)),m=cc),N+3)&O[1])==O[0])a:switch(typeof Q){case "boolean":m=Kc||(Kc=[0,void 0,!0]);break a;case e:m=Q>h?void 0:Q===0?AI||(AI=[0,void 0]):[-Q,void 0];break a;case L:m=[0,Q];break a;case C:m=Q;break a}return(N|48)==N&&YK.call(this,779,O[1],[2]),m},function(N,C,e,L,h,Q){if((N+6&(h= +["G",3,"F"],h)[1])==1){if(e.nodeType===1&&/^(script|style)$/i.test(e.tagName))throw Error(C);e.innerHTML=W[36](7,C,L)}return(((N|16)==N&&(i0||vy||yc||At?eB.call(this,yU.width,yU.height,io,I$):eB.call(this,vc.width,vc.height,io,I$),this.i=this.T=null,this.l=i0||vy||yc||At,this[h[0]]=new Qn(""),P[39](24,'"',this[h[0]],nc),I[5](10,this,this[h[0]]),this[h[2]]=new mS,I[5](24,this,this[h[2]]),this.h=null),N+6)&44)>=N&&N-4<<2<N&&(Q=v[12](70,C,e)),Q},function(N,C,e,L,h,Q,m,O,t,D,q){if(!(N-(q=["render",56, +"j_"],3)>>4))a:{if((t=f[27](31,(Q=new aw(0,0),C),L),L)==(t?f[27](36,C,t):document).documentElement){D=Q;break a}(m=(h=P[10](11,L),W)[46](2,C,t),O=H[49](25,e,m.i),Q.x=h.left+O.x,Q).y=h.top+O.y,D=Q}return(N>>(N<<2>=-88&&(N^72)>>4<4&&p.call(this,C),1)&13||(m=[null,0,"-"],Q=Q===void 0?2:Q,H[18](4,m[0],h.B),t=v[7](2,m[1],!0,m[0],L,h),h.B[q[0]](t,T[3](7,m[2],h.id),String(T[27](4,e,10,h)),I[6](32,h.i,We)),O=h.B.K,D=T[23](9,e,80,t,O,new Map([[Gz,h.UG],[Iz,h.rq],[jq,h.l],[Uk,h.o6],[DD,h.C],[Rz,h.W],[Fa,h.T], +[lo,h[q[2]]],[TW,function(u,B){return(B=[34,78,40],S)[B[0]](B[2],B[1],1024,!0,"",h,u)}],[NL,h.bY],[Zb,h.I5],[NQ,h.iI],[gi,h.Qp],[AM,h.O]]),h,h.A).catch(function(u,B,G,c){if((c=[!(B=["en","-",0],0),"En","B"],(0,B8[c[1]])(),h.kU).contains(O)){if((G=Q-C,G)>e)return K[42](1,1,B[2],L,h,G);h[c[2]].I(I[32](10,c[0],B[0],h),T[3](6,B[1],h.id),c[0])}throw u;})),(N|q[1])==N)&&(D=y[5](77,C,Array.from(Wi.prototype.entries.call(e),L))),D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F){if(((A=[7,41,"endsWith"], +N)&A[1])==N){for(u=(t=(Q=(B=(R=(c=(F=function(Z,X,Y,k,E,J,r){for(m<(X=(r=[0,8,63],q)*r[1],E=(Z=[255,56,64],[]),Z[1])?R(t,Z[1]-m):R(t,Z[2]-(m-Z[1])),k=r[2];k>=Z[1];k--)O[k]=X&Z[r[0]],X>>>=r[1];for(k=(Y=(n(O),r)[0],r[0]);k<5;k++)for(J=24;J>=r[0];J-=r[1])E[Y++]=Q[k]>>J&Z[r[0]];return E},function(Z,X){m=(Q[4]=(Q[Q[Q[Q[(Z=[2,(X=[271733878,4023233417,3285377520],0),2562383102],Z)[1]]=1732584193,1]=X[1],Z[0]]=Z[2],3]=X[0],X[2]),Z[1]),q=Z[1]}),n=function(Z,X,Y,k,E,J,r,z,d,x,w,a,g,M){for(a=(M=(w=0,z=[20,4294967295, +5],[8,2,16]),D);w<64;w+=4)a[w/4]=Z[w]<<24|Z[w+1]<<M[2]|Z[w+M[1]]<<M[0]|Z[w+3];for(w=M[2];w<C;w++)d=a[w-3]^a[w-M[0]]^a[w-e]^a[w-M[2]],a[w]=(d<<1|d>>>31)&z[1];for(x=Q[r=(k=(X=Q[0],Q[M[g=Q[3],1]]),Q[1]),w=0,4];w<C;w++)w<40?w<z[0]?(E=1518500249,Y=g^r&(k^g)):(E=1859775393,Y=r^k^g):w<L?(Y=r&k|g&(r|k),E=2400959708):(E=3395469782,Y=r^k^g),J=((X<<z[M[1]]|X>>>h)&z[1])+Y+x+E+a[w]&z[1],x=g,g=k,k=(r<<30|r>>>M[1])&z[1],r=X,X=J;(Q[3]=(Q[(Q[1]=(Q[0]=Q[0]+X&z[1],Q[1]+r)&z[1],M)[1]]=Q[M[1]]+k&z[1],Q)[3]+g&z[1],Q)[4]= +Q[4]+x&z[1]},function(Z,X,Y,k,E,J,r,z){if(typeof Z===(z=[1,0,"slice"],J=[0,64],"string")){for(Y=(Z=unescape(encodeURIComponent(Z)),Z).length,E=[],k=J[z[1]];k<Y;++k)E.push(Z.charCodeAt(k));Z=E}if(m==J[r=J[z[X||(X=Z.length),1]],z[1]])for(;r+J[z[0]]<X;)n(Z[z[2]](r,r+J[z[0]])),r+=J[z[0]],q+=J[z[0]];for(;r<X;)if(O[m++]=Z[r++],q++,m==J[z[0]])for(m=J[z[1]],n(O);r+J[z[0]]<X;)n(Z[z[2]](r,r+J[z[0]])),q+=J[z[0]],r+=J[z[0]]}),oz()),[]),O=[],D=[],[128]),1);u<64;++u)t[u]=0;G=(c(),{reset:c,update:R,digest:F,AW:function(Z, +X,Y,k,E,J,r){for(J=(E=F(),r=Y,k);r<E.length;r++)J+=B[Z](TH(E[r]/X))+B[Z](E[r]%X);return J}})}return(N-1&A[0])==1&&(e=Zf[Pc()]||"https://www.google.com/recaptcha/api2/",e[A[2]](sZ())||e[A[2]](fc())||(e+="api2/"),C==pz&&(e=e.replace(Xa(),Sb())),G=(l[17](95,e).B?"":cv())+e+C),G},function(N,C,e,L,h,Q,m,O,t,D,q){return(((N^26)&((N&((((N&(D=[16,10,77],D)[2])==N&&(t=[1,0],this.i=typeof C==="number"?new Date(C,e||t[1],L||t[0],h||t[1],Q||t[1],m||t[1],O||t[1]):new Date(C&&C.getTime?C.getTime():P[3](3))),N)+ +4^29)>=N&&(N-5|65)<N&&(L=String(C),e.o&&(L=L.toLowerCase()),q=L),62))==N&&(q=y[44](D[0],C,e,L)),D)[0])<7&&N+7>=D[1]&&(q=(L?Yk():Wc())+f[18](44,e)+C),N+7>>4<4&&(N-6&13)>=5)&&p.call(this,C),q},function(N,C,e,L,h,Q,m){return(N<<2&((N-3|14)<((N>>((N-9|(Q=[11,1,64],29))<N&&(N-5^16)>=N&&(m=C.timeRemaining()),Q[1])&5||!e||(h=e.indexOf(L),0<=h&&e.splice(h,C)),(N-8|69)<N&&N-3<<Q[1]>=N)&&(e="",C=C||{},L=C.vj,f[20](22,Hc(),L,UY(),kk())||(e+="Press R to replay the same challenge. "),m=P8(e+'Press the refresh button to get a new challenge. <a href="https://support.google.com/recaptcha/#6175971" target="_blank">Learn how to solve this challenge.</a>')), +N)&&(N+4&59)>=N&&(C=["rc-doscaptcha-header-text",'Your computer or network may be sending automated queries. To protect our users, we can\'t process your request right now. For more details visit <a href="https://support.google.com/websearch/answer/86640" target="_blank">our help page</a>.','">'],e=T[Q[1]](16,fJ(),'<div><div class="'+H[7](65,"rc-doscaptcha-header")+'"><div class="'+H[7](32,C[0])+C[2]),W[Q[0]](50,e,"Try again later"),T[Q[1]](65,e,'</div></div><div class="'+H[7](65,"rc-doscaptcha-body")+ +'"><div class="'+H[7](Q[2],"rc-doscaptcha-body-text")+'" tabIndex="0">'),W[Q[0]](18,e,C[Q[1]]),T[Q[1]](16,W[Q[0]](86,T[Q[1]](Q[1],e,'</div></div></div><div class="'+H[7](32,"rc-doscaptcha-footer")+C[2]),l[Q[0]](52," ")),jB()),m=e),28))<25&&(N>>Q[1]&15)>=7&&(m=U[13](28,e,r6,C,rY)),m},function(N,C,e,L,h,Q,m,O,t,D){return((N|((N^23)<((D=[1,2,"8x-4t2pegToiW8KmThtO4AQt"],N)-6>>3==3&&YK.call(this,1422,21),21)&&((N|D[1])&7)>=D[0]&&(e.i.length>=C&&(e.i=[y[14](D[1],P[20](18,"[",e.i)).toString()]),e.i.push(L)), +64))==N&&(m=[null,!1,"GET"],this.G=h||m[0],this.ah=m[D[0]],this.NW=e,this.B=L||m[D[1]],this.sn=new sB(C),this.WL="",this.Rz=m[0],this.i=new fz,O=Q||H[13](13,B0.M().get()),S[6](D[0],this.sn,XN,O),v[48](55,W7,this,D[2])),N^51)>=24&&(N+D[0]&12)<D[0]&&(h=C.v?C.v():C)&&(L?y[40].bind(null,32):K[22].bind(null,8))(h,[e]),t},function(N,C,e,L,h,Q,m,O){if(!(((N|(O=[7,21,0],72))==N&&(Q||e!=C?h.Cu&e&&L!=!!(h.Wm&e)&&(h.G.Ih(h,e,L),h.Wm=L?h.Wm|e:h.Wm&~e):h.I6(!L)),N|2)>>4))a:{if(L==null){m=L;break a}if((h=typeof L, +h)==="bigint"){m=String(Ro(C,L));break a}if(!n2){m=L;break a}if(T[49](35,L,e)){if(h==="string"){m=W[2](66,O[2],L,e);break a}if(h==="number"){m=y[49](24,O[2],e,L);break a}}}return(N&((N>>1&31)>=O[1]&&(N<<1&16)<1&&(K[5](9,[-80,-50],v[49].bind(null,2)),K[5](O[1],[-31],I[39].bind(null,O[0])),K[5](3,[-18,-17],W[O[0]].bind(null,16))),60))==N&&(v[22](15,h,L,2),S[6](63,C,h.i,e.length),T[O[0]](36,h,h.i.end()),T[O[0]](34,h,e)),N>>2&11||(L=new Wt,m=H[6](6,e,C,pc,1,L)),m},function(N,C,e,L,h,Q,m,O){if((N>>((N+ +(m=[10,1,"clientX"],5)^19)>=N&&(N-2|m[1])<N&&(this.value=C),m[1])&4)<4&&(N|6)>>3>=m[1])a:{if(L.nodeType==C){Q=P[m[0]](m[0],L),O=new aw(Q.left,Q.top);break a}O=(h=L.changedTouches?L.changedTouches[e]:L,new aw(h[m[2]],h.clientY))}return O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if((G=[3,8,3E3],N+6)>>4<2&&(N+6&15)>=2){for(;!W[27](6,this.i)&&this.A<this.O;)this.A+=1,C=y[42](G[0],this.i),e=I[22](16,this.i),this.G[e](C);W[27](2,this.i)||(this.j=this.i.i)}return(N&(((N|((N^25)>>4||(h=h===void 0?null()+ +G[2]:h,C===void 0&&null(),this.N=Q,this.ez=L,this.e_=h,this.U_=e,this.xx=1),G)[1])&7)==G[0]&&(c=P[44](13,function(A,n,R){R=[2,35,(n=[2,"allow",null],0)];switch(A.B){case e:if((O=((u={},u[YY]="en",u)[W7]="8x-4t2pegToiW8KmThtO4AQt",u[XN]=H[13](1,B0.M().get()),u[JI]=Q.i.S,P[39](13,24,B0.M().get())))==n[R[0]]||!O){A.js(n[R[2]]);break}if(!S[28](48).isSecureContext||!S[28](1).navigator.mediaDevices){A.js((u[EZ]=L,n)[R[2]]);break}return(A.K((t=function(){return S[28](48).navigator.mediaDevices.enumerateDevices()}, +4)),A).i((0,B8.tj)(t,C),h);case h:(u[q=A.G,EZ]=q.some(function(F){return F.kind==="videoinput"}),A).V(n[R[2]]);break;case 4:A.o(),u[EZ]=L;case n[R[2]]:return m=new fz,T[R[1]](3,u,m),B={query:m.toString(),title:"recaptcha challenge expires in two minutes"},(D=P[39](36,24,B0.M().get()))!=n[R[0]]&&D&&(B[n[1]]="camera"),A.return(new zW(Q.B.W2(),B))}})),78))==N&&(c=l[36](G[0],C,L,d6,h,e)),c}]}(),l=function(){return[function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((N+(((N&58)==(B=[47,"window",0],N)&&(L=P[22](49, +T[B[2]](54,w6),VU),u=UR(function(){return L.match(/[^,]*,([\w\d\+\/]*)/)[C]},e)),(N>>1&15)==2)&&(L=C,typeof e.toString==="function"&&(L=C+e),u=L+e[xk()]),9)&15)==2){q=((Q=(t=[".eap.initTwoFactorVerificationHandle",".render",".getPageId"],Zf[B[1]][Bh][az()]&&Zf[B[1]][Bh][az()].indexOf(L)!==-1),Zf)[B[1]][Bh][az()]=[],P[4](14,h)),D=q.next();try{for(;!D.done;D=q.next())m=D.value,U[B[0]](23,H[10].bind(null,6),m+t[1]),U[B[0]](17,I[11].bind(null,8),m+e),U[B[0]](17,y[2].bind(null,10),m+".getResponse"),U[B[0]](21, +H[37].bind(null,41),m+".execute"),m==g6&&Q&&(U[B[0]](24,S[11].bind(null,88),m+".challengeAccount"),U[B[0]](25,K[9].bind(null,3),m+t[B[2]]))}finally{D&&!D.done&&(O=q.return)&&O.call(q)}U[B[0]](23,function(){return Zf.window[Bh][C]},bo+t[2])}return(N>>1&11)==1&&(h=h===void 0?0:h,m=W[33](33,e,L,Q,void 0,y[49].bind(null,15)),u=m!=C?m:h),u},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){if((A=["LD",36,25],(N+7&26)>=N)&&(N+5&13)<N){if(bj)h=K[4](26,186,0,91,C,e);else{if(gw&&M3)a:switch(e){case 93:L=91;break a; +default:L=e}else L=e;h=L}c=h}if((N>>((N&47)==N&&(Q=l5,m=TU,h=m>>C,m=(m<<e|Q>>>C)^h,L(Q<<e^h,m)),N>>1&11||(e===void 0&&(e=C[Rw]|0),e&32&&!(e&4096)&&W[32](32,e|4096,C)),1)&2)==2)a:{if(u=h[Q]){c=u;break a}if(D=h.iA)if(O=D[Q]){c=((m=T[39](17,e,O),G=m[C],t=m[e].JG,G)?(q=W[28](16,L,G),B=y[31](A[2],L,T[A[2]].bind(null,5),S[A[1]].bind(null,13),G,Wf)[A[0]],u=h.tK?og(B,q):function(n,R,F){return t(n,R,F,B,q)}):u=t,h)[Q]=u;break a}}return(N|80)==N&&(c=L.i?L.j==C&&L.T!=e&&L.o.z$:!1),c},function(N,C,e,L){return(N>> +1&((L=[7,120,5],(N+4&L[0])==1)&&(this.i=C),8))<2&&(N-L[2]&L[0])>=L[2]&&p.call(this,C),e},function(N,C,e,L,h,Q,m,O){return(N+7&7)==(((N-3^18)>=((N&90)==(O=[6,null,33],N)&&(L instanceof Je?(e.K=L,f[1](18,O[1],e.K,e.V)):(h||(L=H[40](25,C,MQ,L)),e.K=new Je(L,e.V)),m=e),N)&&(N+O[0]^13)<N&&(eB.call(this,$k.width,$k.height,C||Nm),this.JO=O[1],this.G={Ss:{Jc:null,element:null}},this.h=O[1],this.ZM=1,this.metadata=O[1],this.Xe=void 0),N+3^23)>=N&&(N+7&44)<N&&(m=L(e(),O[2],Ci())),2)&&(h=[15,11,2],Q=L(e(),h[1], +h[0],h[2]),m=Q>0?L(e(),h[1],h[0],26)-Q:-1),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA){if((((M=["add",3,4],N-M[2]^16)>=N&&(N+9&50)<N&&(u=[0,1E3,3],Q=[],G=S[17](5,"",u[2],(h=ec||Zf)==null?void 0:h.location.href),(B=Zf[Li]||Zf[h_]||Zf[Qi]||Zf[m2]||Zf[OT])?q=!0:(typeof document!=="undefined"&&(e=new dq(document),B=e.get(t_)||e.get(UT)||e.get(Dm)||e.get(qm)),q=!!B),q&&(D=(m=G.indexOf(uz())==u[0]||G.indexOf(BZ())==u[0]||G.indexOf(jc())==u[0]||G.indexOf(G7())==u[0])? +Zf[Li]:Zf[h_],D||typeof document==="undefined"||(c=new dq(document),D=c.get(m?t_:UT)||c.get(Dm)),(t=D?W[6](1,u[1],"",C,D,m?cZ:Ki):null)&&Q.push(t),m&&((O=f[30](8,u[1],"",C,m2,A_,qm))&&Q.push(O),(L=f[30](11,u[1],"",C,Qi,yi,Dm))&&Q.push(L))),hA=Q.length==u[0]?null:Q.join(OY())),N)>>2&7)==2){for(t=(B=[0,(O=e.X,5),18],z=B[0],e).o;z<16;z++)w=z*8,O[z]=new mu(t[w]<<24|t[w+1]<<16|t[w+2]<<8|t[w+M[1]],t[w+M[2]]<<24|t[w+B[1]]<<16|t[w+6]<<8|t[w+7]);for(X=16;X<80;X++)Y=O[X-2],r=Y.tO,A=Y.m,G=O[X-15],Z=G.tO,L=G.m, +O[X]=e.A(O[X-16],O[X-7],new mu(L>>>1^Z<<31^L>>>8^Z<<24^L>>>7,Z>>>1^L<<31^Z>>>8^L<<24^Z>>>7^L<<25),new mu(A>>>19^r<<13^r>>>29^A<<M[1]^A>>>6,r>>>19^A<<13^A>>>29^r<<M[1]^r>>>6^A<<26));for(d=(h=e.i[k=(D=(E=e.i[6],e.i)[a=(n=B[0],e).i[M[1]],1],e.i[7]),Q=e.i[M[x=e.i[2],2]],B[1]],e.i[B[0]]);n<80;n++)u=d.m,R=d.tO,q=(new mu(u>>>28^R<<M[2]^R>>>2^u<<30^R>>>7^u<<25,R>>>28^u<<M[2]^u>>>2^R<<30^u>>>7^R<<25))[M[0]](new mu(d.m&D.m|D.m&x.m|d.m&x.m,d.tO&D.tO|D.tO&x.tO|d.tO&x.tO)),c=Q.tO,J=Q.m,F=Q.tO,g=Q.m,m=e.A(k,new mu(J>>> +14^F<<B[2]^J>>>B[2]^F<<14^F>>>9^J<<C,F>>>14^J<<B[2]^F>>>B[2]^J<<14^J>>>9^F<<C),new mu(g&h.m|~g&E.m,c&h.tO|~c&E.tO),iz[n],O[n]),k=E,E=h,h=Q,Q=a[M[0]](m),a=x,x=D,D=d,d=m[M[0]](q);((((((e.i[B[0]]=e.i[B[0]][M[0]](d),e.i)[1]=e.i[1][M[0]](D),e.i)[2]=e.i[2][M[0]](x),e.i[M[1]]=e.i[M[1]][M[0]](a),e.i)[M[2]]=e.i[M[2]][M[0]](Q),e.i)[B[1]]=e.i[B[1]][M[0]](h),e).i[6]=e.i[6][M[0]](E),e).i[7]=e.i[7][M[0]](k)}if(N+M[2]>>1<N&&(N+8&36)>=N){for(t=(u=((q={},Q.i&&W[1](2,Q)>=e)?Q.i.getAllResponseHeaders()||L:"").split(vZ()), +0);t<u.length;t++)S[23](23,u[t])||(D=U[20](22,1,0,h,u[t]),B=D[0],O=D[1],typeof O==="string"&&(O=O.trim(),m=q[B]||[],q[B]=m,m.push(O)));H[5](2,function(mQ){return mQ.join(C)},q)}return(N|48)==N&&(Q=(new ni(1453,"0")).Ec(),Q.hc||(Q.hc=new IX),m=new RX({WS:Q.WS,jP:Q.jP?Q.jP:l[M[2]].bind(null,M[2]),RM:Q.RM,Gk:"https://play.google.com/log?format=json&hasfast=true",g$:!1,B3:!1,Ec:Q.i,lK:Q.lK,hc:Q.hc}),I[5](27,Q,m),m.V=new FI,Q.BE&&(m.BE=Q.BE),I[M[1]](8,e,L,C,h,m.o),Q.hc.a7&&Q.hc.a7(Q.WS),Q.hc.xn&&Q.hc.xn(m), +hA=m),hA},function(N,C,e,L,h,Q){if((N+8&27)>=(Q=["Hm",3,4],N+Q[1]>>Q[2]==Q[2]&&(h=C),N)&&(N+5^26)<N&&e.S&&(Zf.clearTimeout(e.S),e.S=C),!((N|5)>>Q[1])){if(!(C instanceof e))throw Error("Expected instanceof "+y[44](89,e)+" but got "+(C&&y[44](88,C.constructor)));h=C}return(N|((N+Q[2]^26)<N&&(N+Q[2]&54)>=N&&(this.j=this.DR=-1,this.PK=[],this[Q[0]]=-1,this.s5=[],this.yq=C,this.Uj=e,L=L===void 0?[]:L,this.j_=-1,this.K8=I[21](23),this.Zt=!0,this.mC=L),72))==N&&(h=T[42](64,C,e)),h},function(N,C,e,L,h,Q, +m,O,t,D,q,u,B,G){return(N<<(G=[2,41,44],1)>=1&&(N>>G[0]&G[0])<G[0]&&(this.A=void 0,this.o=new lz,T7.call(this,C,e)),(N|6)>>4)||(B=P[G[2]](G[1],function(c,A,n,R){if((R=["i",8,4],e.K).rz){h=P[R[2]](11,e.streams.values()),u=h.next();try{for(;!u.done;u=h.next())if(D=u.value,q=D[R[0]],q instanceof b0&&(q=q[R[0]]),q.B)return c.return([D.G,D[R[0]]])}finally{u&&!u.done&&(Q=h.return)&&Q.call(h)}}t=(m=P[R[2]](10,e.streams.values()),m.next());try{for(;!t.done;t=m.next())return O=t.value,c.return([O.G,O[R[0]]])}finally{t&& +!t.done&&(L=m.return)&&L.call(m)}return A=(n=c[R[0]],new ZE),A.source=e.l,n.call(c,v[R[1]](3,A.ix(D6())),C)})),B},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(((N<<2&(B=["isArray",14,22],B[1])||(e=T[41](11,C),e=H[10](64,31,1,C,e),U[29](4,e,C)),N-4)&16)<11&&N-4>=5)a:{if(Q=l[(m=y[30]((t=h[Rw]|(O=[null,0,1],O[1]),28),128,t),B)[1]](B[1],m,h,e),Q!=O[0]&&Q[MI]===$r){if(!U[B[2]](11,Q)){u=(S[45](24,C,Q),Q.z2);break a}D=Q.z2}else Array[B[0]](Q)&&(D=Q);u=((D=(D&&(q=D[Rw]|O[1],q&2&&(D=S[8](42,34,q,D))),v)[10](55, +O[2],D,L),D)!==Q&&W[26](8,t,e,h,D,m),D)}return(N>>1&15)==1&&xW.call(this,Zm,C),u},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w){if(x=["push",4294967296,20],(N&90)==N){for(E=[1,8,(F=[],255)],m=h;m<Q.length;m++)F[m]=Q[m].D();for(Z=(n=new hl,h);Z<Q.length;Z++){if((D=((R=Q[Z],J=Array.from(F[Z]),J)[h]=y[48](10,L,R,y[11](42),IB).length,J[E[0]]),D===19||D===31)||D===30||D===32)if(T[10](2,L,J,n),D===30?(n.i=L,f[6](58,n),T[0](67,E[0],n)):D===32?(n.i=C,T[0](66,E[0],n)):n.i=L,f[6](49, +n),T[0](65,E[0],n),c=n.i,u=v[35](23,e,n),u!==0){for(X=(O=(q=(r=u>h)?1:-1,(Y=h,r)?Z+E[0]:Z),O);r?X<O+u:X>O+u;X+=q)A=void 0,Y+=q*((A=F[X])==null?NaN:A.length);if(t=(z=(G=Y,Array),z).from,n.K)throw Error();J=((((d=(k=t.call(z,n.B),G),B=[],TH)(d),B)[x[0]](d>>>h&E[2]),B[x[0]](d>>>E[1]&E[2]),B[x[0]](d>>>16&E[2]),B[x[0]](d>>>e&E[2]),k).splice.apply(k,[c,4].concat(T[5](41,B))),k)}F[Z]=J}w=F.flat()}return((((N&((N|40)==N&&(U[21](30,h),m=h.z2,W[26](23,m[Rw]|C,e,m,(Q==="0"?Number(L)===0:L===Q)?void 0:L),w=h), +108))==N&&(w=l[27](33,function(a,g,M){a.subscribe(new zk((M=C,g),function(hA){return e.call(void 0,hA,M++)&&g.next(hA)}))})),N+9>>1<N)&&(N+4&27)>=N&&(h=L*x[1]+(e>>>C),w=Number.isSafeInteger(h)?h:K[x[2]](x[2],16,e,L)),N)|5)>>4||(w=P[44](73,function(a,g){if((g=["subtle","G","B"],a[g[2]])==L)return a.i(crypto[g[0]].digest("SHA-512",Q),h);return(O=a[g[1]],m=new DataView(O),a).return(m.getUint32(e,C))})),w},function(N,C,e,L,h){if((h=["M",9,5],!(N>>2&15))&&C!==KM)throw Error("illegal external caller"); +if((N&((N-h[2]^13)>=N&&(N+6&31)<N&&(L=f[12](62,C,C)),28))==N)a:{if(e.i||e.X){L=!(oX(),1);break a}if(e.J>=C){L=!1;break a}L=!(e.X=(PZ(),e.Xe++,y[h[1]](74,Pe(e.bI,e),v[33](24,2,e,e.J))),e.J++,0)}return N-h[1]<<1>=N&&(N+8^29)<N&&(this.i=B0[h[0]]().get().G2()),L},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(N-(B=[0,16,38],7)<<2<N&&(N-3|44)>=N){for(m=(vh(L.length-(h||B[0]),B[0]),h)||B[0],Q=[];m<L.length;m+=2)W[2](12,C,Q,L[m+e],L[m]);u=Q.join(lC())}return(N&((N|32)==N&&(u=P[44](77,function(G){return t=Object.assign({}, +h,{OK:(q=(O=Q)==e?void 0:O.i)!=e?q:null,d$:(D=(m=Q)==e?void 0:m.UK)!=e?D:null}),G.i(L.uI.send(Fa,new sT(t)),C)})),25))==N&&(u=(C=U[4](10,5170)(fi+"",XI))?v[B[2]](B[1],C.replace(/\s/g,"")):C),u},function(N,C,e,L,h,Q,m){if((N<<2&((m=[7,23,"rc-controls"],N-m[0]<5)&&((N|9)&15)>=0&&(h={},L.forEach(function(O){h[O[C]]=O[e]}),Q=function(O){return h[O.find(function(t){return t in h})]||""}),m[1]))==4)K[m[1]](11,C,L,e);return(N^63)&((N+5&m[0])==(((N^36)&15)>=13&&(N<<2&16)<10&&(this.i=C,this.B=new Sc(e,L)), +1)&&(e=['"><div class="','"></div><div class="',"rc-footer"],Q=P8('<div class="'+H[m[0]](1,e[2])+e[0]+H[m[0]](65,"rc-separator")+e[1]+H[m[0]](65,m[2])+e[0]+H[m[0]](65,"primary-controls")+e[0]+H[m[0]](32,"rc-buttons")+e[0]+H[m[0]](64,"button-holder")+C+H[m[0]](32,"reload-button-holder")+e[1]+H[m[0]](32,"button-holder")+C+H[m[0]](1,"audio-button-holder")+e[1]+H[m[0]](64,"button-holder")+C+H[m[0]](32,"image-button-holder")+e[1]+H[m[0]](33,"button-holder")+C+H[m[0]](33,"liveness-button-holder")+e[1]+ +H[m[0]](32,"button-holder")+C+H[m[0]](64,"qr-button-holder")+e[1]+H[m[0]](65,"button-holder")+C+H[m[0]](65,"help-button-holder")+e[1]+H[m[0]](64,"button-holder")+C+H[m[0]](1,"undo-button-holder")+'"></div></div><div class="'+H[m[0]](33,"verify-button-holder")+'"></div></div><div class="'+H[m[0]](33,"rc-challenge-help")+'" style="display:none" tabIndex="0"></div></div></div>')),m[1])||(Q=U[4](34,2133)(L(C(),5)).length%2==0?5:4),Q},function(N,C,e,L,h,Q,m,O,t,D){if(!((N^26)&(D=[13,0,"call"],N>>1&15|| +(t=function(q){return I[9](42,C,q,e)}),D[0])))p[D[2]](this,C);if((N+7^18)<N&&(N-6^16)>=N)Array.prototype.forEach[D[2]]((m.i||document).querySelectorAll(h+YI),function(q,u,B,G){B=u==((G=[29,4,1],S)[G[0]](19,q,"top",K[G[1]](G[2],C,this).y-O+L),e)?WZ():HZ(),S[G[0]](67,q,Q?{left:"100%",right:"","border-left-color":B,"border-right-color":"transparent"}:{left:"",right:"100%","border-right-color":B,"border-left-color":"transparent"})},m);return(N|48)==N&&(m=[1,11,9],f[5](28,L.i,pP,m[D[1]],e),W[4](10,e,m[D[1]])|| +v[16](5,m[D[1]],e),L.g$||(Q=f[18](33,m[1],L),S[49](24,C,Q)||P[D[1]](14,Q,L.locale,C)),L.B&&(h=f[18](64,m[1],L),U[D[0]](9,h,hC,m[2])||f[5](36,h,hC,m[2],L.B))),t},function(N,C,e,L,h){if((N-5&(h=[7,"tO","m"],N<<2&h[0]||(L=e[h[2]]*4294967296+(e[h[1]]>>>C)),h)[0])==2)U[29](71,null,C);return(N^51)&13||(this.count=C),L},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(!(N+4&((G=[1,"i","o"],(N|24)==N&&(e[G[2]].B==C||e.I||I[19](31,3,G[0],e[G[2]],e)),N<<G[0])&14||L[G[1]].B.send(e).then(C,L.Nz,L),5)))a:{if((u=[null, +1,!0],L)===-1){B=u[0];break a}if(!((t=(Q=e.length-u[G[0]],L+(C?0:-1)),Q)<u[G[0]]+(C?0:-1))){if(t>=Q)if(q=e[Q],q!=u[0]&&typeof q==="object"&&q.constructor===Object)O=u[2],m=q[L];else if(t===Q)m=q;else{B=void 0;break a}else m=e[t];if(h&&m!=u[0]){if((D=h(m),D)==u[0]){B=D;break a}if(!ZH(D,m)){B=(O?q[L]=D:e[t]=D,D);break a}}B=m;break a}}return B},function(N,C,e,L,h,Q,m){if((((N-6|69)>=((Q=["B",26,8],N+Q[2]^22)<N&&(N+4^31)>=N&&(L=e.G,h=e.o,m=new aw(L+C*(e.i-L),h+C*(e[Q[0]]-h))),N)&&(N+4^19)<N&&(e="",e= +W[49](27,C.LI,kI())?e+'Select each image that contains the object described in the text or in the image at the top of the UI. Then click Verify. To get a new challenge, click the reload icon. <a href="https://support.google.com/recaptcha" target="_blank">Learn more.</a>':e+"Click on any tiles you see with the object described in the text. If new images appear with the same object, click those as well. When there are none left, click Verify.",m=P8(e)),N)>>1&7)==2){for(e in L={},C)L[e]=C[e];m=L}return(N- +2^18)<N&&(N+4^Q[1])>=N&&(EF.call(this,rf),this.l={},this.i=0),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){return((((F=[2,32,28],N-8)&6||(Z=K[11](14,20,this.i)),(N&78)==N&&(e=T[41](7,C),L=H[F[0]](76,C),C.Ql[y[1](34,1,e,C)]=L),N-3)&3)==F[0]&&(u=[47,34,4],O=e(),m=new pi,G=L(O,u[1]),n=K[23](11,5,G,m),h=L(O,19),A=K[23](58,u[F[0]],h,n),t=L(O,21),Q=K[23](58,6,t,A),R=L(O,u[F[0]],29),q=K[23](61,F[0],R,Q),B=L(O,u[F[0]],35),D=K[23](F[2],1,B,q),c=L(O,u[F[0]],u[0]),Z=K[23](26,3,c,D).G2()),N+F[0]&10)>= +8&&(N-5&16)<3&&(v[16](F[1],C,e),e.X&&(Zf.clearTimeout(e.X),e.X=C),I[37](26,C,e),e.G.cancel(),e.V&&(typeof e.V==="number"&&Zf.clearTimeout(e.V),e.V=C)),Z},function(N,C,e,L,h){return((N-((N^10)&((L=["hasOwnProperty","i",6],(N-9|90)<N)&&(N+L[2]^L[2])>=N&&(h=C instanceof sB?U[36](7,C):new sB(C)),13)||(C.RX=e),N-5>>4||(h=Object.prototype[L[0]].call(C,e)),8)^32)<N&&(N-1|30)>=N&&(this[L[1]]=!0),(N|1)&10)||p.call(this,C),h},function(N,C,e,L,h,Q,m,O,t){if((N|((((N|((N&78)==(t=[22,6,0],N)&&(J_.call(this,C, +L),this.K=null,this.i=h,this.A=t[2],this.V=t[2],this.G=gH,this.P=U[13](10,e,bw,5,rY)),64))==N&&(O=(h=P[27](27,C,e,L))==C?void 0:h.action),N+t[1])&7)>=4&&(N<<1&t[0])<4&&!K[4](80,"",this)&&(this.v().value="",W[36](72,10,this.uY,this)),56))==N)a:{if(typeof C==="function"){O=C;break a}O=(C[ET]||(C[ET]=function(D){return C.handleEvent(D)}),C[ET])}return((N|8)&27)>=10&&(N^33)<18&&(h=["rc-imageselect-target","rc-imageselect-carousel-instructions-hidden",!1],W[t[0]](t[1],y[47](3,1,h[2],P[43](12,h[t[2]],L)), +"rc-imageselect-carousel-leaving-left"),L.F>=L.i.length||(Q=L.PE(L.i[L.F]),L.F+=1,m=L.rq[L.F],W[t[2]](12,e,!0,t[2],h[2],Q,L).then(function(D,q,u){((D=(u=[8,(q=[1,"rc-imageselect-desc-wrapper",""],45),41],T[0](u[1],q[1])),H[u[2]](22,D),y)[10](2,H[42].bind(null,16),D,{label:T[22](4,q[0],m),PS:zS,eP:T[22](1,7,m)}),K[u[2]](15,q[2],D,S[10](32,null,D.innerHTML.replace(ZD(),q[2]))),T)[u[0]](20,C,L)}),K[33](36,L,"Skip"),W[16](34,T[t[2]](14,"rc-imageselect-carousel-instructions"),h[1]))),O},function(N,C,e, +L,h,Q,m,O){return(N|((((N&((N|(O=[7,12,"]+"],24))==N&&(m=typeof L.className==e?L.className:L.getAttribute&&L.getAttribute(yM())||C),78))==N&&(m=U[O[1]](18,null,P[8].bind(null,1))),N-5|82)<N&&(N+2^31)>=N&&p.call(this,C),(N|O[0])>=23&&N+9<42)&&p.call(this,C),48))==N&&(L=z7[C],L||(L=Q=v[49](17,C),e.style[Q]===void 0&&(h=(M3?df():bj?wf():null)+W[16](O[1],"|[",O[2],"(^",Q),e.style[h]!==void 0&&(L=h)),z7[C]=L),m=L),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){if(((A=["push","function",0],N)-5|58)<N&&(N+ +4&44)>=N&&p.call(this,C,A[2],RE.yl),N-8>=17&&(N<<1&8)<4)a:if(u=["","\\u",0],h==C)L[A[0]](Sq());else{if(typeof h=="object"){if(Array.isArray(h)){for(D=(L[B=(m=h,m).length,A[0]](Vi()),u[A[2]]),O=u[2];O<B;O++)L[A[0]](D),l[20](26,null,e,L,m[O]),D=rX();c=(L[A[0]](yZ()),void 0);break a}if(h instanceof String||h instanceof Number||h instanceof Boolean)h=h.valueOf();else{for(Q in(q=h,L)[A[0]](xI()),t=u[A[2]],q)Object.prototype.hasOwnProperty.call(q,Q)&&(G=q[Q],typeof G!=A[1]&&(L[A[0]](t),H[41](2,u[2],u[1], +Q,L),L[A[0]](C1()),l[20](25,null,e,L,G),t=rX()));c=(L[A[0]](aX()),void 0);break a}}switch(typeof h){case "string":H[41](3,u[2],u[1],h,L);break;case "number":L[A[0]](isFinite(h)&&!isNaN(h)?String(h):Sq());break;case "boolean":L[A[0]](String(h));break;case A[1]:L[A[0]](Sq());break;default:throw Error("Unknown type: "+typeof h);}}return(N<<1&15)>=9&&N+9<29&&p.call(this,C),c},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return N+((N-9^11)>=((((B=[1,2,6],N+B[1])^19)<N&&(N-3^15)>=N&&(this.i=Q,this.o=L,this.K=C, +this.B=e,this.G=h.map(function(G){return new gf(G)})),(N&97)==N)&&(u=W[28](12,32,U[48].bind(null,13),C)),N)&&N+B[1]>>B[1]<N&&p.call(this,C),B[2])&5||(q=[3,!1,34],B0.M().init(v[10](27,q[0],C)),S[4](9,function(G,c,A){((A=["t",13,"k"],c)[A[2]]=H[A[1]](14,v[10](59,3,C)),h)&&h.G.value&&(c[A[0]]=h.G.value)}),O=I[12](28,B[0],P[41](5,B[2],C)),O==q[0]?h=new bz(y[0](69,B[1],P[41](64,B[2],C)),S[4](3,q[0],P[41](8,B[2],C)),T[42](68,19,C)||q[B[0]],T[42](16,20,C)||q[B[0]],T[42](17,31,v[10](91,q[0],C))||q[B[0]], +l[5](77,q[B[1]],v[10](43,q[0],C))||q[B[0]]):h=new Mm(y[0](66,B[1],P[41](65,B[2],C)),O,T[42](36,19,C)||q[B[0]],T[42](20,20,C)||q[B[0]],T[42](21,31,v[10](75,q[0],C))||q[B[0]],l[5](78,q[B[1]],v[10](43,q[0],C))||q[B[0]]),h.render(f[38](84)),Q=new F1(v[12](69,27,C,rY),v[12](71,28,C,rY)||1E4),t=new fa,U[13](30,C,W9,B[0],rY)&&(t.set(U[13](14,C,W9,B[0],rY)),t.load()),e=new $I(Q,C,t),L=null,e.A&&(L=l[4](48,null,"model",11,q[B[0]])),D=l[17](92,K[43](B[1],NH)),S[B[2]](12,D,YY,"en"),S[B[2]](32,D,W7,"8x-4t2pegToiW8KmThtO4AQt"), +m=l[26](B[0],U[31](4,null,D.toString())),this.i=new C$(h,e,m,L)),u},function(N,C,e,L,h,Q){return(((N&56)==(((Q=[5,"iPad",1],N)<<Q[2]&15)==2&&(L=f[37](2,C,e),h=L=="array"||L==C&&typeof e.length=="number"),N+Q[0]>>3==2&&(h=C==null||typeof C==="string"?C:void 0),N)&&(h=eZ&&Ie?!Ie.mobile&&(I[Q[2]](94,Q[1])||I[Q[2]](78,"Android")||I[Q[2]](94,e)):I[Q[2]](75,Q[1])||I[Q[2]](79,"Android")&&!I[Q[2]](92,C)||I[Q[2]](88,e)),N+Q[0])&62)<N&&N-4<<Q[2]>=N&&p.call(this,C),h},function(N,C,e,L,h,Q,m,O,t,D){if((N&(D= +[16,37,54],27))==N){if(e=I[17](34,T[3](D[1],"-",C),document),!e)throw Error("reCAPTCHA client element has been removed: "+C);t=e}return((((((N+3&D[2])<N&&(N+6&61)>=N&&(t=ew[C]||""),N|88)==N&&(O=h[1],Q=["number",0,2],m=y[41](18,L,String(h[C])),O&&(typeof O==="string"?m.className=O:Array.isArray(O)?m.className=O.join(OY()):y[46](4,C,e,O,m)),h.length>Q[2]&&U[47](8,Q[0],Q[1],"object",Q[2],L,h,m),t=m),N)&46)==N&&(Q=U[26](20,17,W[1](41,e,L),h.toString(),c0),t=T[D[0]](28,C,L$,S[10](13,0,y[31](40,Q.length, +19,23,75),Q))),N)|56)==N&&(e=T[41](2,C),U[29](7,C.Ql[y[1](2,1,e,C)],C)),t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(N-2<(N-5<<2<(G=[14,24,"indexOf"],N)&&(N-1|61)>=N&&(hP.call(this,C.O5),this.type=fS),12)&&(N>>2&11)>=2&&(h=l[34](9,0,L)[C]||e,!h&&Zf.self&&Zf.self.location&&(h=Zf.self.location.protocol.slice(0,-1)),B=h?h.toLowerCase():""),(N+9^25)<N&&(N+4&29)>=N){if((Q=[!1,0,2],Q5(),l[16](11,null,e),e.B)==3){if((m=((h=new (((O=(L=e.o6++,U[36](7,e.F)),U[35](77,O,dd(),e.R),U)[35](74,O,wd(),L),U[35](72, +O,mV(),OE()),W)[G[1]](12,O,e),xY)(L,e,void 0,e.K),h.T=Q[2],h).h=f[16](2,U[36](15,O)),Q[0]),Zf).navigator&&Zf.navigator.sendBeacon)try{m=Zf.navigator.sendBeacon(h.h.toString(),"")}catch(c){}(!m&&Zf.Image&&((new Image).src=h.h,m=!0),m||(h.i=v[25](4,C,h.o),h.i.send(h.h)),h).Z=Date.now(),S[2](33,h)}y[27](20,null,Q[1],e)}if((N|40)==N)a:{if(Q=(T[49](37,L,e),oE)(Number(L)),P0(Q)){B=String(Q);break a}B=((h=L[G[2]](ZD()),h)!==-1&&(L=L.substring(C,h)),e||n2?f[G[1]](G[0],"",0,L):L)}if((N-8&19)==3)a:{if(!(D= +L.j.i[String(Q)],D)){B=!0;break a}for(t=(u=!0,D=D.concat(),C);t<D.length;++t)(m=D[t])&&!m.UV&&m.capture==e&&(O=m.handler||m.src,q=m.listener,m.bx&&y[42](33,C,L.j,m),u=q.call(O,h)!==!1&&u);B=u&&!h.defaultPrevented}return B},function(N,C,e,L,h,Q,m,O,t){return O=["i","j",21],(N>>1&7)==1&&(m=this,Q=[1,2,0],C&&(this.Y=C.Q$,this[O[1]]=C.gz,this.P.reset(),this.G=new tP(this.P.B,C.HS,C.w$,function(D){m.K&&m.K(D)}),h=U[O[2]](7,Q[1],P[27](2,Q[0],new bR,C.YU),C.tE),S[45](5,Q[2],h,this.G),C.OK&&C.d$&&(L=U[O[2]](8, +Q[1],P[27](8,Q[0],new bR,C.OK),C.d$),S[45](4,Q[2],L,this.G)),e=U[O[2]](4,Q[1],P[27](7,Q[0],new bR,C.uK),C.z4),S[45](7,Q[2],e,this.G))),(N|24)==N&&(this.B=null,this[O[0]]=null),t},function(N,C,e,L,h,Q,m,O){if((O=[12,9,3],N-O[1]&7)==O[2]){if(!th(C))switch(OP){case 2:throw P[22](O[1],UE());case 1:U[O[2]](64,UE())}m=OP===2?C|0:C}if((N>>1&15||(m=new Worker(H[41](52,C),void 0)),N|16)==N)a:{if(Do.length){m=((Q=Do.pop(),K)[O[0]](O[2],Q,h),Q.i.init(C,e,L,h),Q);break a}m=new qH(C,L,h,e)}return N-7>>4||(m=f[6](57, +this.i)),m},function(N,C,e,L,h,Q,m,O,t){if((N|24)==(((((t=[8,42,2],(N&110)==N)&&(e=B0.M().get(),O=T[t[1]](16,C,e)),N)^55)&t[0])<5&&((N|5)&14)>=5&&H[t[1]](37,0).forEach(function(D,q,u,B,G){for(q=(B=(u=[15,52,53],2),u[2]);;)try{if(B==u[0])break;else B==u[1]?(q=18,Date.now()>parseInt(D.split(yR())[1],10)+1E4&&W[24](3,0,D),B=u[0]):B==2?B=D.startsWith(U[25](27,sY))?u[1]:u[0]:B==18&&(q=u[2],B=u[0])}catch(c){if(q==u[2])throw c;q==18&&(G=c,B=18)}}),N))for(L=["2d",0,10],e=(this.size+L[1])*L[t[2]],C.width= +e,C.height=e,m=C.getContext(L[0]),Q=-0;Q<this.size+L[1];Q++)for(h=-0;h<this.size+L[1];h++)m.fillStyle=this.I(Q,h)?"#000000":"#FFFFFF",m.fillRect((h+L[1])*L[t[2]],(Q+L[1])*L[t[2]],L[t[2]],L[t[2]]);return(N&105)==N&&(O=function(D){if(K[15](4,D==null?void 0:D.Sz))return D.Sz(function(q){try{return C(q,this)}catch(u){this.error(u)}});throw new TypeError("Unable to lift unknown Observable type");}),O},function(N,C,e,L,h,Q,m,O,t){return(((N|40)==(((N+(O=[42,22,4],9)&O[0])<N&&(N+3&58)>=N&&(h={},L=L===void 0? +{}:L,v[6](2,C,M1).forEach(function(D,q,u){(u=M1[D],u).R6&&(q=L[u.getName()]||this.get(u))&&(h[u.R6]=q)},e),t=h),N-O[2]>>3==2)&&(h.set(ul,U[41](41)),t=l[3](16,C,new sB(K[43](10,L)),h.toString(),e).toString()),N)&&(h=P[6](11,C,h,m),I[33](O[2],h,e,void 0,L,Q),h&&!U[O[1]](O[2],h)&&l[1](65,Q.z2),t=Q),N)<<1&15)==2&&(this.i=C||Zf.document||document),t},function(N,C,e,L,h,Q,m,O){return(N&((O=[108,"setAttribute","B9"],(N-6|11)>=N&&N-9<<2<N)&&(Q=e[O[2]]())&&(h=L.getAttribute(BH)||C,Q!=h&&(Q?L[O[1]](BH,Q):L.removeAttribute(BH))), +O)[0])==N&&(this.Bc=C,this.XJ=e,this.yU=L),m},function(N,C,e,L){return(N&62)==N&&(L=C),(N&61)==N&&(this.B=C,this.i=e),L},function(N,C,e,L,h,Q,m,O,t){return(N-(((O=["U_",46,"xx"],N)&O[1])==N&&(VO.call(this,C,L,h,Q,m),this.i=e),3)^11)>=N&&(N+6^16)<N&&(h=T[41](5,C),e=C.nI,h>>>=3,L=e[O[0]].substring(e.e_,e[O[2]],e[O[2]]+h),e[O[2]]+=h,e=K[19](10,0,L),U[29](4,e,C)),t},function(N,C,e,L,h,Q){return(N|(Q=["B",1,7],8))==N&&(this.i=e,this.w$=C,this[Q[0]]=L),h},function(N,C,e,L,h,Q,m,O){if(!((N|8)>>((N&(m=[22, +13,0],46))==N&&(this.i=[]),4)))a:{if(!Q||!h){O=C;break a}if(Q.contains&&h.nodeType==e){O=Q==h||Q.contains(h);break a}if(typeof Q.compareDocumentPosition!="undefined"){O=Q==h||!!(Q.compareDocumentPosition(h)&L);break a}for(;h&&Q!=h;)h=h.parentNode;O=h==Q}if(((N-4&14)==2&&(this.i=C,this.B=e),N+1^18)<N&&(N+5&56)>=N)a:{if(L&(Q=[!0,4096,2],Q)[2]){O=Q[m[2]];break a}if(L&32&&!(L&Q[1])){O=(W[32](32,L|Q[2],h),e.B=NR,Q[m[2]]);break a}O=C}return(N-2^5)>=N&&(N-1^m[0])<N&&(e=[1,0,2],(new jw(I[12](27,e[m[2]],P[41](4, +6,C)),y[m[2]](67,e[2],P[41](m[1],6,C)),T[m[0]](4,7,C,rY),C.kx()||e[1])).render(f[38](93))),O},function(N,C,e,L,h,Q){return N-7<<((Q=[4,"add",2],(N&121)==N)&&(L=e.match(Ge),cH&&["http","https","ws","wss","ftp"].indexOf(L[1])>=C&&cH(e),h=L),Q[2])>=N&&(N-7^22)<N&&(this.B=S[49](26,1,C),this.G=W[Q[0]](15,C,7)==Q[2]?K$():AP(),this.i=new y5,this.i[Q[1]](new il(v[28](92,f[29](1,C,Q[0]))))),h},function(N,C,e,L,h,Q,m){if(!((N^((N<<1&15)==(m=[23,"i","call"],2)&&(C=C===void 0?Date:C,e=e===void 0?H[12](36,C.now()* +1E3):e,this.B=C,this[m[1]]=e),32))>>4))p[m[2]](this,C);if((N-((N|64)==N&&(L=L===void 0?Tt:L,e[m[1]].G>C||e.B.some(function(O){return!!O.kZ}),h=new Promise(function(O,t){U[47](2,C,e,new vH(0,0,null,2,null,Tt,L+qY(),O,t))}),h.catch(H[40].bind(null,60)),Q=h),8)^m[0])<N&&(N-4|54)>=N)p[m[2]](this,C);return Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){if(!(N<<2&(Z=[null,64,16],15)))throw Error("please construct maps as mutable then call toImmutable");if(((N-1&26||(t=[Q>>>L&h,Q>>>e&h,Q>>>8&h,Q&h], +O=Mw.encode(m.toString()),F=new Promise(function(X,Y){n$(O,t,C,8,32,function(k){k?X(k):Y(Error(""))})})),N)|80)==N)a:{if(L[0]==="-"?h=C:(Q=L.length,h=Q<IV?!0:Q===IV&&L<=RV),h){F=L;break a}F=(v[14](2,6,L),K[20](25,e,l5,TU))}if((N|72)==N)a:{if(C==Z[0]){F=C;break a}if(typeof C==="string"&&C)C=+C;else if(typeof C!=="number"){F=void 0;break a}F=F2===2?th(C)?C|0:void 0:C}if((N&43)==N)a:{if((R=(m=(U[21](29,(t=[4096,0,4],e)),e.z2),m)[Rw]|t[1],h)==Z[0]){F=(W[26](8,R,Q,m),e);break a}if(!Array.isArray(h))throw P[22](9); +for(D=B=(n=(A=(c=W[1](23,t[2],(u=G=h===Fq?7:h[Rw]|t[1],G)))||TQ(h),t[1]),!0);n<h.length;n++)q=h[n],l[5](5,q,L),c||(O=U[22](3,q),D&&(D=!O),B&&(B=O));F=((R=((c||(G=D?13:5,G=B?G&-4097:G|t[0]),A&&G===u||(h=v[27](9,h),u=t[1],G=P[30](Z[1],C,G,R)),G)!==u&&W[32](24,G,h),W)[26](27,R,Q,m,h),C&G||!(t[0]&G||Z[2]&G))||l[1](96,m,R),e)}return F},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC){if(((tA=["children",1,2],N)|16)==N){for(z=(E=[new ll((g=[0,(O=document.body, +1),5],O.offsetHeight)*O.offsetWidth,0,O,0)],new Set);E.length>g[0]&&z.size<C;){if(c=(M=E[g[0]],E).pop(),E.length!==0)for(E[g[0]]=c,x=g[0];x<=E.length>>g[tA[1]];){if((m=(n=(t=(F=n=void 0,(Df=(Q=(x<<g[tA[1]])+g[tA[1]],(r=(R=(r=void 0,x<<g[tA[Df=(k=E[x].i,void 0),1]]),E[R]))==e?void 0:r.i))!=e?Df:-1),(F=E[Q])==e?void 0:F.i))!=e?n:-1,t>k)&&t>=m)w=R;else if(m>k)w=Q;else break;E[w]=(E[x]=(D=E[x],E)[w],D),x=w}if((q=(q=(a=(u=M,u),a).B,G=a.element,y[27](27,g[tA[2]],G.tagName,q)),G.id)&&(q=y[27](35,g[tA[2]], +G.id,q)),G.className&&(q=y[27](31,g[tA[2]],G.className.toString(),q)),A=G.type)q=y[27](19,g[tA[2]],A,q),G.name&&(q=y[27](23,g[tA[2]],G.name,q));mQ=(X=(a.depth>=L&&z.add(Te(q,2654435769)),P[4](10,G[tA[0]])),X.next());try{for(;!mQ.done;mQ=X.next()){if((Z=(B=mQ.value,B.offsetHeight*B.offsetWidth),B).tagName==h||B.tagName=="FOOTER")Z=g[tA[1]];for(J=((hA=(UC=new ll(Z,(Y=E,q),B,a.depth+g[tA[1]]),Y.length),Y).push(UC),UC.i);hA>g[0]&&Y[hA>>g[tA[1]]].i<J;)Y[hA]=Y[hA>>g[tA[1]]],Y[hA>>g[tA[1]]]=UC,hA>>=g[tA[1]]}}finally{mQ&& +!mQ.done&&(d=X.return)&&d.call(X)}}OC=z}if((N^6)<12&&(N>>tA[2]&6)>=0)W[tA[2]](25,7,10,L,l[36](78,e),C);return OC},function(N,C,e,L,h){return((N+1^19)>=(N-3>>3!=(h=["proxy",!0,56],1)||e.S||(e.S=C,v[44](36,e,aF),v[44](32,e,Zo)),N)&&(N+3^6)<N&&(Ah||(Ah=S[28](h[2])),L=e==C?Ah.sessionStorage:Ah.localStorage),N&14)==N&&(e.UV=h[1],e.listener=C,e[h[0]]=C,e.src=C,e.handler=C),L},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((B=[9,35,"i"],(N|72)==N)&&(L=y[B[1]](6,e[B[2]]),u=y[2](43,C,e[B[2]],L)),N-6<<2<N&&(N+B[0]& +76)>=N)P[44](45,function(G){((t=Object.assign({},h,{OK:(q=(Q=e)==C?void 0:Q.i)!=C?q:null,d$:(m=(D=e)==C?void 0:D.UK)!=C?m:null}),O=new sT(t),L.P).then(function(c){return c.send(Fa,O)}),G).P()});if((N<<1&6)==2){for(L=(h=C,[]);h<e;h++)L[h]=C;u=L}return(N|32)==N&&(L=y[B[1]](21,e[B[2]]),u=W[41](3,1,C,e[B[2]],C,L)),u},function(N,C,e,L,h,Q,m,O,t,D){if((N^44)>>((((t=["i",!1,(((N^9)&7)==3&&(e=[15,4,16],L=C.charCodeAt(0),D="%"+(L>>e[1]&e[0]).toString(e[2])+(L&e[0]).toString(e[2])),6)],N)^4)<12&&(N-7&5)>=0&& +(this[t[0]]=C),N-t[2]>>3)==3&&(D=e[t[0]]?e.B.B?!0:!(!P[21](9,C,e[t[0]])&&!e[t[0]].getResponse()):!1),3)==2)a:{if(h instanceof wu){D=(y[44](5,null,3,Q,L,h,m),C);break a}if(f[12](8,t[1],h)){D=(h.then(Q,L,m),C);break a}if(I[t[2]](10,h))try{if(O=h.then,typeof O==="function"){D=(T[45](1,!0,t[1],m,Q,h,L,O),C);break a}}catch(q){D=(L.call(m,q),C);break a}D=e}return D},function(N,C,e,L,h,Q,m,O,t,D,q){return(N^70)>>((N&((N^(q=["i","G2",14],(N|24)==N&&(D=U[13](20,e,L,T[33](56,e,void 0,C,h),void 0)),21))>>4|| +(t=new oV,Q=h(new Date,q[2])(),m=K[23](26,1,Q,t),O=pq(),D=T[21](36,m,3,O)[q[1]]()),124))==N&&(D=e<C?-1:e>C?1:0),4)||(this[q[0]]=C),D},function(N,C,e,L,h,Q){return N<<1&((N|((N-6^(N-5<<1<(N+8>>1<N&&(N+6&27)>=N&&(h=(C.stack||"").split(PH)[0]),Q=["B",17,10],N)&&(N-3|69)>=N&&(L=L===void 0?2:L,h=v[18](21,0,"",T[42](6,0,Q[1],e)).slice(C,L)),19))<N&&(N+5^8)>=N&&(e=function(m,O){return[(m=(O=["G","V","K"],C[O[0]]===-1?0:Math.trunc(qY())-C[O[0]]),C).i,C[O[2]],C.P,m,C.A,C[O[1]]]},h=C[Q[0]]?Promise.resolve(C[Q[0]].then(e)): +Promise.resolve(e())),72))==N&&(e=T[41](9,C),W[49](48,2,C,e,0)),Q)[2]||(e=T[41](6,C),H[2](24,C)===0&&H[23](4,3,(C.nI.xx<<3)+e,C)),h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){return(N|(N+(((N^38)&((n=[81,12,5],N-7&11)==2&&(D=P[4](n[1],K[21](37,m,4)),B=D.next().value,q=D.next().value,c=D.next().value,u=D.next().value,G=I[21](87),A=[y[15](70,h,B),ii(B,B,L,t),v[31](88,e,O),sE(O,O),P[37](85,Q,B,u),U[0](95,c,0),G,P[37](86,c,B,q),l[44](57,c,W[0](21,c),C),I[26](4,O,q,W[0](3,c)),P[n[1]](26,W[0](18,c),G, +W[0](22,u))]),7))==2&&(A=P[44](41,function(R,F){if(!T[(F=[20,15,"B"],F)[1]](9,e,L,B0.M()))return R.return(null);return m=new f$(f[17](F[0],C,h)),R.return(Q.i[F[2]].send(m))})),n[2])<15&&((N^73)&15)>=8&&(A=U[38](1)?!1:I[1](93,"Trident")||I[1](95,C)),40))==N&&(A=v[22](n[0],W[33](25,e,C,L,h))),A},function(N,C,e,L,h,Q,m){if((N|72)==((N&104)==(m=[9,2,38],N)&&(L=T[41](10,C),e=H[m[1]](60,C),h=P[25](28,31,L,C),C.put(L,e),U[29](68,h,C)),N))K[23](1,C,e,L);return N+m[0]&3||(Q=document.URL),(N|16)==N&&(Q=P[18](29, +W[39](20,S[32](24,new b4,10),C),[y[m[2]](48,e),y[m[2]](32,L)])),Q},function(N,C,e,L,h,Q){return((N|2)&((N^48)>>(Q=[7,0,60],4)||p.call(this,C),Q[0]))==2&&(e=H[2](Q[2],C),W[49](50,2,C,e,Q[1])),(N|24)!=N||Aa.includes(L)||(Aa.push(L),Aa.length===1&&(X2||(X2=window[C],window[C]=U[9].bind(null,13)),yn=e,Sw||(Sw=XMLHttpRequest.prototype.open,XMLHttpRequest.prototype.open=YD,jL=XMLHttpRequest.prototype.send,XMLHttpRequest.prototype.send=WH),i5=e)),h},function(N,C,e,L,h,Q,m,O,t,D){if((N&(D=[25,11,31],120))== +N)a:{if(HH((e=C,e))){if(!/^\s*(?:-?[1-9]\d*|0)?\s*$/.test(e))throw Error(String(e));}else if(kD(e)&&!Number.isSafeInteger(e))throw Error(String(e));if(B_){t=BigInt(C);break a}t=C=rR(C)?C?"1":"0":HH(C)?C.trim()||"0":String(C)}return(N>>1&((N&D[1])==N&&YK.call(this,291,28),7))==2&&((O=H[3](17,0,U[D[0]](D[0],eq)))?(Q=new p$(new ks,f[34](4,C,0,O+rZ)),Q.reset(),Q.update(L),m=Q.digest(),h=H[D[2]](21,e,m).slice(0,4)):h="",t=h),t},function(N,C,e,L,h,Q,m){return(N|((N-((N|48)==(((m=[29,31,28],N)&44)==N&&(h= +[31,12,10],Q=h[2]*L(e(),m[2],h[0],25)+L(e(),m[2],h[0],h[1])),N)&&p.call(this,C),1)^8)>=N&&(N+4&m[1])<N&&p.call(this,C),N>>2<13&&(N>>1&15)>=8&&(e=H[14](3),v[44](36,e,new JP(e,C))),72))==N&&(KN.call(this,I[14](3,EE),U[5](m[0],l6),y4()),e=v[9](13,0,!1,C),H[47](14,14,H[49](3,1,e)),this.Rz=C.D()),Q},function(N,C,e,L,h,Q,m,O,t,D,q,u){if(!((N^(u=["L",8,24],51))>>4)){Q=(h=(e=H[2](56,C),P[4](11,e)),h).next();try{for(;!Q.done;Q=h.next())U[29](71,Q.value,C)}finally{Q&&!Q.done&&(L=h.return)&&L.call(h)}}if((N| +u[2])==N){if(e==L)throw Error(ze);if(m=L&&e.o&&e.I)h=e.o,Q=e.I,m=h.K&&Q?U[39](10,h.K,Q)||C:null;if(m&&e.o!=L)throw Error(ze);QY[(e.o=L,u)[0]].Q7.call(e,L)}if((N|((N|(N-4<<1>=N&&(N+6&57)<N&&(e=C[g7],q=e instanceof AC?e:null),u)[1])>>4||(h=W[33](25,L,e,void 0,void 0,f[22].bind(null,72)),q=h==C?T[33](45):h),40))==N)a:{if((m=["Safari",(Q=S[16](14),"Silk"),0],Km)===dR){q=l[43](3,"MSIE")?W[36](60,h,"6.0",Q):"";break a}D=(t=f[36](32,3,2,Q),l)[11](2,m[2],L,t);switch(Km){case wR:if(S[20](23,"Opera")){q=D(["Version", +"Opera"]);break a}if(U[38](9)?P[35](22,m[2],wR):I[1](77,"OPR")){q=D(["OPR"]);break a}break;case vQ:if(I[40](9,"Edge")){q=D(["Edge"]);break a}if(K[21](16,m[2])){q=D(["Edg"]);break a}break;case EH:if(S[1](16,"CriOS")){q=D(["Chrome","CriOS","HeadlessChrome"]);break a}}if(Km===V5&&v[36](31,e)||Km===Km&&T[45](26,m[0])||Km===xD&&W[3](7,e,m[1])||Km===A4&&S[17](51,m[1])){q=(O=t[2])&&O[L]||C;break a}q=C}return q},function(N,C,e,L,h,Q,m,O,t,D){return N<<2<((N+(D=[29,4,38],3)&D[1]||(O=new TC,Q=K[23](10,e,h.count, +O),h.count>C&&H[D[2]](3,Q,K[24](D[1],h.B/h.count),2),L>C&&H[D[2]](2,Q,K[24](23,h.B/L),3),h.i>C&&(m=wq(h.i),K[23](27,D[1],m,Q)),t=Q),(N+3^D[0])<N)&&N-1<<1>=N&&(t=new B2(C.width,C.height)),48)&&(N^40)>=28&&(this.oM=!1),t}]}(),U=function(){return[function(N,C,e,L,h,Q,m,O){return(((((O=[31,0,39],(N|72)==N&&(m=P[18](26,W[O[2]](20,S[32](20,new b4,1),C),[y[38](32,e)])),(N|9)&15)>=13&&(N^44)<29&&(h=[0,1,1900],typeof C==="number"?(this.i=y[33](27,h[2],h[O[1]],e||h[O[1]],C,L||h[1]),T[18](O[0],L||h[1],this)): +I[6](15,C)?(this.i=y[33](28,h[2],h[O[1]],C.getMonth(),C.getFullYear(),C.getDate()),T[18](32,C.getDate(),this)):(this.i=new Date(P[3](14)),Q=this.i.getDate(),this.i.setHours(h[O[1]]),this.i.setMinutes(h[O[1]]),this.i.setSeconds(h[O[1]]),this.i.setMilliseconds(h[O[1]]),T[18](30,Q,this))),(N^69)<14&&N+1>>4>=2&&p.call(this,C),N)^82)&15)==2&&(e=Error.call(this,C?C.length+" errors occurred during unsubscription:\n"+C.map(function(t,D){return D+1+") "+t.toString()}).join("\n "):""),this.message=e.message, +"stack"in e&&(this.stack=e.stack),this.errors=C,Object.setPrototypeOf(this,this.constructor.prototype),this.name="UnsubscriptionError"),N^87)>>3||(m=C),m},function(N,C,e,L,h,Q,m,O,t,D){return(N&((D=[((N>>2&15)==1&&(this.i=C),"getUint32"),0,"G2"],(N+1&14)==4)&&(m=[16,!0,0],h=y[49](31,e),h!=null&&(v[22](9,C,L,1),O=C.i,Q=aV||(aV=new DataView(new ArrayBuffer(8))),Q.setFloat64(m[2],+h,m[1]),l5=Q[D[0]](m[2],m[1]),TU=Q[D[0]](4,m[1]),P[8](8,m[D[1]],l5,O),P[8](7,m[D[1]],TU,O))),21))==N&&(Q=K[44](59,"__",h, +e),L[Q]||((L[Q]=K[18](32,D[1],!1,"__",h,L))[K[44](25,"__",h,C)]=L),t=L[Q]),(N|40)==N&&(h=L[D[2]](gR),t=W[39](39,e,h).substring(C)),(N-7^21)>=N&&(N+2^14)<N&&(this.B=this.i=null),t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){if((N&103)==(F=[7,29,"map"],N))U[F[1]](36,3,C);return(N|3)>>3==1&&(B=[1336,1,2],Q=Q===void 0?!1:Q,t=T[41](16),O=P[4](15,y[41](11,c7.M(),B[2])),q=O.next().value,R=O.next().value,t.forEach(function(X,Y,k,E){X.Hm=(Y=(k=((E=[31,10,4],X).P(),S[E[0]](3,e,X)),P[E[2]](E[1],k)),Y.next().value), +X.j=Y.next().value,X.j_=Y.next().value}),A=t[F[2]](function(X,Y,k,E,J){return(E=[(Y=K[21](34,(k=[39,1,(J=["yq","Hm","j"],0)],X),k[1])[k[2]],S)[37](35,k[0],X[J[1]]),P[28](1,k[1],12,X,X.V()),S[37](11,k[0],Y),U[24](57,X[J[1]],W[0](7,Y),W[0](1,X[J[1]])),K[11](7,X[J[2]]),l[44](60,X[J[2]],W[0](21,X[J[2]]),C),S[48](65,X[J[2]],W[0](2,X[J[2]]),bl),U[26](9,X[J[2]],W[0](6,X[J[2]]),k[2]),U[26](2,X.j_,W[0](3,L),X[J[0]]),U[26](3,X.j_,W[0](21,X.j_),W[0](18,X[J[2]]))],K)[26](17,k[2],X),E}),c=t[F[2]](function(X,Y){return(Y= +X.A(),K)[26](16,0,X),Y}),G=t[F[2]](function(X,Y){return Y=[3,null,39],y[38](22,Y[0],Y[2],0,Y[1],Q,X)}),t.forEach(function(X,Y,k){((Y=(k=["i",5,"M"],c7[k[2]]()))[k[0]].apply(Y,T[k[1]](57,X.PK)),X).PK.length=0}),n=I[21](84),D=U[41](40),m=[T[30](38,n,W[0](6,q),D),U[0](89,q,D),y[9](84,B[0],2026,1626,338),A,U[26](3,L,W[0](19,L),-100),K[11](39,R),U[26](1,L,W[0](F[0],L),W[0](19,R)),y[36](5,R),T[30](53,w7,B[1],B[1]),c,P[18](24,S[32](20,new b4,h),[y[38](8,-1)]),n,G,w7],u=MH(m),c7.M().i(q,R),Z=u),Z},function(N, +C,e,L,h,Q){if((N|80)==(((N-1^4)<((N|5)<(Q=["nodeType","captureStackTrace",18],34)&&(N|6)>=Q[2]&&(L=C,typeof e==="string"?L=I[17](2,e,document):I[6](48,e)&&e[Q[0]]==1&&(L=e),h=L),N)&&(N+8^13)>=N&&(C=Error(),W[12](8,"incident",C),x1?I[1](43,C):T[0](37,C)),N|8)==N&&(e=new WeakMap,h=function(m){this.Pm=(m=e.get(this)||Array(C).fill(void 0),e.set(this,this.Pm),m)}),N)){if(Error[Q[1]])Error[Q[1]](this,sH);else if(L=Error().stack)this.stack=L;this.B=!(C&&(this.message=String(C)),e!==void 0&&(this.cause= +e),0)}return N-2>>4||(this.i=null),h},function(N,C,e,L,h){return(N-(L=[3,62,"zzsmc"],2)&7||(e=e=((C^c_|L[0])>>5)+c_,h=$D[(e%L[1]+L[1])%L[1]]),N<<1)&5||(this.B=null,C=this,this.i=null,Zf[L[2]]=function(Q,m,O,t){try{O=C.i,m=v[33](52,Q),t=NO(m),O(t)}catch(D){C.onError(1)}},Zf.zzmcs=function(Q){try{(0,C.B)(new Cv({visible:Q}))}catch(m){C.onError(1)}}),h},function(N,C,e,L,h,Q,m){if(((N|80)==(((((((Q=[60,54,31],(N+3^Q[2])<N)&&(N+6&Q[1])>=N&&(m=e.style.display!=C),N)^28)&7)==1&&(m=function(O){return new C(O)}), +N)|40)==N&&YK.call(this,417,1),N)&&(e=H[2](Q[0],C),e=H[2](28,C)<e?1:0,U[29](69,e,C)),N|7)>=6&&N>>1<10){if(e!==null&&L in e)throw Error('The object already contains the key "'+L+C);e[L]=h}return m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){return N-(((c=[null,29,3],N)-7&c[2])==1&&(A=P[44](73,function(n,R,F){F=["G",17,"B"],R=[null,3,42];switch(n[F[2]]){case e:return n.i(I[25](11,h,O.G2(),m),L);case L:if(!(u=(q=(B=n[F[0]],K[14](7,C,H[1](20,L,U[13](2,e,R[0],new p1,Q[F[2]][F[0]].value),B))),R[0]),t)){(l[43](12, +1,!1,R[2],O,Q).then(function(Z){return P[44](13,function(X,Y){if(!(Y=[22,4,20],Z)||Z.kx())return X.return();(S[47](5,e,T[Y[0]](Y[1],e,Z,rY)),Q.j({id:null,timeout:null,K0:1E3,r$:T[42](Y[2],C,Z)?1:null}),Z).qd()&&Q.uI.send(Zb,new eE(Z.qd())),X.P()})}),n).js(R[1]);break}return(G=new f$(f[F[1]](18,e,O)),n).i(Q.i[F[2]].send(G),C);case C:D=n[F[0]],D.kx()||(u=D.qd(),S[47](4,e,D.DS()),Q.j({id:null,timeout:null,K0:1E3,r$:T[42](68,C,D)?1:null}));case R[1]:return n.return(new aE(q,120,null,null,u))}})),9)<< +2<N&&N-2<<2>=N&&(e=H[2](68,C),e=(0,c[0])(H[2](24,C),e),U[c[1]](7,e,C)),A},function(N,C,e,L,h,Q,m,O){if((N&(O=[25,"call",114],O[2]))==N)p[O[1]](this,C);return((N<<1&15)==2&&(m=l[27](65,function(t,D,q,u,B,G){t.subscribe(new zk(D,function(c,A,n){(u=(q=(B=((n=[20,"unsubscribe",2],A=u)==h||A[n[1]](),e),c),new zk(D,G,void 0,I[38].bind(null,n[2]))),U)[12](n[0],C,Q(c)).subscribe(u)},void 0,(u=(q=h,G=function(c,A){u=((c=u)==h||c.unsubscribe(),h),B&&(A=q,q=h,B=L,D.next(A))},B=L,h),function(){G(),D.complete()}), +function(){q=u=h}))})),N-4)<37&&(N^O[0])>=27&&(hP[O[1]](this,C.O5),this.type=Lv),m},function(N,C,e,L,h,Q,m,O,t){if(((N-(t=[0,1,4],8)&8)<5&&((N|7)&3)>=t[0]&&(e.i.P=e.G,e.P&&(e.i.u=C),e.i.connect(e.o,e.B||void 0)),(N|t[1])<21)&&N+t[1]>=t[2]){h=(m=P[t[2]](11,(Q=[],C)),m.next());try{for(;!h.done;h=m.next())e=h.value,e instanceof hr?Q.push(e):Q.push(new hr(e))}finally{h&&!h.done&&(L=m.return)&&L.call(m)}O=Q}return O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(((B=["toString",4,25],N)+5&15)==2)a:{if(!(q= +[11,null,100],yn)){G=X2(C,e);break a}try{if(m=C instanceof Request?C.url:C[B[0]](),e==q[1]?0:e.keepalive){if(u=Aa.find(function(c){return P[27](25,null,m,c)!==null})){L=f[B[1]](7,B[1],P[3](B[2],q[0],P[30](80,6,P[16](28,10,P[34](13,1,5),u==q[1]?void 0:(D=l[18](69,q[1],m,u))==q[1]?void 0:D.substring(0,q[2])),u.i.iQ),u.i.origin).G2(),u.B),G=U[41](2,q[1],L,C,e);break a}G=X2(C,e);break a}t=(h=P[B[1]](14,Aa),h).next();try{for(;!t.done;t=h.next())if(Q=H[24](1,B[1],1,m,t.value)){G=Promise.resolve(Q.then(function(c){return U[41](18, +null,c,C,e)},function(){return X2(C,e)}));break a}}finally{t&&!t.done&&(O=h.return)&&O.call(h)}G=X2(C,e);break a}catch(c){G=X2(C,e);break a}}return((N&89)==((N&83)==N&&(G=l[8](41,0,L,e==null?e:U[45](8,C,e),h,ZJ())),N)&&(e.i.clear(),e.o=-1,e.G=-1,e.B=-1,Do.length<C&&Do.push(e)),N-8<<1>=N)&&(N-1|B[2])<N&&(K2.call(this),this.B=C),G},function(N,C,e,L,h,Q,m,O,t,D){if(((((t=[11,"i","B"],N)|56)==N&&(e[t[1]]?e[t[1]].add(C):e[t[2]]=C),N)&114)==N)a:try{D=(l[38](3,1,L).setItem(C,e),e);break a}catch(q){D=null; +break a}if(!((N^((N-8&13)==1&&(h=L.K,T[43](31,C,L),D=P[14](21,e,h,L)),5))&t[0])){L[t[1]]==C||L[t[1]].Bj||T[8](48,1,h)!==14||L.X++;try{L.A.next(h)}catch(q){}m=(O=P[4](14,L.streams.values()),O).next();try{for(;!m.done;m=O.next())m.value.K=e}finally{m&&!m.done&&(Q=O.return)&&Q.call(O)}}return D},function(N,C,e,L,h,Q,m,O,t){if(!(N<<1&(t=[15,36,"Start and end points must be the same length"],13))){if(!(Yj.call(this),Array.isArray(C))||!Array.isArray(e))throw Error("Start and end parameters must be arrays"); +if(C.length!=e.length)throw Error(t[2]);(this.G=(this.X=h,C),this.duration=L,this.coords=[],this.progress=0,this).S=e}if(!((N^13)>>3)){for(L=(Q=(m=(e=H[t[0]](1,this),y[34](57,this)),[]),1);L<C;L++)Q.push(y[34](63,this));this.Pm[e]=(h=S[28](1))[m].apply(h,T[5](89,Q))}if(!((N^69)&((N^53)>>4||(O=P0(L)?l[46](32,S[31](56,"-",e,L)):l[46](32,P[41](t[1],C,L,e))),7))){if(typeof C!=="number")throw P[22](5,Qh());if(!th(C))switch(F2){case 2:throw P[22](6,Qh());case 1:U[3](32,Qh())}O=F2===2?C>>>0:C}return O}, +function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if(N+((N>>((((G=[0,15,64],N)|G[2])==N&&(c=P[44](13,function(A,n,R,F){F=["o",10,(n=[1,0,5],"asyncIterator")];switch(A.B){case n[0]:A.K(2,C),R=Q[Symbol[F[2]]],O=R!==void 0?R.call(Q):new mD(P[4](14,Q));case n[2]:return B=void 0,A.i(O.next(),e);case e:if(B=A.G,B.done){A.js(C);break}q=B.value,m.next(q),A.js(n[2]);break;case C:if(!((A.J(),A).Z(h),B)||B.done||!(t=O.return)){A.js(h);break}return A.i(t.call(O),h);case h:if(A.J(n[1],n[1],n[0]),D)throw D.error;A.S(F[1], +n[0]);break;case F[1]:A.S(L);break;case 2:(D=(u=A[F[0]](),{error:u}),A).js(C);break;case L:m.complete(),A.P()}})),N+1^3)<N&&N-6<<1>=N&&(c=function(){var A=arguments,n=this;return UR(function(){return v[12](34,0,function(){return e.apply(n,A)},bH)},C)}),1)&13)==1&&(c=""+Array.from(WL.keys())),5)>>3==3)a:{if((L=[null," where a stream was expected. You can provide an Observable, Promise, Array, AsyncIterable, or Iterable.","You provided "],e)instanceof ZE){c=e;break a}if(e!=L[G[0]]){if(K[G[1]](1,e[Ob])){c= +H[21](3,e);break a}if(e&&typeof e.length==="number"&&typeof e!=="function"){c=U[42](23,G[0],e);break a}if(K[G[1]](2,e==L[G[0]]?void 0:e.then)){c=P[42](19,L[G[0]],e);break a}if(Symbol.asyncIterator&&K[G[1]](3,e==L[G[0]]?void 0:e[Symbol.asyncIterator])){c=v[28](5,e);break a}if(K[G[1]](2,e==L[G[0]]?void 0:e[Pz])){c=W[20](72,L[G[0]],e);break a}}throw new TypeError(L[2]+(e!==null&&typeof e==="object"?"an invalid object":C+e+C)+L[1]);}return c},function(N,C,e,L,h,Q,m,O,t,D,q,u){if(N+9>>((N|72)==(u=[11, +17,44],N)&&(this.i=new tr(C,Q,L,h,e)),4)>=1&&N>>1<u[1])a:{if((O=[0,(t=C.z2,null),!1],Q=t[Rw]|O[0],m=W[14](68,O[1],Q,e,t,L,h),m)==O[1]){q=m;break a}q=(U[Q=t[Rw]|O[0],22](u[0],C,Q)||(D=T[34](1,O[2],m),D!==m&&(S[45](1,!0,C)&&(t=C.z2,Q=t[Rw]|O[0]),m=D,Q=W[26](22,Q,L,t,m,h),l[1](72,t,Q))),m)}return(N|(((N|56)==N&&(C=[null,0,"Submit"],eB.call(this,C[1],C[1],it),this.T=C[0],this.i=new Qn(""),I[5](25,this,this.i),this.F=new Ub,I[5](9,this,this.F),this.h=new mS,I[5](25,this,this.h),this.l=C[0],this.G=P[28](38, +C[2],void 0,void 0,void 0,this),this.u=P[28](37,"Cancel",void 0,void 0,void 0,this)),N^33)>>4||(this.i=C),7))>>3||(q=P[36](u[2],e,C,Dw,h,L,rY)),q},function(N,C,e,L,h,Q,m,O){if(!((N^11)>>((N|(m=["call",5,0],4))>=13&&(N|1)>>m[1]<4&&(Q=[11,7,15],h=L(e(),Q[m[2]],Q[2],Q[1]),O=h>m[2]?L(e(),Q[m[2]],Q[2],38)-h:-1),4)))p[m[0]](this,C);return O},function(N,C,e,L,h,Q,m,O){return N+(m=[0,500,21],(N+4&26)>=N&&(N-5|m[2])<N&&(e=e===void 0?1:e,Q=[1,3,!0],fP?(W[42](2,Q[2],4,fP),C&&(L=new us,h=T[m[2]](40,L,Q[m[0]], +C),f[5](28,fP,us,5,h))):e<Q[1]&&setTimeout(B8.En,m[1],C,e+Q[m[0]])),7)&7||p.call(this,C,m[0],fA.yl),O},function(N,C,e,L,h,Q,m){return((N|32)==((N+7&29)<(m=[2,"i",58],N)&&(N-4|10)>=N&&(h=P[17](36,e),h!=null&&h!=null&&(v[22](6,C,L,0),S[6](m[2],127,C[m[1]],h))),N)&&(this[m[1]]=e>>>0,this.B=C>>>0),((N|5)&m[0])<1&&(N>>1&7)>=3)&&(L.K=C,v[3](17,C,function(){L.K&&Rj.call(e,h)})),Q},function(N,C,e,L,h,Q){return(N-6|(N<<1>=(h=[2,"call","B"],-61)&&(N<<h[0]&8)<1&&(L=[0,"",null],yE[h[1]](this),this.V=e,this.P= +void 0,this.l=C,this.readyState=L[0],this.status=L[0],this.statusText=L[1],this.response=L[1],this.responseText=L[1],this.responseType=L[1],this.onreadystatechange=L[h[0]],this.X=new Headers,this[h[2]]=L[h[0]],this.S=qO(),this.i=!1,this.h=L[h[0]],this.G=L[h[0]],this.o=L[h[0]],this.Y=L[1],this.A=new AbortController),26))>=N&&(N+3&26)<N&&(this.za=typeof AbortController!=="undefined"),Q},function(N,C,e,L,h,Q,m,O){if((N|(N>>(O=[!1,"cK",12],1)&5||(m=U[O[2]](14,null,function(){return S[28](16).frames})), +16))==N)a:{if(L==(h=e[Q=["-unchecked","Invalid checkbox state: ","-checked"],O[1]](),1)){m=h+Q[2];break a}if(L==O[0]){m=h+Q[0];break a}if(L==C){m=h+"-undetermined";break a}throw Error(Q[1]+L);}return m},function(N,C,e,L,h,Q){return N>>(((h=[9,"promise",null],(N&77)==N&&this&&this.C7&&(C=this.C7)&&C.tagName==Iq)&&K[h[0]](56,h[2],!0,C,this.VM),N-2^21)<N&&(N-2^3)>=N&&(this[h[1]]=C,this.resolve=e,this.reject=L),2)&7||(Q=C.classList?C.classList:l[19](88,"","string",C).match(/\S+/g)||[]),Q},function(N, +C,e,L,h,Q,m,O,t,D,q,u,B){if(((N|(((u=["push",2,1],N)&106)==N&&(this.i=new le,this.o=!1,this.B=S[30].bind(null,24),this.G=!1),6))<20&&(N+u[1]&13)>=u[1]&&(B=P[44](77,function(G,c,A){if(c=[0,(A=["G","data",13],1),"reCAPTCHA "],G.B==c[1])return t=h.O5,G.i(T[37](8,C,c[1],e,c[0],t[A[1]]),e);if(Q=(q=(D=G[A[0]],m=D.i,D).message,D.messageType),Q==ub||Q==BJ)m&&L.B.has(m)&&(Q==ub?L.B.get(m).resolve(q):L.B.get(m).reject(Error(c[2]+q)),L.B["delete"](m));else if(L[A[0]].has(Q))O=L[A[0]].get(Q),(new Promise(function(n){n(O.call(L.o, +q||void 0,Q))})).then(function(n){I[13](28,2,n||null,ub,m,L)},function(n){I[13](6,2,(n=n instanceof Error?n.name:n||null,n),BJ,m,L)});else I[A[2]](4,2,null,BJ,m,L);G.P()})),N-u[2]^u[2])<N&&(N-6|13)>=N){for(O=(Q=(m=h.split(L),C),[]);Q>e&&m.length;)O[u[0]](m.shift()),Q--;m.length&&O[u[0]](m.join(L)),B=O}return(N>>u[2]&11)==3&&(h=Zx(L,e),(Q=h>=C)&&Array.prototype.splice.call(L,h,u[2]),B=Q),B},function(N,C,e,L,h,Q){if(((((N|40)==(h=[5,1,21],N)&&(K[h[0]](13,[-10,-100],W[48].bind(null,6)),K[h[0]](15,[-44], +U[6].bind(null,3)),K[h[0]](h[2],[-79,-116],T[7].bind(null,16)),K[h[0]](9,[-62,-49],T[16].bind(null,4))),N-h[1]^13)>=N&&(N-4^h[1])<N&&(Q=f[6](88,1024,e,C,L,T[45].bind(null,6))),N+4)&37)>=N&&(N-7|h[1])<N&&!S[45](16,!0,C)&&U[22](9,C,C.z2[Rw]|0))throw Error();return Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if((N|((A=[4,21,"push"],N&58)==N&&(n=Object.prototype.hasOwnProperty.call(e,C)),72))==N)a:{if((c=[],G=[],Array.isArray(Q)?2:1)==1){n=(QU(c,(G=[m,O],function(R){G.push(R)})),P[A[0]](29,14,C,G.join(OY()))); +break a}(q=[(D=(G=(u=(QU(Q,(t=(B=[],[]),function(R){t.push(R.key),B.push(R.value)})),TH((new Date).getTime()/h)),B).length==L?[u,m,O]:[B.join(C1()),u,m,O],QU(c,function(R){G.push(R)}),P[A[0]](A[1],14,C,G.join(OY()))),u),D],t.length==L)||q[A[2]](t.join(e)),n=q.join(jE())}return(N|6)>>A[0]||(n=e===void 0?C.B!==NR&&!!(2&(C.z2[Rw]|0)):!!(2&e)&&C.B!==NR),n},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return(N|(((N+3&(N-(u=["constructor",6,"&"],u)[1]<<2<N&&(N+7^25)>=N&&(C===void 0&&GP(),B=e),8))<2&&((N^51)&15)>= +3&&(O=H[41](28,Q).toString(),D=O.split(/[?#]/),t=/[?]/.test(O)?"?"+D[e]:"",q=/[#]/.test(O)?L+(t?D[C]:D[e]):"",B=f[2](4,"=",null,u[2],1,q,D[h],t,m)),(N&58)==N)&&(e=H[2](56,C),e=H[2](64,C)+e|0,U[29](37,e,C)),8))>>3==3&&(h=L.z2,Q=h[Rw]|C,B=U[22](u[1],L,Q)?L:l[33](30,e,L,Q,h)?H[40](28,L,h):new L[u[0]](S[8](25,34,Q,h,!0))),B},function(N,C,e,L,h,Q){return((N-1|((N+4^6)<(Q=[64,"B",3],N)&&(N+4^29)>=N&&(e=H[2](Q[0],C),e=H[2](76,C)*e,U[29](5,e,C)),Q)[2])>=N&&(N+9^15)<N&&(h=e[Q[1]]?e[Q[1]]==C:e.i?e.i.has(C): +!1),(N^41)&12)<4&&N>>2>=4&&(h=P[18](31,W[39](16,S[32](20,new b4,11),C),[y[38](16,e),y[38](8,L)])),h},function(N,C,e,L,h){return((N|((L=[768,0,8],N|16)==N&&(h=T[7](9).call(L[0],28).padEnd(4,C1())+C),5))&L[2])<6&&(N|5)>>4>=L[1]&&(h=function(Q,m,O,t){Q=(m=(O=H[t=["map",null,34],15](36,C),y[t[2]](54,C)),y)[t[2]](55,C),C.Pm[O]=(m==t[1]?0:m[t[0]])?m[t[0]](function(D){return e(D,Q)}):e(m,Q)}),h},function(N,C,e,L,h,Q,m,O,t,D){if((((((t=[38,17,11],N+3)^t[2])<N&&(N+7^t[1])>=N&&(O=I[49](37,!0,Q,m),m.K=m.K.then(O, +O).then(function(q,u,B){return P[44](41,function(G,c,A,n){if(((B=!!(A=(u=m[n=["i",2,6],n[0]].j,B0.M().get()),T[42](36,e,A)),Q.AE)||B)&&u)return G.return(U[n[2]](12,4,1,n[1],e,m,u,q,B));return q=(c=q,m.T&&P[0](79,c,m.T,22,rY),c),G.return(S[10](56,C,h,1,L,q,m,u))})}),D=m.K),(N&t[2])==N)&&(D=P[18](57,W[39](16,S[32](68,new b4,3),C),[y[t[0]](8,e),y[t[0]](16,L)])),N>>1)&6)==2&&(Q=T[42](2,0,C,L+h,cJ),m=e.map(function(q,u){return Q[u%Q.length]}),D=W[20](10,0,m,e)),(N|40)==N)a:{if(!(m=Kv.toString(),m)){D= +L;break a}D=(Q=m?String(m).toUpperCase():null,T[6](t[2],C,L,h,function(q){return(!Q||q.nodeName==Q)&&e}))}return D},function(N,C,e,L,h,Q,m,O){return(((N|7)>>(((O=[2,32,8],N>>O[0]&7)==1&&(e.nu&&C!=e.I7&&U[O[1]](O[1],C,e),e.I7=C),(N^38)>>4>=3&&((N^68)&O[2])<3)&&(m=P[18](58,W[39](4,S[O[1]](72,new b4,O[2]),e),[W[0](5,C)])),3)==1&&(Q=new Ar(h===void 0?!1:h,L===void 0?null:L,e,C),tS.set(this,Q)),N)&41)==N&&(m=C===null?"null":C===void 0?"undefined":C),(N|48)==N&&(m=new M$(C,L,e)),m},function(N,C,e,L,h,Q, +m,O,t){return(((N-6^32)>=(((N|(O=[7,5,1],(N&107)==N&&(l[40](57,L,e,Q,h,m,C)||v[3](16,L,kW(m,h))),O[2]))&O[1])>=3&&(N^4)>>4<2&&(QY.call(this),this.G=I[17](50,yh,document),this.P=null,this.S=L,this.h=h,this.cS=Zk[C]||Zk[O[2]],this.l=e,this.F=Q),N)&&(N-O[0]^9)<N&&(L=U[4](10,e),t=function(){return c_==C?ZD():L.apply(this,arguments)}),N)&92)==N&&(S[32](81,null,this.B),(0,B8.tj)(this.Ku.bind(this,C),O[0])),(N|48)==N&&(t=W[18](24,e,C,h,L)),t},function(N,C,e,L,h,Q){if((N+(Q=[1,4,37],Q[1])^26)<N&&(N-Q[0]^ +5)>=N)a:{if((C=(L=I[22](12,this.i),this).Pm[L],C)instanceof ib){h=((e=K[29](2,0,L,this.l),C).i(e),C[Xf()]);break a}h=C}if(!(N>>((N-((N>>2&7)==Q[0]&&e.Ql.push(C),Q)[0]&11)==Q[0]&&(L=L===void 0?"r":L,e.tm()?e.Jt():e.Xd()||(e.r0(C),v[44](Q[2],e,L))),Q[0])&15))U[29](5,-1,C);return h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){return((N+4>>4==((((N^41)>>(A=[42,"port",3],A[2])==A[2]&&(q=l[17](91,h),q.i!=e?(Q&&S[A[0]](7,!0,q,Q+C+q.i),S[12](19,q,q.o)):(t=Zf.location,m=Q?Q+C+t.hostname:t.hostname,B=+t[A[1]], +G=t.protocol,u=new sB(null),G&&S[20](64,e,u,G),m&&S[A[0]](A[2],!0,u,m),B&&S[12](10,u,B),h&&I[34](14,!0,u,h),q=u),O=L.wq,(D=L.Z)&&O&&U[35](77,q,D,O),U[35](72,q,vJ(),L.S_),W[24](11,q,L),c=q),N^24)&21)==1&&(fi=C,CB=L,nv=U[12].bind(null,2),IT=e),4)&&(xW.call(this,"f"),this.error=C),N+6>>A[2]==A[2]&&(m=T[39](6,C),h=[U[0](91,m,L)],Q=MH(h),c=new AS(S[49](25,1,Q.i),v[A[2]](44,Q.i,y[11](35),e).slice(),Q.B)),N)&105)==N&&(this.i=Array.from(C.entries())),c},function(N,C,e,L,h){return(((N&((N|8)==(L=[117,1,27], +N)&&(h=C?e?decodeURI(C.replace(/%25/g,RT())):decodeURIComponent(C):""),L[0]))==N&&(e=U[L[2]](33,e),h=y[5](16,C,e)),N-2)^L[2])<N&&N-2<<L[1]>=N&&YK.call(this,2031,2,[2]),h},function(N,C,e,L,h,Q,m){return((N|7)>>((((N-4&(m=[33,27,22],7))>=6&&(N+4&8)<2&&p.call(this,C),N)^60)>>3==3&&(L=y[10](m[2],e),h=e.v(),C?(y[m[2]](60,y[m[2]](m[0],y[m[2]](52,I[7](3,h,void 0,Fs.oy,L,e.M7),h,[Fs.q4,Fs.IF],e.R),h,lb,e.Xq),h,TP,e.hu),e.u!=U[m[2]].bind(null,39)&&I[7](35,h,void 0,Zw,L,e.u)):(H[39](41,H[39](9,H[39](25,H[39](57, +L,h,Fs.oy,e.M7),h,[Fs.q4,Fs.IF],e.R),h,lb,e.Xq),h,TP,e.hu),e.u!=U[m[2]].bind(null,53)&&H[39](25,L,h,Zw,e.u))),4)>=1&&N+2>>4<2&&(h=y[31](41,Vc(e),oT[C],oT[1],oT[2]),Q=function(){return TH(h()*oT[2])%L}),(N-3&5)>=1&&N+8>>4<2)&&(L=e,C&&(L=Pe(e,C)),L=PJ(L),L=qL(L),sb||(sb=I[m[1]](1,null,0)),sb(L)),Q},function(N,C,e,L,h,Q){if(((Q=[6,"xx",15],N-Q[0])|73)>=N&&(N-4|37)<N)for(C.RC<0?C.RC=C.mp[Q[1]]:C.mp[Q[1]]=C.MW.length,L=C.MW.pop(),C.MW.pop(),e=C.MW.pop(),C.MW.pop(),C.nI[Q[1]]=e;C.Ql.length>L;)H[2](76,C); +return((N&((N-7&3)==2&&(h=fv||(fv=new z6(y[Q[2]](18,C,[]),void 0,void 0,void 0,Xs))),Q[2]))==N&&(e=H[2](24,C),U[29](68,P[25](32,31,e,C),C)),(N<<1&Q[2])>=11&&(N<<1&16)<16)&&(h=new H9(C&4294967295,TH(C/4294967296))),h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if((B=[34,"o",7],N&77)==N){if(L instanceof B2)Q=L.height,L=L.width;else{if(h==void 0)throw Error("missing height argument");Q=h}e.style.width=I[45](B[0],C,L),e.style.height=I[45](19,C,Q)}if((N|40)==N)a:{for(D=(q=(t=SE,L).split(e),0);D<q.length-1;D++){if(!(O= +q[D],O in t)){G=void 0;break a}t=t[O]}m=(Q=t[u=q[q.length-1],u],h)(Q),m!=Q&&m!=C&&Yf(t,u,{configurable:!0,writable:!0,value:m})}return N+6&B[2]||(this[B[1]]=C,this.closed=!1,this.B=this.G=null),G},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if((N-5^(A=[2,0,3],30))<N&&(N+1&22)>=N)P[44](45,function(R){return R.i((m=Q.R.bind(Q,h),(new Promise(function(F){return W[19](1,C,e,F)})).then(function(){mX?mX(m):Q4(m)})),L)});if((N^43)<(N+1&7||(this.next=this.i=this.B=null),19)&&((N|6)&5)>=A[2]){if(D=(B=[3,4, +1],function(R,F){return F.length>=R.length?F:R}),t=new WJ,h=/\b(1[2-9]\d{8}(\d{3})?)\b/g,I[10](5,7)){c=P[4](10,U[4](26,7449)(C,L,function(R,F,Z){return(Z=(F=R.match(h)||[],F.reduce(D,"")),F).filter(function(X){return X.length==Z.length}).map(function(X){return parseInt(X.substring(1,6),10)})})),u=c.next();try{for(;!u.done;u=c.next()){q=(O=P[4](14,u.value),O.next());try{for(;!q.done;q=O.next())G=q.value,l[44](73,B[A[0]],(v[12](71,B[A[0]],t)||A[1])+B[A[0]],t),W[20](4,B[A[1]],t,vh(v[12](69,B[A[1]],t)|| +A[1],G)),T[40](14,A[0],t,RY(v[12](68,A[0],t)||G,G)),v[28](39,B[1],t,(v[12](70,B[1],t)||A[1])+G)}finally{q&&!q.done&&(m=O.return)&&m.call(O)}}}finally{u&&!u.done&&(Q=c.return)&&Q.call(c)}v[12](71,B[A[0]],t)&&v[28](23,B[1],t,TH(v[12](68,B[1],t)/v[12](65,B[A[0]],t)))}n=t.G2()}return(N|72)==N&&C.K.set(e,L),n},function(N,C,e,L,h,Q,m){if((N^(Q=[33,105,39],Q[2]))&7||(m=new sB(C)),(N&Q[1])==N)a:{if(C.B!==2){m=!1;break a}h=l[Q[2]](72,0,C),H[Q[0]](31,L,h===T[Q[0]](43)?void 0:h,e),m=!0}return m},function(N, +C,e,L,h,Q,m){return((((N&100)==((N^54)&((m=["B",8,5],N-m[1]<<1)<N&&N-m[2]<<1>=N&&(Q=P[44](45,function(O){return O.return(W[18](26,1,128,e,C))})),11)||(e=H[2](60,C).length,U[29](m[2],e,C)),N)&&p.call(this,C),N)+1>>4==4&&(this.i=C,this[m[0]]=new Sc(e,L)),N)|56)==N&&(TH(h),TH(L),P[m[1]](m[1],C,h,e),P[m[1]](7,C,L,e)),Q},function(N,C,e,L){if(!((L=[0,"brands",2],N)+L[2]&7))U[29](37,L[0],C);return(N^1)&6||(e=eZ?!!Ie&&Ie[L[1]].length>L[0]:!1),e},function(N,C,e,L,h,Q,m,O,t,D,q){if(((N^50)&7)>=((D=[5,"U_", +0],N>>1)&7||(K2.call(this),this.P=L!=null?C.bind(L):C,this.o=D[2],this.K=e,this.G=!1,this.B=this.i=null),D[2])&&N-4<3){if(m=(Q=[255,0,1],h>>>C),m!==e.e_){for(O=(t=Q[1],e).ez,e.e_=m;t<8;t++)O=(O>>>8|O<<24)+m^e[D[1]][t]|Q[1],m=(m<<C|m>>>29)^O|Q[1];e.xx[7]=m>>>24&Q[D[e.xx[6]=((e.xx[4]=m&Q[e.xx[(e.xx[Q[1]]=O&Q[D[2]],e.xx)[Q[2]]=O>>>8&Q[D[2]],e.xx[2]=O>>>16&Q[D[2]],C]=O>>>24&Q[D[2]],D[2]],e).xx[D[0]]=m>>>8&Q[D[2]],m)>>>16&Q[D[2]],2]]}q=L[h]^e.xx[h&7]}return(N|8)<24&&N>>1>=4&&(q=C!==null&&e in C?C[e]:void 0), +q},function(N,C,e,L,h,Q,m,O,t){if((N&44)==(O=[12,"V",3],N)){for(m=(yO(L,{frameborder:"0",scrolling:"no",sandbox:"allow-forms allow-popups allow-same-origin allow-scripts allow-top-navigation"}),LM)(HJ,L),Q=["allow-modals","allow-popups-to-escape-sandbox","allow-storage-access-by-user-activation"],m.src=H[41](36,e).toString(),h=C;h<Q.length;h++)m.sandbox&&m.sandbox.supports&&m.sandbox.add&&m.sandbox.supports(Q[h])&&m.sandbox.add(Q[h]);t=m}if(!(N-((N|56)==N&&(t=TH(Vn()*C)),1)&15))a:{if(!I[6](22,e)){t= +S[O[0]](27,"&",C,String(e));break a}if(e.f8&&(L=e.f8(),L instanceof Zj)){t=L;break a}t=S[O[0]](31,"&",C,s$())}return N+O[2]<17&&N+1>=7&&(C=y[34](52,this),e=y[34](56,this),this[O[1]]?this[O[1]][C]=e:S[28](41)[C]=e),t},function(N,C,e,L,h,Q,m,O,t,D,q){return(D=["assign","toString",92],(N&114)==N&&(m=L,t=h,((Q=t)==C?0:Q.headers)?(t=Object[D[0]]({},t),t.headers instanceof Headers?(t.headers=new Headers(t.headers),t.headers.set("X-Recaptcha-Token",e)):Array.isArray(t.headers)?(t.headers=t.headers.slice(), +t.headers.push(["X-Recaptcha-Token",e])):(t.headers=Object[D[0]]({},t.headers),t.headers["X-Recaptcha-Token"]=e)):m instanceof Request&&!m.headers.keys().next().done?(m=new Request(m),m.headers.set("X-Recaptcha-Token",e)):(t=Object[D[0]]({},t),O={},t.headers=(O["X-Recaptcha-Token"]=e,O)),q=X2(m,t).then(function(u){return u.status===431?X2(L,h):u})),(N&105)==N)&&(q=TH(Vn()*2147483648)[D[1]](36)+Vc(TH(Vn()*2147483648)^P[3](11))[D[1]](36)),q},function(N,C,e,L,h,Q,m){return((N|(N-((N+9&((N&86)==(((Q= +[13,29,7],N)&Q[0])==N&&p.call(this,C),N)&&(m=hd.charCodeAt),41))>=N&&(N+2&Q[1])<N&&(h=this.i,e=this.B,L=this,m=this.G||h?oo.i:(e.push(C),new oo(function(){return K[45](4,1,L.B,C)}))),6)<<1>=N&&(N+Q[2]^11)<N&&(m=new ZE(function(O,t){for(t=C;t<e.length&&!O.closed;t++)O.next(e[t]);O.complete()})),9))&19)>=9&&(N>>1&14)<9&&(m=String(C).replace(kf,I[48].bind(null,8))),m},function(N,C,e,L,h){return(((((((N+(L=[2,26,31],3)^25)>=N&&N-4<<L[0]<N&&(C=H[15](28,this),e=f[1](67,this),this.Pm[C]=typeof e),N+L[0])& +57)>=N&&N+4>>L[0]<N&&(C=v[4](L[2],this),e=P[L[0]](1,this),this.K.push(new vH(e,this.i.i+C,this.Pm[e],2,null,Tt,Tt))),N-5^L[1])>=N&&(N+1&61)<N&&!e.P&&(e.P=C,v[3](15,C,e.j,e)),((N^38)&10)<1&&N-6>>3>=0)&&(C=["RecaptchaMFrame.show","RecaptchaMFrame.token",null],this.B=C[L[0]],e=this,this.i=C[L[0]],this.G=C[L[0]],U[47](21,function(Q,m){e.B(new jW(null,new B2(Q-20,m)))},C[0]),U[47](19,function(Q,m,O){e.G(new Cv({visible:O!==void 0?O:!0,n0:new B2(Q,m)}))},"RecaptchaMFrame.shown"),U[47](L[1],function(Q,m){e.i(Q, +m)},C[1])),N)|56)==N&&(h=S[41](8,C,void 0,e)),h},function(N,C,e,L,h,Q,m,O){return(m=["S",3,4],N-m[2]<<2>=N&&(N-5^25)<N)&&e[m[0]]!=C&&(r0(),Zf.clearTimeout(e[m[0]]),e[m[0]]=C),N-m[2]>>5<2&&(N^31)>>m[1]>=2&&(Q=xj,O=I[33](12,v[34](61,C,e),L,void 0,Q,h)),O},function(N,C,e,L,h,Q,m,O,t){if(!(N+6>>(((O=[4,27,"from"],N-2)|6)>=N&&N+2>>1<N&&(h=new Set(Array[O[2]](L(C(),9)).map(function(D){return D&&D.hasAttribute&&D.hasAttribute(pv())?(new sB(D.getAttribute(pv()))).i:jE()})),t=Array[O[2]](h).slice(0,25).join(rX())), +O[0])))a:{if(Q=(m=[1024,512,null],L!=m[2]||(L=m[0]),L!==0),!Q&&!n2){t=e;break a}if(!T[49](O[1],e,Q))throw P[22](6,Jr());h=typeof e;switch(L){case m[1]:switch(h){case "string":t=l[24](41,0,!0,e);break a;case C:t=String(sR(64,e));break a;default:t=P[41](34,"",e,!0);break a}case m[0]:switch(h){case "string":t=I[49](8,64,0,e);break a;case C:t=l[46](24,sR(64,e));break a;default:t=U[11](51,"",!0,e);break a}case 0:switch(h){case "string":t=l[24](44,0,!1,e);break a;case C:t=l[46](16,sR(64,e));break a;default:t= +S[31](54,"-",!1,e);break a}default:t=v[24](59,"!",L);break a}}return t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E){if((N+3&(k=[26,2,18],7))==k[1]){for(Z=(c=(R=(X=e.A,[16,0,3]),R)[F=e.o,1],R[1]);Z<F.length;)X[c++]=F[Z]<<24|F[Z+1]<<R[0]|F[Z+k[1]]<<8|F[Z+R[k[1]]],Z=c*4;for(G=R[0];G<64;G++)u=X[G-C]|R[1],n=X[G-k[1]]|R[1],X[G]=((X[G-R[0]]|R[1])+((u>>>7|u<<25)^(u>>>k[2]|u<<14)^u>>>R[k[1]])|R[1])+((X[G-7]|R[1])+((n>>>17|n<<C)^(n>>>19|n<<13)^n>>>10)|R[1])|R[1];for(t=(B=e.i[7]|R[1],h=(O=e.i[6]| +R[1],e.i[1])|R[Y=e.i[4]|R[1],1],Q=(L=e.i[R[k[1]]]|R[1],e).i[k[1]]|R[1],e).i[q=e.i[R[1]]|R[1],5]|R[1],A=R[1];A<64;A++)D=((q>>>k[1]|q<<30)^(q>>>13|q<<19)^(q>>>22|q<<10))+(q&h^q&Q^h&Q)|R[1],m=(B+((Y>>>6|Y<<k[0])^(Y>>>11|Y<<21)^(Y>>>25|Y<<7))|R[1])+(((Y&t^~Y&O)+(Tb[A]|R[1])|R[1])+(X[A]|R[1])|R[1])|R[1],B=O,O=t,t=Y,Y=L+m|R[1],L=Q,Q=h,h=q,q=m+D|R[1];e.i[7]=e.i[e.i[6]=(e.i[5]=e.i[e.i[4]=(e.i[(e.i[e.i[1]=(e.i[R[1]]=e.i[R[1]]+q|R[1],e.i[1]+h)|R[1],k[1]]=e.i[k[1]]+Q|R[1],R)[k[1]]]=e.i[R[k[1]]]+L|R[1],e.i[4]+ +Y)|R[1],5]+t|R[1],e.i[6]+O|R[1]),7]+B|R[1]}if((N|24)==N){if(!e)throw Error("Invalid class name "+e);if(typeof C!=="function")throw Error("Invalid decorator function "+C);}return(N&120)==N&&(this.i=C),E},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if((N&(G=[8,"T",5],86))==N){for(h=(m=L.TX,Q=C,L.T$);Q<e.B.length;Q++){if(O=e.B[Q],O.T$>=h&&O.TX<=m)break;m=(h=vh(O.T$,h),O.T$<h&&(e[G[1]]+=1,O.T$=h),RY(O.TX,m)),O.TX=m}e.qp(L)&&e.ZM(L)&&T[13](1,1,2,e)}if(((N|1)&11)>=G[0]&&N+G[2]<28)for(B=function(c){c&&O.appendChild(typeof c=== +"string"?Q.createTextNode(c):c)},q=h;q<m.length;q++)if(t=m[q],!l[22](33,L,t)||I[6](G[0],t)&&t.nodeType>e)B(t);else{a:{if(t&&typeof t.length==C){if(I[6](9,t)){D=typeof t.item=="function"||typeof t.item=="string";break a}if(typeof t==="function"){D=typeof t.item=="function";break a}}D=!1}QU(D?v[40](45,t):t,B)}if(N-G[0]>>3>=0&&(N^27)<18)for(L=e.split(ZD()),h=Zf;L.length&&(Q=L.shift());)L.length||C===void 0?h[Q]&&h[Q]!==Object.prototype[Q]?h=h[Q]:h=h[Q]={}:h[Q]=C;if(!(N+G[2]&14))a:{if(Q=typeof L,h=h=== +void 0?!1:h,L==C){u=L;break a}if(Q==="bigint"){u=String(sR(e,L));break a}if(!h&&!n2){u=L;break a}if(T[49](30,L,h)){u=Q==="string"?l[24](45,0,h,L):h||Jp?P[41](35,"",L,h):S[31](57,"-",h,L);break a}}return u},function(N,C,e,L,h){return((((N-3&7)>=(h=[64,32,24],1)&&(N<<1&4)<4&&(L=I[28](18)?l[46](40,BigInt.asIntN(h[0],(BigInt.asUintN(h[1],BigInt(e))<<BigInt(h[1]))+BigInt.asUintN(h[1],BigInt(C)))):l[46](h[2],y[8](15,"",C,e))),(N+5&44)>=N&&N+7>>1<N)&&(K[5](5,[-61,-73],P[8].bind(null,38)),K[5](23,[-63],y[h[2]].bind(null, +27))),N)<<1&16)<9&&((N|1)&11)>=0&&(L=C.Object.getOwnPropertyNames),L},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){return(((N^((c=[18,45,5],N+8>>3>=0)&&(N^13)<10&&(this.DX=C,this.yM=e,this.QY=h,this.Az=L),25))>>3==1&&(A=P[44](c[1],function(n,R,F,Z){R=[2,(Z=[1,0,"could not contact reCAPTCHA."],3),"verifyAccount request failed."];switch(n.B){case h:if(!Q.G)throw Error(Z[2]);if(!Q.B)return n.return(I[41](13,Z[1],R[Z[1]]));if(typeof m!=="string"||m.length!=C)return n.return(I[41](12,Z[1],4));return n.K(R[Z[1]]), +n.i(Q.G,4);case 4:n.V((u=n.G,R[Z[0]]));break;case R[Z[1]]:throw n.o(),Error(Z[2]);case R[Z[0]]:return B={pin:m},O={},t=(O[Yz]=Q.i,O[jt]=W[39](45,R[Z[0]],QI(B)),O),n.K(e),n.i(u.send(Eb,t,1E4),7);case 7:return q=n.G,G=new zP(q),D=G.kx(),Q.i=S[49](23,R[Z[1]],G),Q.i&&D!=R[Z[1]]&&D!=C&&D!=L||(Q.B=!1),G.jZ()&&(F=G.jZ(),U[10](48,NP,F,Z[1])),n.return(I[41](27,Z[1],D,G.i()));case e:throw n.o(),Error(R[2]);}})),N)-2^c[2])>=N&&(N-6^c[0])<N&&(m=new j8,O=new AbortController,Q=setTimeout(function(){(O.abort(), +P)[15](32,m,d0(),C,L)},1E4),fetch(h,{signal:O.signal}).then(function(n){(clearTimeout(Q),n).ok?P[15](22,m,w0(),e,L):P[15](21,m,Vh(),C,L)}).catch(function(){(clearTimeout(Q),P)[15](23,m,xf(),C,L)})),A}]}(),H=function(){return[function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB){return(N|64)==((N-(((N^7)<(OC=[89,0,44],17)&&(N+7&7)>=4&&(KB=e==null?e:I[12](2,512,C,null,16,e)),N&60)==N&&(F=[690,12,1],Df=P[4](11,K[21](34,e,5)),hA=Df.next().value,k=Df.next().value, +B=Df.next().value,z=Df.next().value,G=Df.next().value,e.Zt?(A=y[41](75,c7.M(),F[1]),R=P[4](15,A),c=R.next().value,d=R.next().value,UC=R.next().value,J=R.next().value,n=R.next().value,Q=R.next().value,X=R.next().value,R.next(),R.next(),a=R.next().value,R.next(),w=R.next().value,r=[S[48](1,z,W[OC[1]](2,z),W[OC[1]](21,1846)),l[OC[2]](16,z,W[OC[1]](3,z),W[OC[1]](16,1213)),f[38](15,W[OC[1]](18,z),z,W[OC[1]](3,1454)),P[37](86,w,C,X),l[OC[2]](29,X,W[OC[1]](6,X),W[OC[1]](1,z)),f[38](13,W[OC[1]](6,X),X,256), +I[26](4,C,w,W[OC[1]](5,X))],Y=[f[38](21,W[OC[1]](21,B),c,256),I[26](2,C,Q,W[OC[1]](3,c)),H[45](18,d,W[OC[1]](18,B),256),ii(B,UC,J,d)],t=[T[14](65,21,C,W[OC[1]](5,C)),U[OC[1]](74,n,aT),P[37](80,n,C,n),l[OC[2]](18,Q,W[OC[1]](19,n),4),f[38](21,W[OC[1]](19,z),z,W[OC[1]](2,1454)),l[OC[2]](18,z,W[OC[1]](2,z),W[OC[1]](7,1454)),f[38](22,W[OC[1]](18,z),z,W[OC[1]](16,1454)),U[OC[1]](91,w,OC[1]),y[17](13,n,w,r),y[15](45,191,UC),v[31](73,UC,UC),y[15](OC[2],F[OC[1]],J),U[24](27,n,W[OC[1]](5,n),F[2]),U[24](59, +Q,W[OC[1]](18,Q),F[2]),y[17](13,n,Q,Y,-1),y[36](1,UC),y[36](5,J),y[36](3,a)],(x=c7.M()).i.apply(x,T[5](71,A)),m=t):(mQ=I[47](5,65535),u=y[41](8,c7.M(),5),E=P[4](14,u),L=E.next().value,tA=E.next().value,Z=E.next().value,g=E.next().value,q=E.next().value,h=[P[37](81,Z,C,g),U[26](10,q,W[OC[1]](3,g),W[OC[1]](1,tA)),l[OC[2]](49,tA,W[OC[1]](3,tA),W[OC[1]](16,g)),I[26](36,C,Z,W[OC[1]](7,q))],D=[T[14](66,21,C,W[OC[1]](2,C)),U[OC[1]](95,tA,mQ),U[OC[1]](OC[0],L,aT),P[37](85,L,C,L),U[OC[1]](88,Z,OC[1]),y[17](13, +L,Z,h),U[OC[1]](90,tA,mQ),I[26](2,C,L,W[OC[1]](5,tA))],(O=c7.M()).i.apply(O,T[5](39,u)),m=D),M=m,KB=[K[11](38,k),l[OC[2]](22,k,W[OC[1]](23,k),632),S[48](41,k,W[OC[1]](21,k),bl),U[26](1,k,W[OC[1]](23,k),OC[1]),U[26](11,B,W[OC[1]](23,e.j),W[OC[1]](18,k)),U[26](2,z,W[OC[1]](22,e.j_),W[OC[1]](19,k)),M,e.K8,S[37](3,39,hA),U[24](27,hA,W[OC[1]](5,hA),W[OC[1]](3,e.DR)),U[OC[1]](OC[0],G,e.Uj),K[39](32,7,[G,C,hA,e.Hm])]),6)^24)<N&&(N+8^8)>=N&&(this.m=e|OC[1],this.tO=C|OC[1]),N)&&(L=e.content,e.textContent= +C,KB=L),KB},function(N,C,e,L,h,Q,m,O,t,D,q){return N-(((N|((((q=["c9",2,28],N<<q[1]&21)||(e=H[q[1]](64,C),e=H[q[1]](56,C)&&e?1:0,U[29](39,e,C)),N)^37)<20&&(N-4&14)>=8&&(m=L[q[0]],C[e]=function(u,B,G,c){return m(u,B,(c=[1,null,40],G),O||(O=y[31](c[0],2,H[c[0]].bind(c[1],33),f[37].bind(c[1],18),h,FN).LD),t||(t=S[c[2]](20,c[1],h)),Q)}),24))==N&&(e=H[q[1]](q[2],C),e=H[q[1]](q[2],C)<<e,U[29](39,e,C)),(N^91)>>3)==3&&(hP.call(this,h),this.type=g0,this.keyCode=C,this.repeat=L),q[1])&13||(D=P[0](76,e,L,C, +rY)),D},function(N,C,e,L,h,Q,m,O,t){if((N<<1&15)==(((O=[2,29,0],N)&46)==N&&p.call(this,C),O[0]))a:{for(Q=(h=L.split(ZD()),Zf),m=C;m<h.length;m++)if(Q=Q[h[m]],Q==e){t=e;break a}t=Q}if((N&55)==N){if(Q=[null,"none",!0],bb){h=C;try{h=!T[48](8,Q[O[2]]).document}catch(D){h=Q[O[0]]}h&&(W[48](58,bb),bb=Q[O[2]])}t=(m=(L=oG||f[38](93),!bb&&L&&(bb=LM(HJ),S[O[1]](35,bb,"display",Q[1]),L.appendChild(bb)),S[28](56)),bb&&(m=T[48](1,Q[O[2]])||m),e)(m)}return N+3>>3>=O[0]&&(N<<O[0]&14)<4&&(t=C.Ql.pop()),t},function(N, +C,e,L,h,Q){if((N|2)>=((N+(h=[21,null,0],6)&29)>=N&&N-5<<2<N&&(K[5](3,[-110,-111],v[42].bind(h[1],1)),K[5](15,[-30,-78],l[48].bind(h[1],48)),K[5](25,[-43],H[20].bind(h[1],1)),K[5](25,[-5,-112],U[38].bind(h[1],6)),K[5](h[0],[-67,-3],T[12].bind(h[1],1)),K[5](h[0],[-36,-95],y[h[2]].bind(h[1],8))),8)&&(N^60)<28)a:{if((L=[!1,null,64],C)==L[1]){Q=C;break a}if((e=typeof C,e)==="bigint"){Q=String(sR(L[2],C));break a}if(!n2){Q=C;break a}if(T[49](28,C,L[h[2]])){if(e==="string"){Q=l[24](40,h[2],L[h[2]],C);break a}if(e=== +"number"){Q=S[31](58,"-",L[h[2]],C);break a}}}if((N-1^h[0])<N&&(N+9^12)>=N)a:try{Q=l[38](35,1,C).getItem(e);break a}catch(m){Q=h[1];break a}return Q},function(N,C,e,L,h,Q,m,O,t,D,q){return(N&((N&((D=["b",24,"B"],N-4>>3||(L=L===void 0?!0:L,h=h===void 0?S[7].bind(null,8):h,q=function(u,B,G){var c=["apply",44,3],A=aq[c[0]](c[2],arguments);u=u===void 0?T[45](99):u;var n,R,F,Z,X,Y,k,E=this;return P[c[1]](73,function(J,r,z,d){for(d=(z=[3,2,32],84);d!=25;)if(d==29)n=J.G,k=n.YL,R=n.Ss,P[0](78,F,R,r[z[1]]), +function(x){return K[23](10,3,x,F)}(bH.IX()),d=50;else if(d==24)d=J.B==r[z[1]]?88:29;else if(d==50)d=G!=void 0&&MO==G?z[2]:42;else if(d==z[2])X=new Jw,l[36](79,W[33](25,F,z[0]))==0||Z.i.IX()==0?y[44](14,r[z[1]],X,r[0]):Z.G?y[44](9,r[z[1]],X,z[0]):Z.o?y[44](18,r[z[1]],X,4):y[44](14,r[z[1]],X,r[z[1]]),P[0](77,X,k,r[0]),pA.push(X),MO=void 0,d=42;else if(d==84)r=[2,!1,1],d=24;else{if(d==42)return J.return(new $f(k,F,e));if(d==88)return bH=B||bH,MO=MO||G,Y=Vc(y[14](z[0],u)),F=K[7](z[1],r[0],Y),L&&UR(function(x){return A[x= +["unshift",10,4],x[0]](U[x[2]](18,8549)(),U[x[2]](26,8924)(),U[x[2]](18,9708),U[x[2]](x[1],8441))},0),Z=H[6](1,r[z[1]],r[0],'"',r[1],function(){return C.apply(E,A)},h),J.i(Z.B(Y),r[0])}})}),N|40)==N&&(this.G=Q,this[D[2]]=L,this.config=C,this.Dp=e,this.state=0,this.i=new TN,this.channel=I[5](1,1,"c",D[0],"d",this,h)),92))==N&&(Q===0||L.includes(Q),t=P[D[1]](1,C,m),O=P[49](11,C,h,L,t,m,e),O!==Q&&(O&&(e=W[26](27,e,O,m,void 0,h)),t.set(L,Q)),q=e),89))==N&&(this[D[2]]=-1),N>>2>=11&&(N^60)<15&&p.call(this, +C),q},function(N,C,e,L,h,Q,m){if(N+((m=[59,9,1],N-m[1])&7||(L=L===void 0?null:L,h=h===void 0?!1:h,this.i=L,this.XI=h,this.B=C===void 0?null:C,this.yM=e=e===void 0?null:e),m)[2]>>m[2]<N&&N+6>>m[2]>=N)for(L in e)C.call(void 0,e[L],L,e);if((N-8^24)>=N&&(N+5^29)<N)K[23](m[0],C,L,e);return Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if((((((N+(B=[48,2,"addListener"],B)[1]&15)==3&&(D=function(c,A){return P[44](41,function(n,R){return R=[42,0,3],n.B==C?n.i(m(A,c),e):n.return({Ss:n.G,YL:l[R[0]](R[2],R[1],A)})})}, +t=bH,O=O===void 0?200:O,q=new NT,q.B=function(c,A){return P[44](73,function(n,R,F){R=(F=[34,"i",25],[0,3,"number"]);switch(n.B){case C:if((A=null,n).K(e),q[F[1]].IX()==R[0]){n.js(4);break}return n[F[1]](v[12](2,R[0],Q,t),5);case 5:if(A=n.G,A!=null)return typeof A!="string"||A.includes(Cd())||A.includes(eT())?typeof A==R[2]?A=""+A:A instanceof EA?(q.o=!0,A=A[F[1]]):A=W[28](F[0],h,function(Z){return Z.stringify(A)}):A=L+A+L,n.return(D(c,A));case 4:n.V(R[1]);break;case e:n.o(),q.G=!0;case R[1]:return n.return(S[30](F[2], +c))}})},q.i=I[13](96,O),G=q),N>>1)&15)==3&&(G=I[33](12,e==C?e:T[21](18,": ",e),h,void 0,L,Q)),N)&106)==N)a:{if(!O)throw Error("Invalid event type");if(u=((t=I[6](14,m)?!!m.capture:!!m,q=l[B[0]](64,e))||(e[g7]=q=new AC(e)),q.add(O,L,Q,t,h)),u.proxy){G=u;break a}if(u.proxy=(D=y[29](58),D),D.src=e,D.listener=u,e.addEventListener)Ld||(m=t),m===void 0&&(m=C),e.addEventListener(O.toString(),D,m);else if(e.attachEvent)e.attachEvent(v[9](88,O.toString()),D);else if(e[B[2]]&&e.removeListener)e[B[2]](D);else throw Error("addEventListener and attachEvent are unavailable."); +G=(ag++,u)}if(N>>1>=10&&(N|B[1])>>5<1&&e.G){if(!e.j)throw new hf(e);e.j=C}return(N^59)>>5<1&&(N>>1&31)>=25&&(e=this.B,G=e===C||Array.isArray(e)&&e.includes(C)),G},function(N,C,e,L,h,Q,m,O,t){if((t=[null,1,48],(N^43)&15)==2)a:{if(e==(Q=[1,!0,"http"],QW)){O=QW;break a}h=(m=I[34](15,Q[t[1]],new sB(e),""),L=l[3](24,t[0],m,""),S)[20](12,"",T[25](26,L,""),l[24](8,Q[0],t[0],e)),h.o!=t[0]||(h.B=="https"?S[12](11,h,443):h.B==Q[2]&&S[12](18,h,C)),O=h.toString()}if((N>>t[1]&15||(O=v[43](28,C,TS)?U[42](81,W[16](7, +"",C.U5())):String(C).replace(op,I[t[2]].bind(t[0],6))),N>>t[1]&3)==3)K[5](35,[-53],U[24].bind(t[0],2));return(N+6^18)<N&&(N-4^23)>=N&&(e?W[22](7,C,L):W[16](2,C,L)),O},function(N,C,e,L,h){return((((L=[18,38,0],N)|3)>>4||(e=H[14](16),v[44](L[1],e,new mW(e,C))),N-4)|L[0])<N&&(N+2&59)>=N&&(C=[null,!1],this.o=C[L[2]],this.B=C[L[2]],this.G=C[L[2]],this.i=C[L[2]],this.next=C[L[2]],this.K=C[1]),h},function(N,C,e,L,h,Q){return N<<(N+(h=[31,1,7],h)[2]>=-59&&(N<<2&4)<4&&(L=C.n7,e=C.hE,Q=T[h[1]](65,W[11](20, +T[h[1]](h[1],fJ(),"<div><div></div>"),P[h[0]](h[1],{id:e,name:L})),jB())),h[1])>=h[2]&&(N^21)<11&&Oz.call(this,pM),Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w){if(((N-7>>3==(w=[1,"getAttribute","getName"],w[0])&&tf(function(){throw C;}),N>>w[0])&7)==3){if(!(Z=(I[6](21,(L=(e=e===void 0?{}:e,L===void 0)?!0:L,C))&&C.nodeType==w[0]||!I[6](13,C)||(e=C,C=y[41](14,document,EC),f[38](86).appendChild(C),e[We[w[2]]()]=He),U)[3](20,null,C),Z))throw Error(Uz());if(!(c=h||new ww,e[s6[w[2]]()])&& +window[Bh][D9()]&&window[Bh][D9()].length>0&&(e[s6[w[2]]()]=window[Bh][D9()][0]),L?(q=Z,R=q[w[1]](cV),A=q[w[1]](qT),k=q[w[1]](uS),u=q[w[1]](BR),t=q[w[1]](jT),d=q[w[1]](G3),Q=q[w[1]](cR),r=q[w[1]](Kd),D=q[w[1]](Af),m=q[w[1]](yW),G=q[w[1]](iS),n=q[w[1]](vR),J={sitekey:R,type:A,theme:k,size:u,tabindex:t,bind:d,preload:Q,badge:r,s:D,pool:m,"content-binding":G,action:n},(B=q[w[1]](nd))&&(J[Il()]=B),(X=q[w[1]](Rl))&&(J[Fu()]=X),(Y=q[w[1]](lS))&&(J[T3()]=Y),(O=q[w[1]](Z9))&&(J[ol()]=O.toLowerCase()==="false"? +!1:!!O),z=J,e&&yO(z,e)):z=e,I[w[0]](3,Z))throw Error(PR());if(Z.tagName==$n||Z.tagName==xn&&(Z.type==sz||Z.type==fd))z[Yq[w[2]]()]=Z,E=y[41](17,document,EC),Z.parentNode.insertBefore(E,Z),Z=E;if(S[44](3,w[0],Z).length!==0)throw Error(Xu());if(!z||!I[6](7,z))throw Error(ST());x=(F=new Yx(Z,c,z),window[Bh][GN()][F.id]=F,F.id)}if((N&(N+8&15||p.call(this,C),(N|48)==N&&(x=f[5](48,e,lH,C,L)),84))==N){for(h=(Q=(~(h>>C)&L.Ql.length)-h-e,L).Ql[Q];Q<L.Ql.length-e;Q++)L.Ql[Q]=L.Ql[Q+e];L.Ql.pop(),x=h}return x}, +function(N,C,e,L,h,Q,m,O,t,D){if(!(N+3&((N&(D=[58,1,7],107))==N&&(t=P[0](79,e,L,C,rY)),11))){if(h.nu&&h.Wm&e&&!L)throw Error(WR);!L&&h.Wm&e&&K[47](78,C,e,!1,h),h.Cu=L?h.Cu|e:h.Cu&~e}if(!(N<<D[1]&D[2])){Q=P[4](14,(h=h===void 0?Tt:h,L.K)),m=Q.next();try{for(;!m.done;m=Q.next())U[47](64,C,L,m.value)}finally{m&&!m.done&&(O=Q.return)&&O.call(Q)}(new Promise((L.K.length=C,function(q,u){U[47](4,C,L,new vH(0,0,null,2,e,Tt,h+qY(),q,u))}))).catch(H[40].bind(null,D[0]))}return t},function(N,C,e,L){if(((L=[2, +1,"Iterator result "],N+L[0])^30)<N&&N-L[0]<<L[1]>=N&&!(C instanceof Object))throw new TypeError(L[2]+C+" is not an object");return(N<<L[1]>=-59&&(N>>L[0]&8)<8&&p.call(this,C),N+6&78)<N&&(N-3|52)>=N&&(e=C>0?C>=0x7fffffffffffffff?HR:new mu(C/4294967296,C):C<0?C<=-0x7fffffffffffffff?kx:S[27](L[1],new mu(-C/4294967296,-C)):iC),e},function(N,C,e,L,h,Q,m){return N<<((N-((N|56)==(Q=[58,"B",11],N)&&(this.i=e,this[Q[1]]=C),2)^13)>=N&&(N+3&Q[0])<N&&(this.G=C,this.i=h,this[Q[1]]=e,this.o=L),N-2<21&&(N-5&15)>= +5&&(m=T[22](1,2,C,rY)),1)&Q[2]||(this[Q[1]]=!1,this.G=null,this.i=""),m},function(N,C,e){return(N>>2&(N>>(C=[84,"o","B"],2)&3||(e=rV=rV||new yE),7))==1&&(YK.call(this,1994,26),this.H=this.K=this[C[1]]=-1,this.G=this[C[2]]=-1,this.X=I[21](C[0]),this.h=I[21](7)),e},function(N,C,e,L,h){return(N-2^(((L=[3,12,7],(N+L[0]&73)<N&&(N-L[2]|20)>=N&&C&&(this.VY=C),N)<<2&8)<2&&N>>1>=-70&&(T[0](19,1,C.i),h=I[22](L[1],C.i)),L[2]))<N&&N-2<<2>=N&&(C.i.K=e,C.B.G.value=e),h},function(N,C,e,L,h,Q){return(N&((h=[31,0, +1],N-3)>=23&&N>>h[2]<30&&C.isEnabled()&&f[h[0]](2,C,e,"recaptcha-checkbox-clearOutline"),46))==N&&(e=C.nI,L=e.U_.substring(e.e_,e.xx,e.xx+8),L=(new null(L.buffer)).getFloat64(h[1],!0),e.xx+=8,U[29](5,L,C)),Q},function(N,C,e,L,h,Q,m,O,t,D){if(!(((D=["push","B","i"],N+1)&13||(this[D[2]]=C,this[D[1]]=e),N+5)>>4)&&h)((Q=(O=(m=e[ro])!=C?m:e[ro]=new V$)[L])!=C?Q:O[L]=[])[D[0]](h);return t},function(N,C,e,L,h,Q,m){return N-((N^((N-((Q=[3,2,6],(N+Q[1]^27)>=N&&(N-Q[2]^9)<N)&&(H[41](19,e.o),e.K=C),Q)[0]^29)>= +N&&(N+4&56)<N&&(h=xj,m=I[33](28,P[44](27,C,L),1,void 0,h,e)),54))<7&&(N|Q[1])>>Q[0]>=Q[1]&&(m=L&&L.Yq?L.Yq[C]||e:e),Q[2])&7||(this.Z=this.Z,this.J=this.J),m},function(N,C,e,L,h,Q,m,O,t,D){return(N|9)>>(((D=[3,33,15],N)-2>>D[0]==2&&L&&(e.onmessage=function(q){L(new pd(q.data,S[3](5,void 0,q.ports[C])))}),(N+D[0]^D[2])<N&&(N+5&60)>=N)&&(O=T[D[1]](61,h,void 0,e,Q),m=h.z2,t=W[14](69,C,m[Rw]|0,L,m,O)||L[NM]||(L[NM]=y[23](1,L))),4)||(t=new Promise(function(q){(window.addEventListener("visibilitychange", +function(){q()},{once:!0}),document).hidden||q()})),t},function(N,C,e,L,h,Q,m){return N-(((Q=["-selected","replace","cK"],N)+8&7)==1&&(e=T[41](12,C),H[2](28,C)===0&&H[23](12,3,e,C)),9)<18&&(N<<1&5)>=2&&(h=L[Q[2]](),h[Q[1]](/\xa0|\s/g,OY()),L.i={1:h+"-disabled",2:h+e,4:h+"-active",8:h+Q[0],16:h+"-checked",32:h+"-focused",64:h+C}),m},function(N,C,e,L,h,Q,m,O,t,D,q){if((N|(N+((N|(q=[32,36,2],80))==N&&(this.o7=e=e===void 0?f[33](16,!1):e,this.i=C),q)[2]<q[0]&&(N+5&15)>=13&&(L=H[15](1,this),e=y[34](60, +this),C=y[34](56,this),this.Pm[L]=e[C]),40))==N)a:try{D=((m||!h?h=new Rp:O&&I[22](22,C,h,l[q[1]].bind(null,74),T[45].bind(null,7),L,-1),Q&&(t=v[3](42,Q,y[11](42),L))&&t.length)&&I[22](23,C,h,l[q[1]].bind(null,75),T[45].bind(null,9),L,t[e]),h);break a}catch(u){}return N+8>>4==((N+7^10)<N&&(N-1^29)>=N&&(D=new ZE(function(u,B){if((B=C[Ob](),K)[15](3,B.subscribe))return B.subscribe(u);throw new TypeError("Provided object does not correctly implement Symbol.observable");})),4)&&(sN.length>=100&&P[13](14, +10,1),sN.push(C)),D},function(N,C,e,L,h,Q,m,O){if(!(O=[64,"B",1],N+2&7)){if(L=e.v(),S[37](30,C))e.v().placeholder!=e.G&&(e.v().placeholder=e.G);else v[8](12,!0,e);K[13](38,Jf,L,e.G),K[4](85,"",e)?(h=e.v(),W[16](27,h,"label-input-label")):(e.X||e.ux||(Q=e.v(),W[22](3,Q,"label-input-label")),S[37](28,C)||W[36](O[0],10,e.F,e))}return N<<O[2]&4||(L=[0],e=Ez,typeof e==="string"?(this.G=e==z3?C:0,this.P=e==dV?C:0,this.o=e==Ez?C:0,this.i=e==wV?C:0,this.K=e==VW?C:0,this[O[1]]=e==xx?C:0):(this[O[1]]=L[0], +this.P=e||L[0],this.K=C||L[0],this.o=L[0],this.i=L[0],this.G=L[0])),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F){return(N^((N&(R=[78,19,7],(N>>1&R[2])==1&&(h=e.y-C.y,L=C.x-e.x,F=[h,L,h*C.x+L*C.y]),R[0]))==N&&(L.nI.xx=e>>>C),R[1]))>>4||(F=P[44](77,function(Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA){if((hA=[43,(E=[2,1E6,1E3],12),3],Z.B)==1)return u=new al,J=new gV,k=f[5](44,J,Pt,1,m),a=K[23](60,4,t,k),q=K[23](hA[1],L,O,a),D&&(X=D.o!=C?l[13](2,e,D.o)/E[1]:void 0,x=H[38](7,q,K[24](5,X),E[0]),r=D.G!=C?H[hA[1]](34, +D.B.now()*E[2]).add(D.G):void 0,w=(c=r)==C?void 0:c.toString(),T[21](24,x,hA[2],w)),Z.i(P[11](18,h,q,"/v1/chooseServer",Q.B,bS,v[16](8,Q.i)),E[0]);if((B=((g=(z=(M=K[21](10,e,H[35](1,C,(n=(d=u,Z.G),n),4)),K)[21](13,e,H[35](2,C,n,L)),H[hA[1]](hA[0],d.B.now()*E[2])),Y=H[30](30,z,M),d).o=H[30](28,H[30](26,g,d.i),Y),d.G=H[30](28,H[30](26,M,d.i).add(z),g).div(H[hA[1]](35,E[0])),S)[41](40,1,void 0,n),B)==C)throw Error("ChooseServer response is missing gsessionid");return Z.return({Iy:B,K7:(A=l[hA[0]](59, +E[0],n))!=C?A:0,wI:(G=l[36](73,W[33](29,n,hA[2])))!=C?G:0,N4:u})})),F},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((N>>2&15)==(B=["call","push","string"],2))a:if(C==null||typeof C==B[2]||C instanceof dX){u=C;break a}if(!((N^((N+8&46)>=N&&N-6<<2<N&&(u=(Q=P[27](17,null,L,h))?(new Promise(function(G,c){h.o(Q.action).then(function(A){A?G(A):c(Error("No token"))},c),setTimeout(function(A,n){A=setInterval(function(){h.K()||(n++,n>=2&&(c(MT),clearInterval(A)))},(n=0,2E3))},11500)})).catch(function(G,c,A,n){return f[4](6, +C,(c=(n=["B",3,"i"],[0,6,null]),P[16](27,10,P[n[1]](24,11,P[30](82,c[1],P[34](45,e,G===MT?1:3,G==c[2]?void 0:G.message),h[n[2]].iQ),h[n[2]].origin),(A=Q.action)==c[2]?void 0:A.substring(c[0],100)).G2()),h[n[0]])}):null),15))&15)){m=(D=P[4](11,(Q=new $x((q=e,q)),Nr(Q))),D.next());try{for(O={};!m.done;O={y$:void 0},m=D.next())O.y$=m.value,h={},C6(Q,O.y$,(h[er]=function(G){q=G}.bind(Q),h[L6]=function(G){return function(c){return(fu(Q,(c={},G.y$),(c[hq]=q,c[QJ]=C,c[mi]=C,c[OK]=C,c)),L)(),q}}(O).bind(Q), +h[OK]=C,h[mi]=C,h))}finally{m&&!m.done&&(t=D.return)&&t[B[0]](D)}u=Q}if((N&124)==N)C.G[B[1]](U[25](33,C,function(G,c){return G*c}),U[25](1,C,function(G,c){return G/c}),C.tM,U[25](32,C,function(G,c){return G%c}),C.xq,C.a5);return u},function(N,C,e,L,h,Q,m,O,t,D){if((D=["toString","i",4096],N>>1&7)||(O=Q[D[1]][C[D[0]]()],m=-1,O&&(m=v[37](10,0,e,L,h,O)),t=m>-1?O[m]:null),N-2>>5<1&&(N-6&7)>=3)a:{if(h&e){t=Q;break a}!L||D[2]&h||16&h?Q=S[8](27,C,h,Q,!1,L&&!(h&16)):(v[22](64,C,Q),h&4&&$4(Q)),t=Q}return(N+ +8&8)<5&&(N>>1&7)>=1&&(t=function(q,u,B){for(u={C0:(B=[],0)};B&&!q.closed&&u.C0<h.length;u={C0:u.C0},u.C0++)B.push(U[12](21,L,h[u.C0]).subscribe(new zk(q,function(G){return function(c,A){if(B){for(A=C;A<B.length;A++)A!==G.C0&&B[A].unsubscribe();B=e}q.next(c)}}(u))))}),t},function(N,C,e,L,h,Q){return(N>>2&((N>>2&(h=[8,1,!0],h)[0])<h[0]&&(N-7&3)>=2&&(Q=l[h[0]](47,0,2,I[12](17,null,e),L,C)),7))==h[1]&&(KN.call(this,tq(),U[5](21,zP),y4()),this.ah=h[2],v[14](31,this,C)),Q},function(N,C,e,L,h,Q,m,O,t,D, +q,u){return(N-(N-2>>(((N^46)&13)>=((N>>(u=[33,"V",1],u)[2]&15)>=0&&N-7<6&&(this.S=C,this.K=e,this.J=!1,L=["'",!0,""],O=this,this.streams=new Map,this[u[1]]=new Set,this.G=new gX,this.l=new UK,this.h=u[2],this.A=new UK,this.status=new DR(new tC),this.T=new qr,this.j=[],this.X=0,this.P=[],this.Z=!1,this.I=new TN,this.B=function(B){Promise.resolve().then(function(G,c){(c=O.K.JE)==null||(G=c.i)==null||G.call(c,B)}).catch(function(){})},((m=this.K.JE)==null?0:m.i)&&y[22](31,this.I,H[14](u[2]),uf,function(B){O.B(B)}), +this.A.ix(U[7](u[2],L[0],L[u[2]],!1,null,function(B){return T[8](1,1,B)===0?Promise.resolve():new Promise(function(G){W[36](88,500,G)})})).subscribe(this.status),this.Y=new B1,this.V$=(Q=(h=e.V$)==null?void 0:h.ix(K[31](27,L[0],null,function(){return jr}),Gj(jr)))!=null?Q:jr,S[15](21,L[2],this)),8)&&N>>2<13&&(e.count+=C,e.B+=L,L>e.i&&(e.i=L)),3)==3&&(q=P[44](13,function(B,G,c){G=[null,(c=["J",1,0],3),8];switch(B.B){case L:if(!Q.G)return B.return([null,null]);return(((D=[],Q.K=function(A,n,R,F,Z,X, +Y,k,E){E=[1,5,38],R=[3,null,4],A.length>0&&(n=A[0],n>0&&(A[L]?(Z=new c1,X=H[E[2]](7,Z,P[44](29,R[E[0]],A[C]),C),Y=H[E[2]](4,X,P[44](26,R[E[0]],A[R[0]]),R[0]),k=new Uint8Array(Object.values(A[L])),H[E[2]](E[1],Y,y[39](8,R[E[0]],k,e),R[2]),F=Y):F=R[E[0]],D[n-L]=F))},qY)(),B).K(C,G[c[1]]),B).i((0,B8.tj)(function(){return Q.G.i(Q.Y)},14),G[c[1]]);case G[c[1]]:(B[c[0]](),Q).K=G[c[2]],B.S(4);break;case C:B.o(),B.js(G[c[1]]);break;case 4:((m=T[14](25,L,new K6,new Aq(D)),qY)(),B).js(h);break;case h:return t= +m.G2(),B.i(Promise.resolve(T[16](30,4,yJ,f[30](c[1],255,256,Q.j,W[c[1]](57,h,t)))),G[2]);case G[2]:return O=B.G,B.return([y[14](6,t),O])}})),5)|u[0])<N&&(N-8|59)>=N&&(e=H[2](60,C),e=null(e),U[29](37,e,C)),q},function(N,C,e,L,h,Q,m,O,t,D,q,u){if((q=["v","tO",28],(N&54)==N)&&(Ar.prototype.I=U[3](41,2048),this.Pm.length>0&&this.Pm.push(this.Pm.shift())),!((N^83)&13))a:{if(L.m>=(m=[0,10],m)[0]){u=L.toString(void 0);break a}u=((D=(h=(O=I[t=L.m,4](58,m[0],m[1]),Q=v[15](q[2],t>>>C,L[q[1]]>>>C|t<<e),Q.div(O).shiftLeft(C)), +H)[30](29,L,h.multiply(O)),D.compare(O)>=m[0])&&(h=h.add(v1),D=H[30](57,L,h.multiply(O))),h.toString(m[1]))+D.toString(m[1])}if((N-3&(((N|7)&27)!=3||K[4](81,"",this)||(this[q[0]]().value=this.G),15))>=7&&((N|9)&q[2])<21)a:switch(L=L===void 0?null:L,e){case ha:u=new n6;break a;case ML:u=new I9;break a;case IM:u=new R9;break a;case Nm:u=new v0;break a;case Fz:u=new v0(Fz);break a;case rf:u=new lf;break a;case io:u=new Tj;break a;case zS:u=new ZR;break a;case o9:u=new P1;break a;case pM:u=new sK;break a; +case nq:u=new f6;break a;case it:u=new Xz;break a;case zz:u=new Sr(L);break a;case C:u=new Y5;break a}return(N|88)==N&&YK.call(this,1278,22,[2]),u},function(N,C,e,L,h,Q,m,O){if(((N&(m=[106,2,1],m[0]))==N&&(Q=[],y[41](m[2],e,C,h,Q,C,L),O=Q),N+7>>m[2])>=N&&N+m[2]>>m[2]<N)K[5](23,[-101],l[16].bind(null,m[1]));return O},function(N,C,e,L,h,Q,m,O,t){if(N-((t=['" dir="ltr"><div tabIndex="0" class="',2,65],N-3&7)||(L.remove(Q),h.length>C&&(L.G=e,L.i.set(K[44](71,Q,L),v[40](36,h)),L.B+=h.length)),t[1])>>3== +t[1]){for(L=(Q='<div class="'+H[7](1,(e=[(h=C.text,1),"</table></div></div>",'"></div><table class="'],"rc-prepositional-challenge"))+'"><div id="rc-prepositional-target" class="'+H[7](1,"rc-prepositional-target")+t[0]+H[7](t[2],"rc-prepositional-instructions")+e[t[1]]+H[7](1,"rc-prepositional-table")+'" role="region">',m=vh(0,wq(h.length-0)),0);L<m;L++)Q+='<tr role="presentation"><td role="checkbox" tabIndex="0">'+W[20](52,h[L*e[0]])+"</td></tr>";O=P8(Q+e[1])}return(N|24)==N&&(O=C.add(S[27](4,e))), +O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if(!((n=["V",64,null],N>>2&3)||(B=[!0,2,0],yE.call(this),this.G=e||n[2],this.K=W1(),this[n[0]]=W[42].bind(n[2],49),this.B={},this.P=C,L))){for(u=(h=["requestAnimationFrame","mozRequestAnimationFrame","webkitAnimationFrame",(G=(c=((q=(Q=this.i=new H1((this.i=n[2],Pe(this.o,this))),f[2](73,B[1],wX(),Q),this.i),f)[2](72,B[1],k5(),q),this.i),Zf[Wh()]||Zf[Hh()]),"msRequestAnimationFrame")],B)[2];u<h.length;u++)t=h[u],h[u]in G&&f[2](74,B[1],t,c);for(O=Pe((te= +B[D=this.i,0],D).i,D),m=B[2];m<Os.length;m++)Os[m](O);Us.push(D)}return N-((N|1)>=-84&&(N|3)>>4<1&&(L=['"></span>','"><label class="',"rc-anchor-checkbox-holder"],e='<div class="'+H[7](32,"rc-inline-block")+'"><div class="'+H[7](33,"rc-anchor-center-container")+'"><div class="'+H[7](32,"rc-anchor-center-item")+C+H[7](32,L[2])+'"></div></div></div><div class="'+H[7](1,"rc-inline-block")+'"><div class="'+H[7](n[1],"rc-anchor-center-container")+L[1]+H[7](33,"rc-anchor-center-item")+C+H[7](65,"rc-anchor-checkbox-label")+ +'" aria-hidden="true" role="presentation"><span aria-live="polite" aria-labelledby="'+H[7](65,"recaptcha-accessible-status")+L[0],A=P8(e+"I'm not a robot</label></div></div>")),5)>>3==2&&(A=Array.prototype.map.call(e,function(R,F){return(F=R.toString(16),F).length>1?F:C+F}).join("")),A},function(N,C,e,L,h,Q,m,O,t,D,q){if((N&86)==(((N&(N-1<(q=[2,4,64],28)&&((N^q[2])&23)>=12&&(L=H[q[0]](72,C),e=H[q[0]](72,C),W[49](51,q[0],C,L,e)),60))==N&&(D=W[11](79,fJ(),l[11](12," "))),N-q[0]|q[1])<N&&(N+7^31)>=N&& +(yE.call(this),this.i=new ra(e),this.B=e&&e.gI||null,this.o=C,m=e&&e.lJ||null,e&&e.Io&&(m?m[p6]=Jq:m=Lx(p6,Jq)),t=e&&e.Uy||null,this.i.j=m,e&&e.v3&&(t?t[EK]=e.v3:t=Lx(EK,e.v3)),e&&e.Dt&&(t?t[zj]=e.Dt:t=Lx(zj,e.Dt)),h=e&&e.HY,this.i.rq=t,h&&!S[23](38,h)&&(this.i.A=h),this.K=e&&e.hp||!1,this.P=e&&e.hW||!1,(Q=e&&e.yI)&&!S[23](22,Q)&&(L=this.B,this.i.Z=Q,L!==null&&Q in L&&(O=this.B,Q in O&&delete O[Q])),this.G=new da(this)),N)&&(K2.call(this),this.X={},this.l=C),!((N|5)>>q[1])){L=L===void 0?!0:L;try{i5&& +Bj.set(this,{url:e.toString(),EZ:L})}catch(u){}Sw.call(this,C,e,L,h,Q)}return D},function(N,C,e,L,h,Q,m,O,t,D){if((N-1&15)==(((D=[4,77,"j"],N+D[0])&11)==1&&(UK.call(this),this.o=C),2)&&(K2.call(this),this.i=C,this.o=e||0,this.B=L,this.G=Pe(this.U8,this)),!((N^26)>>3))W[26](10,L[Rw]|0,C,L,e,y[30](29,128,L[Rw]|0));if((N>>1&((N&D[1])==N&&(h=L||wa.M(),jj.call(this,null,h,e),this.S=C!==void 0?C:!1),7))==D[0])a:{try{if((O=e.call(L.i[D[2]],Q),H)[12](57,O),!O.done){t=(L.i.Y=!1,O);break a}m=O.value}catch(q){t= +(L.i[D[2]]=C,y[37](12,q,L.i),v[40](6,null,L));break a}t=(h.call(L.i,(L.i[D[2]]=C,m)),v[40](7,null,L))}return t},function(N,C,e,L){if(!(N<<(e=[3,4,1],e[2])&e[0]))U[29](e[1],e[1],C);if(!((N|8)&6)){if(Rf>=C)throw new SyntaxError;Rf++}return L},function(N,C,e,L,h,Q,m,O){if((((O=[2,5,7],(N&83)==N&&(Q=Q===void 0?ZJ():Q,m=(h=W[19](24,C,e,L))!=C?h:Q),N<<1>=-30)&&(N^72)>>O[1]<O[0]&&(e=C.v())&&P[49](8,e,!1),N-O[2]|12)>=N&&(N+3^17)<N&&(L=new IB,m=U[44](1,null,e,C,L)),N-3<25)&&(N<<O[0]&23)>=O[2])K[23](12,C,L, +e);return(N-8^11)>=N&&N+O[0]>>1<N&&(P[26](O[0],this,4)&&v[0](13,4,!1,this),P[26](4,this,32)&&this.WE(!1)),m},function(N,C,e,L,h,Q,m){return((((N|(Q=["iterator",4,1],Q)[1])>>Q[1]||(m=function(O){return Promise.resolve(O.value).then(function(t){return{value:t,done:!!O.done}})},this[Symbol.asyncIterator]=function(){return this},this[Symbol[Q[0]]]=function(){return C},this.next=function(O){return(new Promise(function(t){t(C.next(O))})).then(m)},this["throw"]=function(O){return(new Promise(function(t, +D,q,u){(q=C["throw"],q!==void 0)?t(q.call(C,O)):(u=C["return"],u!==void 0&&u.call(C),D(new TypeError("no `throw` method")))})).then(m)},C["return"]!==void 0&&(this["return"]=function(O){return(new Promise(function(t){t(C["return"](O))})).then(m)})),N)^25)<37&&N+Q[2]>=18&&(this.i=C),(N-7|54)>=N)&&(N+Q[1]^18)<N&&(h=l[8](42,0,Q[2],v[34](45,C,L),e,0)),h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(!(N+(N-8>>5<(B=["nodeValue","getName",3],1)&&(N|2)>=5&&p.call(this,C),9)&13)){if(!(L=(e=(C=C===void 0?f[0](12, +0):C,e===void 0?{}:e),q=W[10](1,null,C,e),m=q.fI,q.client),v)[16](26,L.i))throw Error(VJ());t=(h=P[4](12,xJ(m)),h).next();try{for(;!t.done;t=h.next())if(D=t.value,![Cu[B[1]](),eH[B[1]](),x5[B[1]](),ai[B[1]](),Qe[B[1]](),Ka[B[1]]()].includes(D))throw Error(a9());}finally{t&&!t.done&&(O=h.return)&&O.call(h)}u=((m[eH[B[1]]()]&&m[eH[B[1]]()].length>0||m[x5[B[1]]()])&&(Q=H[B[2]](30,0,NP))&&(m[hE[B[1]]()]=Q),I[37](69,L.V(L.Xa.bind(L,h5,m)),function(G){L.i.has(NB)||L.i.set(NB,G)}))}if((N+5^10)>=N&&(N+B[2]^ +5)<N&&!(e.nodeName in bf))if(e.nodeType==B[2])L?h.push(String(e[B[0]]).replace(/(\r\n|\r|\n)/g,C)):h.push(e[B[0]]);else if(e.nodeName in Mr)h.push(Mr[e.nodeName]);else for(Q=e.firstChild;Q;)H[37](44,"",Q,L,h),Q=Q.nextSibling;return u},function(N,C,e,L,h,Q,m,O){if((((m=[1,0,6],N)+m[2]&66)<N&&(N-m[0]|17)>=N&&(U[21](28,C),Q=C.z2,W[26](23,Q[Rw]|m[1],L,Q,e,h),O=C),(N-9|37)>=N)&&N+m[2]>>2<N)a:{if(!Number.isFinite(e)){O=String(e);break a}O=((h=(Q=String(e),L=Q.indexOf(ZD()),L===-1&&(L=Q.length),Q[m[1]])=== +"-"?yR():"")&&(Q=Q.substring(m[0])),h)+$5("0",vh(m[1],C-L))+Q}return O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if((N-7&7)==((N>>1&14)==((((N^(n=["K","now",!1],3))&14)==2&&(A=UR(function(R,F,Z){return(F=(Z=function(X,Y){return(Y=["slice","indexOf","trim"],X[Y[1]](xI())!=-1&&(X=X[Y[0]](X[Y[1]](xI()))),X).replace(/\s+/g,OY()).replace(/\n/g,C)[Y[2]]()},Z(C+L)),R=Z(C+h),F)==R},e)),N-6&6)||xW.call(this,uf,C),2)&&(this.i=e,this.B=n[2],this[n[0]]=C,this.o=L,this.G=Date[n[1]]()),2)){if(Array.isArray(L))for(G= +0;G<L.length;G++)H[39](41,C,e,L[G],h,Q,m);else if(B=h||C.handleEvent,u=m||C.l||C,D=I[6](51,Q)?!!Q.capture:!!Q,B=l[18](59,B),q=!!D,O=S[7](7,e)?H[25](32,String(L),B,u,q,e.j):e?(c=l[48](67,e))?H[25](48,L,B,u,q,c):null:null,t=O)y[40](3,t),delete C.X[t.key];A=C}return A},function(N,C,e,L,h,Q,m,O){if((N|7)>>3==(O=["V",28,9],1)&&(e instanceof NV||(e=new NV(e,C)),m=e),(N^74)>>4||(L=[null],TN.call(this),this.A=L[0],this[O[0]]=L[0],this.o=C,this.F=e,this.K=L[0],this.P=L[0],this.i=L[0],this.G=L[0],this.Y=Date.now(), +this.h=L[0],this.C=L[0],this.R=L[0]),!(N+O[2]&25))a:{if(typeof L==="string"){Q=encodeURI(L).replace(e,l[40].bind(null,10)),h&&(Q=Q.replace(/%25([0-9a-fA-F]{2})/g,Cl())),m=Q;break a}m=C}return(N&O[1])==N&&(h=new C.constructor(e),L&&(h.B=NR),h.G=NR,m=h),m},function(N,C,e,L,h,Q,m){if(!(m=["i","push",13],N<<2&m[2]))a:{if(C instanceof u5){Q=C[m[0]];break a}throw Error("");}if(!(N-2>>4))h[m[1]](Cd(),L.replace(eK,function(O,t,D){return(t=(D=[65536,"toString","charCodeAt"],Ll[O]),t)||(t=e+(O[D[2]](C)|D[0])[D[1]](16).slice(1), +Ll[O]=t),t}),Cd());if(!(N-8>>4))for(;e=C.firstChild;)C.removeChild(e);return Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){if((N&((N|7)>>(F=["Select all images with <strong>statues</strong>.",65,"/m/01bjv"],4)||(e=H[2](64,C),e=(L=H[2](56,C))==null?void 0:L[e],U[29](39,e,C)),23))==N){B=(m=["/m/01pns0","/m/07jdr",(n=C.label,"/m/01mqdt")],fJ());switch(I[6](17,n)?n.toString():n){case "stop_sign":T[1](17,B,'<div class="'+H[7](33,"rc-imageselect-candidates")+'"><div class="'+H[7](F[1],"rc-canonical-stop-sign")+ +'"></div></div><div class="'+H[7](64,"rc-imageselect-desc")+'">');break;case "vehicle":case "/m/07yv9":case "/m/0k4j":T[1](17,B,'<div class="'+H[7](32,"rc-imageselect-candidates")+'"><div class="'+H[7](33,"rc-canonical-car")+'"></div></div><div class="'+H[7](F[1],"rc-imageselect-desc")+'">');break;case "road":T[1](81,B,'<div class="'+H[7](32,"rc-imageselect-candidates")+'"><div class="'+H[7](33,"rc-canonical-road")+'"></div></div><div class="'+H[7](32,"rc-imageselect-desc")+'">');break;case "/m/015kr":T[1](80, +B,'<div class="'+H[7](32,"rc-imageselect-candidates")+'"><div class="'+H[7](33,"rc-canonical-bridge")+'"></div></div><div class="'+H[7](1,"rc-imageselect-desc")+'">');break;default:T[1](17,B,'<div class="'+H[7](F[1],"rc-imageselect-desc-no-canonical")+'">')}h=(q=C.PS,fJ)();switch(I[6](7,q)?q.toString():q){case "tileselect":case "multicaptcha":u=(c=C.eP,L=(t=C.PS,C).label,"");switch(I[6](18,L)?L.toString():L){case "TileSelectionStreetSign":case m[2]:u+="Select all squares with <strong>street signs</strong>"; +break;case "TileSelectionBizView":u+="Select all squares with <strong>business names</strong>";break;case "stop_sign":case "/m/02pv19":u+="Select all squares with <strong>stop signs</strong>";break;case "sidewalk":case "footpath":u+="Select all squares with a <strong>sidewalk</strong>";break;case "vehicle":case "/m/07yv9":case "/m/0k4j":u+="Select all squares with <strong>vehicles</strong>";break;case "road":case "/m/06gfj":u+="Select all squares with <strong>roads</strong>";break;case "house":case "/m/03jm5":u+= +"Select all squares with <strong>houses</strong>";break;case "/m/015kr":u+="Select all squares with <strong>bridges</strong>";break;case "/m/0cdl1":u+="Select all squares with <strong>palm trees</strong>";break;case "/m/014xcs":u+="Select all squares with <strong>crosswalks</strong>";break;case "/m/015qff":u+="Select all squares with <strong>traffic lights</strong>";break;case m[0]:u+="Select all squares with <strong>fire hydrants</strong>";break;case F[2]:u+="Select all squares with <strong>buses</strong>"; +break;case "/m/0pg52":u+="Select all squares with <strong>taxis</strong>";break;case "/m/04_sv":u+="Select all squares with <strong>motorcycles</strong>";break;case "/m/0199g":u+="Select all squares with <strong>bicycles</strong>";break;case "/m/015qbp":u+="Select all squares with <strong>parking meters</strong>";break;case "/m/01lynh":u+="Select all squares with <strong>stairs</strong>";break;case "/m/01jk_4":u+="Select all squares with <strong>chimneys</strong>";break;case "/m/013xlm":u+="Select all squares with <strong>tractors</strong>"; +break;case "/m/07j7r":u+="Select all squares with <strong>trees</strong>";break;case "/m/0c9ph5":u+="Select all squares with <strong>flowers</strong>";break;case "USER_DEFINED_STRONGLABEL":u+="Select all squares that match the label: <strong>"+W[20](56,c)+"</strong>";break;default:u+="Select all images below that match the one on the right"}(D=(W[49](28,t,h0())&&(u+='<span class="'+H[7](64,"rc-imageselect-carousel-instructions")+'">',u+="If there are none, click skip.</span>"),P8(u)),W)[11](20,h, +D);break;default:e=(R=(O=(A=C.PS,C.label),""),C.eP);switch(I[6](49,O)?O.toString():O){case "1000E_sign_type_US_stop":case "/m/02pv19":R+="Select all images with <strong>stop signs</strong>.";break;case "signs":case m[2]:R+="Select all images with <strong>street signs</strong>.";break;case "ImageSelectStoreFront":case "storefront":case "ImageSelectBizFront":case "ImageSelectStoreFront_inconsistent":R+="Select all images with a <strong>store front</strong>.";break;case "/m/05s2s":R+="Select all images with <strong>plants</strong>."; +break;case "/m/0c9ph5":R+="Select all images with <strong>flowers</strong>.";break;case "/m/07j7r":R+="Select all images with <strong>trees</strong>.";break;case "/m/0cdl1":R+="Select all images with <strong>palm trees</strong>";break;case "/m/09d_r":R+="Select all images with <strong>mountains or hills</strong>.";break;case "/m/03ktm1":R+="Select all images of <strong>bodies of water</strong> such as lakes or oceans.";break;case "/m/06cnp":R+="Select all images with <strong>rivers</strong>.";break; +case "/m/0b3yr":R+="Select all images with <strong>beaches</strong>.";break;case "/m/01bqvp":R+="Select all images of <strong>the sky</strong>.";break;case "/m/07yv9":R+="Select all images with <strong>vehicles</strong>";break;case "/m/0k4j":R+="Select all images with <strong>cars</strong>";break;case "/m/0199g":R+="Select all images with <strong>bicycles</strong>";break;case "/m/04_sv":R+="Select all images with <strong>motorcycles</strong>";break;case "/m/019jd":R+="Select all images with <strong>boats</strong>"; +break;case "/m/0pg52":R+="Select all images with <strong>taxis</strong>.";break;case "/m/02yvhj":R+="Select all images with a <strong>school bus</strong>.";break;case F[2]:R+="Select all images with a <strong>bus</strong>.";break;case m[1]:R+="Select all images with <strong>trains</strong>.";break;case "/m/013_1c":R+=F[0];break;case "/m/0h8lhkg":R+="Select all images with <strong>fountains</strong>.";break;case "/m/015kr":R+="Select all images with <strong>bridges</strong>.";break;case "/m/01_m7":R+= +"Select all images with <strong>pillars or columns</strong>.";break;case "/m/03jm5":R+="Select all images with <strong>a house</strong>.";break;case "/m/01nblt":R+="Select all images with <strong>an apartment building</strong>.";break;case m[0]:R+="Select all images with <strong>a fire hydrant</strong>.";break;case "/m/01knjb":case "billboard":R+="Select all images with <strong>a billboard</strong>.";break;case "/m/06gfj":R+="Select all images with <strong>roads</strong>.";break;case "/m/014xcs":R+= +"Select all images with <strong>crosswalks</strong>.";break;case "/m/015qff":R+="Select all images with <strong>traffic lights</strong>.";break;case "/m/01jw_1":R+="Select all images with <strong>bus stops</strong>";break;case "/m/03sy7v":R+="Select all images with <strong>traffic cones</strong>";break;case "/m/015qbp":R+="Select all images with <strong>parking meters</strong>";break;case "/m/01lynh":R+="Select all images with <strong>stairs</strong>";break;case "/m/01jk_4":R+="Select all images with <strong>chimneys</strong>"; +break;case "/m/013xlm":R+="Select all images with <strong>tractors</strong>";break;default:G="Select all images that match the label: <strong>"+W[20](50,e)+"</strong>.",R+=G}Q=(W[49](28,A,QB())&&(R+="<span>Click verify once there are none left.</span>"),P8)(R),W[11](10,h,Q)}Z=(T[1](1,W[11](50,B,h),jB()),B)}if((N-3^14)>=N&&(N-8|27)<N)a:try{Z=xJ(l[38](36,1,C)||{});break a}catch(X){Z=[];break a}return Z},function(N,C,e,L,h,Q){if((N|9)>>((N^60)&((h=[". </div>",54,"call"],N-3<<1>=N&&(N-3|87)<N)&&(L=['<div id="', +"rc-anchor-aria-status",'" aria-hidden="true">'],e=f[20](19,uo(),C,UY(),QR()),Q=P8(L[0]+H[7](65,"recaptcha-accessible-status")+'" class="'+H[7](64,L[1])+L[2]+W[20](h[1],e)+h[0])),15)||(Q=sN),4)==4)p[h[2]](this,C);if(((N-7&15)==4&&(e=H[2](64,C),e=H[2](24,C)-e,U[29](69,e,C)),N&42)==N)p[h[2]](this,C);return Q},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){return(((N&((n=[5,92,"M"],N&11)==N&&(B0[n[2]]().init(I[40](66,2,C)),S[4](41,function(R,F,Z){F.k=(Z=[13,"fu",40],H)[Z[0]](11,I[Z[2]](64,2,C)),e&&e[Z[1]]()&& +(F.t=e[Z[1]]())}),e=new Rg,e.render(f[38](n[1])),h=new F1(v[12](71,6,C,rY),v[12](69,7,C,rY)||1E4),L=new sL(h,C,new fa,new mm),this.i=new Ss(e,L)),N+1&14||(this.i=C),102))==N&&xW.call(this,"d"),(N&113)==N)&&(G=h.onMessage,D=h.zk,t=D===void 0?void 0:D,B=G===void 0?void 0:G,c=h.Hj,O=h.destination,q=h.rI,m=h.Tm,u=m===void 0?void 0:m,Q=h.Zp,new Ow(function(R,F,Z){O.addEventListener((Z=function(X,Y){(Y=["data",", but received ",4],X.source&&X.source===q()&&c.i(X.origin)&&(X[Y[0]][t0]||X[Y[0]])===Q)&&(O.removeEventListener(nM, +Z,e),u&&X[Y[0]][Uw]!==u?F(Error('Token mismatch while establishing channel "'+Q+'". Expected '+u+Y[1]+X[Y[0]][Uw]+C)):(R(S[3](Y[2],B,X.ports[L])),t&&t(X)))},nM),Z,e)})),(N|80)==N)&&(A=[].concat(T[n[0]](39,Object.values(DZ)),T[n[0]](73,Object.values(qV)))),A},function(N,C,e,L,h,Q){return((Q=[28,40,9],N+4>>2)<N&&(N+Q[2]^Q[0])>=N&&(C=e?T[45](19,C):l[36](74,C),h=C==null?L?0:void 0:C|0),N-Q[2]>>4)||(h=P[18](56,W[39](20,S[32](76,new b4,13),C),[y[38](16,e),y[38](Q[1],L)])),h},function(N,C,e,L,h,Q,m,O){return N<< +(((((N-(O=[25,26,56],3)&15)==1&&p.call(this,C),N|O[2])==N&&(K[5](15,[-37],v[O[0]].bind(null,57)),K[5](17,[-47,-106],y[27].bind(null,36)),K[5](35,[-21],l[42].bind(null,O[1]))),N-7)&7)==3&&(m=new un(C,Q,e,L,h)),1)>=-89&&(N-7&6)<1&&(l5=L=e>>>C,TU=(e-L)/4294967296>>>C),m},function(N,C,e,L,h,Q,m,O,t){if(!(N+3>>(t=["scale(0)","Wm","opacity"],(N|8)==N&&(L=H[13](11,B0.M().get()),O=P[0](78,e,L,C,rY)),4)))if(m.I6(e),Q)S[29](55,m.h,t[2],h),S[29](39,m.h,"transform",t[0]),W[36](74,C,Pe(function(){S[29](23,this.h, +"display",L)},m));else S[29](71,m.h,"display",L);return N+9&6||(O=!!(h.Cu&e)&&!!(h[t[1]]&e)!=L&&(!(0&e)||v[44](38,h,v[30](48,32,16,C,1,e,L)))&&!h.J),O},function(N,C,e,L,h,Q,m,O,t,D){if(!(N<<(D=["hO","z$",28],1)&7))a:{if(((e=C.offsetWidth,Q=C.offsetHeight,L=M3&&!e&&!Q,e)===void 0||L)&&C.getBoundingClientRect){h=P[10](12,C),t=new B2(h.right-h.left,h.bottom-h.top);break a}t=new B2(e,Q)}return((N^8)&7)==1&&(h=h===void 0?B4:h,m=["Undo","Verify with mobile","Get a visual challenge"],Q=Q===void 0?null:Q, +QY.call(this),this.qp=L,this.wq=h,this.Fe=new B2(C,e),this.X=null,this.bI=h==I$,this.DR=h==rq,this[D[1]]=h==B4,this.P=this.Fe,this.iz=h==dw,this.response={},this[D[0]]=[],this.mF=Q,O=v[10](2,"div",!1),this.lI=P[D[2]](39,void 0,O?jK:Gv,c4,"Get a new challenge",this,Kl),this.R=P[D[2]](33,void 0,O?A0:yB,v4,"Get an audio challenge",this,Kl),this.j_=P[D[2]](37,void 0,O?nl:I4,R4,m[2],this,Kl),this.C=P[D[2]](36,void 0,F4,ln,"Get a liveness challenge",this,Kl),this.o6=P[D[2]](33,void 0,Tv,ZZ,m[1],this,Kl), +this.S_=P[D[2]](36,void 0,O?o4:P4,sw,"Help",this,Kl,!0),this.iI=P[D[2]](35,void 0,O?fl:X4,SK,m[0],this,Kl,!0),this.S=P[D[2]](38,"Verify",void 0,Yt,void 0,this),this.Hm=new W4),t},function(N,C,e,L,h,Q,m){return(((m=["compatMode","scrollingElement","scrollTop"],N)-9&4)<4&&((N^2)&6)>=2&&(L=e[m[1]]?e[m[1]]:M3||e[m[0]]!="CSS1Compat"?e.body||e.documentElement:e.documentElement,h=e.defaultView,Q=new aw((h==C?void 0:h.pageXOffset)||L.scrollLeft,(h==C?void 0:h.pageYOffset)||L[m[2]])),N>>1)&6||(Q=P[0](12,e, +"8x-4t2pegToiW8KmThtO4AQt",C,rY)),Q}]}(),T=function(){return[function(N,C,e,L,h,Q,m,O,t,D){if(((N<<2>=(t=["prototype",0,1],(N+t[2]&58)>=N&&N+t[2]>>t[2]<N&&(L=e.z2,D=f[8](13,C,T[18].bind(null,25),L[Rw]|t[1],L)),28)&&(N-5&30)<6&&Zf.setTimeout(function(){throw C;},t[1]),(N<<t[2]&31)>=12&&(N|5)>>5<2)&&(m=e||document,Q=[0,"*",null],m.getElementsByClassName?h=m.getElementsByClassName(C)[Q[t[1]]]:(L=document,h=C?(e||L).querySelector(C?"."+C:""):S[19](24,Q[t[2]],C,L,e,Q[t[2]])[Q[t[1]]]||Q[2]),D=h||Q[2]), +N^85)>>4||(O=function(){},O[t[0]]=e[t[0]],C.L=e[t[0]],C[t[0]]=new O,C[t[0]].constructor=C,C.Yb=function(q,u,B){for(var G=Array(arguments.length-2),c=2;c<arguments.length;c++)G[c-2]=arguments[c];return e.prototype[u].apply(q,G)}),!(N>>2&11))f[20](24,e.i+C,e);return D},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ){if((N-3&((N&44)==((((N&81)==(hA=["now",57,45],N)&&(C.i!==void 0?C.i.push(e):C.B+=e,mQ=C),(N^23)<44)&&(N^7)>=27&&(u=t.i.fu(),A=I[22](40,C,t.B.i),c=t.i,G= +Date[hA[0]]()-c.A,n=t.i,B=Date[hA[0]]()-n.V,R=new i9(u,A,G,B,L,Q,O,h,e,m,D,q),t.i.B.send(R).then(t.Xn,t.Nz,t)),(N&74)==N)&&(mQ=l[27](41,function(Df,UC,tA){Df.subscribe(new zk(UC,(tA=C,function(OC){UC.next(e.call(void 0,OC,tA++))})))})),N)&&(mQ=(e=P[18](22,ro))?C[e]:void 0),14))==2)a:{if((J=[1,12,5],Q)instanceof Xn){mQ=y[48](26,J[0],m,y[11](3),be).length>0?null:Q.B?H4.apply(Xn,T[5](71,Q.i)):kt.apply(Xn,T[5](25,Q.i));break a}t=(X=Array.of.apply(Array,T[5](71,Q.i.i)),P)[4](11,y[48](34,J[0],m,y[11](26), +be)),x=t.next();try{for(;!x.done;x=t.next())switch(g=x.value,T[14](52,null,g,$z)){case 4:X.push(T[15](55,K[21](9,0,v[34](68,null,g,4))));break;case e:X.push(P[37](10,K[21](8,0,v[34](66,null,g,e))));break;case L:X.push(T[15](23,new N0(y[47](10,32,P[31](7,null,T[33](55,g,void 0,L,$z),g)))));break;case C:X.push(P[37](11,new N0(y[47](12,32,P[31](15,null,T[33](54,g,void 0,C,$z),g)))));break;case 10:case h:X.push(new hr(new rx(g)));break;case 3:(n=(z=(d=(A=X,A.push),T)[33](54,g,void 0,3,$z),S)[41](34,z, +void 0,g),d).call(A,T[15](56,n));break;case J[0]:(D=T[r=(G=X,G).push,33](59,g,void 0,J[0],$z),O=S[41](32,D,void 0,g),r).call(G,P[37](72,O));break;case 7:(q=(Z=T[33](53,g,void 0,7,(a=void 0,R=X,E=R.push,$z)),W[33](29,g,Z,void 0,void 0,f[22].bind(null,74))),E).call(R,P[37](73,(a=q)==null?void 0:new Uint8Array(v[hA[2]](52,3,a)||0)));break;case J[2]:c=(k=(u=(Y=void 0,M=X,M).push,T[33](63,g,void 0,J[2],$z)),W[33](13,g,k,void 0,void 0,f[22].bind(null,75))),u.call(M,T[15](24,(Y=c)==null?void 0:new Uint8Array(v[hA[2]](49, +3,Y)||0)));break;case J[1]:if((w=W[40](12,e,null,l[41](61,J[1],g,eX,$z)),w)===null){mQ=null;break a}X.push(new hr(w));break;case 11:if(F=W[40](13,e,null,l[41](hA[1],11,g,eX,$z)),F===null){mQ=null;break a}X.push(T[15](32,F));break;case 13:X.push(new hr(null));break;case 0:X.push(new hr(new rx(g)));break;default:mQ=null;break a}}finally{x&&!x.done&&(B=t.return)&&B.call(t)}mQ=Q.i.B?H4.apply(Xn,T[5](hA[1],X)):kt.apply(Xn,T[5](89,X))}return mQ},function(N,C,e,L,h,Q){return N-2<<(((Q=[20,7,'" title="'], +N)&43)==N&&(this.G=C||null,this.B=this.i=null,this.o=!!e),1)>=N&&(N+4^5)<N&&(L=C.c3,e='<a class="'+H[Q[1]](64,C.jQ)+'" target="_blank" href="'+H[Q[1]](33,S[6](21,L))+Q[2],e+=U[42](17,"Alternatively, download audio as MP3"),h=P8(e+'"></a>')),(N^Q[0])<Q[1]&&(N|2)>=2&&(h=T[38](40,"</div>",'">',C.label)),h},function(N,C,e,L,h,Q,m){return N<<((N&((N>>1&14)==((Q=["X",15,"call"],N-8&Q[1])==1&&(m=function(O,t,D,q,u,B,G,c){c=[9,"z2",100];a:{q=(B={bK:!0},t&&Object.assign(B,t),l[26](24,O,void 0,void 0,B));try{G= +((u=(D=new L,D[c[1]]),S)[40](4,C,e)(u,q),D);break a}catch(A){if(A instanceof RangeError)throw new SyntaxError;throw A;}finally{U[c[0]](c[0],c[2],q)}G=void 0}return G}),2)&&(m=pl+(e?C+e:"")),113))==N&&(this.h=!!h,this[Q[0]]=C,J0[Q[2]](this,e,L)),2)&Q[1]||(this.V=0,this.B=C,this.G=L,this.o=h,this.K=1,this.i=e),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){return N+4>>((N|(((G=["floor",2,"i"],N)|1)>>4<G[1]&&N-1>=13&&(this[G[2]]=C,this.B=e),48))==N&&(this[G[2]]=new Map),4)||(q=l[49](25,L.P).width-14,m=Q== +4&&h==4?1:2,u=new B2((h-e)*m*G[1],(Q-e)*m*G[1]),O=new B2(q-u.width,q-u.height),B=e/h,D=e/Q,t=typeof D==="number"?D:B,O.width*=B,O.height*=t,O[G[0]](),c={iJ:O.height+C,Ze:O.width+C,rowSpan:Q,colSpan:h}),c},function(N,C,e,L,h,Q,m,O){if(!(N>>(O=[13,127,107],1)&15))a:{if((L=[171,0,222],e>=48&&e<=57||e>=96&&e<=106)||e>=65&&e<=90||M3&&e==L[1]){m=!0;break a}switch(e){case 32:case 43:case 63:case 64:case O[2]:case 109:case 110:case 111:case 186:case 59:case 189:case 187:case 61:case 188:case 190:case 191:case 192:case L[2]:case 219:case 220:case 221:case 163:case 58:m= +!0;break a;case 173:case L[0]:m=bj;break a;default:m=C;break a}}if(!(N-7&((N-3|46)>=N&&(N-1|50)<N&&Tk.call(this),O)[0])){if(C instanceof Array)e=C;else{for(L=(Q=P[4](12,C),[]);!(h=Q.next()).done;)L.push(h.value);e=L}m=e}return(N|(N+9>>1>=N&&(N-6^1)<N&&(m=v[12](68,C,e)),4))>>3==2&&(h=l[22](15,e),h!=null&&K[47](36,O[1],T[28](4,63,192,h),L,C)),m},function(N,C,e,L,h,Q,m,O){if(N-(N+(m=[2,5,4],m)[1]>>m[2]||(O=H[m[0]](7,C,function(t,D){return(D=t.crypto)?L(D.subtle||D.i,D):L(e,e)})),8)<19&&(N<<m[0]&7)>= +m[2])a:{for(Q=C;L;){if(h(L)){O=L;break a}L=(Q++,L.parentNode)}O=e}return O},function(N,C,e,L,h,Q,m,O,t){return((((N|((O=[5,2,24],N|O[2])==N&&(h=[3,0,8],Q=new Ew,Q.update(L),m=Q.digest(),t=(m[h[1]]<<O[2]|m[e]<<C|m[O[1]]<<h[O[1]]|m[h[0]])>>>h[1]),O[0]))>>4||(t=cJ.toString),N)&39)==N&&e.length!==0&&(C.G.push(e),C.B+=e.length),N^30)>>3==1&&(e=H[O[1]](60,C),e=H[O[1]](28,C)-e|0,U[29](39,e,C)),t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X){if((Z=["i",28,37],N-3)>>3==2&&(B=["marginTop",null,"rc-imageselect-desc-wrapper"], +u=T[0](59,"rc-imageselect-desc",e.h),t=T[0](Z[1],"rc-imageselect-desc-no-canonical",e.h),D=u?u:t)){for((m=(F=(L=T[0](22,(A=P[48](20,(Q=P[48](19,he,D),zv),D),B[2]),e.h),l[49](Z[1],e.P).width-C*P[10](5,"Left","padding",L).left),u&&(c=T[0](62,"rc-imageselect-candidates",e.h),F-=P[47](38,c).width),q=P[47](22,L).height,P[10](4,"Left","padding",L).top),R=q-C*m+C*P[10](1,"Left","padding",D).top,D).style.width=I[45](18,"px",F),G=0;G<A.length;G++)v[Z[2]](33,B[1],A[G],-1);for(n=0;n<Q.length;n++)v[Z[2]](32, +B[1],Q[n],-1);(h=(v[Z[2]](1,B[1],D,R),P[47](70,D).height),h>R)&&(O=vh(-m,(h-R)/C*-1),S[29](35,D,B[0],O+"px"))}return(((N^35)<12&&(N+3&5)>=2&&(this[Z[0]]=C||{cookie:""}),N)&49)==N&&(L=L===void 0?0:L,X=(h=l[36](74,W[33](9,e,C)))!=null?h:L),X},function(N,C,e,L,h,Q,m,O){if((N&(O=[4,"indexOf",29],102))==N){if(typeof e==="function")L=e;else if(typeof e==="object")L=e.constructor;else throw Error(void 0);m=P[0](61,C,function(t){return t instanceof L})}if(!((N|1)>>(((N|9)&7)==1&&(this.B=new Set,this.G=new Map), +O[0])))a:{if(h=oE(Number(L)),P0(h)&&h>=e){m=l[46](24,h);break a}m=(Q=L[O[1]](ZD()),Q!==-1&&(L=L.substring(e,Q)),I[28](1)?l[46](56,Ro(64,BigInt(L))):l[46](32,l[36](82,C,16,L)))}return(N-8<30&&(N+7&15)>=11&&(e=H[2](72,C),e=H[2](60,C)+e,U[O[2]](71,e,C)),N-9)>>O[0]==O[0]&&(this.dispose(),U[20](39,0,this,fo)),m},function(N,C,e,L,h,Q,m,O,t){return(N>>(O=["B","o",5],2)&7||(m=T[23](49,C,e,L.bK),L[O[1]]=h||0,L.K=m.i,L[O[0]]=m.buffer,L.i=L[O[1]],L.G=Q!==void 0?L[O[1]]+Q:L[O[0]].length),(N^38)&O[2])==1&&(this.Qy= +C),t},function(N,C,e,L,h,Q,m,O,t){return((N^8)>=-((O=["endTime","P",4],(N&109)==N)&&(Q=Vn(),m=RY(L,h!=e?h:L),t=vh(m+(24E4+4E4*Q)-L,C)),75)&&((N^11)&8)<7&&(L<h.startTime&&(h[O[0]]=L+h[O[0]]-h.startTime,h.startTime=L),h.progress=(L-h.startTime)/(h[O[0]]-h.startTime),h.progress>e&&(h.progress=e),v[20](9,0,h.progress,h),h.progress==e?(h.i=0,y[12](22,C,h),h[O[1]](),h.B(JZ)):h.i==e&&h.A()),N|7)>>O[2]<2&&(N<<2&5)>=1&&YK.call(this,375,10),t},function(N,C,e,L,h,Q,m){if(N-2<(Q=[1,15,47],20)&&(N<<Q[0]&Q[1])>= +5&&v[16](42,this.i))a:{if(((e=this.B,e).S=!e.S,e.style)==dx)C=wx();else if(e.style==VB)C=xt();else break a;S[29](55,e.B,C,e.S?a4:gx)}return((N&113)==N&&(e=H[2](72,C).length,U[29](7,e,C)),N-5)>>4>=3&&(N^50)>>5<5&&(h=K[42](3,C,null,e),L=P[Q[2]](54,e),m=new XQ(L.height,h.y,L.width,h.x)),m},function(N,C,e,L,h,Q,m,O,t){if(O=["B","eval",54],(N-2^2)>=N&&N-8<<2<N)for(h=C,L=Date.now();h<e.j.length;)L>=e.j[h].G+6E4?e.j.splice(h):++h;if(((N+3&15)==2&&(t=pq()),(N-1&7)>=3)&&(N^80)<9){if((h=window,e)instanceof +ls)L=e.i;else throw Error(C);h[(Q=L,O)[1]](Q)===Q&&h[O[1]](Q.toString())}return((N&25)==N&&(Q=L[O[0]][L[O[0]].length-C],m=qY(),Q.TX<=m&&(Q.T$=e),L.X&&L.X>=Q.T$||(Q.T$===1?(L.X=C,h=Q.TX-m,L.JO(h)):(L.X=e,L.s5()))),N-3^27)>=N&&(N+9&O[2])<N&&(e[O[0]]=C,e.i&&(clearTimeout(e.i),e.i=void 0)),t},function(N,C,e,L,h,Q,m,O,t,D,q){if((N&30)==(((q=[18,31,38],(N&60)==N)&&(Q=e.z2,D=P[49](41,C,h,L,P[24](9,C,Q),Q)),(N|24)==N)&&(D=f[5](20,e,Aq,C,L)),N))a:{if(!Zf.document&&!Zf.window){D=L;break a}m=(Q=P[4](14,[ye, +ci]),Q.next());try{for(;!m.done;m=Q.next())if(O=window.location.href,t=K[43](2,m.value),O.lastIndexOf(t,e)==e){D=L;break a}}finally{m&&!m.done&&(h=Q.return)&&h.call(Q)}D=C}return((N>>2&15)==4&&(h=H[2](72,C),e=H[2](60,C),L=H[2](68,C),L[(h>>q[1]&L.length)+h]=e,U[29](4,L,C)),N)-8>=13&&(N>>2&12)<2&&(D=P[q[0]](27,W[39](24,S[32](72,new b4,C),e),[y[q[2]](40,L)])),D},function(N,C,e,L,h,Q,m,O,t){return(((N|(((N+4&14)==(O=[2,9,33],O)[0]&&(this.i=C,this.B=e,this.G=L),N<<1<20&&((N|4)&7)>=O[0]&&(L.i?(h=W[45](4, +4,v[22].bind(null,O[2]),y[11](34),8,rY,void 0,L.i),Q=S[O[1]](42,h,e)):Q=C,t=Q),(N&78)==N)&&(Q=T[O[2]](53,L,void 0,e,xj),h=void 0,h=h===void 0?0:h,t=(m=P[17](68,W[O[2]](13,L,Q)))!=C?m:h),72))==N&&(t=TQ(C)&&TQ(C.raw)),N)-6^30)<N&&(N+1&57)>=N&&(e=C instanceof hr?C:new hr(C),t=e.value===null||e.value instanceof rx?e:new hr(e.value,!0)),t},function(N,C,e,L,h,Q){return((N+7>>2<((h=[54,1961,26],N&43)==N&&(Q=U[4](h[2],31)(U[4](34,h[1])(U[4](h[2],8584)(C).replace(/\s/g,bn()),/.*[<\(\^@]([^\^>\)]+)/))),N)&& +(N+3&78)>=N&&(e=H[2](64,C),e=H[2](72,C)|e,U[29](36,e,C)),(N-4|24)<N&&(N+7^10)>=N)&&(Q=e+S[11](h[0],2,L,C)),N+6)>>3==3&&(L=T[23](23,0,C,K[43](h[2],ci),null,new Map([[[Kx,uj,jq,Gz,Uk],e.A],[[MV],e.SW],[[$t],e.Vk],[Ns,e.jW]]),e),L.catch(function(){}),Q=L),Q},function(N,C,e,L,h){if(!(N-6&((L=["call",19,1],N|40)==N&&(UK[L[0]](this),this.destination=C,this.source=e),L)[2]))YK[L[0]](this,895,14);return(N<<L[2]&7)>=0&&N+3<L[1]&&(h=e.i[C]&&e.i[C].i),h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(N+1>>2<(((N+ +9>>(N-3>>(B=[4,28,"isArray"],B[0])==B[0]&&(G=Q.filter(function(c){return(c<Ch[C]||c>Ch.substr(1,h))&&(c<Ch[h]||c>Ch[4])&&(c<Ch[L]||c>Ch[e])})),1)<N&&(N+2&46)>=N&&e.getDate()!=C&&e.i.setUTCHours(e.i.getUTCHours()+(e.getDate()<C?1:-1)),N-B[0])>>B[0]||(h=h===void 0?document:h,m=(O=(Q=h).querySelector)==null?void 0:O.call(Q,L+"[nonce]"),G=m==null?"":m[C]||m.getAttribute(C)||e),(N-5|35)<N&&(N+5&51)>=N)&&(e=H[2](76,C),e=H[2](B[1],C)^e,U[29](69,e,C)),N)&&(N-8^15)>=N)a:{O=["number","object","bigint"];switch(typeof C){case O[0]:G= +Number.isFinite(C)?C:""+C;break a;case O[2]:G=oH(C)?Number(C):""+C;break a;case "boolean":G=C?1:0;break a;case O[1]:if(Array[B[2]](C)){G=(D=C[Rw]|0,C.length===0&&D&1?void 0:f[8](5,!1,T[18].bind(null,24),D,C));break a}if(C!=null&&C[MI]===$r){G=T[0](32,!1,C);break a}if(C instanceof dX){if((t=C.i,t)==null)q="";else{if(typeof t==="string")e=t;else{if(jJ){for(m=(u=t.length-(L=0,10240),"");L<u;)m+=String.fromCharCode.apply(null,t.subarray(L,L+=10240));Q=btoa((m+=String.fromCharCode.apply(null,L?t.subarray(L): +t),m))}else Q=S[11](53,2,t);e=C.i=Q}q=e}G=q;break a}if(C instanceof z6){G=(h=C.size!==0?K[42](59,8192,C,f[29].bind(null,40)):void 0,h);break a}G=void 0;break a}G=C}return G},function(N,C,e,L,h,Q,m,O,t){if((((t=["Punctual client is missing",3,8],N)-t[2]|26)<N&&(N+4^22)>=N&&p.call(this,C),N<<1>=24)&&N<<1<41)a:{if(!Q.T){O=y[34](t[1],Error(t[0]));break a}O=(m=new b0(kt(Q.F)),new wu(function(D,q){(W[(q=[34,1,"subscribe"],q)[0]](2,0,!0,e,L,Q.T,m)[q[2]](function(){}),I)[18](2,q[1],null,L,m,Q.T)[q[2]]({next:function(u, +B,G,c,A,n,R,F,Z,X,Y,k){if(k=[2,4,1E6],A=[null,1,26],u instanceof eD&&u.Ss){F=void 0;try{Y=Lh(u.Ss),n=U[13](21,Y,eX,A[1]),G=Number(H[35](3,A[0],n,A[1])),B=T[8](1,C,n),Z=(new Date(G*h+B/k[2])).getTime(),R=Date.now()-Z,X=S[28](26,L,P[k[1]](41,C,K[44](38,A[1],new u4,A[k[0]]),Z),R),(0,B8.h2)(X),F=S[49](27,C,Y)}catch(E){F=(new TextDecoder("utf-8")).decode(u.Ss)}D(F)}u instanceof hv&&(c=S[28](30,L,P[k[1]](56,C,K[44](42,A[1],new u4,25),Q.u),qY()-Q.u),(0,B8.h2)(c))},error:function(){},complete:function(){}})}))}return O}, +function(N,C,e,L,h){return((L=[31,76,"h2"],N+2&5)==1&&(S[28](27,3,C,qY()-v[28](L[1],P[L[0]](47,null,2,C))),B8[L[2]](C)),N+2)<28&&N<<1>=19&&(h=e.length===0?l[5].bind(null,61):e.length===1?e[C]:function(Q){return e.reduce(function(m,O){return O(m)},Q)}),h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((((N&78)==(B=[null,4,38],N)&&D.info(function(G,c,A,n,R,F,Z,X,Y,k){if((Y=[(k=["","]: ",null],"=redacted&"),") [attempt ","type"],D).i)if(q){for(R=q.split((n=k[0],lC())),Z=L;Z<R.length;Z++)c=R[Z].split(js()),c.length> +1&&(A=c[1],G=c[L],F=G.split(jE()),n=F.length>=e&&F[1]==Y[2]?n+(G+"="+A+h):n+(G+Y[0]));X=n}else X=k[2];else X=q;return"XMLHTTP REQ ("+O+Y[1]+t+k[1]+m+C+Q+C+X}),N)-2^B[1])>=N&&(N+B[1]^25)<N){if(typeof e!=="boolean")throw Error("Expected boolean but got "+f[37](3,"object",e)+C+e);u=e}return(N-2&11)==((N|((N-2&11)==2&&(u=H[B[2]](6,C,L==B[0]?L:U[45](2,"bigint",L,h),e,Q)),9))<24&&((N|7)&7)>=6&&(L=C,e.B&&(L=e.B,e.B=L.next,L.next=C),e.B||(e.o=C),u=L),1)&&(u=C^e^L),u},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(N+ +7<((u=["o","V",61],(N+1&22)>=N&&N-8<<2<N)&&(B=S[41](34,C,L,e,FG)),19)&&N<<2>=18){if((h=e[u[t=[0,null,1],1]]?e[u[1]].length:0,L).nu&&!e.nu)throw Error(WR);if(h<t[0]||h>(e[u[1]]?e[u[1]].length:0))throw Error(QD);if(L[u[e.K&&e[u[1]]||(e[u[1]]=[],e.K={}),0]]==e)Q=e.K,m=P[9](17,":",L),Q[m]=L,U[20](47,t[0],L,e[u[1]]);else U[5](2,C,e.K,P[9](15,":",L),L);l[48](24,t[1],L,e),mk(e[u[1]],h,t[0],L),L.nu&&e.nu&&L[u[0]]==e?(O=e.s5(),(O.childNodes[h]||t[1])!=L.v()&&(L.v().parentElement==O&&O.removeChild(L.v()),D= +O.childNodes[h]||t[1],O.insertBefore(L.v(),D))):e.nu&&!L.nu&&L.B&&L.B.parentNode&&L.B.parentNode.nodeType==t[2]&&L.Vl()}if((N+9>>4==4&&(K[5](23,[-54,-121],f[31].bind(null,4)),K[5](19,[-34],H[43].bind(null,11)),K[5](25,[-71],T[9].bind(null,20)),K[5](13,[-96,-83],W[16].bind(null,1)),K[5](35,[-89],l[42].bind(null,73)),K[5](7,[-58],f[22].bind(null,2))),(N-4|75)<N)&&N-9<<1>=N&&Q)for(m=Q.split(lC()),O=C;O<m.length;O++)q=m[O].indexOf(js()),D=L,q>=C?(t=m[O].substring(C,q),D=m[O].substring(q+e)):t=m[O],h(t, +D?decodeURIComponent(D.replace(/\+/g,OY())):"");return(N-9^22)>=N&&(N+3&u[2])<N&&(KN.call(this,I[14](34,Om),U[5](29,bw),y4(),4),H[49](16,1,C),H[47](26,14,C),this.Rz=C.D()),B},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R){if(N+(R=[11,36,87],(N^26)>>3||(c=[6,!1,3],B=y[41](10,c7.M(),2),q=P[4](15,B),A=q.next().value,D=q.next().value,G=I[21](71),u=I[21](84),O=[y[R[1]](3,Q),K[0](20,2,L,u,A,h),P[37](84,T[39](9,c[2]),A,D),T[30](52,m,W[0](19,D),W[0](6,Q)),yg(A,T[39](7,C),D),T[30](40,m,W[0](1,A),c[1]),ii(Q, +T[39](7,c[0]),T[39](6,e),D),y[R[1]](2,A),y[R[1]](1,D),T[30](53,G,0,0),u,y[R[1]](6,L),y[R[1]](6,A),y[R[1]](5,D),T[30](39,m,0,0),G],(t=c7.M()).i.apply(t,T[5](89,B)),n=O),5)<19&&((N^25)&15)>=1)a:{if(L instanceof tv){n=L.z2;break a}if(Array.isArray(L)){n=v[10](R[2],C,L,e);break a}}if(N+4>>2<N&&(N-7^12)>=N&&(O=O===void 0?15E3:O,y[0](25),t=function(F,Z,X,Y,k,E){return k=(X=(Y=(E=[9,"ports",(Z=F.O5,"source")],Z).data==Z_,H[7](25,e,Z.origin)==H[7](E[0],e,L)),!h||Z[E[2]]==h.contentWindow),Y&&X&&k&&Z[E[1]].length> +C?Z[E[1]][C]:null},n=new Promise(function(F,Z,X){(X=P[44](4,t,function(Y,k){F((k=new (HL["delete"](X),oB)(Y,Q,m,L),y[22](55,k,S[28](49),nM,function(E,J){(J=t(E))&&J!=Y&&T[44](1,J,k)}),k))}),W)[36](72,O,function(){Z((HL["delete"](X),Error("reCAPTCHA Timeout")))})})),(N>>1&R[0])>=5&&(N^39)<25)a:{if(typeof e==="string"){n=new Um(K[1](18,C,0,e),L);break a}if(Array.isArray(e)){n=new Um(new Uint8Array(e),L);break a}if(e.constructor===Uint8Array){n=new Um(e,!1);break a}if(e.constructor===ArrayBuffer){Q= +new Uint8Array(e),n=new Um(Q,!1);break a}if(e.constructor===dX){m=v[45](48,C,e)||new Uint8Array(0),n=new Um(m,!0,e);break a}if(e instanceof Uint8Array){h=e.constructor===Uint8Array?e:new Uint8Array(e.buffer,e.byteOffset,e.byteLength),n=new Um(h,!1);break a}throw Error();}if((N-1&16)<6&&(N-3&19)>=13)a:{if(C instanceof wu){n=C;break a}n=((e=new wu(U[22].bind(null,37)),v)[45](5,null,2,C,e),e)}return n},function(N,C,e,L,h,Q,m,O,t){if(!(N-(t=[9,3,2],t[1])>>4))throw Error("Do not instantiate directly"); +return(N|72)==(N-((N&118)==N&&(this.i=C,this.map=e),6)>>4<t[2]&&((N^42)&11)>=t[0]&&(L=L===void 0?{}:L,h=h===void 0?!1:h,O=P[44](45,function(D,q){if(D.B==(q=[null,23,"Gt"],1)){if(m=(e.B[q[2]](!1),e).G,e.G==vf)return D.js(C);return D.i((e.G=ij,e.B).Rh(),C)}m===(Q=e.i.i&&!e.i.K,Cx)||Q&&(m===FF||m===RI)?K[q[1]](20,C,e,L,h):m!=A5&&e.P.then(function(u){return u.send(Iz,new Cv({visible:!0,XI:h}))},T[0].bind(q[0],37)),D.P()})),N)&&(this.i=C),O},function(N,C,e,L,h,Q,m,O,t,D){return N-((t=[20,5,"A"],N)+t[1]< +t[0]&&(N+1&7)>=1&&(O=L.JG,C[e]=function(q,u,B,G){return O((G=[11,2,31],q),u,B,m||(m=y[G[2]](24,G[1],T[25].bind(null,1),S[36].bind(null,G[0]),h,Wf).LD),Q||(Q=W[28](17,G[1],h)))}),2)&6||(C[t[2]]=L?U[31](10,e):e,D=C),D},function(N,C,e,L,h,Q){return(((N-5^31)<((N<<(h=[32,4,2],h[2])&14||(Q=(L=e!=C?e:void 0)!=C?L:Promise),N<<h[2]&15)>=h[2]&&((N^71)&15)<h[2]&&(L=U[h[0]](25,0,pq(),C),Q=P[14](h[1],C,1,0,5,e,L)),N)&&(N+6^25)>=N&&(this.cE=function(){return e},this.CD=function(){return L},this.J2=function(m){m[C- +1]=S[31](12,L)}),N)|1)>>h[1]||(C=H[15](1,this),e=y[34](58,this),this.Pm[C]=new ib(e,C,this)),Q},function(N,C,e,L,h,Q,m,O){return(N|9)>>((O=[15,26,6],N>>1&O[2])||(Q=L.z2,h=Q[Rw]|C,m=U[22](O[0],L,h)?L:l[33](47,!1,L,h,Q)?H[40](24,L,Q):S[8](O[1],e,h,Q)),4)||(L.i.has(DB)?(Q=L.i.get(DB),h=vh(C,parseInt(Q,e))):h=C,m=h),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){if(A=[1,0,"Found an unpaired surrogate"],(N+7^20)>=N&&(N+A[0]&27)<N){if(t=(t=!(D=[0,128,6],1),t===void 0?!1:t),qs){if(t&&(uI?!L[Bo]():/(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])/.test(L)))throw Error(A[2]); +u=(jD||(jD=new TextEncoder)).encode(L)}else{for(q=(m=new Uint8Array((h=D[A[1]],Q=t,3*L.length)),D[A[1]]);q<L.length;q++)if(B=L.charCodeAt(q),B<D[A[0]])m[h++]=B;else{if(B<2048)m[h++]=B>>D[2]|e;else{if(B>=55296&&B<=57343){if(B<=56319&&q<L.length)if(O=L.charCodeAt(++q),O>=56320&&O<=57343){m[(m[m[G=(B-55296)*1024+O-56320+65536,h++]=G>>18|240,h++]=G>>12&C|D[A[0]],m)[h++]=G>>D[2]&C|D[A[0]],h++]=G&C|D[A[0]];continue}else q--;if(Q)throw Error(A[2]);B=65533}m[m[h++]=B>>12|224,h++]=B>>D[2]&C|D[A[0]]}m[h++]= +B&C|D[A[0]]}u=h===m.length?m:m.subarray(D[A[1]],h)}c=u}if(N<<A[0]>=A[0]&&(N<<A[0]&8)<2)a:{O=(D=y[14](42,8105,30),P)[4](12,U[4](10,5340)(C,L,function(n){return n})),q=O.next();try{for(;!q.done;q=O.next())if(t=P[4](12,q.value.split(js())),Q=t.next().value,h=t.next().value,Q.trim()===D){c=h;break a}}finally{q&&!q.done&&(m=O.return)&&m.call(O)}c=""}return c},function(N,C,e,L,h,Q,m,O,t){return((N<<((N&(O=[16,"i",7],106))==N&&(oo.call(this),this[O[1]]=!1,this.destination=C instanceof $s?C:new NI(!C||K[15](1, +C)?{next:C!=null?C:void 0}:C),I[14](5,C)&&C.add(this)),1)&11)==2&&(t=new Gh(e,C)),N&93)==N&&(h=h===void 0?!1:h,t=(m=S[O[0]](20,W[33](29,e,L,Q)))!=C?m:h),(N^51)<26&&((N^68)&15)>=O[2]&&(co.call(this),this.status=1,this.errorCode=C),t},function(N,C,e,L,h,Q,m,O,t){return(((N|9)&((N^(O=[45,6,4],16))>>O[2]||(e instanceof String&&(e+=""),Q=0,h=C,m={next:function(D){if(!h&&Q<e.length)return D=Q++,{value:L(D,e[D]),done:!1};return{done:!(h=!0,0),value:void 0}}},m[Symbol.iterator]=function(){return m},t=m), +16))<O[1]&&(N-O[2]&10)>=3&&(K[5](19,[-75],l[44].bind(null,8)),K[5](13,[-104,-119],P[O[0]].bind(null,O[2]))),(N|32)==N)&&(t=new Kh(C,e,L,19)),t},function(N,C,e,L){if((e=["call",4,3],N-e[2]&e[2])==1)p[e[0]](this,C);if(((N^39)&e[2])==1)p[e[0]](this,C,e[1]);return L},function(N,C,e,L,h,Q,m,O,t,D,q,u){return(N>>((N&(((q=[106,31,"O"],(N>>1&7)<7)&&(N>>1&5)>=3&&(u=P[44](41,function(B,G,c,A){if((G=[1E4,0,(A=[24,"V","i"],2)],B).B==C){if(Q[A[2]]instanceof Av)return B.return(Promise.resolve());return B[((((D= +(t=(c=new yD,P[0](15,c,m,C)),v[16](A[0],Q[A[2]])),D.L0)==e&&(D.L0={}),D).L0.gsessionid=O,D).T2=G[0],B).K(G[2]),A[2]](P[11](19,h,t,"/v1/refreshCreds",Q.B,iI,D),L)}if(B.B!=G[2])return B[A[1]](G[1]);B.o(),B.P()})),(N-1^q[1])<N&&(N+8&q[1])>=N)&&(h=new vo,L&&(P[29](42,y[10](23,e),h,$g,Pe(e[q[2]],e,!0)),P[29](41,y[10](24,e),h,JZ,Pe(e[q[2]],e,C))),u=h),q[0]))==N&&(this.i.i.m$(new aE(this.B.i.RW(),60)),P[15](11,this,!1)),1)&15)==3&&p.call(this,C),u},function(N,C,e,L,h,Q,m){return((((N>>2&7)>=(m=[5,3,12], +m)[1]&&(N^63)<m[2]&&(Q=T[14](36,null,C,h,e)===L?L:-1),(N^59)>>m[1]==2&&(Q=nh||(nh=new dX(null,KM))),(N^15)>>m[1]>=0)&&N+m[0]<11&&(this.left=e,this.top=L,this.width=C,this.height=h),N^m[0])&7)==1&&p.call(this,C),(N|4)>>m[1]==m[1]&&(this.i=C),Q},function(N,C,e,L,h,Q,m){return(N-8^(N-(((N|4)&9)>=(m=[32,1,"constructor"],7)&&(N|2)<17&&(YK.call(this,614,23),this.G=this.B=this.H=-1,this.o=I[21](71)),6)<<m[1]<N&&(N+3^9)>=N&&(h=e.z2,L=h[Rw]|0,Q=U[22](13,e,L)?l[33](16,!1,e,L,h)?H[40](20,e,h,!0):new e[m[2]](S[8](11, +34,L,h,C)):e),13))>=N&&(N+m[1]&72)<N&&(L.B||L.i!=e&&L.i!=C||U[43](13,!0,L),L.o?L.o.next=h:L.B=h,L.o=h),(N|64)==N&&(Q=P[18](59,W[39](28,S[m[0]](24,new b4,2),C),[y[38](m[0],e),y[38](16,L)])),Q},function(N,C,e,L,h,Q,m,O,t,D){if((D=["G",57,3],N<<2&5)>=D[2]&&(N|7)<18)P[20](10,C,function(q,u){this.add(u,q)},e);if(((N&D[1])==N&&(e.o[D[0]]=C,e.flush(),e.o[D[0]]=!1),N|16)==N)W[4](16,C,e,L,h,{destination:window,kL:m,origin:O,Zp:IS,onMessage:function(q){Q(RS(q.data))}});return t},function(N,C,e,L,h,Q,m,O,t){return(N| +((t=[1,32,65],N+6^t[1])<N&&(N-2^30)>=N&&(Q=['" role="presentation"><div class="',"rc-anchor-normal-footer","rc-anchor-logo-img"],Gt(),UY(),XG(),cL(),UY(),XG(),m=T[t[0]](t[0],fJ(),'<div class="'+H[7](t[2],Q[t[0]])+C),h=P8('<div class="'+H[7](t[2],"rc-anchor-logo-large")+Q[0]+H[7](t[2],Q[2])+e+H[7](t[0],"rc-anchor-logo-img-large")+'"></div></div>'),O=T[t[0]](t[2],W[11](86,W[11](46,m,h),S[38](3,e,L)),jB())),2))>>4||p.call(this,C),O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(N+(N-(G=["i",43,1],4)>>4|| +(B=P[44](77,function(c,A){if(c.B==(A=[40,28,14],e))return O=W[A[1]](35,C,function(n){return n.parse(Q)}),c.i(U[37](A[2],O[h],O[e]+O[L]),L);return c.return(new ZK(W[A[1]](A[0],C,(m=c.G,function(n){return n.parse(m)})),O[e],O[L]))})),6)>>3>=0&&(N<<G[2]&16)<4){if(h=this[this[D=(this.G=((J_.call(this,C,(Q=[1,null,86400],L)),this).V=T[22](3,4,e,rY),!!T[42](20,10,e)),P)[41](9,6,e),G[0]]=l[G[1]](62,Q[0],D)==3&&!this.G,G[0]])m=v[10](27,3,e),h=!T[42](68,18,m);(this.F=((this.l=(this.Y=((q=(this.X=(O=(this.R= +(u=(this.j=(this.u=(t=((this.P=!!T[42](64,(this.K=h,14),e),this).A=!!T[42](32,15,e),W)[33](17,e,11,rY,void 0,P[0].bind(null,40)),K[22](51,Q[G[2]],t)||Q[2]),T)[22](3,13,e,rY),K)[22](23,Q[G[2]],W[33](25,e,18,rY,FG,P[0].bind(null,41))))!=Q[G[2]]?u:0,K[22](24,Q[G[2]],W[33](13,e,31,rY,FG,P[0].bind(null,42)))))!=Q[G[2]]?O:0,this.I=v[3](36,e,y[11](18,F3),21,rY),U[13](23,e,W9,Q[0],rY)))==Q[G[2]]?void 0:T[22](3,4,q,rY))||"",v[3](45,e,y[11](10,F3),23,rY)),this.T=T[22](4,24,e,rY)||"",this).h=v[12](71,27,e,rY)|| +0,y[48](2,29,e,y[11](19),lI,rY)),this).S=T[22](2,30,e,rY)||""}return(N+2^24)<N&&(N-5|12)>=N&&p.call(this,C,0,M0.yl),B},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J){if((N>>2&(J=["Tap the center of the <strong>street signs</strong>",4,"forEach"],6))==2){h=(Q=["/m/0k4j","rc-imageselect-desc-no-canonical",'<div class="'],Q[2]+H[7](33,Q[1])+e);switch(I[6](50,L)?L.toString():L){case "TileSelectionStreetSign":h+=J[0];break;case Q[0]:h+="Tap the center of the <strong>cars</strong>";break;case "/m/04w67_":h+= +"Tap the center of the <strong>mail boxes</strong>"}E=P8(h+C)}if((N|(((N>>1&14)>=0&&N-8<14&&(C=H[15](28,this),this.Pm[C]=Math.trunc(qY())),(N|16)==N)&&C.V&&C.V[J[2]](e,void 0),64))==N&&(c=[11,"bigint",0],F=Date.now()-L,Z=B0.M().get(),Q.i.A))if(t=new Th,k=H[13](1,Z),R=H[26](1,"",k,t),u=l[8](45,c[2],3,h==null?h:l[26](44,h),R,c[2]),n=l[8](43,c[2],J[1],H[0](13,e,F),u,ZJ()),m!=void 0&&U[9](18,c[1],m,5,n),D=Q.wq,X=new hZ,A=n.G2(),q=P[0](79,X,A,C),B=K[23](11,c[0],2,q),B instanceof hZ)D.log(B);else try{O= +new hZ,Y=B.G2(),G=P[0](14,O,Y,C),D.log(G)}catch(r){T[46](21,null,D,J[1],1)}return E},function(N,C,e,L,h){return N-1>>((N-3|41)>=((N^50)<(L=[27,2,"isArray"],33)&&N>>1>=L[0]&&(this.status=C),N)&&N-7<<L[1]<N&&(h=c7.M().G.get(C)),3)==L[1]&&(h=Array[L[2]](e)?e[C]instanceof M$?e:[ZB,e]:[e,void 0]),h},function(N,C,e,L,h,Q,m){if(!(((N&(Q=["call",7,"prototype"],89))==N&&(C=8,C=C===void 0?1:C,this.max=8,this.B=Date.now(),this.i=C),N)-Q[1]&Q[1]))p[Q[0]](this,C,19);if((N+6&15)==4)K[23](60,C,L,e);if((N+2&60)>= +N&&(N-Q[1]^25)<N){if((C[Q[2]]=oS(e[Q[2]]),C)[Q[2]].constructor=C,Po)Po(C,e);else for(L in e)L!=Q[2]&&(sm?(h=JS(e,L))&&fu(C,L,h):C[L]=e[L]);C.L=e[Q[2]]}return(N>>1&Q[1])==2&&(L.endsWith("/")&&(L=L.substring(C,L.length-e)),h.startsWith("/")&&(h=h.substring(e)),m=L+"/"+h),m},function(N,C,e,L,h,Q,m){return((N|(m=[5,"xx",127],m[0]))>>4||(C=C.nI,h=[3,128,28],L=U[39](3,h[0],C.U_,C.e_,C[m[1]]++),e=L&m[2],L&h[1]&&(L=U[39](6,h[0],C.U_,C.e_,C[m[1]]++),e|=(L&m[2])<<7,L&h[1]&&(L=U[39](4,h[0],C.U_,C.e_,C[m[1]]++), +e|=(L&m[2])<<14,L&h[1]&&(L=U[39](2,h[0],C.U_,C.e_,C[m[1]]++),e|=(L&m[2])<<21,L&h[1]&&(L=U[39](m[0],h[0],C.U_,C.e_,C[m[1]]++),e|=L<<h[2])))),C=e,Q=C>>>1^-(C&1)),(N|9)>>4>=2&&(N>>2&8)<m[0]&&(Q=L>=C?L>=1E4?wq(Math.log10(1+L)):L<e?3:4:L<10?1:2),(N+2^23)<N)&&(N-1|59)>=N&&(C=new fh,Q=[new X3,new SD,new Yw,new Wo,new Ho,new kw,new rE,new ph,new Jv,new Em,new zh,C,new dE,new wE,new VD,new xw,new aS,new gE(C),new bI,new Ms,new $w,new Nh,new Cj,new eG,new Lj]),Q},function(N,C,e,L,h,Q,m,O,t,D,q,u){if((N|9)>> +(q=[5,18,16],3)==1){for(m=(t=(D=[12,255,5],Q=[],C),h=h===void 0?4:h,C);m<=L.length/D[0];m++)O=L.slice(m*D[0],RY((m+1)*D[0],L.length)),t=y[41](33,1,3,D[2],0,O,t),Q.push.apply(Q,T[q[0]](87,new Uint8Array([D[1]&t>>24,D[1]&t>>q[2],D[1]&t>>8,D[1]&t])));u=S[10](9,0,y[31](42,t,e,11,25),Q).slice(C,h)}return((N<<1&7)==((N+1&11)==1&&(u=S[q[2]](q[1],W[33](9,e,C,rY,FG))),2)&&(u=T[42](64,C,e)),N+7&7)==2&&(e=T[41](3,C),W[49](49,2,C,(C.nI.xx<<3)+e,0)),u},function(N,C,e,L,h,Q,m){if(!(N+3&(N-8>>((m=[0,2,6],(N-m[1]^ +13)>=N&&(N+m[2]^18)<N)&&C.G.push(C.H9,C.Bw,C.R5,U[25](7,C,function(O,t){return O^t}),C.CV,C.Wc,C.Gz),4)||(e=T[41](1,C),H[m[1]](24,C)!==0&&H[23](10,3,e,C)),9))){h=[0,8,5];try{switch(e.B){case h[m[0]]:e.B!=h[m[0]]?T[43](33,4,e):f[m[2]](62,e.i);break;case 1:T[m[0]](65,h[1],e.i);break;case m[1]:S[46](25,4,m[1],e);break;case h[m[1]]:T[m[0]](1,C,e.i);break;case 3:L=(H[34](9,100),e.G);try{do{if(!I[13](85,!1,e))throw Error();if(e.B==C){if(e.G!=L)throw Error();break}T[43](3,4,e)}while(1)}catch(O){if(O instanceof +RangeError)throw new SyntaxError;throw O;}finally{Rf>h[m[0]]&&Rf--}break;default:throw Error();}}catch(O){if(O instanceof RangeError)throw new SyntaxError;throw O;}}return Q},function(N,C,e,L,h,Q,m,O){if(N+(m=[9,"i",19],m[0])>>1<N&&N-1<<2>=N)a:{if(L==C){O=new h;break a}if(!Array.isArray((Q=L,Q)))throw Error();if(TQ(Q)||Object.isSealed(Q)||!My(Q))throw Error();O=new h(v[1](6,e,(L=Q,L)))}return N>>2<m[2]&&(N+2&3)>=2&&(e[m[1]].close(),e[m[1]]=C,y[22](31,e,e[m[1]],nM,function(t){return U[20](4,!1,2,e, +t)}),e[m[1]].start()),O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){if((F=[18,2,"j"],N+F[1]&15)>=5&&N-5<F[0]){if(typeof C!=="number")throw P[22](5,hs());if(!th(C))switch(F2){case F[1]:throw P[22](7,hs());case 1:U[3](48,hs())}Z=F2===2?C|0:C}if((N>>1&15)==1){for(C=(L=[],h=h===void 0?0:h,C===void 0?8:C),e=0;e<C;e++)L.push(pq()%(QT+1)^I[47](7,QT));Z=W[39](50,h,v[F[0]](20,0,"",L))}if((N+F[1]^24)>=((N&90)==N&&(e=["Android","Coast","Silk"],Z=I[1](93,C)&&!(S[1](17,"CriOS")||(U[38](24)?0:I[1](89,e[1]))|| +S[20](87,"Opera")||I[40](3,"Edge")||K[21](F[0],0)||(U[38](32)?P[35](21,0,wR):I[1](93,"OPR"))||v[36](47,"FxiOS")||S[17](19,e[F[1]])||I[1](90,e[0]))),N)&&(N-F[1]^28)<N){t=(D=(q=e,function(X){q||(q=C,h.call(L,X))}),function(X){q||(q=C,m.call(L,X))});try{O.call(Q,D,t)}catch(X){t(X)}}if(((N^74)&15)==1&&(e=[0,null,1],this.X=e[1],this.B.length!==0)){(G=((B=(R=(this.o=qY(),e[1]),this).o,this).HS&&(R=(0,B8.Kg)(C?17:16)),e[0]),O=this.E5,O).i=B;for(C&&(G=this.o+K[45](8,C));this.B.length>e[0];){if(((m=this.B.pop(), +m.TX<=B)&&(m.T$=F[1]),this).j_&&m.T$===1){if(!C)break;if((n=K[45](38,C),n)===0)break;G=B+n}else if(B>this.o+10)break;if(m.kZ)try{S[20](33,"",e[0],e[F[1]],3,this,m.kZ),m.kZ=e[1],B=qY()}catch(X){m=(m.QU(),e)[1];break}if(m.Da<=B){m.QU(),this.u+=e[F[1]],m=e[1];break}if(((u=(t=(B=((((this.O=(h=C?G-B:this.o+10-B,L=B,this).P?h*vh(this.P/this.J,5):h*5,this).I(),m.H&&(this.Pm[m.H]=m.DM,m.H=e[0]),this.i.i=m.TD,this).A=e[0],this).rq()&&(this.F+=e[F[1]],this.H9()),qY()),B-L),this).A,t=vh(t,.1),this.P?(this.J= +t+.9*this.J,this.P=u+.9*this.P):(this.J=t,this.P=u),B<L)&&(this.W=O.i),this.I(),this)[F[2]]===null)m.kO(),m=e[1];else{this[F[2]]=(m.TD=this[F[2]],e[1]);break}}if((q=(Q=(m&&this.B.push(m),this.o),D=G,B),this.Z+=B-this.o,D)>Q)D+=e[F[1]],A=RY(q,D)-Q,c=vh(q,D)-D,H[27](F[0],e[F[1]],this.C,A),c>e[0]&&H[27](16,e[F[1]],this.Y,c);else H[27](17,e[F[1]],this.Y,q-Q);(R&&(0,B8.cc)(R),this.B.length>e[0])&&T[13](8,e[F[1]],F[1],this)}return Z},function(N,C,e,L,h,Q,m,O,t){return(N-((N|2)>>(O=["map",41,7],4)||(m=U[42](2), +Q=U[O[1]](9).split("").slice(C,e)[O[0]](function(D){return m.call(D,C)}),encodeURIComponent(L).split("").forEach(function(D,q){Q.push(T[21](23,m.call(h,q%h.length),m.call(D,C),Q[q%e]))}),t=Q),O[2])|30)>=N&&(N+6&75)<N&&((Q=e.A)==C||Q.qa(L,h)),t},function(N,C,e,L,h,Q,m,O){if((m=[14,1,28],N|80)==N&&(this.i=P[19](25,null,C),e=y[20](32,this),e.length>0))throw Error("Missing required parameters: "+e.join());if((N|40)==(((N<<m[1]&27||p.call(this,C),N|6)<m[2]&&((N^20)&15)>=11&&(O=Vc(e.x-L.x)<=C&&Vc(e.y-L.y)<= +C),N-m[1]>>3==3)&&(L=new Wt,O=H[6](7,e,C,pc,2,L)),N))a:{if(S[7](11,(h=oF,L))){O=I[m[0]](23,e,C,L.j,h!==void 0?String(h):void 0);break a}O=(Q=l[48](66,L),!!Q&&I[m[0]](7,e,C,Q,h))}return O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){if((c=[41,2,0],N-4)>>3==1){for(B=(t=(Q=(q=[1,3,2],m=C,By(String(L))).split(ZD()),By(String(e)).split(ZD())),vh(Q.length,t.length)),u=C;m==C&&u<B;u++){G=t[h=Q[u]||"",u]||"";do{if((D=(O=/(\d*)(\D*)(.*)/.exec(h)||["","","",""],/(\d*)(\D*)(.*)/).exec(G)||["","","",""],O)[C].length== +C&&D[C].length==C)break;m=(h=O[q[1]],l[c[0]](12,D[G=D[q[1]],q[c[2]]].length==C?0:parseInt(D[q[c[2]]],10),O[q[c[2]]].length==C?0:parseInt(O[q[c[2]]],10))||l[c[0]](8,D[q[c[1]]].length==C,O[q[c[1]]].length==C)||l[c[0]](4,D[q[c[1]]],O[q[c[1]]]))}while(m==C)}A=m}if((N&89)==N)a:{e=bb;try{A=e.contentWindow||(e.contentDocument?S[28](16,e.contentDocument):null);break a}catch(n){}A=C}return A},function(N,C,e,L,h,Q,m,O,t){if((N+((O=[!1,"i","qr"],N)<<1&11||p.call(this,C),7)^26)>=N&&N+9>>2<N)a:switch(typeof C){case "bigint":t= +!0;break a;case "number":t=th(C);break a;case "string":t=e||n2?mo.test(C):!!C&&isFinite(C);break a;default:t=O[0];break a}return(N>>1&15)>=0&&(N|5)>>4<1&&(m=[100,0,":"],Q=Q===void 0?null:Q,L[O[1]]&&(v[31](53,null,m[2],m[1],L,L[O[1]]),K[34](4,L[O[1]])),L[O[1]]=H[28](10,O[2],h,Q),T[22](8,C,L,L[O[1]]),L[O[1]].render(L.v()),v[19](26,m[0],e,m[1],L.v()),K[31](8,"*",L.v()).then(function(D){v[19](23,(D=[34,44,100],D[2]),e,"",L.v()),v[D[1]](D[0],L,"g")})),t}]}(),P=function(){return[function(N,C,e,L,h,Q,m){if(!((N^ +((N^((N>>2&15)==(Q=["nU",3,1],(N+2&62)>=N&&(N-Q[1]|57)<N&&(e[Q[0]]=C,m=e),Q[1])&&(m=H[38](4,C,I[12](18,null,e),L,h)),43))>>Q[1]==Q[2]&&(e=String(C),m="0000000".slice(e.length)+e),42))>>Q[1]))a:{if(C==(L=typeof C,e=[null,!0,""],e)[0]){m=C;break a}if(L==="bigint"){m=l[46](24,sR(64,C));break a}if(T[49](33,C,e[Q[2]])){m=L==="string"?I[49](24,64,0,C):U[11](50,e[2],e[Q[2]],C);break a}}return m},function(N,C,e,L,h,Q,m){if(N-((m=[34,6,64],N)>>2&10||(L=L===void 0?1:L,h=[null,!1,1],e.P&&(f[24](10,h[1],h[2], +e.P.i),e.P=h[0]),e.G.then(function(O){return K[34](2,O)},function(){}),e.G=h[0],K[m[0]](3,e.B),e.B=h[0],e.J&&e.J.dispose(),e.o&&(e.o.dispose(),e.o=h[0]),K[m[0]](m[1],e.K),e.K=h[0],y[7](2,h[1],C,L,e)),(N&108)==N&&(this.error=C),9)<<1>=N&&(N-7|m[2])<N)K[23](60,C,L,e);return((N|4)&8)<1&&(N<<2&8)>=7&&((h=P[m[0]](55,null))==C||h.zzsh(e,L.width,L.height)),Q},function(N,C,e,L,h,Q,m,O,t){if(t=[35,17,"i"],(N<<2&14)>=8&&(N|3)>>4<3)a:{if(!(Q=Array.from(nS(Ij)).find(function(D){return D.type===vi}),Q)){O=L;break a}O= +(m=(h=Array.from(nS(Ij)).filter(function(D){return[Od,Fy,Zy].includes(D.type)}).slice(e,C).filter(function(D){return D.compareDocumentPosition(Q)===Node.DOCUMENT_POSITION_FOLLOWING}).filter(y[7].bind(null,6)).reverse().find(function(D){return D.value}))==L?void 0:h.value)!=L?m:null}if(N-7<(N>>1&7||(y[42](4,C[t[2]]),f[6](59,C[t[2]]),y[42](1,C[t[2]]),O=C.nR()),t)[1]&&(N-1&14)>=2)for(h=y[t[0]](15,L[t[2]]),Q=L[t[2]][t[2]]+h;L[t[2]][t[2]]<Q;)e.push(C(L[t[2]]));return O},function(N,C,e,L,h,Q,m,O,t){return(N| +((N|6)>>((N^(t=[0,3,48],53))&7||(Q=[null,"",!1],e=Q[2],C&&C instanceof Element&&(e=(Q[1]+((m=C.id)!=Q[t[0]]?m:"")+((L=C.className)!=Q[t[0]]?L:"")+((h=C.textContent)!=Q[t[0]]?h:"")).match(ts)!=Q[t[0]]),O=e?Ud():ZJ()),t)[1]==t[1]&&(O=P[t[0]](78,e,L,C,rY)),t)[2])==N&&YK.call(this,545,8),(N-4&15)>=t[1]&&N+7<23&&(O=Date.now()),O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R){if(N+9>>((R=[11,80,"append"],(N+5&7)==2)&&(h=K[43](1,R[1],C,e,27),h.update(L),n=h.AW("charAt",16,0,"").toLowerCase()),N+8&14||(n= +H[38](5,e,H[0](7,!1,L),C)),3)==1){Q=(O=O===void 0?!1:O,[null,"",9]);a:{if(((G=(D=(t=C(e||JA,L),O),D=D===void 0?!1:D,m=h||W[46](R[0],Q[2]),t)&&t.Ty?t.Ty():null,G)||(c=U[40](33,Q[0],t),D?(B=S[R[0]](65,Q[0],m),B.innerHTML=W[36](38,Q[1],c),A=H[0](70,Q[1],B).childNodes):(G=m.createElement(EC),G.innerHTML=W[36](22,Q[1],c),A=G.childNodes)),A).length==1&&(u=A[0],u.nodeType==1)){q=u;break a}q=(G||(G=m.createElement(EC),G[R[2]].apply(G,T[5](41,A))),G)}n=q}if((N^3)>>3==1)a:{if(e=typeof Symbol!="undefined"&& +Symbol.iterator&&C[Symbol.iterator]){n=e.call(C);break a}if(typeof C.length=="number"){n={next:W[R[0]](24,0,C)};break a}throw Error(String(C)+" is not an iterable or ArrayLike");}return n},function(N,C,e,L,h,Q,m,O,t,D){return N>>(N<<(D=[49,1,"K"],D[1])&4||(O=I[D[0]](34,!0,Q,m),m[D[2]]=m[D[2]].then(O,O).then(function(q,u,B){return P[44](41,function(G,c,A){c=[4,(A=[1,"i",15],1),12];switch(G.B){case h:if(B=m[A[u=null,1]].j,!B){G.js(C);break}return G[A[1]](I[25](A[2],c[2],q.G2(),B),L);case L:u=G.G;case C:return G[A[1]](l[43](20, +c[A[0]],!1,e,q,m),c[0]);case c[0]:return G.return({k7:G.G,VI:u})}})}),t=m[D[2]]),2)&6||C.info(function(){return"TIMEOUT: "+e}),t},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X){if((Z=[9,2,0],N<<1)<14&&(N^18)>>3>=Z[2]){for(C=Z[2];IT=IT.parentElement||null;)C++;X=C}if((N&105)==N){if((B=[0,!0,1],L.P&&L.G)&&S[15](Z[0],B[Z[1]],L)){if(t=Dd[n=L.P,n])Zf.clearTimeout(t.i),delete Dd[n];L.P=B[Z[2]]}for(h=(q=(O=(L.i&&(L.i.A--,delete L.i),C),L.B),C);L.K.length&&!L.V;)if(R=L.K.shift(),F=R[B[Z[2]]],c=R[B[Z[1]]], +A=R[Z[1]],Q=L.o?c:F)try{if(G=Q.call(A||L.h,q),G===qh&&(G=void 0),G!==void 0&&(L.o=L.o&&(G==q||G instanceof Error),L.B=q=G),f[12](10,C,q)||typeof Zf[uY()]==="function"&&q instanceof Zf[uY()])O=L.V=e}catch(Y){L.o=e,q=Y,S[15](8,B[Z[1]],L)||(h=e)}(L.B=q,O)&&(D=Pe(L.X,L,e),u=Pe(L.X,L,C),q instanceof Rq?(I[43](11,B[1],D,q,u),q.S=e):q.then(D,u)),h&&(m=new Br(q),Dd[m.i]=m,L.P=m.i)}if(!(N<<1&15)){if((D=((m=((O=["","\nInner error ","\n"],L)||(L={}),L[l[Z[2]](5,O[Z[2]],e)]=C,e)[xk()]||O[Z[2]],t=e.cause)&&!L[l[Z[2]](4, +O[Z[2]],t)]&&(m+="\nCaused by: ",t.stack&&t.stack.indexOf(t.toString())==Z[2]||(m+=typeof t==="string"?t:t.message+O[Z[1]]),m+=P[6](48,!0,t,L)),e.errors),Array).isArray(D)){for(Q=Z[h=1,2];Q<D.length&&!(h>4);Q++)L[l[Z[2]](36,O[Z[2]],D[Q])]||(m+=O[1]+h++ +": ",D[Q].stack&&D[Q].stack.indexOf(D[Q].toString())==Z[2]||(m+=typeof D[Q]==="string"?D[Q]:D[Q].message+O[Z[1]]),m+=P[6](24,!0,D[Q],L));Q<D.length&&(m+="\n... "+(D.length-Q)+" more inner errors")}X=m}return(N>>Z[1]&16)<14&&N-Z[0]>>4>=3&&(X=K[18](88, +S[11](52,C,h.D()),v[17](20,L,e)).then(function(Y){return U[10](34,U[25](30,zY),Y,e)})),N-4<<1>=N&&N-Z[0]<<1<N&&(e!=C?l[5](6,e,L):e=void 0,X=e),X},function(N,C,e,L,h,Q,m,O,t,D,q){if(!(((D=[40,4,11],N+2>>5<1)&&N>>1>=-38&&C.P&&K[18](54,e,C.P),N<<1)&D[2])){if(!(h=(QY.call(this,L),e))){for(O=this.constructor;O;){if(m=(t=f[18](13,O),jG[t]))break;O=(Q=Gn(O.prototype))&&Q.constructor}h=m?typeof m.M==="function"?m.M():new m:null}(this.G=h,this).RX=C!==void 0?C:null}if((N^48)>>3==2)a:{if(h=(Q=[6348,500,0], +L(C(),9)),h.length==Q[2]){q=cr();break a}q=(O=U[D[0]](56,h.length),m=h[O].hasAttribute(pv())?U[D[1]](10,Q[0])(h[O].getAttribute(pv()).split(/[?#]/)[Q[2]]):U[D[1]](2,8467)(U[D[1]](34,191)(h[O].text,CB),Q[1]),O+","+m)}return q},function(N,C,e,L,h,Q,m,O,t,D){if((((N&(t=[2,1,0],N-9<<t[0]<N&&(N-7|39)>=N&&(h=[255,0,24],TH(e),L.i.push(e>>>h[t[1]]&h[t[2]]),L.i.push(e>>>8&h[t[2]]),L.i.push(e>>>C&h[t[2]]),L.i.push(e>>>h[t[0]]&h[t[2]])),49))==N&&(D=document),N)-t[1]|37)<N&&N-6<<t[1]>=N){for(e=(L=H[t[0]](28, +C),h=[],t)[2];e<L;++e)h.push(H[t[0]](72,C));(h.reverse(),U)[29](36,h,C)}if(N-5>>3==3)a:{if(Array.isArray(h)){for(O=t[2];O<h.length;O++)P[8](30,!0,e,L,h[O],Q,m);D=null;break a}e=l[18](56,e),D=S[7](10,L)?K[32](32,!0,L,e,h,I[6](19,Q)?!!Q.capture:!!Q,m):H[6](t[0],!1,L,e,m,C,Q,h)}return D},function(N,C,e,L,h,Q,m,O,t,D){return N+5>>3==((N^33)>>(N<<2&15||(e=~e,L?L=~L+C:e+=C,t=[L,e]),D=["j","o",7],4)||(O=[0,"\n",null],h.Z=Date.now(),S[2](1,h),h.J=U[36](15,h.h),S[6](4,h.J,Kj(),h.O),m=h[D[1]].u,h.X=O[0],h.B= +new M4,h.i=v[25](37,m?L:null,h[D[1]],!h.A),h.R>O[0]&&(h.u=new As(Pe(h.Ku,h,h.i),h.R)),I[D[2]](32,h.i,void 0,wj,h.j_,h.Xe),Q=h.l?l[15](5,h.l):{},h.A?(h[D[0]]||(h[D[0]]=y4()),Q[yT()]=iY(),h.i.send(h.J,h[D[0]],h.A,Q)):(h[D[0]]=qO(),h.i.send(h.J,h[D[0]],O[2],Q)),l[47](20,e),T[21](64,O[1],C,O[0],"&",h.J,h[D[0]],h.K,h.O,h.G,h.A)),2)&&(t=e.I||(e.I=C+(e.PK.i++).toString(36))),t},function(N,C,e,L,h,Q,m,O,t,D){if((N|((D=["Top",6,4],(N^45)>>D[2])||(h=H[24](10,e),h!=null&&K[47](28,127,T[23](51,3,h,!0).buffer, +L,C)),8))==N)a:try{t=C.getBoundingClientRect();break a}catch(q){t={left:0,top:0,right:0,bottom:0};break a}return N+D[1]>>D[2]||(h=P[22](50,L,e+C),Q=P[22](53,L,e+"Right"),O=P[22](51,L,e+D[0]),m=P[22](52,L,e+"Bottom"),t=new vr(parseFloat(h),parseFloat(m),parseFloat(Q),parseFloat(O))),t},function(N,C,e,L,h,Q,m,O,t){return((N+(N>>(t=[33,4,""],1)&7||(v[43](21,C,QK)||v[43](29,C,qw)?Q=String(C).replace(m7,I[43].bind(null,17)):(C instanceof O$?e=K[t[0]](16,S[8](t[1],t[2],C)):(C instanceof u5?L=K[t[0]](17, +H[41](32,C).toString()):(h=String(C),L=nj.test(h)?h.replace(m7,I[43].bind(null,18)):BV()),e=L),Q=e),O=Q),t[1])>=t[1]&&(N^22)<12&&(m=m===void 0?{}:m,O=h.request(C,L,e,Q,m)),N)+5&7)==1&&(C=['" tabIndex="0"></span><div class="','<div class="rc-2fa"><span class="',"rc-2fa-payload"],O=P8(C[1]+H[7](t[0],"rc-2fa-tabloop-begin")+C[0]+H[7](32,C[2])+'"></div><span class="'+H[7](1,"rc-2fa-tabloop-end")+'" tabIndex="0"></span></div>')),O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if((N+4&(n=[38,22,"sort"], +7))>=4&&(N^94)<n[1]){c=(G=((q=(O.i={channel:Q(function(R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB,R6,LB,sC,Sp,ur,g8,$W,q4,br,o6,VE,Ph,AA,OW,v8,YW,FK,td,d8,ir,fB,c8,Nx,Xq,pJ,CP,UW,UN,e8,XK,LP,SN,l4,DI,nJ,x4,c2,hJ,KJ,KP,EW,qx,T0,AJ,Y4){DI=(T0=(LP=y[48](26,(k=[1,2,8],Y4=[58,33,"J"],k[0]),R,y[11](2),R5),P[4](12,LP)),T0.next());try{for(;!DI.done;DI=T0.next())if(hA=DI.value,O.i!=C&&(O.i.Bj=!0),O.X=0,KJ=W[19](28,C,hA,k[0]),KJ!=C)if(ur=Number(KJ),K[38](32,0,3,FP,lY,hA)){a:{if(Sp=l[41](Y4[0],3,hA, +FP,lY))if(VE=U[13](18,Sp,Tn,k[0])){o6=VE;break a}o6=void 0}if(o6&&(Df=O,Ph=o6,Y=ur,fB=Df.streams.get(Y)))if(Df.streams["delete"](Y),l[36](73,W[Y4[1]](29,Ph,k[0]))===0)fB.B.complete();else{a:switch(T[8](1,k[0],Ph)){case 4:case k[2]:case 14:M=!0;break a;default:M=h}if(M&&++fB.V<=3){c8=(UN=(fB.K=k[1],Date.now()),void 0);switch(T[8](16,k[0],Ph)){case k[2]:c8=6E4;break;default:c8=5E3}(d8=(Nx=(e+.25*Vn())*c8,UN+Nx),Df.V).add(fB),f[34](43,k[0],fB,Df.G,d8),I[10](3,0,Df)}else fB.B.error(Df.K.Oc?new Zd(Ph): +Ph)}}else if(OW=l[41](Y4[0],k[1],hA,o5,lY))switch(T[14](32,C,OW,Pr)){case k[0]:if(EW=($W=(g=(Z=(hJ=l[41](57,(r=O,k[0]),OW,sd,Pr),f)[29](8,hJ,k[0]),r),y)[47](8,32,Z),R6=ur,g.streams.get(R6)),EW instanceof ru){try{EW.B.next(new hv)}catch(Qq){}g.streams.set(R6,EW.start($W))}break;case 3:a:{if(nJ=l[41](63,3,OW,fj,Pr))if(Xq=W[19](25,C,nJ,k[0]),Xq!=C){br=new XP(K[21](11,0,Xq));break a}br=void 0}if(br&&(F=br,KP=O.streams.get(ur),KP instanceof Co)){sC=F.i,J=KP,KP.V=0,sC>J.P&&(J.P=sC,J.A=!0);try{KP.B.next(F)}catch(Qq){}}break; +case k[1]:if(!(LB=O.streams.get(ur),LB instanceof Co))break;if(g8=l[41](59,k[1],OW,(AJ=LB.i,pJ=void 0,SG),Pr)){tA=P[4](14,(ir=new YQ,y)[48](42,k[0],g8,y[11](Y4[0]),Wr)),x=tA.next();try{for(;!x.done;x=tA.next())UC=x.value,l4=U[13](11,UC,gu,6),CP=W[19](26,C,UC,3),l4&&CP!=C&&(x4=void 0,AA=(x4=W[Y4[1]](37,UC,k[1],void 0,void 0,f[22].bind(null,73)))==C?void 0:new Uint8Array(v[45](51,3,x4)||0),w=AA==C?void 0:AA,(FK=T[1](5,k[2],k[1],6,L,AJ,l4))&&ir.add(new eD(FK,K[21](10,0,CP),w,!!S[16](23,W[Y4[1]](17,UC, +7)),!!S[16](22,W[Y4[1]](Y4[1],UC,k[2])))))}finally{x&&!x.done&&(pJ=tA.return)&&pJ.call(tA)}YW=ir}else YW=void 0;if(YW){OC=(KB=P[4](15,(qx=void 0,UW=LB,YW.i)),KB).next();try{for(;!OC.done;OC=KB.next()){XK=OC.value,mQ=new eD(XK.G,XK.version,XK.Ss,XK.B,XK.i);try{UW.B.next(mQ)}catch(Qq){}}}finally{OC&&!OC.done&&(qx=KB.return)&&qx.call(KB)}}break;case 5:if(c2=O,X=c2.streams.get(ur)){X instanceof Co&&(T[13](2,0,c2),(a=y[40](25,X,c2))?(a.i=X.P,a.B=!0,a.G=Date.now()):c2.j.push(new Hr(X.i,X.P,X.G)));try{X.B.complete()}catch(Qq){}}}}finally{DI&& +!DI.done&&(td=T0.return)&&td.call(T0)}if(v[18](69,0,R,kQ,k[1]))switch(q4=U[13](22,R,kQ,k[1]),l[43](42,k[0],q4)){case k[0]:d=(SN=P[4](12,O.streams.values()),SN).next();try{for(;!d.done;d=SN.next())d.value.K=3}finally{d&&!d.done&&(E=SN.return)&&E.call(SN)}O.i&&O.i.channel.close()}v[18](70,0,R,rA,3)&&O.i&&(z=O.i,v8=U[13](29,R,rA,3),e8=S[49](27,k[0],v8),z.k_=e8,O.i.hG=Date.now(),O[Y4[2]]||(I[4](14,k[0],h,O),O[Y4[2]]=!0))},(O.B(new I5),O.P.unshift(Date.now()),O),m.Iy),K7:m.K7,Iy:m.Iy,Bj:!1},Array.from(O.streams.entries())), +q)[n[2]](function(R,F){return R[0]-F[0]}),P[4](11,q)),G.next());try{for(;!c.done;c=G.next())B=P[4](10,c.value),B.next(),u=B.next().value,S[46](10,4,3,O,u)}finally{c&&!c.done&&(D=G.return)&&D.call(G)}W[36](64,(t=O.i,45E3),function(){O.i===t&&O.Y.reset()})}if((N|56)==((N|1)>>3==3&&(A=new Kh(e,C,L,31)),(N&105)==N&&p.call(this,C),N)&&(L=new pj(C),v[44](32,e,L))){h=new Js(C);try{v[44](n[0],e,h)}finally{C.i()}}return N-9>>3||(this.i=C),A},function(N,C,e,L,h,Q,m,O,t,D,q){if(!((D=["sort",65535,10],N)+7&30)){for((t= +(Q=l[37](16,h,e,4,C),Array.from(Q)),t)[D[0]](function(u,B){return u-B}),m=O=0;m<RY(2,t.length);m++)O<<=L,O|=t[m]&D[1];q=O}return(N-2^(((N-7<<2<N&&(N+9&D[2])>=N&&(q=P[22](55,C,e)||(C.currentStyle?C.currentStyle[e]:null)||C.style&&C.style[e]),N+2)&15)>=9&&(N>>1&12)<5&&(yE.call(this),C&&W[48](51,this,C,e)),8))<N&&(N+9&63)>=N&&(L=sN.filter(function(u){return Ed.includes(W[4](13,u,e))}),sN=sN.slice(C+L.length),sN.push.apply(sN,T[5](25,L))),N+8>>3==3&&(this.i=this.B=this.count=0),q},function(N,C,e,L,h, +Q,m,O,t,D){if((N>>(D=[1,64,36],D[0])&11)>=4&&N-3>>5<4)a:if(!L.c2){t=y[2](41,C,(h=L.i.i-e,L.i.i=e,L.i),h);break a}return(N-5<16&&(N-4&7)>=2&&(Q=['">','<div class="'," "],uo(),UY(),QR(),e=f[20](22,qQ(),C.cS,UY(),QR()),L=f[20](7,zn(),C.SQ,UY(),tF()),h=f[20](16,dA(),C.OZ,UY(),XG()),Gt(),UY(),XG(),cL(),UY(),XG(),Hy(),UY(),XG(),kj(),UY(),XG(),t=T[D[0]](81,W[11](79,W[11](54,W[11](22,T[D[0]](80,fJ(),Q[D[0]]+H[7](D[1],"rc-anchor")+Q[2]+H[7](33,"rc-anchor-invisible")+Q[2]+H[7](32,e)+" "+(L===1||L===2?H[7](D[1], +"rc-anchor-invisible-hover"):H[7](33,"rc-anchor-invisible-nohover"))+Q[0]),H[43](88,C.FI)),y[32](37)),L===1!==h?W[11](42,W[11](42,fJ(),T[D[2]](35,Q[0],Q[2],C)),y[D[2]](48,Q[2],C)):W[11](80,W[11](20,fJ(),y[D[2]](49,Q[2],C)),T[D[2]](34,Q[0],Q[2],C))),jB())),(N&46)==N)&&(O=U[32](26,L,pq(),h),t=function(q,u){return{QI:(q=(u=[29,"reduce",13],S)[u[0]](8,e,C,L,m,e+O()),l[u[2]](8,0,Q.concat(q).map(function(B){return H[12](42,B)})[u[1]](function(B,G){return B.xor(G)}))),UK:q}}),t},function(N,C,e,L,h,Q,m,O){if(((N| +6)&8)<(O=[3,"onabort","ip"],O[0])&&(N<<1&O[0])>=0)try{Q&&(Q.onload=null,Q.onerror=null,Q[O[1]]=null,Q.ontimeout=null),h(L)}catch(t){}return N-1&4||C.i.i[O[2]](W[39](7,C.B),e).then(function(t){(t=["i","B","V"],C)[t[1]][t[0]]&&(C[t[1]][t[0]].X=C[t[2]])}),m},function(N,C,e,L,h,Q,m,O){return(N^((N|((N&120)==((N|48)==((N+9&10)>=(O=["window",26,!0],N)&&(N-8|61)<N&&(Zf[O[0]][Bh]||U[47](24,{},Bh),Zf[O[0]][Bh][wA()]===void 0&&(Zf[O[0]][Bh][wA()]=function(t){return v[43](1,e,".ready",h,t)},Zf[O[0]][Bh][VT()]= +function(t){return l[0](9,"pid",".reset",!0,t)},Zf[O[0]][Bh][jp()]=h,Zf[O[0]][Bh][S5()]=h,Zf[O[0]][Bh][GN()]={},Zf[O[0]][Bh][jP()]={},Zf[O[0]][Bh][xQ()]=L,window.addEventListener(C,function(){return ZN.M().start()},!1)),Q=(window[Bh][Bi()]||[]).map(function(t){return t?g6:bo}),Q.length==h&&Q.push(bo),Zf[O[0]][Bh][Bi()]=[],Zf[O[0]][Bh][VT()](Q),W[19](2,C,O[2],function(){return Zf.window[Bh][wA()](Q)})),N)&&(this.S||P[15](25,this,!1)),N)&&(TN.call(this),I[7](33,C,!1,PV,this,e),I[7](2,C,!1,nu,this,e)), +24))==N&&(m=P[0](77,e,L,C,rY)),7))>>4==4&&(e=[!1,2,4],!y[24](2,e[0],16,this.v(),C)&&v[44](34,this,a5)&&(P[O[1]](5,this,e[2])&&v[0](29,e[2],e[0],this),P[O[1]](3,this,e[1])&&v[41](20,e[1],e[0],this))),m},function(N,C,e,L,h){if((N&((N&99)==(h=[20,1,2],N)&&(e=["rc-defaultchallenge-payload",'" style="display:none">',"Multiple correct solutions required - please solve more."],C=T[h[1]](65,fJ(),'<div tabindex="0"></div><div class="'+H[7](32,"rc-defaultchallenge-response-field")+'"></div><div class="'+H[7](32, +e[0])+'"></div><div class="'+H[7](64,"rc-defaultchallenge-incorrect-response")+e[h[1]]),W[11](42,C,e[h[2]]),W[11](52,T[h[1]](h[1],C,jB()),l[11](h[0]," ")),L=C),124))==N)a:{if(C==null){L=C;break a}if(typeof C==="string"&&C)C=+C;else if(typeof C!=="number"){L=void 0;break a}L=F2===2?th(C)?C>>>0:void 0:C}return(N>>(N>>h[2]&9||P[26](h[2],this,32)&&this.WE(!0),h[1])&15)>=6&&(N-7&16)<5&&(e=H[h[2]](64,C),C.O7(e)),(N^49)>>4||(fP=C,B8.h2(C)),L},function(N,C,e,L,h){return(N|24)==((N|((h=[3,10,2],N+h[2]&7)|| +(L=C),h[0]))>>h[0]||p.call(this,C),N)&&(L=l[36](h[1],h[2],C,IB,e,h[0])),L},function(N,C,e,L,h,Q,m){return((m=[15,4,"hasOwnProperty"],N+m[1]>>1<N)&&(N+8&34)>=N&&(L=l[m[0]](m[1],e),h=We.getName(),gA[m[2]](L[h])||(L[h]=C),Q=L),N<<1&6)||bY.call(this,typeof C==="string"?C:"Type the text",e),Q},function(N,C,e,L,h,Q,m,O,t){if((((O=["replace","[",1],N)|32)==N&&(t=W[42](6,L,C,e)),N+5)>>3==O[2])for(h in C)e.call(L,C[h],h,C);if((N|16)==N){if(m=[":","","]"],Q=typeof e,L=m[O[2]],Q==="object")for(h in e)L+=C+Q+ +m[0]+h+P[20](16,O[1],e[h])+m[2];else L=Q==="function"?L+(C+Q+m[0]+e.toString()+m[2]):L+(C+Q+m[0]+e+m[2]);t=L[O[0]](/\s/g,m[O[2]])}return t},function(N,C,e,L,h){if((N^4)>>3==(h=["i","responseText","iterator"],1))a:try{L=e[h[0]]?e[h[0]][h[1]]:"";break a}catch(Q){L=C;break a}return(((N+7>>4||(this.data=C,this.channel=e),N-7<20&&(N^14)>=18)&&(this[h[0]]=!1),N)|40)==N&&(e={next:C},e[Symbol[h[2]]]=function(){return this},L=e),L},function(N,C,e,L,h,Q,m,O){if((m=["",15,4],N<<1&m[1])>=0&&(N^49)<14)a:{if((L= +f[27](33,9,C),L.defaultView&&L.defaultView.getComputedStyle)&&(h=L.defaultView.getComputedStyle(C,null))){O=h[e]||h.getPropertyValue(e)||m[0];break a}O=m[0]}if(((N+3>>m[2]||(e=Error(C),W[12](16,"warning",e),I[1](41,e),O=e),N+8&9||(O=P[18](28,W[39](m[2],S[32](68,new b4,22),C),[y[38](8,e),y[38](40,L)])),N)+m[2]^12)>=N&&(N-5|92)<N)a:{if(e instanceof(Q=Q===void 0?Mh:Q,O$)){O=e;break a}for(h=C;h<Q.length;++h)if(L=Q[h],L instanceof ZL&&L.Qy(e)){O=new O$(e);break a}}if(N+m[2]>>3==2)a:{if(h!=C)switch(h.v2){case L:O= +L;break a;case -1:O=-1;break a;case e:O=e;break a}O=C}return O},function(N,C,e,L,h,Q,m,O){if(!(N+(((N^(m=["startTime","C",77],44))<24&&(N>>1&13)>=12&&p.call(this,C),N^70)<15&&((N|6)&15)>=7&&xW.call(this,"c"),4)&14))P[44](m[2],function(t,D){return(D=[28,32,"cookieDeprecationLabel"],L.S||(h=S[D[0]](41).navigator)==C||!h[D[2]])?t.return():t.i(S[D[0]](D[1]).navigator[D[2]].getValue().then(function(q){return L.S=q}),e)});return(N&26)==N&&(yE.call(this),this.i=0,this.endTime=this[m[0]]=null),(N&70)!=N|| +h&&Q&&Q.width==e&&Q.height==e||(W[35](25,"",C,"top",!0,Q,L,h),y[40](1,L[m[1]]),h?(S[46](4,.9,"",L),L.P.focus(),L.G==R$&&(L[m[1]]=K[26](8,$Q,S[28](32),function(){return L.W()},{passive:!0}))):L.K.focus(),L.Y=Date.now()),O},function(N,C,e,L,h,Q,m){if(((N|((N+2&7)==(((Q=[1,12,"i"],N)|Q[0])<33&&N-2>=19&&(h=H[3](39,e),h!=null&&(K[Q[1]](11,6,h),P[31](48,6,"number",h,C,L))),Q[0])&&(e={},C=new Np((e[Yz]=this[Q[2]].fu(),e[jt]=I[22](9,4,this.B[Q[2]]),e)),this[Q[2]].B.send(C).then(this.I,this.Nz,this)),Q[0]))& +7)==Q[0])a:{if(Jd){m=(L=e[Cb])!=C?L:e[Cb]=new Map;break a}if(Cb in e){m=e[Cb];break a}m=(fu((h=new Map,e),Cb,{value:h}),h)}return m},function(N,C,e,L,h,Q){return(N<<(N<<(h=[1,2,"T"],h[0])&7||(Q=L.Ql[(~(e>>C)&L.Ql.length)-e-h[0]]),(N|h[1])>>4<h[0]&&N+7>=-64&&(v0.call(this,C),this[h[2]]=[],this.O=!1,this.u=[]),h[0])&7)==h[1]&&(Q=e.G==em?e.i:y[47](h[0],C,!1,e.i)),Q},function(N,C,e,L,h){return(N|32)==(h=[12,"hO",(N<<2<21&&(N^16)>>3>=2&&(L=!!(C.SZ&e)&&!!(C.Cu&e)),4)],N)&&(T[43](24,C),v[46](h[2],C),H[24](h[0], +C),f[34](16,C),f[39](1,C),C.G.push(C.H9,C.Xe,C[h[1]],C.qh,C.AM),y[22](h[0],C),C.G.push(C.eC,C.zz,C.rZ,C.hM),C.G.forEach(function(Q,m,O){return O[m]=Q.bind(C)})),L},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((N<<1&11)==(u=["call","G",0],2))a:{Q=(O=(q=(D=new sB(e),h=D.i.length>u[2]?D.i:location.hostname,D)[u[1]],P[4](15,L[u[1]])),O.next());try{for(;!Q.done;Q=O.next())if(m=Q.value,m.B.test(q)&&m.i.test(h)){B=m;break a}}finally{Q&&!Q.done&&(t=O.return)&&t[u[0]](O)}B=C}if((N|40)==((N|5)>=4&&(N|9)<16&&(B=P[u[2]](15, +e,L,C)),N))p[u[0]](this,C);return B},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R){if(N-7<(R=[5,0,41],14)&&((N^7)&15)>=6)a:{if(h.length===0){n=h;break a}if((q=(A=(c=((D=[],Q)||(Q=I[21](20),D.push(Q)),I[21](23)),[T[30](R[2],c,W[R[1]](3,L.yq),Ud()),T[30](48,Q,C,C),c]),[]),G=Q,L).mC&&L.mC.length!==0){m=(t=(B=T[39](4,e),P)[4](10,L.mC),t).next();try{for(;!m.done;m=t.next())O=m.value,q.push(T[30](51,G,W[R[1]](7,B),O))}finally{m&&!m.done&&(u=t.return)&&u.call(t)}}n=[].concat(T[R[0]](R[2],A),T[R[0]](87,q), +T[R[0]](39,h),T[R[0]](89,D))}if((N+1&13)==1)W[36](80,C,function(){this.xU()},e);if((N^46)>>3==3)U[29](71,2,C);return N-8>>3==3&&(D=[!0,'"',16],t=new Lb(m,C,void 0,Q.A,function(F){return v[0](19,4096,F,wi,Q.Hm)}),L&&P[39](25,D[1],t,L),h&&t.v9(h),e&&I[24](32,D[R[1]],t,e),O&&H[11](13,1,D[2],D[R[1]],t),T[22](7,D[1],Q,t),n=t),n},function(N,C,e,L,h,Q,m){if((N>>(m=[9,!1,"B"],2)&7)==2)I[7](8,0,!0,C,void 0,e,L,h);return(N&113)==(N+6<37&&N<<1>=20&&p.call(this,C),N)&&(L=[null,"p",3],TN.call(this),this[m[2]]= +C,I[5](26,this,this[m[2]]),this.i=e,I[5](m[0],this,this.i),this.h=m[1],this.V=L[0],this.A=L[0],this.S=m[1],this.j=Date.now(),this.Y=L[0],this.K=L[0],this.G=L[0],this.P=new Hv,I[5](24,this,this.P),y[6](36,L[2],L[1],30,33,this),this.o=L[0]),Q},function(N,C,e,L,h,Q,m,O){return(N^(((N|(N-((N|(m=[2,"G",44],80))==N&&(O=P[0](13,e,L,C,rY)),5)>>3==3&&(L.B?(h=vh(L.o()-L.K,e),h<L[m[1]]*C?L.i=setTimeout(function(){P[30](33,.8,0,L)},L[m[1]]-h):(L.i&&(clearTimeout(L.i),L.i=void 0),L.aM(),L.B&&(T[13](67,!1,L),L.start()))): +L.i=void 0),9))>>4==4&&(O=e=(C&L?e|C:e&-3)&-273),(N|8)==N)&&(L=L===void 0?0:L,h=h===void 0?!1:h,O=P[m[2]](45,function(t,D,q){D=(q=[36,1,2],[6E4,5E3,4]);switch(t.B){case q[1]:if(!(L>0)){t.js(C);break}return t.i(H[19](q[1]),C);case C:return h||e.i.set(mn,SY),t.K(D[q[2]]),t.i(e.V(e.Xa.bind(e,h5)),6);case 6:t.V(5);break;case D[q[2]]:t.o();case 5:Q=174E4,L<C&&(h?L==0?Q=D[q[1]]:L==q[1]&&(Q=D[0]):Q=D[0]),W[q[0]](80,Q,function(){return P[30](9,2,e,++L,h)}),t.P()}})),7))>>3==m[0]&&(O=encodeURIComponent(String(C))), +O},function(N,C,e,L,h,Q,m,O,t,D,q){if(((N>>1&(q=[3,null,((N&28)==N&&($D[C]=e),30)],15)||(D=S[4](76,C.id,C.name)),(N-5&23)==2)&&(Q=Q===void 0?py:Q,h=W[33](33,L,e,void 0,void 0,P[45].bind(q[1],13)),D=h!=C?h:Q),(N|48)==N)&&L!=q[1])switch(v[22](q[0],h,Q,0),typeof L){case e:(TH((m=h.i,L)),v)[39](51,0,L),y[49](q[0],l5,TU,m);break;case "bigint":t=y[q[0]](27,0,my,W[14].bind(q[1],1),L),y[49](99,t.B,t.i,h.i);break;default:O=S[q[2]](74,C,L),y[49](67,O.B,O.i,h.i)}return D},function(N,C,e,L,h,Q,m,O){if(!(O=["i", +14,"fu"],N+1>>3)){if(this.sm!==TS)throw Error("Sanitized content was not of kind HTML.");m=S[O[1]](3,null,this.toString())}return(N<<1&15)==((N^15)>>3==2&&(h=[32,!0,null],S[3](40,this.A),C=B0.M().get(),e=this.B[O[0]].wq,e===I$&&T[42](36,h[0],C)||e===B4&&T[42](48,33,C)||(L=this.BU.bind(this),this[O[0]][O[0]].rJ()==Ip?this[O[0]][O[0]].Fq(kW(L,h[2]).bind(this),this[O[0]][O[2]](),h[1]):((Q=this[O[0]].o[O[0]])==h[2]?0:T[22](4,3,Q,rY))?this[O[0]].o.execute().then(L,function(){return L()}):Promise.resolve().then(L))), +(N|72)==N&&YK.call(this,1313,25),2)&&(this[O[0]]=null,this.o=C,this.B=0,this.G=e),m},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){return(N&74)==(((N^80)&14)==((N+((N|3)>>3==(B=[5,"M",2],B[2])&&(this.i=C),B)[0]&15)==1&&(this.z2=I[39](B[2],128,B[2],C,e,L,2048)),B)[2]&&(K[B[0]](25,[-114],P[17].bind(null,13)),K[B[0]](39,[-4,-25],U[B[2]].bind(null,1)),K[B[0]](11,[-68],H[27].bind(null,40)),K[B[0]](B[0],[-102,-57],v[0].bind(null,48)),K[B[0]](11,[-1,-11],S[12].bind(null,B[0])),K[B[0]](37,[-91,-41],S[15].bind(null, +3))),N)&&(t=y[41](72,c7[B[1]](),C),O=P[4](11,t).next().value,m||(m=P[4](10,y[41](9,c7[B[1]](),C)).next().value,t.push(m)),D=[U[0](91,m,e),U[0](92,O,aT),P[37](87,O,L,O)],u=[P[37](83,m,L,Q),h],D.push(y[17](9,O,m,u)),(q=c7[B[1]]()).i.apply(q,T[B[0]](71,t)),G=D),G},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if(!(N-7&(((c=["messageHandlers",9,44],N+3>>4)||(G=P8('<div>For site owner: v1beta1 is deprecated. <a href="https://docs.cloud.google.com/recaptcha/docs/migration-v1" target="_blank">Take action.</a></div>')), +(N+8^31)<N)&&(N+1^26)>=N&&(h=[3,2,"8x-4t2pegToiW8KmThtO4AQt"],Q=new Hi,t=y[c[2]](c[1],5,Q,e,rY),D=K[0](11,C,t,(B=(q=performance)==null?void 0:q.timeOrigin)!=null?B:Date.now()),m=P[0](12,D,h[2],4,rY),u=P[0](79,m,l[c[2]](3),h[0],rY),O=P[0](76,u,navigator.userAgent,12,rY),L&&P[0](14,O,L,h[1],rY),(0,B8.iU)(C),G=O),7)))a:{if(Zf.zzmb){G=Zf.zzmb;break a}if(h=(L=Zf.webkit)==C?void 0:(e=L[c[0]])==C?void 0:e.zzmb){G=new hW(h);break a}}return G},function(N,C,e,L,h,Q,m){if((m=[!1,"ctrlKey",1],N+8)>>3==3)a:{if(!eZ|| +!Ie){Q=m[0];break a}for(h=C;h<Ie.brands.length;h++)if((L=Ie.brands[h].brand)&&y[48](49,e,L)){Q=!0;break a}Q=m[0]}return(N|32)==(((N<<m[2]&15)<6&&N<<m[2]>=-51&&(Q=W[37](2,C,"iPhone")||I[m[2]](73,"iPad")||I[m[2]](89,C)),N+5&12)<6&&(N^35)>>3>=m[2]&&(L=[!1,0,""],xW.call(this,C?C.type:""),this.relatedTarget=this.B=this.target=null,this.clientX=L[m[2]],this.clientY=L[m[2]],this.screenX=L[m[2]],this.screenY=L[m[2]],this.button=L[m[2]],this.key=L[2],this.keyCode=L[m[2]],this[m[1]]=L[0],this.altKey=L[0],this.shiftKey= +L[0],this.metaKey=L[0],this.state=null,this.K=L[0],this.pointerId=L[m[2]],this.pointerType=L[2],this.timeStamp=L[m[2]],this.O5=null,C&&this.init(C,e)),N)&&(Q=Qy.now()),Q},function(N,C,e,L,h,Q,m,O,t,D){if((N^(D=[3,16,33],9))>>D[0]==2)a:{if(!(m=UR(function(q){return(q=/SamsungBrowser\/([.\d]+)/.exec(navigator.userAgent))&&parseFloat(q[e])>=C},h),Q=KX(),document)[Q]||m){t=T[23](D[2],e);break a}O=y[D[1]](10),document[Q]().then(function(q){return O.resolve(q?2:3)},function(){return O.resolve(L)}),t=O.promise}return(N| +(N<<1&((N|72)==N&&(L=new C,L.cK=function(){return e},t=L),7)||(t=I[D[2]](20,I[12](D[1],C,h),e,m,L,Q)),1))>>4||(W[9](18,128,1,h,function(q,u,B,G,c){(G=[1,3,(c=[0,1,2],2)],u!=null)&&((B=l[c[1]](28,G[c[0]],c[0],G[c[2]],L,q))?B(Q,u,q):q<C||f[21](14,G[c[0]],G[c[1]],mK))},h[Rw]|e),(m=T[1](12,h))&&v[19](D[1],function(q,u,B,G,c){for(G=(T[7](32,Q,(c=[37,"end",45],Q).i[c[1]]()),e);G<B.length;G++)T[7](c[0],Q,v[c[2]](50,3,B[G])||new Uint8Array(0))},m)),t},function(N,C,e,L,h,Q,m){return((N^80)>>((N|24)==((N>> +((N&(Q=["i",57,20],Q[1]))==N&&(h=[y[38](32,C)],L&&h.push(y[38](48,L)),m=P[18](26,W[39](12,S[32](24,new b4,Q[2]),e),h)),1)&14)==4&&(m=new hr(C)),N)&&(m=L==C?Oh():L==e?FQ():lM()),4)||(m=P[18](29,W[39](28,S[32](Q[2],new b4,5),L),[W[0](22,e),W[0](19,C)])),N-5)<<1>=N&&(N-7^32)<N&&(this[Q[0]]=C),m},function(N,C,e,L,h){if((N&45)==((N&(L=[26,0,"call"],123))==N&&(e.readyState=C,e.G=null,e.o=null,e.h=null,v[45](L[0],e)),N))eB[L[2]](this,L[1],L[1],ML,tW);return h},function(N,C,e,L,h,Q,m,O){if((O=[5,52,1],N)>> +O[2]>=18&&(N+8&8)<3)a:{if(e instanceof dr){m=e.i;break a}throw Error(C);}return(N&109)==(((N|O[2])&7)==O[2]&&(e.o&&e.o.K&&(Q=e.o.K,h=e.I,h in Q&&delete Q[h],U[O[0]](O[2],C,e.o.K,L,e)),e.I=L),N)&&(m=T[42](O[1],C,e)),m},function(N,C,e,L,h,Q,m){return(((N-((N|(m=[7,",",31],56))==N&&p.call(this,C),8)^m[0])<N&&(N+1&36)>=N&&(e=H[2](24,C),C=P[25](40,m[2],0,C),C.splice((e>>m[2]&C.length)+e,1)),(N^37)&6||(e=e===void 0?!1:e,this.errorCode=C,this.i=e),N<<1)&m[0])==2&&(Q=(h=L(e(),16))?h.length+m[1]+L(h,22).length: +Uh()),Q},function(N,C,e,L,h,Q,m){return(N&77)==((N-2^(((((Q=[57,8,18],N)^76)&13||(m=S[41](40,C,void 0,e)),N-9)^21)>=N&&(N-7^Q[1])<N&&(m=W[Q[2]](2,new aI,U[4](Q[2],9566)(C,L,function(O){return O.split(js())[0]})).toString()),32))<N&&(N+6&Q[0])>=N&&(T[49](41,e,L),e=oE(e),!L&&!n2||P0(e)?h=String(e):(v[39](59,0,e),h=y[Q[1]](14,C,l5,TU)),m=h),N)&&(m=U[13](28,e,DY,C,rY)),m},function(N,C,e,L,h,Q,m,O,t,D){if(D=["v","i","prototype"],!(N-3>>4))a:{if((L=qp,C[D[1]])[L]){t=C[D[1]][L];break a}if(Object[e=C.B,D[2]].hasOwnProperty.call(e, +L)&&(O=JS(e,L))&&"value"in O){t=C[(h=O[uD()],delete e[L],Q=Promise.resolve(h),D)[1]][L]=Q;break a}t=C[(m=new Promise(function(q){fu(e,L,{configurable:!0,set:function(u){q(u),delete e[L]}})}),D)[1]][L]=m}return N-7<<1>=(((N|56)==N&&(t=UR(function(){return e().parent!=e()?!0:e().frameElement!=null?!0:!1},!0)),(N+6&9)==1&&!y[24](1,!1,16,this[D[0]](),C)&&v[44](37,this,Bq))&&this.isEnabled()&&P[26](1,this,2)&&v[41](19,2,!0,this),N)&&(N+9^16)<N&&(t=new ZE(function(q){e.then(function(u){q.closed||(q.next(u), +q.complete())},function(u){return q.error(u)}).then(C,H[10].bind(null,15))})),t},function(N,C,e,L,h){if((((L=["call",4,46],N)-1>>L[1]||(h=e.B?T[0](L[2],C,e.B||e.A.i):null),N+3)&7)==1){for(;C=V4.remove();){try{C.B[L[0]](C.i)}catch(Q){T[0](74,Q)}jm.put(C)}wH=!1}if(((N^28)&7)==1)p[L[0]](this,C);return h},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w){if((N&11)==(((N>>((x=[3,15,"prototype"],N-9&27||(w=W[13](16,new GO(new cq(C)))),(N|x[0])>>x[0]==x[0])&&(w=e==C?e:U[11](21,e)),1)& +x[1])==x[0]&&(L=new GO(new cq(e)),Po&&C[x[2]]&&Po(L,C[x[2]]),w=L),(N-x[0]&x[1])==1)&&(L=U[41](9),HL.set(L,{filter:C,aM:e}),w=L),N)){O=(d=RY(L.o.length,(z=["ofs=",0,!0],h)),L.P?Pe(L.P.P,L.P,L):null);a:{for(c=(G=-1,L).o;;){for(F=(J=(G==(r=["count="+d],-1)?d>z[1]?(G=c[z[1]].i,r.push(z[0]+G)):G=z[1]:r.push(z[0]+G),z[2]),z[1]);F<d;F++)if(q=c[F].i,q-=G,A=c[F].map,q<z[1])G=vh(z[1],c[F].i-100),J=C;else try{k=(Y="req"+q+"_"||e,void 0);try{R=(m=A instanceof Map?A:Object.entries(A),P)[4](x[1],m),E=R.next(); +try{for(;!E.done;E=R.next())B=P[4](11,E.value),u=B.next().value,n=X=B.next().value,I[6](16,X)&&(n=(new P7).G2(X)),r.push(Y+u+"="+encodeURIComponent(n))}finally{E&&!E.done&&(k=R.return)&&k.call(R)}}catch(a){throw r.push(Y+"type="+encodeURIComponent(Kb())),a;}}catch(a){O&&O(A)}if(J){t=r.join(lC());break a}}t=void 0}w=(Q.Y=(Z=(D=t,L).o.splice(z[1],d),Z),D)}return w},function(N,C,e,L,h,Q){if(((((N|40)==(((Q=[46,"G",2],N)&44)==N&&(e=H[Q[2]](76,C),U[29](36,C.Ql[y[1](32,1,e,C)],C)),N)&&(e=e===void 0?!0: +e,C[Q[1]]&&e?(C[Q[1]].classList.add("recaptchaJavascriptChallengeQrCodeVisible"),C[Q[1]].classList.remove("recaptchaJavascriptChallengeQrCodeHidden")):C[Q[1]]&&!e&&(C[Q[1]].classList.add("recaptchaJavascriptChallengeQrCodeHidden"),C[Q[1]].classList.remove("recaptchaJavascriptChallengeQrCodeVisible"))),N-1^28)<N&&(N-Q[2]^Q[2])>=N&&p.call(this,C,0,E_.yl),N)>>Q[2]&15)==3)a:{if(e=typeof C,L=[64,0,!1],C==null){h=C;break a}if(e==="bigint"){h=l[Q[0]](40,Ro(L[0],C));break a}if(T[49](25,C,!0)){h=e==="string"? +T[9](10,L[Q[2]],L[1],C):v[0](Q[2],L[1],!0,C);break a}}return h},function(N,C,e,L,h,Q,m,O,t){if(((t=[34,35,":"],N^t[1])&14)==2)if(typeof e.dispose=="function")e.dispose();else for(L in e)e[L]=C;if((((N-4&((N+9&9)==1&&(AW(),L.i=new xY("rpc",L,L.Xe,L.K),L.A===null&&(L.i.l=L.j),L.i.R=0,h=U[36](7,L.qp),U[t[1]](75,h,wd(),yy()),U[t[1]](76,h,dd(),L.R),U[t[1]](75,h,VI(),L.T),U[t[1]](78,h,iD(),L.l?ZJ():Ud()),!L.l&&L.Fe&&U[t[1]](76,h,vq(),L.Fe),U[t[1]](76,h,mV(),nb()),W[24](10,h,L),L.A&&L.j&&W[41](81,t[2],L.A, +L.j,h),L.C&&L.i.setTimeout(L.C),m=L.E5,Q=L.i,Q.T=C,Q.h=f[16](8,U[36](31,h)),Q.A=e,Q.C=!0,P[9](t[0],2,C,m,Q),Is()),(N|72)==N&&(O=U[4](26,4227)(L(C(),39))),15))==2&&p.call(this,C),N)|48)==N)a:{for(h=L(C(),9),Q=0;Q<h.length;Q++)if(h[Q][pv()]&&S[36](42).test(h[Q][pv()])){O=Q;break a}O=-1}return O},function(N,C,e,L,h,Q,m,O,t,D){if(!(N+(t=[49,(N<<1&10||(2&e&&(L|=2),D=L|C),"t2"),4],2)&3))a:{if(O=H[48].bind(null,t[2]),P[13](t[2],C,"display")!="none"){D=O(C);break a}D=(((h=((((Q=(e=C.style,e).position,L=e.display, +m=e.visibility,e).visibility=OR(),e).position=Rs(),e).display=FH(),O(C)),e).display=L,e.position=Q,e).visibility=m,h)}if(((N|2)&((N+8^13)>=N&&(N-1^8)<N&&(this.BK=this[t[1]]=-1,this.Cs=C.altKey),7))==3){e.P||(e.P=f[2](t[0])),h=h===void 0?e.withCredentials:h,m=(C=C===void 0?null:C,{});try{Q=(new URL(e.P)).toString()}catch(q){Q=(new URL(e.P,S[28](16).location.origin)).toString()}(O=new URL(Q),C)&&(m.Authorization=C),e.RM&&(m["X-Goog-AuthUser"]=e.RM,O.searchParams.set("authuser",e.RM)),D={url:O.toString(), +body:L,UZ:1,wz:m,oF:"POST",withCredentials:h,SP:e.SP}}return D},function(N,C,e,L,h,Q,m,O){if((N|64)==((m=[24,25,"concat"],(N&41)==N&&lD.call(this,8,TO),(N+1&59)<N)&&(N-1^10)>=N&&(O=(e||document).getElementsByTagName(String(C))),N)){for(e=(h=H[15]((L=[],4),this),y[34](53,this)),Q=1;Q<C;Q++)L.push(y[34](53,this));this.Pm[h]=new (Function.prototype.bind.apply(e,[null][m[2]](T[5](m[1],L))))}if((N+5&44)>=N&&(N-1^m[0])<N)a:{if(C.B){e=C.B,O=v[8](1,e).then(function(t,D){return new (e.subscribe((D=new DR(t), +D)),ZY)(D)});break a}O=C.i?C.G?Promise.resolve(new os(C.G,C.i)):C.K?Promise.resolve(new Av(C.i)):Promise.resolve(new Pq(C.i,C.o)):Promise.reject(Error("An API key or OAuth token stream is required"))}return O},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(((B=["call",20,"G"],N)|24)==N)Oz[B[0]](this,o9);if((N-5^10)>=N&&(N+7^28)<N&&(t=[3,2,null],L.i==e))if(L[B[2]]){if((m=L[B[2]],m).B){for(q=(D=m.B,u=e,Q=C,C);D&&(D.K||(u++,D.i==L&&(Q=D),!(Q&&u>1)));D=D.next)Q||(q=D);if(Q)if(m.i==e&&u==1)P[49](21,t[2],0,m, +h);else{if(q)O=q,O.next==m.o&&(m.o=O),O.next=O.next.next;else T[21](1,t[2],m);K[23](15,t[1],t[2],h,m,t[0],Q)}}L[B[2]]=C}else v[45](6,C,t[0],h,L);if((N-((((N+1&15)==4&&(this.element=e,this.i=L,this.depth=h,this.B=C),N)&14)==N&&(C.style.display=e?"":sh()),9)^15)>=N&&N+2>>1<N)a:{if(t=h.get(L),t!=C){G=t;break a}for(t=O=0;O<L.length;O++)D=L[O],l[14](B[1],e,Q,D)!=C&&(t!==0&&(m=W[26](10,m,t,Q,void 0,e)),t=D);G=(h.set(L,t),t)}return G}]}(),fb,kl=function(N){return H[10].call(this,8,N)},XH=function(N){return f[7].call(this, +14,N)},kw=function(){return K[34].call(this,18)},Sm,UA=function(N){return y[19].call(this,2,N)},Wo=function(){return U[31].call(this,18)},Sj=function(N){return S[33].call(this,20,N)},Y7,Wq=function(N,C,e){if(!N)throw Error();if(arguments.length>2){var L=Array.prototype.slice.call(arguments,2);return function(){var h=["slice","call","prototype"],Q=Array[h[2]][h[0]][h[1]](arguments);return(Array[h[2]].unshift.apply(Q,L),N).apply(C,Q)}}return function(){return N.apply(C,arguments)}},yD=function(N){return T[49].call(this, +16,N)},oo=function(N){return U[34].call(this,2,N)},V,Hq,$D=[],Dx=function(N){return f[6].call(this,1,N)},k7=((fb=self)==null||(Hq=fb.document)==null||(Y7=Hq.createEvent)==null||(Sm=Y7.bind)==null||Sm.call(Y7,document),function(N){return U[30].call(this,60,N)}),Gb=/[-_.]/g,rF,eL=function(N,C){return v[42].call(this,7,N,C)},UO=function(N){return l[35].call(this,4,N)},zk=function(N,C,e,L,h){return y[4].call(this,1,N,C,e,L,h)},pP=function(N){return W[25].call(this,2,N)},pb,JW,Eh,Te=(rF=self)==null?void 0: +(JW=rF.Math)==null?void 0:(pb=JW.imul)==null?void 0:(Eh=pb.bind)==null?void 0:Eh.call(pb,Math),zO,dF,wF,oV=function(N){return y[7].call(this,9,N)},b6=function(N,C,e,L,h,Q,m){return v[36].call(this,6,N,C,e,L,h,Q,m)},Vy,Mf=function(N){return K[35].call(this,3,N)},nS=(zO=self)==null?void 0:(wF=zO.document)==null?void 0:(Vy=wF.getElementsByTagName)==null?void 0:(dF=Vy.bind)==null?void 0:dF.call(Vy,document),x7,as,gF,bD,a$=((as=self)==null||(x7=as.Math)==null||(bD=x7.sign)==null||(gF=bD.bind)==null||gF.call(bD, +Math),function(N,C,e){return K[19].call(this,48,N,C,e)}),u5=function(N){return l[40].call(this,1,N)},nj=/^[^&:\/?#]*(?:[\/?#]|$)|^https?:|^filesystem:https?:|^ftp:|^data:image\/[a-z0-9+-]+;base64,[a-z0-9+\/]+=*$|^blob:/i,Mp,$7,J_=function(N,C){return W[8].call(this,1,N,C)},NK,C9,eO=function(N,C){return P[32].call(this,9,N,C)},L9=($7=self)==null?void 0:(C9=$7.Math)==null?void 0:(NK=C9.sqrt)==null?void 0:(Mp=NK.bind)==null?void 0:Mp.call(NK,Math),hx,QC,al=function(N,C){return l[35].call(this,1,N,C)}, +mp,Ou;(Ou=self)==null||(hx=Ou.document)==null||(mp=hx.createTextNode)==null||(QC=mp.bind)==null||QC.call(mp,document); +var tx,Uu,Dc,P1=function(){return P[49].call(this,29)},qK,uU=function(N,C){return y[20].call(this,20,N,C)},Zu=(tx=self)==null?void 0:(Dc=tx.document)==null?void 0:(qK=Dc.createElement)==null?void 0:(Uu=qK.bind)==null?void 0:Uu.call(qK,document),Bl,jO,G2,cl,Yl=function(N){return P[18].call(this,1,N)},bi=function(N){return P[33].call(this,16,N)},K9=(jO=self)==null?void 0:(G2=jO.document)==null?void 0:(Bl=G2.getElementById)==null?void 0:(cl=Bl.bind)==null?void 0:cl.call(Bl,document),Ax,m7=/[\x00- \x22\x27-\x29\x3c\x3e\\\x7b\x7d\x7f\x85\xa0\u2028\u2029\uff01\uff03\uff04\uff06-\uff0c\uff0f\uff1a\uff1b\uff1d\uff1f\uff20\uff3b\uff3d]/g, +yC,Tk=function(){return T[24].call(this,8)},iU=/[#\?]/g,MQ=/[#\?@]/g,vl,n9,xJ=(Ax=self)==null?void 0:(vl=Ax.Object)==null?void 0:(yC=vl.keys)==null?void 0:(n9=yC.bind)==null?void 0:n9.call(yC,Object),I3=function(N,C,e,L){return y[30].call(this,6,N,C,e,L)},R3,FV,lU,NT=function(){return U[20].call(this,32)},T2,GH=(T2=self)==null?void 0:(lU=T2.JSON)==null?void 0:(R3=lU.parse)==null?void 0:(FV=R3.bind)==null?void 0:FV.call(R3,JSON),Zc,o3,Pl,K6=function(N){return P[43].call(this,21,N)},I9=function(){return P[38].call(this, +4)},su,SO=[0],WQ=(Zc=self)==null?void 0:(su=Zc.Math)==null?void 0:(Pl=su.clz32)==null?void 0:(o3=Pl.bind)==null?void 0:o3.call(Pl,Math),b0=function(N){return U[13].call(this,34,N)},Yo,Wl=["POST","PUT"],Hl,ko,vo=function(){return v[22].call(this,18)},r_,QI=(Yo=self)==null?void 0:(r_=Yo.JSON)==null?void 0:(Hl=r_.stringify)==null?void 0:(ko=Hl.bind)==null?void 0:ko.call(Hl,JSON),p9,Jx,Eu,z2,DK=function(N){return T[39].call(this,54,N)},Gn=(p9=self)==null?void 0:(z2=p9.Object)==null?void 0:(Eu=z2.getPrototypeOf)== +null?void 0:(Jx=Eu.bind)==null?void 0:Jx.call(Eu,Object),d_,w_,VC=function(N,C,e){return l[29].call(this,4,N,C,e)},o$=function(N){return P[23].call(this,56,N)},xo,a3=function(N,C,e,L){return f[40].call(this,42,N,C,e,L)},g_,TQ=(w_=self)==null?void 0:(g_=w_.Object)==null?void 0:(xo=g_.isFrozen)==null?void 0:(d_=xo.bind)==null?void 0:d_.call(xo,Object),bU,MK,$o,dr=function(N){return U[46].call(this,8,N)},N7,ae=(N7=self)==null?void 0:(bU=N7.Math)==null?void 0:($o=bU.round)==null?void 0:(MK=$o.bind)== +null?void 0:MK.call($o,Math),Wt=function(N){return l[19].call(this,16,N)},eG=function(){return l[46].call(this,1)},CO,eR,LO,hy,wq=(hy=self)==null?void 0:(LO=hy.Math)==null?void 0:(eR=LO.ceil)==null?void 0:(CO=eR.bind)==null?void 0:CO.call(eR,Math),QP,Lc=function(){return y[22].call(this,1)},mM,Oq,ty,nN=(QP=self)==null?void 0:(mM=QP.Object)==null?void 0:(ty=mM.getOwnPropertyNames)==null?void 0:(Oq=ty.bind)==null?void 0:Oq.call(ty,Object),Uq,DF,q7,uG,RY=(q7=self)==null?void 0:(uG=q7.Math)==null?void 0: +(DF=uG.min)==null?void 0:(Uq=DF.bind)==null?void 0:Uq.call(DF,Math),Lb=function(N,C,e,L,h,Q,m){return K[12].call(this,8,N,C,e,L,h,Q,m)},OL=function(N,C,e,L,h){return H[4].call(this,40,N,e,C,L,h)},BS,jR,Gr,A3=function(N){return v[2].call(this,16,N)},cS,Vc=(BS=self)==null?void 0:(Gr=BS.Math)==null?void 0:(jR=Gr.abs)==null?void 0:(cS=jR.bind)==null?void 0:cS.call(jR,Math),HV=function(N){return f[28].call(this,18,N)},fo=[],KO,tf=function(){var N=[5,null,"apply"];setTimeout[N[2]](N[1],T[N[0]](71,aq[N[2]](0, +arguments)))},Ay,cq=function(N){return y[23].call(this,50,N)},yP,iG,oM=(Ay=self)==null?void 0:(iG=Ay.Math)==null?void 0:(yP=iG.pow)==null?void 0:(KO=yP.bind)==null?void 0:KO.call(yP,Math),wi=function(N){return l[2].call(this,2,N)},ls=function(N){return v[12].call(this,8,N)},vS=function(N,C,e,L){return y[38].call(this,80,C,N,e,L)},Tn=function(N){return H[12].call(this,1,N)},nO,IN=function(N){return y[1].call(this,66,N)},Fx,lG,MB=function(N){return v[20].call(this,8,N)},Tr,ZH=(Fx=self)==null?void 0: +(lG=Fx.Object)==null?void 0:(Tr=lG.is)==null?void 0:(nO=Tr.bind)==null?void 0:nO.call(Tr,Object),ZF=function(N,C,e){return T[15].call(this,15,e,C,N)},oN=function(){return l[7].call(this,1)},hl=function(N,C,e,L){return y[11].call(this,12,N,C,e,L)},PS,of=/^\s*(?!javascript:)(?:[\w+.-]+:|[^:/?#]*(?:[/?#]|$))/i,sq,M$=function(N,C,e,L){return y[45].call(this,11,C,e,N,L)},fO,Xx,SG=function(N){return H[43].call(this,2,N)},vh=(sq=self)==null?void 0:(PS=sq.Math)==null?void 0:(Xx=PS.max)==null?void 0:(fO=Xx.bind)== +null?void 0:fO.call(Xx,Math),SR,Yc,WS=function(){return T[4].call(this,48)},HS,kc=[0],rp,pO=(HS=self)==null?void 0:(SR=HS.Math)==null?void 0:(Yc=SR.log)==null?void 0:(rp=Yc.bind)==null?void 0:rp.call(Yc,Math),Jy,Eq,zr,N0=function(N){return K[48].call(this,1,N)},dp,eP=/[^\d]+$/,My=(Eq=self)==null?void 0:(zr=Eq.Object)==null?void 0:(Jy=zr.isExtensible)==null?void 0:(dp=Jy.bind)==null?void 0:dp.call(Jy,Object),wp,px=function(){},mu=function(N,C){return H[0].call(this,1,C,N)},VP,xc,aN,gp=(wp=self)==null? +void 0:(xc=wp.Object)==null?void 0:(VP=xc.seal)==null?void 0:(aN=VP.bind)==null?void 0:aN.call(VP,Object),bG,M7,$c,tI=function(N,C){return W[16].call(this,56,N,C)},NS=function(N,C,e,L,h){return U[0].call(this,36,N,C,e,L,h)},CF,ev=function(N,C){return T[24].call(this,2,C,N)},Wy=(bG=self)==null?void 0:($c=bG.Object)==null?void 0:(CF=$c.create)==null?void 0:(M7=CF.bind)==null?void 0:M7.call(CF,Object),OA=function(N){return K[35].call(this,4,N)},LF,hQ=function(N){return S[40].call(this,3,N)},Qx,mR,OG, +TH=(OG=self)==null?void 0:(Qx=OG.Math)==null?void 0:(mR=Qx.floor)==null?void 0:(LF=mR.bind)==null?void 0:LF.call(mR,Math),tQ,UG,D8,qS,$4=(UG=self)==null?void 0:(D8=UG.Object)==null?void 0:(tQ=D8.freeze)==null?void 0:(qS=tQ.bind)==null?void 0:qS.call(tQ,Object),$f=function(N,C,e){return T[26].call(this,26,e,N,C)},ua,B3,jv,G8,sm=(B3=self)==null?void 0:(G8=B3.Object)==null?void 0:(ua=G8.defineProperties)==null?void 0:(jv=ua.bind)==null?void 0:jv.call(ua,Object),c3,KF,AQ,C$=function(N,C,e,L,h,Q,m,O){return f[35].call(this, +1,N,C,e,L,h,Q,m,O)},yx,fu=(AQ=self)==null?void 0:(KF=AQ.Object)==null?void 0:(yx=KF.defineProperty)==null?void 0:(c3=yx.bind)==null?void 0:c3.call(yx,Object),ia,v3,nF,IQ,JS=(v3=self)==null?void 0:(ia=v3.Object)==null?void 0:(nF=ia.getOwnPropertyDescriptor)==null?void 0:(IQ=nF.bind)==null?void 0:IQ.call(nF,Object),RQ,Fe,la,T8,Z8=(Fe=self)==null?void 0:(T8=Fe.Reflect)==null?void 0:(RQ=T8.setPrototypeOf)==null?void 0:(la=RQ.bind)==null?void 0:la.call(RQ,Reflect),oQ,P3,$I=function(N,C,e,L,h,Q,m,O,t,D, +q){return T[37].call(this,1,N,C,e,L,h,Q,m,O,t,D,q)},sG,fF,Xe=(oQ=self)==null?void 0:(fF=oQ.Reflect)==null?void 0:(sG=fF.construct)==null?void 0:(P3=sG.bind)==null?void 0:P3.call(sG,Reflect),Sv=function(N,C,e,L,h,Q,m,O,t){return S[43].call(this,2,N,C,e,L,h,Q,m,O,t)},YL,W3,H3,kL,IH=function(N,C){return v[27].call(this,16,N,C)},Vn=(kL=self)==null?void 0:(W3=kL.Math)==null?void 0:(YL=W3.random)==null?void 0:(H3=YL.bind)==null?void 0:H3.call(YL,Math),rB=y[6](68,6,115,31106),pF=y[6](84,16,104,31090),JQ= +y[6](16,5,104,31085),Pt=function(N){return f[19].call(this,72,N)},EG=y[6](64,22,68,31030),z8=y[6](64,4,99,31026),Db=y[6](16,4,120,25144),dB=y[6](68,9,57,30868),wB=y[6](68,9,91,31014),Vx=y[6](84,14,49,30554),xL=y[6](64,5,52,15165),aQ=y[6](64,4,26,31010),gB=y[6](16,2,85,31008),ba=y[6](16,10,68,30998),MS=y[6](84,9,70,30989),$L=y[6](68,4,2191,2341),N6=y[6](84,26,84,30963),Xn=function(N,C){return W[46].call(this,4,N,C)},UB=function(){return I[5].call(this,30)},CK=y[6](16,20,101,30943),BV=y[6](84,19,53, +4606),x3=y[6](64,31,64,23679),tZ=y[6](16,32,126,5402),XW=y[6](64,10,87,30916),eQ=y[6](84,3,112,30913),LK=y[6](68,167,65,309),h1=y[6](64,8,4030,11886),Qk=y[6](64,4,106,30909),mv=y[6](64,8,6,30901),O3=y[6](84,13,84,30888),t1=y[6](84,11,50,30877),wx=(P[31](24,47,["uib-"]),y)[6](68,5,71,26450),U3=y[6](68,6,57,30868),DV=y[6](68,4,4384,8903),q6=y[6](84,11,61,30857),zc={},uV=y[6](64,4,8,30853),qR=y[6](84,4,74,30849),a9=y[6](16,41,4,30808),r6=function(N){return W[19].call(this,41,N)},Z6=function(N){return f[19].call(this, +1,N)},Bb=y[6](84,13,28,30795),jQ=y[6](84,10,15,26081),G$=y[6](64,29,120,30766),cb=y[6](84,11,64,30755),KK=y[6](64,3,509,14768),Os=[],A1=y[6](68,10,89,30737),yk=y[6](64,9,85,30728),iV=y[6](64,2,16,30718),vb=y[6](64,4,6,14728),nK=y[6](84,4,59,11441),DR=function(N){return H[33].call(this,17,N)},I2=y[6](64,4,9,30714),DW=y[6](16,12,65,30702),s5=function(N){return y[7].call(this,24,N)},jN=y[6](16,3,100,18577),R2=y[6](68,10,126,30692),FC=y[6](68,5,2,30687),lV=y[6](84,17,41,30670),T$=y[6](68,11,20,27847), +ZV=y[6](84,6,65,30641),o2=y[6](84,6,70,19179),Pb=y[6](16,1,1591,3427),s3=y[6](84,7,8,30599),ht=function(N,C,e){return U[37].call(this,65,e,C,N)},fK=y[6](64,5,217,18918),po=function(N,C,e,L,h,Q){return K[36].call(this,64,N,C,e,L,h,Q)},VZ=y[6](84,10,74,30589),iA=function(N,C,e,L){return v[21].call(this,58,N,C,e,L)},XC=y[6](64,19,6,8677),SQ=y[6](16,6,1008,8466),YS=y[6](16,17,98,16029),Wb=y[6](64,9,46,30580),Hb=y[6](16,4,67,30576),kS=y[6](84,22,49,30554),re=y[6](68,8,14,30546),pK=y[6](68,12,115,30534), +J1=y[6](68,3,3,30531),E3=y[6](68,6,124,30525),w3=function(N){return y[14].call(this,22,N)},z$=y[6](68,14,114,5567),de=y[6](16,22,14,30503),we=y[6](84,46,31,14398),Vk=y[6](64,7,4,7389),xS=y[6](84,19,4,30431),FH=y[6](64,6,3589,28314),sK=function(){return H[9].call(this,17)},a2=y[6](68,7,109,30424),ge=y[6](16,10,43,9719),bV=y[6](64,11,45,30413),M6=y[6](64,6,44,30396),$S=y[6](64,7,87,30389),N5=y[6](84,3,20,29276),ru=function(N,C,e,L){return T[3].call(this,8,L,e,C,N)},Nw=y[6](84,8,2019,4503),h0=y[6](16, +12,74,30374),SB=y[6](84,4,117,30370),Id={},Cs=function(N,C,e,L){return H[44].call(this,3,N,C,e,L)},Pr=[1,2,3,5],eS=y[6](16,2,25,30368),lC=y[6](84,1,59,14762),Ls=y[6](84,8,93,30328),pv=y[6](84,3,1315,5875),co=function(){return P[23].call(this,65)},hK=y[6](84,3,104,2168),wX=y[6](68,10,116,30300),Qf=y[6](84,16,64,30284),mh=y[6](84,20,99,30264),SP=function(N){return f[13].call(this,1,N)},Ol=y[6](84,5,127,6814),tK=y[6](64,8,3591,27296),Ul=y[6](68,12,103,30252),DM=y[6](84,4,92,30248),$w=function(){return P[32].call(this, +72)},q5=y[6](16,6,79,30242),Xs={},EL=y[6](64,38,52,30108),Zd=function(N,C){return W[3].call(this,1,N,C)},uy=y[6](64,6,72,20796),BE=y[6](68,5,36,30103),sh=y[6](68,4,83,30099),jS=y[6](84,19,27,30080),Ga=y[6](84,3,104,30077),cE=y[6](16,6,1195,19368),QR=y[6](68,6,9196,5676),Bk=[],uD=y[6](64,5,4794,5629),iH=function(N){return W[37].call(this,65,N)},Ks=function(N){return U[32].call(this,3,N)},AK=y[6](84,13,99,30001),yf=y[6](68,5,116,29996),IX=function(){return U[17].call(this,10)},fN=function(N){return K[32].call(this, +1,N)},iy=y[6](68,1,941,1763),vE=y[6](16,17,122,29979),ns=y[6](68,2,18,4937),It=y[6](84,6,3484,3446),Rt=y[6](16,10,2911,27119),KC=function(N,C){return I[47].call(this,50,N,C)},Jt=y[6](68,41,41,29913),zA=y[6](16,41,17,29872),Fv=y[6](84,4,82,16079),ly=y[6](16,1,4012,1799),Ta=y[6](68,7,125,29845),ZM=y[6](64,4,406,5230),ot=y[6](84,6,102,29814),DH=y[6](64,13,68,29801),Rs=y[6](84,8,28,29793),PE=y[6](68,4,17,29789),sl=y[6](16,5,259,1112),Fk=function(N){return l[13].call(this,1,N)},fs=y[6](68,15,42,29774), +uz=y[6](68,6,68,9207),Xv=y[6](64,4,119,29736),SS=y[6](84,7,5250,20015),Ya=y[6](64,6,56,29730),UP=function(){return y[34].call(this,4)},WE=y[6](84,19,127,29711),HE=y[6](64,14,92,26519),ka=y[6](68,22,126,29486),rP=y[6](84,7,53,29704),ps=y[6](16,6,98,29698),JK=y[6](16,9,33,19950),kI=y[6](64,11,2969,3441),El=y[6](16,8,11,29690),za=y[6](68,13,18,29677),VX=function(N){return T[32].call(this,6,N)},QB=y[6](64,7,84,29663),dP=function(N,C,e,L){return f[37].call(this,24,N,C,e,L)},wP=y[6](84,11,28,29652),Oh= +y[6](84,5,16,29647),Vf=y[6](16,9,57,29638),xa=y[6](84,21,51,29605),at=y[6](16,10,56,29595),Aq=function(N){return I[43].call(this,4,N)},jH=y[6](68,7,52,29588),pi=function(N){return I[4].call(this,12,N)},gP=function(N,C,e,L){return y[32].call(this,2,N,C,e,L)},by=y[6](84,3,7,29579),M5=y[6](64,21,9,10959),$a=y[6](84,29,108,29550),Nq=y[6](68,24,36,29526),CG=y[6](68,3,541,15859),Zj=function(N){return l[41].call(this,65,N)},eo=y[6](68,16,36,29526),LG=y[6](84,8,25,29245),hb=y[6](16,18,113,29508),Qw=y[6](64, +6,2889,812),DY=function(N){return f[26].call(this,8,N)},mV=y[6](84,4,692,29493),mJ=y[6](68,4,419,22321),OQ=y[6](68,25,98,29461),tb=y[6](68,11,101,29450),UQ=y[6](16,15,56,29435),JJ=function(N){return H[2].call(this,8,N)},D4=y[6](84,13,105,29422),FP=function(N){return K[16].call(this,41,N)},qq=y[6](64,3,39,9436),l6=function(N){return I[28].call(this,4,N)},uQ=y[6](68,26,82,9490),BW=y[6](64,6,111,27654),jo=y[6](68,5,10,29417),kJ=function(N,C,e){return H[40].call(this,65,N,C,e)},G9=y[6](68,7,12,29341), +Wr=function(N){return W[45].call(this,8,N)},jY=y[6](68,13,29,29328),cW=y[6](68,8,1053,9500),hS=y[6](64,13,120,29315),KG=y[6](16,24,110,29291),Ab=y[6](64,7,22,29284),yw=y[6](64,8,20,29276),iQ=y[6](16,13,64,29263),lt=y[6](68,10,27,29253),vW=y[6](16,4,25,29245),wd=y[6](64,3,618,19942),nG=y[6](68,17,57,29228),i1=function(N){return I[46].call(this,57,N)},Hr=function(N,C,e){return H[39].call(this,4,e,C,N)},IP=y[6](84,14,77,29183),RP=y[6](16,17,44,29166),Fm=y[6](64,20,102,29146),lQ=y[6](16,3,64,29143),T9= +y[6](68,9,8,29134),Z4=y[6](68,3,103,29131),oP=y[6](68,33,71,29098),PW=y[6](16,64,40,17364),sQ=y[6](68,5,80,29078),fG=y[6](84,5,39,9436),Xy=y[6](84,3,55,29075),c9=y[6](84,4,235,26331),Xm=y[6](68,21,27,29054),sE=function(N,C){var e=[4,76,18],L=aq.apply(2,arguments).map(function(h){return W[0](16,h)});return P[e[2]](31,W[39](e[0],S[32](e[1],new b4,34),N),[W[0](23,C)].concat(T[5](89,L)))},OE=y[6](68,9,10,29045),So=y[6](64,16,94,19553),Wc=y[6](16,12,58,28998),WJ=function(N){return I[23].call(this,1,N)}, +YA=y[6](68,5,2956,13963),WW=y[6](68,10,9,24509),HW=y[6](16,22,118,28976),kA=y[6](84,23,107,28946),Jl=y[6](84,16,21,2797),rI=y[6](84,3,124,28943),pG=y[6](64,7,105,28936),Jb=y[6](16,10,119,28926),EQ=y[6](16,2,1806,3429),tv=function(N,C,e){return P[33].call(this,12,N,C,e)},Mt=function(N){return v[37].call(this,19,N)},YJ=y[6](84,26,126,3731),z9=y[6](84,4,102,12505),UV=function(N){return P[40].call(this,56,N)},dI=y[6](68,6,2305,19349),wI=y[6](84,6,52,28844),Vw=y[6](64,9,79,28835),xA=y[6](64,5,518,11622), +xq={},aP=y[6](16,3,26,28832),gI=y[6](16,17,30,28793),M9=y[6](16,47,98,28746),Yk=y[6](68,10,103,28736),bQ=function(N){return f[25].call(this,11,N)},Mq=y[6](64,22,63,27512),Yg=function(N){return l[17].call(this,21,N)},$A=y[6](64,4,70,28732),Nk=y[6](84,51,80,25958),sF=[1,2],C3=y[6](84,5,29,27920),e7=y[6](64,7,42,27063),L3=y[6](16,16,1227,19339),h$=y[6](64,4,99,28674),Q1=y[6](84,4,2465,6599),mt=y[6](68,3,4,28671),OU=y[6](16,2,7,28669),zM=y[6](64,38,104,22713),Lj=function(){return K[3].call(this,1)},t$= +y[6](68,2,2252,1778),z7={},fc=y[6](64,11,5,28658),UU=y[6](64,7,1,28651),D$=y[6](64,9,51,28642),Qn=function(N,C){return P[19].call(this,4,N,C)},qk=y[6](64,3,47,28639),u$=y[6](64,18,87,28590),Bu=y[6](64,6,112,28584),j7=y[6](68,39,52,6493),GL=y[6](68,21,62,28563),H4=function(){return new Xn(U[8](3,aq.apply(0,arguments)),!0)},cu=y[6](16,3,657,17758),K3=y[6](16,1,3368,597),A$=y[6](64,14,46,28484),y1=y[6](68,5,29,28470),i$=function(){return y[17].call(this,16)},kk=y[6](84,22,4,28448),W9=function(N){return y[16].call(this, +3,N)},vu=y[6](16,3,14,28445),n3=y[6](84,4,2572,21628),hr=function(N,C){return v[20].call(this,5,N,C)},Ic=y[6](16,9,29,28436),kg=function(N){return S[36].call(this,72,N)},Rc=y[6](84,12,30,28424),FJ=y[6](64,11,97,28374),l$=y[6](64,9,106,28365),WX=y[6](16,4,1030,11798),TL=y[6](16,3,18,28362),Z$=y[6](68,6,62,28356),oc=function(N,C,e){var L=[30,"M",11],h=[1,7,4],Q=aq.apply(3,arguments),m=P[4](10,y[41](L[2],c7[L[1]](),h[0])).next().value,O=I[21](23);return Q=[y[36](3,N),v[24](16,3,m,C,e),T[L[0]](43,O,W[0](17, +N),W[0](22,m)),yg(m,T[39](4,h[2]),m),yg(m,T[39](5,h[1]),m),T[L[0]](56,O,W[0](6,m),!1),ii.apply(null,[N,C,e].concat(T[5](89,Q))),O,y[36](3,m)],c7[L[1]]().i(m),Q},Pu=y[6](64,22,56,28334),sA=y[6](64,57,107,14629),Hh=y[6](84,10,10,28324),sU=y[6](64,13,57,28266),f3=y[6](84,32,57,28234),XJ=y[6](64,4,1,28230),S7=y[6](16,28,124,19328),YH=y[6](16,6,15,28115),Wu=y[6](84,9,107,28106),Hu=y[6](68,1,7039,1834),kH=y[6](64,7,16,28041),rU=y[6](84,10,26,28031),rx=function(N){return H[36].call(this,28,N)},p3=y[6](68, +31,73,12932),J$=y[6](84,9,76,28022),EU=y[6](16,2,3375,13967),zL=y[6](16,5,85,28017),dU=y[6](68,8,17,28009),O$=function(N){return P[12].call(this,10,N)},wU=y[6](68,5,2,28004),V1=y[6](84,21,72,13132),xH=function(N){return H[37].call(this,4,N)},ac=y[6](84,3,99,28001),gU=function(N){return I[3].call(this,25,N)},b$=y[6](16,5,8,27956),Cd=y[6](84,1,1557,3426),d0=y[6](16,23,95,27933),hf=function(){return y[3].call(this,14)},Mk=y[6](16,21,62,4535),D_={},Bv=function(){return W[20].call(this,2)},$H=y[6](68, +8,56,27925),NN=y[6](68,4,113,27921),C_=y[6](68,31,84,27889),ea=y[6](84,5,93,27884),L_=y[6](68,5,107,27879),Il=y[6](84,8,2132,21595),hk=y[6](68,14,77,16439),Qo=y[6](68,3,73,27876),m$=y[6](68,1,9955,1866),Oy=y[6](64,18,123,27858),VJ=y[6](16,55,80,4844),tk=y[6](84,5,677,27853),ck=y[6](16,5,124,27761),t3=function(N){return W[47].call(this,1,N)},Uy=y[6](16,11,106,27750),Dr=y[6](84,10,13,12455),qN=function(N,C){return I[44].call(this,1,N,C)},uh=y[6](68,9,97,27741),CC=function(N){return I[4].call(this,6, +N)},bM=y[6](16,35,3,27660),kt=function(){return new Xn(U[8](4,aq.apply(0,arguments)),!1)},BC=y[6](64,4,90,25785),ja=y[6](84,5,188,27655),G1=y[6](68,7,10,27647),cC=y[6](64,58,118,11204),qr=function(N){return T[40].call(this,1,N)},Pk=y[6](84,4,5163,2549),rH=y[6](84,5,16,27617),K_=y[6](64,4,17,27613),Ak=y[6](64,2,9583,1862),yo=y[6](16,9,45,27567),ih=y[6](84,22,65,27545),vC=y[6](84,5,79,26675),n_=y[6](64,1,5427,17426),rj={0:"An unknown error has occurred. Try reloading the page.",1:"Error: Invalid API parameter(s). Try reloading the page.", +2:"Session expired. Reload the page.",10:'Invalid action name, may only include "A-Za-z/_". Do not include user-specific information.'},Ir=y[6](64,8,71,27537),EV=4478,Jw=function(N){return y[20].call(this,12,N)},Rr=y[6](64,25,63,27512),vJ=y[6](64,3,381,19939),XP=function(N){return v[29].call(this,40,N)},FL=y[6](16,11,2,27501),lh=y[6](68,14,60,21152),T1=y[6](64,15,5,9553),mD=function(N){return H[36].call(this,1,N)},Zr=y[6](84,4,110,27445),or=y[6](84,1,1940,17779),DJ=y[6](64,21,17,27424),PC=y[6](84, +12,60,2148),sy=y[6](84,4,5123,13314),f_=y[6](84,14,10,27377),XL=y[6](68,8,116,14173),y$=y[6](84,3,42,27374),Sa=y[6](68,20,41,27354),Y9=y[6](84,13,2925,9862),WC=y[6](68,4,104,8114),HC=y[6](64,8,112,27346),k9=y[6](84,29,92,27229),rT=y[6](84,2,27,27227),p_=y[6](68,6,44,27221),Jk=y[6](64,4,75,9125),OY=y[6](84,1,98,3410),BZ=y[6](84,17,101,27204),Ey=y[6](84,6,10,27198),z1=y[6](68,4,11,27194),GC=y[6](64,39,30,24559),dT=function(N,C){return P[40].call(this,12,N,C)},wT=y[6](64,3,44,27085),Vo=y[6](84,14,42, +27063),x9=y[6](64,16,2,14801),ar=y[6](84,11,48,26949),w0=y[6](68,18,66,26931),gT=y[6](64,21,26,26910),CX=function(N){return v[35].call(this,16,N)},UZ=/^https?$/i,bh=y[6](68,3,0,26853),MN=y[6](68,11,79,26675),sd=function(N){return S[24].call(this,8,N)},$9=y[6](84,25,92,14732),N8=y[6](68,5,52,26789),wu=function(N,C,e,L){return I[12].call(this,33,N,C,e,L)},C4=y[6](84,15,97,26774),ef=y[6](64,7,91,26426),L4=y[6](16,6,30,26768),hj=y[6](84,4,65,26699),Qz=y[6](16,3,6,26696),Rp=function(N){return I[9].call(this, +1,N)},mg=y[6](64,7,4463,13978),Op=y[6](84,10,21,26686),K$=y[6](84,12,99,18609),tj=function(N){return l[35].call(this,40,N)},kz=function(N){return l[34].call(this,23,N)},Up=y[6](84,6,615,26680),oz=y[6](68,16,67,26659),Dl=y[6](68,3,93,26656),q8=y[6](68,3,40,26653),uF=y[6](68,6,122,26597),BN=y[6](16,13,75,26541),S8=function(N){return K[18].call(this,15,N)},jf=y[6](68,22,92,26519),GZ=function(N){return GZ[OY()](N),N},hM=y[6](84,7,18,26512),cN=y[6](16,4,93,26477),K4=y[6](64,12,80,26465),Aj=y[6](16,15, +71,26450),yz=y[6](16,3,109,26423),rA=function(N){return y[22].call(this,72,N)},iF=y[6](16,3,115,26420),ta=y[6](68,20,26,26400),vN=y[6](64,6,79,26394),gu=function(N){return W[11].call(this,7,N)},n4=y[6](68,6,111,26388),IO=function(N,C){return f[39].call(this,8,C,N)},PR=y[6](84,51,92,14505),RO=y[6](16,3,120,26347),Io=y[6](68,6,115,26323),FR=y[6](68,42,24,26281),lF=y[6](64,10,80,4844),TZ=y[6](68,8,81,26172),Zl=y[6](16,3,65,26169),VT=y[6](16,2,3383,3445),oO=y[6](84,8,58,13153),PN=y[6](64,2,5731,9641), +sp=y[6](16,3,62,26146),f4=y[6](68,6,117,6056),Sf=y[6](68,5,549,6824),Pf=y[6](84,11,109,26135),Y$=y[6](64,4,107,26131),WN=y[6](64,4,507,6765),HN=y[6](16,7,47,26124),k$=y[6](84,5,542,26086),rG=y[6](68,4,1828,1668),p4=y[6](68,10,35,19811),Jj=y[6](64,7,586,4487),mN=y[6](16,16,39,26065),Xa=y[6](64,4,60,25066),Ep=y[6](84,4,7,26061),zZ=y[6](16,9,118,26052),dG=y[6](84,14,47,26038),wG=y[6](84,8,62,26030),ch=y[6](64,27,108,16938),Vz=y[6](64,6,6275,8565),x$=function(N,C,e){return N.call.apply(N.bind,arguments)}, +yY=function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return S[47].call(this,11,N,C,e,L,h,Q,m,O,t,D,q,u,B)},aO=y[6](16,3,4517,26006),sk=y[6](64,10,89,13167),Ys=y[6](64,2,9210,452),gG=y[6](64,7,104,25951),bF=y[6](68,1,64,25901),M8=y[6](68,15,87,25886),$$=y[6](16,9,18,25877),Na=y[6](68,10,68,25867),CT=y[6](84,3,112,25864),ei=(P[31](20,18,S[42](96,S[42](46,S[42](62,747,S[42](33,665,S[42](49,598,578,617,77,135,35),680,147,145,54),756,84,120,109),S[42](56,S[42](61,S[42](60,S[42](57,335,319,340,399,790,170),S[42](59, +249,240,272,119,160),530,147,170,43),231),S[42](38,142,131,151,112,175,56)),885),S[42](34,S[42](58,S[42](63,110,86),77),S[42](59,7,0,16,161,200,49)))),y[6](16,11,122,25853)),NY=y[6](84,1,1393,4619),c1=function(N){return P[46].call(this,6,N)},D9=y[6](68,5,13,20827),LT=y[6](64,16,39,25808),h9=y[6](68,8,46,25800),Qb=y[6](64,11,123,25789),m6=y[6](16,2,221,25787),OJ=y[6](68,9,69,25776),Kq=y[6](16,3,1279,19604),t9=y[6](64,23,49,25753),UJ=y[6](16,6,2819,8433),D3=y[6](68,5,83,25748),SW=function(N){return H[46].call(this, +4,N)},qa=y[6](84,5,46,25743),um=y[6](64,20,61,25650),Vq=y[6](64,4,64,25646),BK=y[6](64,19,94,25627),ji=y[6](16,20,37,4020),Gl=y[6](16,7,24,25620),cK=y[6](64,12,102,14614),f$=function(N,C){return l[47].call(this,73,N,C)},SD=function(){return K[46].call(this,32)},KT=y[6](16,12,81,25608),A9=y[6](16,6,66,25602),RT=y[6](84,5,0,25585),yb=y[6](68,23,14,25562),im=y[6](16,20,24,25542),KX=y[6](68,16,46,25526),vK=y[6](68,7,29,25519),VR=y[6](64,46,77,25473),nT=y[6](64,14,51,25459),I_=y[6](64,18,13,25441),aG= +y[6](68,33,69,11028),R_=y[6](68,21,68,15784),FD=function(N,C){return W[23].call(this,8,N,C)},lm=y[6](64,11,80,15519),Tl=y[6](84,5,118,11204),Z3=y[6](68,8,100,25305),o_=y[6](64,8,103,25297),PK=y[6](84,19,75,20206),Dg=function(N,C,e){return S[35].call(this,48,C,N,e)},sJ=y[6](84,3,72,25294),fT=y[6](84,3,29,17750),XD=y[6](16,28,59,25261),Si=y[6](16,7,14,25254),YC=y[6](84,22,35,25232),WK=y[6](64,2,39,10160),HK=y[6](68,11,13,25175),kC=y[6](64,2,443,3414),rN=y[6](84,5,13,25170),cr=y[6](16,3,71,20599),pT= +y[6](84,12,13,25158),J9=y[6](16,3,1,25155),Mc=[3,6,4,11],EJ=y[6](16,11,120,25144),zl=y[6](16,2,235,8406),dN=y[6](68,30,22,25106),wN=y[6](68,10,65,25096),Vb=y[6](16,18,78,25078),xC=y[6](16,11,107,22991),a_=y[6](16,7,16,25071),sZ=y[6](64,5,60,25066),gN=y[6](68,8,108,25058),bm=y[6](64,9,22,25049),Ma=y[6](68,7,76,25042),$C=y[6](64,6,31,25036),NJ=y[6](68,5,18,5441),Ct=y[6](16,4,116,24933),e_=y[6](84,25,125,24908),Lt=y[6](68,8,67,24900),hc=y[6](68,31,53,23388),Q6=y[6](64,12,53,24877),mY=y[6](64,2,7225, +1836),LJ=y[6](16,12,113,24865),Oj=y[6](68,15,61,24850),rJ=function(N){return T[24].call(this,72,N)},tc=y[6](64,6,118,24767),Uj=y[6](64,1,4400,1804),DG=y[6](64,12,85,14556),w5=y[6](64,40,6,24727),qJ=y[6](84,9,116,24718),eY=function(N){return K[44].call(this,11,N)},uT=y[6](16,15,24,24486),Bw=y[6](16,5,4030,11886),j_=y[6](84,3,126,24715),Xu=y[6](16,43,86,24672),G4=y[6](68,6,1228,22873),cw=y[6](64,10,79,24615),Kt=y[6](68,17,45,24598),Ac=y[6](64,8,90,16924),SV=function(N){return l[2].call(this,5,N)},Jr= +y[6](68,5,3346,24593),y6=y[6](64,3,3520,24552),iT=y[6](64,7,223,24512),vw=y[6](68,11,126,9133),nt=y[6](16,23,24,24486),Ia=y[6](68,3,111,24483),E_=function(N){return P[45].call(this,18,N)},Ra=y[6](84,22,15,20281),FX=function(N,C,e,L){return v[37].call(this,64,N,C,e,L)},lT=y[6](68,11,36,24472),zP=function(N){return K[29].call(this,12,N)},T4=y[6](64,3,125,24469),ZG=y[6](64,4,2492,4648),hv=function(){return K[28].call(this,1)},oa=y[6](16,17,81,24449),Pw=y[6](84,3,725,24436),sj=y[6](64,11,82,24417),ft= +y[6](64,30,98,24387),d5=y[6](64,42,62,6772),u4=function(N){return l[45].call(this,49,N)},XX=y[6](16,3,4318,4666),jc=y[6](84,31,8,24352),S_=y[6](68,3,191,21328),YG=y[6](16,3,12,24345),EF=function(N){return P[25].call(this,2,N)},Ww=y[6](68,8,35,22510),Hw=y[6](64,18,12,16147),kG=y[6](84,12,41,23232),rW=y[6](16,11,99,24277),pt=y[6](68,3,104,24250),Bt=y[6](84,6,2399,14532),jb=y[6](64,36,61,24214),Jc=y[6](64,13,127,14312),Ej=y[6](68,6,30,24208),z4=y[6](16,14,55,6066),dW={},wW=y[6](84,12,109,24196),V6=y[6](68, +5,123,24093),OB=function(){return y[20].call(this,2)},xG=y[6](16,15,122,24078),aa=y[6](84,8,75,24070),gW=y[6](84,14,69,23993),bT=y[6](84,6,70,23987),MJ=y[6](84,3,29,23984),jp=y[6](16,5,2850,23962),$G=y[6](64,6,95,23928),Nl=y[6](68,15,29,23913),CY={sZ:!0},eh=y[6](84,11,123,23902),LY=y[6](16,2,2,23900),hU=y[6](84,2,11,23764),Ud=y[6](16,1,782,1761),Qd=y[6](16,3,5,23761),V$=function(){return S[25].call(this,21)},Cq=y[6](16,5,837,23755),mU=y[6](84,5,1392,14521),OX=y[6](64,5,809,22893),tU=y[6](64,3,47, +23745),UX=y[6](64,24,1,23710),DC=y[6](16,7,61,22879),y4=y[6](84,4,359,23683),ql=y[6](64,2,128,5435),uO=y[6](68,5,2969,3441),B6=y[6](84,6,4,5452),jh=y[6](68,27,59,15629),Xz=function(N){return U[13].call(this,56,N)},GG=y[6](16,2,2235,8523),F1=function(N,C,e){return v[13].call(this,4,N,C,e)},pc=[1,2,3,15],c6=y[6](64,7,63,23569),KY=y[6](16,3,40,23566),Hc=y[6](64,15,119,23551),AU=y[6](64,4,10,23536),yd=y[6](68,65,116,19962),iO=y[6](84,31,90,16048),v6=y[6](84,3,4327,3454),ct=y[6](64,3,64,23486),nY=y[6](64, +17,85,23469),I0=y[6](64,14,45,23455),Th=function(N){return U[42].call(this,1,N)},v_=y[6](64,7,2416,23412),R0=y[6](84,10,21,23378),Fb=y[6](84,1,10382,1870),OH=function(N){return T[31].call(this,2,N)},lO=y[6](64,13,42,12367),TG=y[6](84,6,7,23369),hp=function(N){return K[38].call(this,2,N)},ZC=y[6](16,3,38,23363),o0=y[6](68,18,112,23345),C2=["platform","platformVersion","architecture","model","uaFullVersion"],P6=y[6](64,8,102,23337),Vh=y[6](68,28,19,23267),sX=y[6](16,3,97,23264),fY=y[6](68,30,29,17750), +Xb=y[6](68,9,101,23255),Sh=y[6](64,2,1749,8517),aS=function(N){return W[30].call(this,42,N)},YO=y[6](16,5,1156,15795),W6=y[6](68,3,2576,6600),H6=y[6](16,7,111,23248),r8=function(N){return y[9].call(this,40,N)},Um=function(N,C,e){return S[23].call(this,1,N,C,e)},ZD=y[6](16,1,2530,3436),GQ=y[6](84,4,105,23244),kO=y[6](16,3,672,23238),rO=y[6](16,4,1301,1498),pY=y[6](84,8,1,23099),JU=y[6](68,6,84,23093),EX=y[6](68,5,127,23088),zG=y[6](16,47,47,10392),dO=y[6](16,4,0,23012),wO=y[6](64,4,30,23008),Vd=y[6](64, +17,107,22991),xO=y[6](64,16,16,22975),a0=y[6](16,17,9,22958),gO=y[6](16,4,0,22954),be=function(N){return K[0].call(this,4,N)},bO=function(N,C){return U[0].call(this,16,N,C)},Ml=y[6](16,10,122,22944),$O=y[6](84,12,77,22886),ZL=function(N){return T[10].call(this,5,N)},Nv=y[6](64,11,63,19356),C0=y[6](84,2,126,22880),el=y[6](64,17,24,22862),L0=y[6](84,4,111,22858),lM=y[6](84,5,72,22853),h6=y[6](84,6,23,22751),QH=y[6](68,9,2693,22741),m3=y[6](68,4,35,22510),qB=y[6](64,8,360,20333),Ot=y[6](84,10,43,22500), +t6=y[6](84,15,95,22485),Ut=y[6](64,35,92,22450),Da=function(N,C,e,L){return v[27].call(this,2,C,N,e,L)},qv=y[6](64,7,73,22443),uN=y[6](16,3,2467,18747),BM=y[6](84,5,41,22438),jl=y[6](16,17,108,22421),Gp=y[6](16,7,2846,20359),cM=y[6](84,4,60,22417),K0=y[6](84,2,10382,1870),v2=y[6](64,24,11,22383),A6=y[6](64,11,76,22372),s$=y[6](68,5,1990,7046),yH=y[6](64,4,99,22368),iN=y[6](68,8,39,5112),vM=y[6](16,31,74,22337),il=function(N,C,e){return H[22].call(this,1,N,C,e)},n0=y[6](64,2,90,219),Ik=y[6](68,4,9, +22333),Rk=y[6](64,5,12,22328),FE=y[6](68,10,31,17354),lN=function(N,C){return l[33].call(this,18,N,C)},Tp=y[6](68,8,3,22317),pS=y[6](84,1,4,9737),Za=function(N){return T[29].call(this,56,N)},js=y[6](16,1,23159,2015),ok=y[6](68,2,7588,8579),du=y[6](84,26,83,20303),PM=y[6](68,5,30,13038),st=y[6](16,3,59,22195),f0=y[6](16,4,111,22080),XE=y[6](16,1,8229,1848),Sl=y[6](64,4,2,22040),Yy=y[6](68,5,122,22035),u0=y[6](16,1,3375,10425),WM=y[6](64,5,115,21950),HM=y[6](16,5,734,3255),ky=y[6](16,14,52,21936),rc= +y[6](68,2,3484,3446),p0=y[6](68,4,3,21932),J6=y[6](84,2,49,3245),Et=y[6](64,23,42,21877),zp=y[6](84,4,31,21873),dc=y[6](64,13,112,21817),wc=y[6](16,6,49,21811),VH=y[6](16,6,4794,5629),Kb=y[6](64,7,61,21804),Kj=y[6](16,1,577,1759),xy=y[6](84,43,37,4020),ak=y[6](16,5,74,5209),bN=y[6](64,10,85,21790),Mv=y[6](64,3,88,21787),Ms=function(){return T[34].call(this,8)},$y=y[6](16,7,791,1702),NA=y[6](64,4,5989,21783),Cr=y[6](16,3,6,21723),eI=y[6](84,5,48,21718),Lr=y[6](68,9,104,21709),hB=y[6](16,5,64,21704), +Q2=y[6](84,2,2730,1784),Iw=y[6](84,2,47,21702),mb=y[6](84,2,8589,5669),O8=y[6](68,9,111,21651),tB=y[6](68,9,204,10642),dX=function(N,C){return I[41].call(this,1,N,C)},I5=function(){return y[5].call(this,4)},U8=y[6](84,3,5517,15161),AP=y[6](16,13,40,18295),$3=y[6](68,29,74,21574),DQ=y[6](64,4,1836,19980),qA=y[6](68,28,76,21546),ll=function(N,C,e,L){return P[49].call(this,3,C,e,N,L)},uu=y[6](64,8,82,21538),Bm=y[6](68,3,80,21535),jI=y[6](84,9,117,21526),GD=y[6](68,4,76,21479),cm=y[6](64,6,43,21473), +Kr=y[6](84,1,1170,1766),jE=y[6](84,1,13194,3542),AB=y[6](64,9,87,21360),GO=function(N){return y[32].call(this,14,N)},y2=y[6](68,4,4,21356),iu=y[6](64,12,124,21344),vm=/[#\?:]/g,yy=y[6](68,3,1390,15999),nr=y[6](84,4,731,21335),In=y[6](84,1,71,21326),Rn=function(N){return K[14].call(this,10,N)},F6=y[6](68,9,120,21267),lu=y[6](64,9,115,21258),TD=y[6](64,4,68,9155),ZQ=y[6](64,32,104,6976),Ku=y[6](68,3,14,21202),on=y[6](16,2,97,21200),Pm=y[6](16,16,117,21184),uo=y[6](16,18,4,21166),lI=function(N){return l[19].call(this, +1,N)},xt=y[6](68,4,60,21152),s8=y[6](84,3,98,21149),v7=y[6](68,5,59,21144),St=y[6](68,5,90,21108),fr=y[6](16,8,39,21100),X6=y[6](64,1,371,1757),yj=[2,3,4,5,6],SI=y[6](84,8,57,21092),C1=y[6](16,1,14135,3551),Y0=y[6](84,13,2,21068),Wm=y[6](84,8,107,18593),u6=function(N){return v[3].call(this,60,N)},Hm=y[6](68,17,111,21016),k0=y[6](84,14,48,21002),rC=y[6](64,8,29,20954),pr=y[6](64,4,79,20950),i8=y[6](68,16,121,20934),Sq=y[6](84,4,709,319),Y1=function(){return K[37].call(this,12)},JB=y[6](68,3,108,20864), +E8=y[6](84,4,94,20860),S5=y[6](68,14,2,20837),zn=y[6](84,10,13,20827),zD=y[6](68,5,2407,4923),dC=y[6](68,9,1,20633),gZ=y[6](68,29,32,20604),Uh=y[6](64,5,71,20599),yG=y[6](68,1,371,20598),wC=y[6](64,3,4,20586),r0=y[6](16,30,10,20556),Br=function(N){return K[29].call(this,14,N)},V2=y[6](84,9,438,9401),mo=/^-?([1-9][0-9]*|0)(\.[0-9]+)?$/,x0=y[6](64,5,701,5699),an=function(N){return y[6].call(this,21,N)},gC=y[6](16,7,1,20549),bu=y[6](64,12,10,20537),MA=y[6](64,4,100,20498),UY=y[6](64,6,38,15513),$0=y[6](84, +1,2038,1776),ND=y[6](84,3,2846,20359),CW=y[6](68,10,109,15697),dd=y[6](16,3,1295,16043),eu=y[6](64,6,1856,20323),LW=y[6](16,1,2149,1777),hm=y[6](68,3,64,20282),Q7=y[6](16,12,8,20269),mZ=y[6](84,8,94,19553),Oe=y[6](16,9,109,20225),tm=y[6](16,7,702,20212),Ue=y[6](64,3,4595,10902),xg=y[6](16,7,14,20199),D1=y[6](84,4,67,20195),qD=[],uB=y[6](64,6,32,20189),BA=y[6](84,2,122,20187),ju=y[6](68,12,13,4978),hF=y[6](64,10,66,20177),Hy=y[6](64,25,125,20152),Gf=y[6](84,16,29,20136),cA=y[6](64,7,1836,19980),KW= +y[6](16,2,6268,4685),Am=function(N){return W[48].call(this,69,N)},y7=y[6](84,3,114,19959),Ci=y[6](84,6,359,19953),iB=y[6](64,14,112,19936),vA=y[6](16,11,89,19925),nW=y[6](64,24,72,19901),IW=y[6](64,3,113,19821),RW=y[6](68,2,254,18404),UE=y[6](84,4,35,19811),FB=y[6](68,4,126,19807),As=function(N,C,e){return U[39].call(this,16,N,C,e)},lB=y[6](16,14,46,19793),Tf=y[6](64,9,70,19784),GP=y[6](64,9,6,19765),Z1=y[6](68,1,469,1758),f6=function(){return S[20].call(this,2)},oW=y[6](16,9,1423,18820),ZR=function(){return W[25].call(this, +8)},PA=y[6](16,15,120,19750),se=y[6](16,4,29,19746),fW=y[6](64,10,127,19736),CJ=y[6](68,1,84,19735),XB=y[6](84,5,82,19730),vH=function(N,C,e,L,h,Q,m,O,t){return I[42].call(this,16,N,h,e,C,L,Q,m,O,t)},LC=[2,3,4,5,6,8],cj=y[6](84,20,27,19710),yR=y[6](16,1,540,3415),Su=y[6](16,6,124,19648),Yb=y[6](68,11,18,19637),cv=y[6](84,2,1337,19605),WA=y[6](16,6,47,19585),HA=y[6](64,5,4093,4783),p2=y[6](68,16,33,19569),kb=y[6](68,4,94,19553),rD=y[6](16,5,37,19548),pW=y[6](64,7,69,19541),Jm=y[6](64,4,114,19537), +Ee=y[6](64,6,116,19439),zf=y[6](68,14,26,19425),Qj=function(N){return H[4].call(this,48,N)},dD=function(){return l[9].call(this,18)},wD=y[6](16,24,63,19356),V7=y[6](68,11,1760,19344),xb=y[6](68,7,67,19252),aW=y[6](84,3,2,19249),B7=[2,5],gD=y[6](84,18,15,19231),bB=y[6](16,5,11,19185),GW=y[6](64,45,100,19133),r3=y[6](84,4,58,19129),MD=y[6](64,6,35,19123),$b=y[6](16,4,14,19119),N2=y[6](68,7,88,19112),Cn=y[6](68,6,75,19106),ez=y[6](68,4,41,19071),Ln=y[6](16,8,98,19063),Fu=y[6](16,16,546,15181),hY=y[6](64, +1,2450,1781),zw=(P[31](28,40,function(N,C){return UR(function(){return N[y[14](10,8105,C)].bind(N)},null)}),function(N){return U[1].call(this,6,N)}),Qv=y[6](68,9,28,19054),mH=y[6](64,15,111,18979),l8=y[6](68,61,29,15104),Ox=y[6](64,2,823,18926),tY=y[6](84,1,11103,1878),qO=y[6](84,3,1441,10808),kj=y[6](68,24,65,18892),Ux=y[6](84,9,107,18883),Dv=y[6](84,12,113,18848),Xj=y[6](16,9,1591,3427),q2=y[6](16,8,63,18840),u3=y[6](84,6,124,18834),B$=y[6](68,2,107,18804),az=y[6](16,13,7,18791),jz=y[6](68,8,69, +18783),GR=y[6](16,4,33,18719),c$=y[6](16,20,116,18654),Kn=y[6](16,6,43,18648),AW=y[6](68,24,107,18624),AY=y[6](64,3,8,18621),yv=y[6](16,5,99,18609),i3=y[6](16,3,63,18606),v$=y[6](64,5,81,18601),nn=y[6](64,4,69,5582),Iy=y[6](84,6,701,5699),Ry=y[6](64,8,586,4487),FS=y[6](16,8,83,18580),jV=/^--.+/,l3=y[6](64,2,160,18578),TR=y[6](16,2,1962,18426),Zv=y[6](16,1,18641,1964),oy=y[6](84,5,63,10290),P$=y[6](84,3,1018,7761),sx=y[6](16,10,123,18333),fn=y[6](64,25,83,18308),XS=y[6](16,10,31,10949),Sz=y[6](68, +5,40,18295),YX=y[6](84,3,103,18292),W$=y[6](16,1,4826,1809),H$=y[6](64,8,1830,3369),J3=1923,kX=y[6](64,11,50,18281),rs=y[6](68,4,96,18244),pn=y[6](64,18,88,18127),JY=y[6](64,4,6,18123),Ex=y[6](84,24,25,18099),MX=function(N,C){return l[30].call(this,1,N,C)},zR=y[6](84,1,4319,1803),ds=y[6](68,2,4287,3039),ws=y[6](16,1,1384,17766),kW=function(N,C){var e=Array.prototype.slice.call(arguments,1);return function(){var L=e.slice();return(L.push.apply(L,arguments),N).apply(this,L)}},Vv=y[6](68,4,117,17725), +xX=y[6](68,12,126,7752),ay=y[6](64,2,2961,4513),gs=y[6](68,9,60,17716),b3=y[6](68,1,100,17715),M2=y[6](64,4,101,17711),Uz=y[6](16,54,90,17657),$X=y[6](64,5,62,17652),Ne=y[6](64,9,123,17643),yq=y[6](84,16,89,17627),CD=y[6](16,4,25,17623),B9=y[6](64,3,82,17620),e2=y[6](84,2,8449,647),Dd={},uM=y[6](68,21,89,17548),LD=y[6](68,16,38,17532),hn=y[6](16,4,35,17528),Ql=y[6](68,8,76,16979),m9=y[6](68,4,2,17463),OZ=function(N,C,e){return S[25].call(this,73,N,e,C)},On=y[6](16,5,31,17458),EB=y[6](16,30,121,17428), +tn=y[6](64,2,3727,17406),Un=y[6](84,8,232,17356),Dq=y[6](16,9,79,17345),qe=y[6](84,3,72,17308),lR=y[6](84,10,96,17298),$Y=y[6](16,45,0,17253),VY=y[6](64,7,56,17246),uq=y[6](68,1,65,17245),yg=function(N,C){var e=["concat",41,"map"],L=aq.apply(2,arguments)[e[2]](function(h){return W[0](19,h)});return P[18](31,W[39](28,S[32](20,new b4,38),N),[W[0](3,C)][e[0]](T[5](e[1],L)))},Bs=y[6](68,45,68,17200),EO=y[6](84,8,106,17117),j2=y[6](68,15,39,17096),Gw=y[6](16,6,118,17090),wA=y[6](68,3,97,17087),Gg=y[6](16, +5,658,6897),cs=y[6](68,10,31,17044),KD=y[6](16,27,78,17017),An=y[6](64,12,107,17005),yl=y[6](84,5,51,17E3),iq=y[6](68,13,121,16987),vs=y[6](84,5,233,16981),Wz=y[6](84,1,7886,1844),nD=y[6](84,14,12,16965),I8=/[#\/\?@]/g,GN=y[6](64,7,1076,16951),R8=y[6](68,6,70,16932),FU=y[6](84,4,90,16924),lq=y[6](84,6,51,16887),Tg=y[6](84,7,76,16880),Zq=y[6](64,5,80,16875),o8=y[6](16,11,58,16864),G0=y[6](16,8,113,16856),Ps=y[6](64,2,1705,3428),sn=y[6](64,4,650,13571),fD=y[6](64,2,21,16720),XU=y[6](68,6,1033,3744), +S2=y[6](64,5,65,16715),Yu=y[6](64,9,123,16706),Ws=y[6](16,8,118,16663),Hs=y[6](64,3,13,16660),ku=y[6](84,29,35,16631),pa=y[6](84,55,4,9737),dA=y[6](64,3,509,16520),r$=y[6](64,4,82,16509),pD=y[6](68,6,77,15657),Jn=y[6](16,7,64,16453),En=y[6](84,3,1132,16450),zg=y[6](84,1,3154,1789),e5=y[6](84,7,1660,4640),HZ=y[6](64,4,72,16394),d$=y[6](68,4,85,16390),w$=y[6](64,20,56,16370),bC=y[6](16,51,5,167),Vl=y[6](84,14,121,16236),xu=y[6](16,18,82,9490),a8=y[6](64,4,66,16232),g$=y[6](84,5,35,16227),bq=y[6](84, +4,37,16165),Qh=y[6](84,6,82,7051),Me=y[6](68,7,12,16147),$u=y[6](16,6,69,16141),UF=y[6](16,2,45,16139),aB=y[6](16,7,102,16132),NE=y[6](64,9,307,15521),Ce=y[6](84,12,82,16079),gX=function(N,C,e,L,h,Q,m,O,t,D){return S[3].call(this,50,N,C,e,L,h,Q,m,O,t,D)},eU=y[6](68,5,2652,16074),Le=y[6](68,2,123,16046),h7=y[6](16,6,1077,16040),QS=y[6](68,19,47,16010),md=y[6](16,8,71,15978),ad=y[6](16,11,32,15868),z_=y[6](64,48,28,15805),Bi=y[6](68,10,1156,15795),fj=function(N){return U[7].call(this,16,N)},OS=y[6](64, +6,26,15778),t7=y[6](16,6,2,762),iY=y[6](16,33,47,10392),bI=function(){return H[28].call(this,88)},US=y[6](64,20,56,15758),Dz=y[6](64,1,18500,1962),f1=y[6](68,7,74,15751),ZJ=y[6](84,1,144,1754),qE=y[6](64,8,90,15727),Ko=y[6](16,5,88,15722),ug=y[6](16,9,77,15657),Bp=y[6](64,1,101,15656),jU=y[6](84,4,2177,15652),Gq=y[6](68,4,60,13043),cp=y[6](68,3,4293,8051),jB=y[6](64,6,107,8208),QZ=function(N){return K[17].call(this,16,N)},Ke=y[6](16,8,69,15592),A7=y[6](68,8,87,15549),yS=y[6](64,4,12,15545),Pc=y[6](84, +15,9,15530),ig=y[6](16,2,619,15524),AZ=y[6](68,1,38,15513),vp=y[6](64,7,35,15506),GB=y[6](16,5,86,15501),Nh=function(){return H[14].call(this,4)},ne=y[6](16,4,86,15501),IR=y[6](64,3,38,15389),RR=y[6](64,7,554,11101),F8=y[6](16,8,29,15381),Cv=function(N,C,e,L,h,Q,m,O){return f[21].call(this,16,N,C,e,L,h,Q,m,O)},lg=y[6](68,4,18,15377),Tq=y[6](16,5,34,15372),Zz=function(N,C){var e=[5,56,18],L=aq.apply(2,arguments).map(function(h){return W[0](18,h)});return P[e[2]](e[1],W[39](12,S[32](24,new b4,e[2]), +N),[W[0](19,C)].concat(T[e[0]](39,L)))},oR=y[6](84,14,95,9441),Pp=y[6](16,1,4222,5623),sS=y[6](84,10,104,15197),fe=y[6](64,4,5101,3462),X8=y[6](16,21,91,15176),SU=y[6](64,11,52,15165),ol=y[6](68,4,3900,15144),Y2=y[6](68,19,73,15056),Wp=y[6](64,10,110,14992),Hp=y[6](16,2,121,14990),k2=y[6](68,4,20,14972),rz=y[6](16,6,4013,542),pe=y[6](84,16,74,8745),J7=y[6](68,6,4485,14902),hC=function(N){return P[27].call(this,40,N)},mC=y[6](84,5,34,14817),df=y[6](64,6,2,14801),Gt=y[6](64,17,106,14784),ES=y[6](64, +9,12,14775),eN=y[6](68,9,4508,4889),zq=y[6](64,4,94,14771),dz=y[6](84,4,59,14757),yT=y[6](16,12,1253,14745),VI=y[6](64,3,85,14729),wz=y[6](68,9,21,14699),VS=y[6](64,13,36,14686),x2=y[6](84,2,3170,13965),KM={},XF=y[6](64,5,2941,14659),aR=y[6](84,3,69,14626),gz=y[6](16,10,329,14616),i6=function(N,C){return l[33].call(this,39,N,C)},bg=y[6](68,6,712,14562),ME=y[6](64,3,2513,14533),$2=y[6](16,18,49,12465),Nb=y[6](84,4,116,14501),W1=y[6](84,8,1432,10871),Cw=y[6](64,5,122,14450),ee=y[6](16,6,62,14444),Lw= +{done:!0,value:void 0},U$=y[6](68,12,4093,4783),hT=y[6](84,4,95,14394),Qs=y[6](84,4,29,14380),m1=y[6](16,4,99,14376),O7=y[6](16,5,23,14371),u9=function(){return y[6].call(this,2)},tT=y[6](68,7,127,14312),Du=function(N){return T[33].call(this,12,N)},U7=y[6](16,5,23,14303),zH=y[6](68,30,96,14137),Dp=y[6](84,22,105,6829),qb=y[6](64,11,101,14126),uJ=y[6](16,29,8,14097),xz=function(N,C){return I[0].call(this,4,N,C)},BY=y[6](16,15,38,13917),Vj=function(){return S[41].call(this,1)},je=y[6](68,7,21,13876), +wJ=y[6](64,3,67,13873),Go=y[6](68,5,1216,12447),cY=y[6](84,4,7,13865),Kw=function(N,C,e,L,h){return y[10].call(this,15,N,C,e,L,h)},AT=y[6](68,6,98,13859),ys=y[6](84,9,30,13850),iJ=y[6](16,1,75,13849),vY=y[6](84,16,91,13833),nw=y[6](16,6,3911,10715),IK=y[6](16,15,36,13818),RK=y[6](64,8,75,9125),Fd=y[6](16,2,6597,3476),lJ=y[6](68,3,108,13641),To=y[6](84,6,68,13575),Zp=y[6](16,10,23,13565),oK=y[6](16,25,106,13540),PY=y[6](16,7,107,13533),s7=y[6](16,26,79,13507),fw=y[6](16,2,1,13260),Xd=y[6](84,6,279, +13169),Se=y[6](68,3,18,13164),xQ=y[6](64,3,96,13161),Lz=y[6](68,1,192,1755),Yh=y[6](68,4,471,13157),WY=y[6](68,14,72,13132),HY=y[6](68,16,69,1695),kh=y[6](84,11,83,13121),lH=function(N){return U[0].call(this,65,N)},rK=y[6](84,2,10798,1875),r7=y[6](64,46,29,13075),iD=y[6](84,2,60,13043),pw=y[6](84,2,30,13038),JT=y[6](84,16,55,12973),E7=y[6](84,4,11,12969),zo=y[6](68,6,112,12963),dK=y[6](68,5,890,12941),wK=y[6](64,10,89,12886),Vs=y[6](84,8,76,12878),xh=y[6](16,7,113,12871),aK=y[6](64,18,102,12807), +gK=y[6](84,8,47,12799),bJ=y[6](64,3,42,12715),DX=y[6](84,3,80,12712),ep=y[6](68,1,4577,1806),Mb=y[6](64,6,32,12706),$h=y[6](64,19,19,12687),No=y[6](64,2,0,12685),CL=y[6](68,5,113,12680),ex=y[6](68,17,47,12663),LL=function(N,C,e){return U[17].call(this,1,N,C,e)},hL=y[6](16,4,54,12659),Qm=y[6](84,2,20069,1980),mP=function(N,C,e,L,h){return I[15].call(this,41,N,L,e,h,C)},vq=y[6](64,2,324,1237),mO=y[6](16,11,52,12564),Oo=y[6](16,6,102,12505),tL=y[6](68,6,1396,12497),Uo=y[6](68,7,49,12465),qM={},qQ=y[6](16, +5,468,12460),Dt=y[6](16,20,76,12435),qo=y[6](64,8,34,12427),uZ=y[6](68,10,56,12417),Bx=function(N){return y[35].call(this,11,N)},jx=y[6](84,3,94,12414),GX=y[6](16,26,6,12388),Ca=function(N){return f[32].call(this,2,N)},cx=y[6](64,3,2314,10415),KL=y[6](16,8,57,12380),AL=y[6](16,3,71,12364),ym=y[6](16,9,69,12355),iZ=y[6](64,18,62,12273),vx=y[6](64,9,127,12264),nL=y[6](16,7,94,12248),Iv=y[6](64,4,7,12244),Rv=y[6](16,33,81,12211),Ft=y[6](64,8,61,12203),lZ=y[6](16,8,113,12195),TX=y[6](68,10,14,12185), +GY=y[6](64,6,46,12143),Zt=y[6](68,5,6,12138),ov=y[6](68,5,902,9033),Px=y[6](68,16,1,12070),so=y[6](64,4,56,12066),fL=y[6](84,10,61,12056),Xt=y[6](68,14,59,12042),Sx=y[6](16,9,82,9490),Ye=y[6](68,8,48,11991),Wx=y[6](68,8,67,11983),XG=y[6](64,7,868,11960),Hx=y[6](16,6,71,11837),ke=y[6](68,3,28,11834),ry=y[6](84,2,22525,2008),Ve=y[6](64,15,9,11787),pL=y[6](16,1,79,1753),JL=y[6](68,1,1831,1774),Eo=y[6](68,6,2864,11722),is=function(N){return T[19].call(this,1,N)},zX=y[6](68,3,78,11640),dy=y[6](16,3,4137, +2539),i4=y[6](68,3,18,11637),wy=y[6](68,4,55,11633),ow=y[6](84,6,2981,5021),Vm=y[6](16,16,66,11617),xe=y[6](68,6,4068,11569),dZ=y[6](16,13,121,11513),av=y[6](68,4,25,11509),gy=y[6](16,2,85,11507),bZ=y[6](16,2,2230,3433),Mo=y[6](64,17,44,11459),WV=function(N){return f[28].call(this,2,N)},ui=y[6](16,4,9,11455),$e=y[6](84,7,106,11448),eT=y[6](84,1,59,11441),NF=y[6](16,12,25,11324),CI=y[6](16,9,110,11315),eC=y[6](16,8,4942,11254),Nc=function(N){return v[35].call(this,88,N)},Wv=y[6](84,43,57,11161),LI= +y[6](16,6,112,11108),hg=y[6](64,12,18,11096),wZ=y[6](16,13,119,11083),nb=y[6](68,7,116,11061),Qr=function(N){return S[42].call(this,2,N)},xU=y[6](64,25,69,11028),G7=y[6](64,14,91,11014),m8=y[6](68,10,1172,10970),OM=y[6](64,4,658,10955),tg=y[6](84,12,76,10937),PZ=y[6](68,18,52,10793),UM=y[6](68,4,647,10781),D5=y[6](16,6,2994,2601),aX=y[6](84,1,205,8674),k4=y[6](64,1,3243,10673),aq=function(){for(var N=Number(this),C=[],e=N;e<arguments.length;e++)C[e-N]=arguments[e];return C},Is=y[6](84,19,124,10622), +rX=y[6](84,1,206,311),qF=y[6](68,3,16,10574),uP=y[6](84,4,103,10485),Cl=y[6](16,3,25,10476),xK=function(N,C){return I[19].call(this,2,N,C)},ST=y[6](16,37,35,10439),BO=y[6](68,11,47,10392),jC=y[6](84,40,115,10352),X3=function(){return v[48].call(this,9)},Gs=y[6](16,8,63,10290),cO=y[6](16,15,124,10177),KI=y[6](84,10,69,10167),Ag=y[6](16,4,38,10163),Sc=function(N,C){return H[21].call(this,80,N,C)},yr=y[6](16,3,39,10160),iP=y[6](68,6,67,9987),vO=y[6](84,10,100,9946),nI=y[6](68,3,3300,6524),IU=y[6](16, +7,46,9939),pN=y[6](16,5,70,9792),RU=y[6](84,2,833,9747),oe=y[6](84,8,86,9729),Fh=y[6](64,4,43,9719),lP=y[6](64,1,831,1762),Ts=y[6](64,1,3679,1795),Z5=y[6](84,3,24,9579),oU=y[6](68,2,9931,8603),PO=y[6](84,3,18,9576),sM=y[6](64,23,5,9553),fI=y[6](64,13,73,9540),Xh=y[6](84,8,70,9529),FQ=y[6](64,4,6979,8572),uY=y[6](16,7,16,9522),fx=y[6](16,6,113,9516),SC=y[6](68,4,1053,9500),YP=y[6](68,3,37,9455),WO=y[6](68,1,12631,1896),HO=y[6](16,4,39,9436),sW=y[6](84,11,3663,5028),Q5=y[6](64,12,118,9398),$E=function(N){return S[47].call(this, +34,N)},qP=y[6](16,9,126,9389),kP=y[6](84,4,69,9385),xk=y[6](16,5,802,9376),rS=y[6](64,4,114,9315),K5=y[6](64,5,68,9207),pI=y[6](16,7,38,9159),Jg=y[6](84,2,183,9156),EM=y[6](64,2,32,9153),zs=y[6](84,9,115,9144),dS=y[6](64,10,209,9134),oj=function(N){return f[25].call(this,6,N)},wS=y[6](64,4,358,9129),Vr=y[6](64,5,41,9120),bn=y[6](84,1,53,9064),xP=y[6](16,8,42,9056),aU=y[6](68,9,25,9047),kY=y[6](84,8,4606,1586),tC=function(N){return l[47].call(this,57,N)},gS=y[6](68,6,44,9038),bP=y[6](68,13,34,9025), +MF=y[6](68,20,110,9005),$P=y[6](64,7,119,8998),N_=y[6](84,1,5947,1822),C7=y[6](68,1,6731,1831),e0=y[6](16,16,19,8982),L7=y[6](84,16,41,8966),hi=y[6](68,8,48,8850),Qu=y[6](84,3,17,8847),mI=function(N){return P[12].call(this,1,N)},mw=y[6](84,23,75,8824),O0=y[6](16,12,33,8761),ti=y[6](84,8,891,8753),nA=function(N){return T[22].call(this,73,N)},tq=y[6](84,29,108,8716),U0=y[6](68,7,72,8709),De=y[6](64,1,10898,1876),q_=y[6](84,9,3595,1576),jw=function(N,C,e,L){return y[31].call(this,5,N,C,e,L)},uK=y[6](16, +10,85,8699),BF=y[6](68,3,35,8696),T3=y[6](68,14,461,8682),j0=y[6](64,5,71,8672),Gu=y[6](64,14,4,8625),cF=y[6](68,7,73,8618),K7=y[6](16,2,10816,8612),Ai=y[6](16,12,3,8488),yu=y[6](16,4,49,8484),iK=function(N,C){return f[17].call(this,2,N,C)},vF=y[6](16,28,77,8456),ib=function(N,C,e,L,h,Q,m){return v[13].call(this,1,e,N,C,L,h,Q,m)},n7=y[6](16,4,870,2943),IC=y[6](16,52,52,8404),RC=y[6](68,8,22,8396),Fr=y[6](68,2,52,8363),xv=y[6](64,3,889,3194),lK=y[6](68,9,100,8263),ph=function(){return T[11].call(this, +3)},Tu=y[6](68,4,760,3738),W8=y[6](68,12,107,8208),Ze=y[6](64,4,447,1007),oC=y[6](68,3,1555,8132),SH=y[6](16,3,104,8114),PF=y[6](84,12,3,7996),s0=y[6](64,9,89,7935),f7=y[6](64,1,8034,1846),y5=function(N,C,e,L,h,Q,m,O){return K[44].call(this,9,N,C,e,L,h,Q,m,O)},Xr=y[6](16,4,0,7819),S0=y[6](64,9,80,7774),YT=y[6](68,10,58,7764),WF=y[6](64,6,126,7752),Yx=function(N,C,e,L,h,Q,m,O,t){return S[25].call(this,28,C,e,N,L,h,Q,m,O,t)},HF=y[6](64,5,128,4482),kT=y[6](68,26,11,7676),Cc=function(N){return U[30].call(this, +1,N)},r1=y[6](84,3,91,7673),p7=y[6](64,4,23,7573),Ji=y[6](64,2,4799,7507),E0=y[6](68,17,4,7389),zu=y[6](64,3,44,1110),d1=y[6](64,5,83,7243),w1=y[6](84,9,14,7140),hs=y[6](16,5,199,7052),Vu="Int8 Uint8 Uint8Clamped Int16 Uint16 Int32 Uint32 Float32 Float64".split(" "),Wh=y[6](68,6,27,7018),xT=y[6](16,4,12,7014),kZ=y[6](84,2,28,7012),H0=y[6](68,4,47,7008),aC=y[6](68,17,1456,6991),f2=y[6](16,14,56,6962),g1=y[6](84,1,2252,1778),bK=y[6](68,11,31,6891),Co=function(N,C,e,L,h,Q){return v[33].call(this,1,L, +N,h,Q,e,C)},M_=y[6](64,11,47,6880),$T=y[6](68,6,89,6874),eD=function(N,C,e,L,h){return K[0].call(this,68,N,C,e,L,h)},gV=function(N){return v[10].call(this,1,N)},DE=y[6](16,101,36,5581),s_=[2,3],O1=y[6](64,23,106,6851),NW=y[6](16,16,105,6829),CZ=y[6](84,10,7,6819),ve=function(N){return y[24].call(this,16,N)},ey=y[6](84,3,127,6814),LZ=y[6](16,7,989,6783),ho=y[6](84,3,110,6769),Q_=y[6](64,9,52,6760),mz=y[6](16,12,14,6748),O2=y[6](16,7,76,6699),to=y[6](16,2,76,6619),U2=y[6](64,1,20,6618),TC=function(N){return I[13].call(this, +8,N)},Dn=y[6](68,30,3,6573),qW=y[6](64,25,18,6548),uk=y[6](84,16,70,6532),LN=y[6](84,7,52,6493),BD=y[6](16,1,96,6492),jy=y[6](84,4,17,6488),Gx=y[6](84,27,115,6461),vk=function(N){return v[15].call(this,5,N)},cD=y[6](68,4,5941,6394),KZ=y[6](84,11,82,6323),Ao=y[6](68,5,86,6318),y_=y[6](84,6,64,6312),ik=y[6](64,3,57,6309),vD=y[6](84,4,68,6305),nZ=y[6](68,10,111,6295),Ih=y[6](16,10,118,6285),Rh=y[6](64,5,2227,3405),Xf=y[6](16,2,4092,6238),U1=y[6](16,12,4,6187),WZ=y[6](64,4,939,6076),ut=y[6](64,4,38,6062), +FT=y[6](84,11,6,6045),lk=y[6](84,5,56,6040),Tx=y[6](68,1,7433,1838),Zn=y[6](68,18,21,5812),oh=y[6](64,4,104,4344),PD=y[6](16,5,22,5712),s2=y[6](84,3,38,5709),fZ=y[6](16,4,70,5705),XT=y[6](16,12,44,5693),sT=function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return v[3].call(this,2,N,C,e,L,h,Q,m,O,t,D,q,u,B)},Sy=y[6](16,11,122,5682),Yp=y[6](84,2,8012,5662),WD=y[6](84,8,114,5567),HD=y[6](68,9,6,5558),yM=y[6](64,5,4031,5501),kp=y[6](16,2,4,5452),Ad=y[6](64,3,84,2462),rg=y[6](84,11,18,5441),pZ=y[6](64,7,63,5434),Sb= +y[6](84,3,1159,5413),Jo=y[6](16,22,97,5380),FZ=function(N){return U[19].call(this,4,N)},E2=y[6](16,6,43,5331),zx=y[6](68,9,44,5322),dg=y[6](68,8,81,5226),wg=y[6](68,17,74,5209),V_=y[6](64,5,126,5204),xp=y[6](68,8,41,5124),ah=y[6](68,4,38,5120),gg=y[6](16,6,196,5114),bk=y[6](84,8,99,5104),MW=y[6](84,5,1802,4917),$p=y[6](84,5,759,4985),Nu=y[6](16,1,13487,1906),Ck=y[6](84,2,685,3417),e1=y[6](16,5,18,4937),Lk=y[6](84,9,83,4928),hH=y[6](84,29,38,4899),Qa=y[6](16,7,1168,4855),m0=y[6](16,2,4940,4791),OD= +y[6](68,6,106,4734),jZ=y[6](68,2,124,4732),d7=y[6](68,19,124,4713),tH=y[6](68,7,650,4612),UD=y[6](16,8,336,4538),DT=y[6](16,12,112,4516),Tc=y[6](68,35,96,4481),qu=y[6](84,2,125,4479),uL=y[6](68,6,79,4473),k5=y[6](68,11,44,4462),B5=y[6](68,9,104,4344),j1=y[6](68,8,47,4336),GI=y[6](68,3,115,4333),c5=y[6](68,4,12,4329),zW=function(N,C){return I[21].call(this,18,N,C)},Kk=function(N){return H[43].call(this,64,N)},AH=y[6](64,14,43,4315),ya=y[6](16,7,2977,4221),S6=y[6](16,12,7,4178),iL=y[6](64,9,25,4169), +v5=function(N){return H[8].call(this,22,N)},nk=y[6](68,3,0,4166),Fj=y[6](84,10,64,4156),IZ=y[6](68,6,2144,4041),RZ=y[6](64,3,102,4017),FM=y[6](16,2,5,3992),lL=y[6](68,4,117,3988),TI=y[6](84,7,2339,3963),ZT=y[6](64,3,6,3937),oZ=y[6](84,5,95,3923),P5=y[6](68,2,115,3863),sD=y[6](64,7,82,3856),fk=y[6](84,1,2933,1786),XM=y[6](64,7,74,3757),S1=y[6](68,5,126,3731),YV=y[6](68,3,4122,3622),W5=y[6](64,2,3909,3450),oX=y[6](68,27,36,3350),H5=y[6](16,3,49,3245),kV=y[6](16,4,53,3241),r9=y[6](64,10,19,3231),xr= +y[6](84,16,5,3215),pk=y[6](68,264,79,1753),JH=y[6](16,2,6,2959),ED=y[6](68,4,69,2955),UH=y[6](64,3,17,2952),zI=y[6](68,5,118,2947),d9=y[6](84,11,101,2936),w9=y[6](64,13,67,2923),Va=y[6](16,8,45,2915),xV=y[6](68,30,73,2885),aZ=y[6](84,5,63,2880),g9=y[6](16,3,96,2877),bL=y[6](68,15,36,2862),Mu={3:13,12:144,63232:38,63233:40,63234:37,63235:39,63236:112,63237:113,63238:114,63239:115,63240:116,63241:117,63242:118,63243:119,63244:120,63245:121,63246:122,63247:123,63248:44,63272:46,63273:36,63275:35,63276:33, +63277:34,63289:144,63302:45},xf=y[6](16,21,112,2841),$V=y[6](16,4,244,2800),Nd=y[6](16,11,70,2786),ZY=function(N){return P[37].call(this,39,N)},C8=y[6](16,1,4578,2617),CA=y[6](84,10,16,2490),cL=y[6](84,25,102,2465),xI=y[6](84,1,208,2464),Bc=y[6](68,31,9,2289),ma=y[6](68,42,104,2168),en=y[6](84,20,60,2148),L8=y[6](84,7,25,2125),nP=y[6](84,30,93,2095),vz=(P[31](24,45,l[47].bind(null,4)),function(N){return W[36].call(this,1,N)}),hO=y[6](84,18,82,2017),Q8=y[6](16,2,1393,1769),mF=y[6](84,12,11,1741),Ov= +y[6](84,5,54,1711),tO=y[6](84,7,1018,1704),tF=y[6](64,6,2397,1674),OR=y[6](16,6,65,1434),gj=y[6](84,39,7,1395),Uv=y[6](84,9,78,1368),D2=y[6](68,3,121,1365),qd=y[6](64,4,113,1361),u7=y[6](84,8,112,1348),yZ=y[6](64,1,1625,331),Bn=y[6](64,14,108,281),jn=y[6](68,7,73,1296),GK=y[6](16,8,81,1288),jP=y[6](84,19,4,1269),cn=y[6](68,10,11,1240),K8=y[6](84,6,89,1234),vZ=y[6](64,2,118,1232),AO=y[6](64,4,102,1228),y8=y[6](16,7,6,1221),i7=y[6](16,9,26,1160),vn=y[6](16,3,72,1117),n8=y[6](68,7,44,1110),ID=y[6](84, +14,101,1096),RD=y[6](84,8,15,1003),Fg=y[6](64,3,60,1E3),l7=y[6](16,3,19,781),TK=y[6](84,5,48,776),Z2=y[6](68,3,28,773),oD=y[6](16,5,119,768),Pn=y[6](68,4,117,763),sv=y[6](16,7,55,688),f8=y[6](84,16,94,672),Xg=y[6](16,8,62,664),Sn=y[6](64,2,3965,603),Y_=y[6](84,4,13,560),Wn=y[6](16,2,4350,545),Hn=y[6](84,3,12,476),Vi=y[6](16,1,65,309),me=function(){return S[46].call(this,11)},nz=y[6](16,5,58,304),k_=y[6](64,9,44,295),wf=y[6](84,3,108,281),rt=y[6](84,3,13,278),p8=y[6](64,15,92,263),JO=y[6](64,9,47, +227),Ev=y[6](68,2,1022,178),zK=y[6](16,17,14,52),oS=typeof Object.create=="function"?Object.create:function(N,C){return(C=function(){},C).prototype=N,new C},Yf=typeof Object.defineProperties=="function"?Object.defineProperty:function(N,C,e){if(N==Array.prototype||N==Object.prototype)return N;return N[C]=e.value,N},SE=W[22](85,0,"object","Math",this),vt=(typeof Symbol==="function"&&JL(),SE.BigInt64Array&&(Vu.push(mv()),Vu.push(lu())),Vu),Hf=function(N,C,e,L){return f[39].call(this,16,N,C,e,L)},dt= +function(N){function C(){function e(){}return new ((new e,Xe)(e,[],function(){}),e)instanceof e}if(typeof Reflect!="undefined"&&Reflect.construct){if(C())return Reflect.construct;return N=Reflect.construct,function(e,L,h,Q){return(Q=N(e,L),h)&&Z8(Q,h.prototype),Q}}return function(e,L,h,Q){return(Q=oS((h===void 0&&(h=e),h).prototype||Object.prototype),Function.prototype.apply).call(e,Q,L)||Q}}(),VD=function(){return W[5].call(this,8)},wt; +if(typeof Object.setPrototypeOf=="function")wt=Object.setPrototypeOf;else{var V8;a:{var x_={a:!0},aD={};try{(V8=aD.a,aD).__proto__=x_;break a}catch(N){}V8=!1}wt=V8?function(N,C){if(N.__proto__=C,N.__proto__!==C)throw new TypeError(N+" is not extensible");return N}:null} +var gt=typeof Object.assign=="function"?Object.assign:function(N,C){if(N==null)throw new TypeError("No nullish arg");for(var e=(N=Object(N),1);e<arguments.length;e++){var L=arguments[e];if(L)for(var h in L)l[17](12,L,h)&&(N[h]=L[h])}return N},Po=wt,Ho=(((v[21](40,"Object.assign",function(N){return N||gt}),Ca).prototype.l=function(N){this.G=N},Ca.prototype)[E0()]=function(){return this.B},Ca.prototype[Kt()]=function(){return this.G},function(){return v[47].call(this,16)}),kf=((((((((Ca.prototype[(Ca.prototype.return= +function(N){this.B=this.X,this.A={return:N}},Vz)()]=Ca.prototype.return,Ca.prototype.T=function(N,C){this.X<(this[C=["A",null,"B"],C[0]]={js:N},N)?(this[C[0]]=C[1],this[C[2]]=N):this[C[2]]=this.X},Ca).prototype[Ex()]=Ca.prototype.T,Ca.prototype.i=function(N,C){return this.B=C,{value:N}},Ca).prototype[oy()]=Ca.prototype.i,Ca.prototype.u=function(N,C,e,L,h){if(e=(L=P[h=["i",56,4],h[2]](10,N),L).next(),H[12](h[1],e),e.done)this.G=e.value,this.B=C;else return this.j=L,this[h[0]](e.value,C)},Ca).prototype[Gs()]= +Ca.prototype.u,Ca.prototype).js=function(N){this.B=N},Ca).prototype[U3()]=Ca.prototype.js,Ca.prototype).P=function(){this.B=0},Ca).prototype[dB()]=Ca.prototype.P,Ca.prototype.K=function(N,C){(this.h=N,C)!=void 0&&(this.X=C)},/[\x00\x22\x27\x3c\x3e]/g),my=(((((((((Ca.prototype[Xm()]=Ca.prototype.K,Ca.prototype).Z=function(N){(this.X=N||0,this).h=0},Ca).prototype[j2()]=Ca.prototype.Z,Ca).prototype.V=function(N,C){this.B=(this.h=C||0,N)},Ca.prototype[Y0()]=Ca.prototype.V,Ca.prototype).o=function(N,C){return this.h= +(C=this.A.Fl,this.A=null,N||0),C},Ca.prototype[C4()]=Ca.prototype.o,Ca.prototype).J=function(N,C,e,L){this.h=((L=["I","A",0],e)?this[L[0]][e]=this[L[1]]:this[L[0]]=[this[L[1]]],this[L[1]]=null,this.X=C||L[2],N||L[2])},Ca).prototype[lV()]=Ca.prototype.J,Ca.prototype).S=function(N,C,e,L,h){(e=(L=this.I.splice((h=["B","A",0],C||h[2]))[h[2]],this)[h[1]]=this[h[1]]||L)?e.W3?this[h[0]]=this.h||this.X:e.js!=void 0&&this.X<e.js?(this[h[1]]=null,this[h[0]]=e.js):this[h[0]]=this.X:this[h[0]]=N},Ca.prototype)[wg()]= +Ca.prototype.S,function(N,C){return W[43].call(this,17,N,C)}),b7=(Ca.prototype[(Ca.prototype.F=function(N){return new b7(N)},rD)()]=Ca.prototype.F,function(N,C){return f[5].call(this,1,N,C)}),p1=((((((((((((((b7.prototype[b7.prototype.B=function(N,C){for(C=["G","i",null];this[C[1]].length>0;)if(N=this[C[1]].pop(),N in this[C[0]])return N;return C[2]},Vk()]=b7.prototype.B,v[21](25,"Symbol",function(N,C,e,L,h,Q){if(Q=[0,"jscomp_symbol_","_"],N)return N;return L=(h=Q[1]+((C=(e=function(m,O){Yf(this, +"description",(this.i=m,{configurable:!0,writable:!0,value:O}))},e.prototype.toString=function(){return this.i},function(m){if(this instanceof C)throw new TypeError("Symbol is not a constructor");return new e(h+(m||"")+"_"+L++,m)}),Vn)()*1E9>>>Q[0])+Q[2],Q)[0],C}),v[21](24,"Symbol.iterator",function(N,C){if(N)return N;return Yf(Array.prototype,(C=Symbol("Symbol.iterator"),C),{configurable:!0,writable:!0,value:function(){return P[21](40,W[11](8,0,this))}}),C}),v[21](72,"Symbol.asyncIterator",function(N){return N? +N:Symbol("Symbol.asyncIterator")}),v)[21](25,"globalThis",function(N){return N||SE}),v)[21](73,"Reflect.setPrototypeOf",function(N){return N?N:Po?function(C,e){try{return Po(C,e),!0}catch(L){return!1}}:null}),v[21](89,"Promise",function(N,C,e,L,h){h=["G","prototype","j"];function Q(){this.i=null}function m(O){return O instanceof e?O:new e(function(t){t(O)})}if(N)return N;return(((C=(((((((e=(Q[Q[h[1]][h[0]]=function(O){L(O,0)},Q[h[1]].o=function(O){this.G(function(){throw O;})},h[1]].B=function(O, +t,D){this[((D=["push",null,"i"],this[D[2]]==D[1])&&(this[D[2]]=[],t=this,this.G(function(){t.K()})),D)[2]][D[0]](O)},function(O,t,D){this.G=void 0,(this[D=[!1,"o","B"],D[2]]=[],this).V=D[0],this.i=0,t=this[D[1]]();try{O(t.resolve,t.reject)}catch(q){t.reject(q)}}),e[L=SE.setTimeout,h[1]]).o=function(O,t){function D(q){return function(u){t||(t=!0,q.call(O,u))}}return{resolve:D((t=(O=this,!1),this).J),reject:D(this.K)}},Q)[h[1]].K=function(O,t,D,q){for(q=[null,"i","o"];this[q[1]]&&this[q[1]].length;)for(D= +this[q[1]],t=0,this[q[1]]=[];t<D.length;++t){D[t]=(O=D[t],q[0]);try{O()}catch(u){this[q[2]](u)}}this[q[1]]=q[0]},e[h[1]].K=function(O){this.A(O,2)},e[h[1]].J=function(O,t,D){if(D=[null,"K","object"],O===this)this[D[1]](new TypeError("A Promise cannot resolve to itself"));else if(O instanceof e)this.Y(O);else{a:switch(typeof O){case D[2]:t=O!=D[0];break a;case "function":t=!0;break a;default:t=!1}t?this.h(O):this.P(O)}},e)[h[1]].S=function(O){L(function(t){O.X()&&(t=SE.console,typeof t!=="undefined"&& +t.error(O.G))},(O=this,1))},e[h[1]]).h=function(O,t){t=void 0;try{t=O.then}catch(D){this.K(D);return}typeof t=="function"?this.Z(t,O):this.P(O)},e[h[1]][h[2]]=function(O,t){if((t=["B",0,null],this[t[0]])!=t[2]){for(O=t[1];O<this[t[0]].length;++O)C[t[0]](this[t[0]][O]);this[t[0]]=t[2]}},e)[h[1]].A=function(O,t,D){if(this[(D=["S","i","Cannot settle("],D)[1]]!=0)throw Error(D[2]+t+", "+O+"): Promise already settled in state"+this[D[1]]);(this[D[1]]=(this.G=O,t),this[D[1]]===2&&this[D[0]](),this).j()}, +e)[h[1]].P=function(O){this.A(O,1)},e[h[1]].X=function(O,t,D,q,u,B){if(this[O=[!1,"Event",(B=["V","initCustomEvent","reason"],"CustomEvent")],B[0]])return O[0];if((u=(D=SE.dispatchEvent,SE[(t=SE[O[2]],O)[1]]),typeof D)==="undefined")return!0;return(((typeof t==="function"?q=new t("unhandledrejection",{cancelable:!0}):typeof u==="function"?q=new u("unhandledrejection",{cancelable:!0}):(q=SE.document.createEvent(O[2]),q[B[1]]("unhandledrejection",O[0],!0,q)),q).promise=this,q)[B[2]]=this.G,D)(q)},new Q), +e[h[1]]).Y=function(O,t){(t=this.o(),O).OV(t.resolve,t.reject)},e)[h[1]].Z=function(O,t,D){D=this.o();try{O.call(t,D.resolve,D.reject)}catch(q){D.reject(q)}},e[h[1]].then=function(O,t,D,q,u){function B(G,c){return typeof G=="function"?function(A){try{u(G(A))}catch(n){q(n)}}:c}return D=new e(function(G,c){u=(q=c,G)}),this.OV(B(O,u),B(t,q)),D},e)[h[1]].catch=function(O){return this.then(void 0,O)},e[h[1]].OV=function(O,t,D,q){q=[null,"B","push"];function u(B){B=["i","G",2];switch(D[B[0]]){case 1:O(D[B[1]]); +break;case B[2]:t(D[B[1]]);break;default:throw Error("Unexpected state: "+D[B[0]]);}}this.V=(this[q[D=this,1]]==q[0]?C[q[1]](u):this[q[1]][q[2]](u),!0)},e.resolve=m,e.reject=function(O){return new e(function(t,D){D(O)})},e.race=function(O){return new e(function(t,D,q,u){for(q=P[4](12,O),u=q.next();!u.done;u=q.next())m(u.value).OV(t,D)})},e.all=function(O,t,D){return(t=(D=P[4](15,O),D.next()),t).done?m([]):new e(function(q,u,B,G){function c(A){return function(n){(G[B--,A]=n,B)==0&&q(G)}}G=[],B=0;do G.push(void 0), +B++,m(t.value).OV(c(G.length-1),u),t=D.next();while(!t.done)})},e}),v[21](72,"String.prototype.codePointAt",function(N){return N?N:function(C,e,L,h,Q,m,O){if((C=(e=[1024,0,(O=[51,1,null],55296)],Q=f[30](O[0],"",this,O[2],"codePointAt"),h=Q.length,Number(C)||e[O[1]]),C>=e[O[1]])&&C<h){if(L=(C|=e[O[1]],Q.charCodeAt(C)),L<e[2]||L>56319||C+O[1]===h)return L;return(m=Q.charCodeAt(C+O[1]),m)<56320||m>57343?L:(L-e[2])*e[0]+m+9216}}}),v)[21](41,"String.fromCodePoint",function(N){return N?N:function(C){for(var e= +[1023,0,"fromCharCode"],L=e[1],h=[10,65536,"invalid_code_point "],Q="";L<arguments.length;L++){var m=Number(arguments[L]);if(m<e[1]||m>1114111||m!==TH(m))throw new RangeError(h[2]+m);m<=65535?Q+=String[e[2]](m):(m-=h[1],Q+=String[e[2]](m>>>h[e[1]]&e[0]|55296),Q+=String[e[2]](m&e[0]|56320))}return Q}}),v[21](89,"WeakMap",function(N,C,e,L,h){h=["preventExtensions","has","prototype"];function Q(){}L=function(D,q,u,B,G){if(this[G=[4,"i",1],G[1]]=(C+=Vn()+G[2]).toString(),D)for(q=P[G[0]](15,D);!(u=q.next()).done;)B= +u.value,this.set(B[0],B[G[2]])};function m(D,q){return(q=typeof D,q)==="object"&&D!==null||q==="function"}function O(D,q){l[17](19,D,e)||(q=new Q,Yf(D,e,{value:q}))}function t(D,q){(q=Object[D])&&(Object[D]=function(u){if(u instanceof Q)return u;return(My(u)&&O(u),q)(u)})}if(function(D,q,u,B,G){if(!(G=["delete",(u=[!1,2,3],0),"seal"],N)||!Object[G[2]])return u[G[1]];try{if((B=new N([[(q=(D=gp({}),gp)({}),D),2],[q,3]]),B).get(D)!=u[1]||B.get(q)!=u[2])return u[G[1]];return!(B[G[0]](D),B.set(q,4),B).has(D)&& +B.get(q)==4}catch(c){return u[G[1]]}}())return N;return(((((e="$jscomp_hidden_"+Vn(),t)("freeze"),t)(h[0]),t)("seal"),C=0,L)[h[2]].set=function(D,q){if(!m(D))throw Error("Invalid WeakMap key");if(!(O(D),l)[17](15,D,e))throw Error("WeakMap key fail: "+D);return D[e][this.i]=q,this},L[h[2]].get=function(D){return m(D)&&l[17](14,D,e)?D[e][this.i]:void 0},L[h[2]])[h[1]]=function(D){return m(D)&&l[17](18,D,e)&&l[17](9,D[e],this.i)},L[h[2]]["delete"]=function(D,q){return m((q=[17,9,11],D))&&l[q[0]](q[1], +D,e)&&l[q[0]](q[2],D[e],this.i)?delete D[e][this.i]:!1},L}),v)[21](24,"Map",function(N,C,e,L,h,Q,m,O){if(O=["entries",0,"prototype"],function(t,D,q,u,B,G){if(!(u=[!1,"s",1],G=[0,2,"entries"],N)||typeof N!="function"||!N.prototype[G[2]]||typeof Object.seal!="function")return u[G[0]];try{if((t=gp({x:4}),D=new N(P[4](15,[[t,"s"]])),D.get(t)!=u[1]||D.size!=u[G[1]]||D.get({x:4})||D.set({x:4},"t")!=D)||D.size!=G[1])return u[G[0]];if((q=(B=D[G[2]](),B).next(),q).done||q.value[G[0]]!=t||q.value[u[G[1]]]!= +u[1])return u[G[0]];return(q=B.next(),q.done||q.value[G[0]].x!=4||q.value[u[G[1]]]!="t"||!B.next().done)?!1:!0}catch(c){return u[G[0]]}}())return N;return Q=O[((((L=new (e=function(t,D,q){return P[21](41,(q=t[1],function(){if(q){for(;q.head!=t[1];)q=q.uQ;for(;q.next!=q.head;)return q=q.next,{done:!1,value:D(q)};q=null}return{done:!0,value:void 0}}))},m=function(t,D,q,u,B){if((this[(B=[0,4,1],this)[B[0]]={},B[2]]=h(),this).size=B[0],t)for(q=P[B[1]](14,t);!(u=q.next()).done;)D=u.value,this.set(D[B[0]], +D[B[2]])},C=function(t,D,q,u,B,G,c,A,n,R){if((G=((q=[0,"p_",(A=D&&typeof D,R=[0,"","function"],"object")],A==q[2])||A==R[2]?L.has(D)?c=L.get(D):(n=R[1]+ ++Q,L.set(D,n),c=n):c=q[1]+D,t)[q[R[0]]][c])&&l[17](12,t[q[R[0]]],c))for(u=q[R[0]];u<G.length;u++)if(B=G[u],D!==D&&B.key!==B.key||D===B.key)return{id:c,list:G,index:u,entry:B};return{id:c,list:G,index:-1,entry:void 0}},WeakMap),m[O[2]]).set=function(t,D,q,u,B){return(q=C(this,(u=[1,(B=[0,"push",1],t=t===0?0:t,0)],t)),q).list||(q.list=this[u[B[2]]][q.id]= +[]),q.entry?q.entry.value=D:(q.entry={next:this[u[B[0]]],uQ:this[u[B[0]]].uQ,head:this[u[B[0]]],key:t,value:D},q.list[B[1]](q.entry),this[u[B[0]]].uQ.next=q.entry,this[u[B[0]]].uQ=q.entry,this.size++),this},h=function(t){return(t={},t).uQ=t.next=t.head=t},m[O[2]]["delete"]=function(t,D,q){return(D=(q=["splice",null,!1],C)(this,t),D).entry&&D.list?(D.list[q[0]](D.index,1),D.list.length||delete this[0][D.id],D.entry.uQ.next=D.entry.next,D.entry.next.uQ=D.entry.uQ,D.entry.head=q[1],this.size--,!0):q[2]}, +m[O[2]].clear=function(){this[1]=(this[0]={},this[1]).uQ=h(),this.size=0},m[O[2]]).has=function(t){return!!C(this,t).entry},m[O[2]].get=function(t,D){return(D=C(this,t).entry)&&D.value},m[O[2]])[O[0]]=function(){return e(this,function(t){return[t.key,t.value]})},m)[O[2]].keys=function(){return e(this,function(t){return t.key})},m[O[2]].values=function(){return e(this,function(t){return t.value})},m[O[2]].forEach=function(t,D,q,u,B){for(u=this.entries();!(B=u.next()).done;)q=B.value,t.call(D,q[1], +q[0],this)},m[O[2]][Symbol.iterator]=m[O[2]][O[0]],1],m}),v)[21](41,"Array.prototype.entries",function(N){return N?N:function(){return T[30](17,!1,this,function(C,e){return[C,e]})}}),v)[21](41,"Object.setPrototypeOf",function(N){return N||Po}),v)[21](25,"Symbol.dispose",function(N){return N?N:Symbol("Symbol.dispose")}),v)[21](40,"Array.prototype.find",function(N){return N?N:function(C,e){return K[17](2,0,this,C,e).P3}}),v[21](41,"Set",function(N,C,e){if(e=["add","iterator","prototype"],function(L, +h,Q,m,O,t){if((m=[!(t=[2,"add",0],1),2,1],!N||typeof N!="function"||!N.prototype.entries)||typeof Object.seal!="function")return m[t[2]];try{if(Q=new N((O=gp({x:4}),P[4](12,[O]))),!Q.has(O)||Q.size!=m[t[0]]||Q[t[1]](O)!=Q||Q.size!=m[t[0]]||Q[t[1]]({x:4})!=Q||Q.size!=m[1])return m[t[2]];if((L=Q.entries(),h=L.next(),h).done||h.value[t[2]]!=O||h.value[m[t[0]]]!=O)return m[t[2]];return h=L.next(),h.done||h.value[t[2]]==O||h.value[t[2]].x!=4||h.value[m[t[0]]]!=h.value[t[2]]?!1:L.next().done}catch(D){return m[t[2]]}}())return N; +return(((((C=function(L,h,Q){if(this.i=new Map,L)for(Q=P[4](14,L);!(h=Q.next()).done;)this.add(h.value);this.size=this.i.size},C)[e[2]][e[0]]=function(L){return this.size=(this.i.set((L=L===0?0:L,L),L),this.i.size),this},C[e[2]]["delete"]=function(L,h){return(h=this.i["delete"](L),this).size=this.i.size,h},C)[e[2]].clear=function(){this.i.clear(),this.size=0},C)[e[2]].has=function(L){return this.i.has(L)},C[e[2]]).entries=function(){return this.i.entries()},C[e[2]].values=function(){return this.i.values()}, +C[e[2]].keys=C[e[2]].values,C)[e[2]][Symbol[e[1]]]=C[e[2]].values,C[e[2]].forEach=function(L,h,Q){this.i.forEach((Q=this,function(m){return L.call(h,m,m,Q)}))},C}),v)[21](73,"Math.log2",function(N){return N?N:function(C){return pO(C)/Math.LN2}}),v[21](73,"Object.values",function(N){return N?N:function(C,e,L){for(L in e=[],C)l[17](11,C,L)&&e.push(C[L]);return e}}),v[21](25,"Array.prototype.includes",function(N){return N?N:function(C,e,L,h,Q,m){Q=((L=this,L instanceof String)&&(L=String(L)),e||0),m= +L.length;for(Q<0&&(Q=vh(Q+m,0));Q<m;Q++)if(h=L[Q],h===C||ZH(h,C))return!0;return!1}}),v[21](40,"String.prototype.includes",function(N){return N?N:function(C,e,L){return f[L=["indexOf","includes",30],L[2]](41,"",this,C,L[1])[L[0]](C,e||0)!==-1}}),v)[21](24,"Array.from",function(N){return N?N:function(C,e,L,h,Q,m,O,t,D,q){if(O=(q=(e=e!=null?e:function(u){return u},["function",(D=[],"call"),"iterator"]),typeof Symbol!="undefined"&&Symbol[q[2]])&&C[Symbol[q[2]]],typeof O==q[0])for(C=O[q[1]](C),Q=0;!(t= +C.next()).done;)D.push(e[q[1]](L,t.value,Q++));else for(m=0,h=C.length;m<h;m++)D.push(e[q[1]](L,C[m],m));return D}}),v)[21](24,"Object.entries",function(N){return N?N:function(C,e,L){for(e in L=[],C)l[17](13,C,e)&&L.push([e,C[e]]);return L}}),v)[21](72,"Number.isFinite",function(N){return N?N:function(C){return typeof C!=="number"?!1:!isNaN(C)&&C!==Infinity&&C!==-Infinity}}),v)[21](41,"Number.MAX_SAFE_INTEGER",function(){return 9007199254740991}),function(N){return y[23].call(this,2,N)}),KN=((((((v[21](88, +"Number.MIN_SAFE_INTEGER",function(){return-9007199254740991}),v)[21](88,"Number.isInteger",function(N){return N?N:function(C){return Number.isFinite(C)?C===TH(C):!1}}),v[21](40,"Number.isSafeInteger",function(N){return N?N:function(C){return Number.isInteger(C)&&Vc(C)<=Number.MAX_SAFE_INTEGER}}),v)[21](72,"String.prototype.startsWith",function(N){return N?N:function(C,e,L,h,Q,m,O,t,D){for(Q=(O=(L=(m=(h=f[30](52,(t=(D=[0,2,""],["startsWith",!1,0]),D[2]),this,C,t[D[0]]),h.length),C+=D[2],C.length), +vh(t[D[1]],RY(e|t[D[1]],h.length))),t[D[1]]);Q<L&&O<m;)if(h[O++]!=C[Q++])return t[1];return Q>=L}}),v[21](88,"String.prototype.endsWith",function(N){return N?N:function(C,e,L,h,Q,m,O){for(Q=((h=f[O=[1,(m=[0,"","endsWith"],23),30],O[2]](O[1],m[O[0]],this,C,m[2]),C+=m[O[0]],e)===void 0&&(e=h.length),L=vh(m[0],RY(e|m[0],h.length)),C).length;Q>m[0]&&L>m[0];)if(h[--L]!=C[--Q])return!1;return Q<=m[0]}}),v)[21](89,"Math.trunc",function(N){return N?N:function(C,e){if((C=Number(C),isNaN(C)||C===Infinity|| +C===-Infinity)||C===0)return C;return(e=TH(Vc(C)),C<0)?-e:e}}),v[21](89,"Math.log10",function(N){return N?N:function(C){return pO(C)/Math.LN10}}),v[21](88,"Number.isNaN",function(N){return N?N:function(C){return typeof C==="number"&&isNaN(C)}}),v)[21](88,"Array.prototype.keys",function(N){return N?N:function(){return T[30](18,!1,this,function(C){return C})}}),v[21](73,"Array.prototype.values",function(N){return N?N:function(){return T[30](16,!1,this,function(C,e){return e})}}),v[21](73,"String.prototype.repeat", +function(N){return N?N:function(C,e,L,h,Q){if((L=f[30]((h=[0,null,""],Q=[1,24,"repeat"],Q)[1],h[2],this,h[Q[0]],Q[2]),C)<h[0]||C>1342177279)throw new RangeError("Invalid count value");e=h[2];for(C|=h[0];C;)if(C&Q[0]&&(e+=L),C>>>=Q[0])L+=L;return e}}),v[21](40,"Array.prototype.findIndex",function(N){return N?N:function(C,e){return K[17](1,0,this,C,e).MW}}),v)[21](89,"Array.of",function(N){return N?N:function(C){return Array.from(arguments)}}),function(N,C,e,L,h,Q,m){return K[46].call(this,67,N,C,e, +L,h,Q,m)}),Zf=((v[21](24,"Array.prototype.flat",function(N){return N?N:function(C,e){return(C=C===(e=[],void 0)?1:C,Array.prototype.forEach).call(this,function(L,h,Q){if(Q=[1,"push","call"],Array.isArray(L)&&C>0)h=Array.prototype.flat[Q[2]](L,C-Q[0]),e[Q[1]].apply(e,h);else e[Q[1]](L)}),e}}),v)[21](72,"String.prototype.padEnd",function(N){return N?N:function(C,e,L,h,Q,m,O,t,D){return((L=(Q=(t=f[30](42,(D=(m=[null,0,""],[0,"repeat","padStart"]),m[2]),this,m[D[0]],D[2]),C)-t.length,e!==void 0)?String(e): +" ",Q>m[1]&&L)?(h=wq(Q/L.length),O=L[D[1]](h).substring(m[1],Q)):O=m[2],t)+O}}),v[21](25,"Array.prototype.fill",function(N){return N?N:function(C,e,L,h,Q,m,O){if((e<(h=(O=[0,(m=[0,null],1)],this.length||m[O[0]]),m[O[0]])&&(e=vh(m[O[0]],h+e)),L==m[O[1]])||L>h)L=h;for((L=Number(L),L<m[O[0]])&&(L=vh(m[O[0]],h+L)),Q=Number(e||m[O[0]]);Q<L;Q++)this[Q]=C;return this}}),v[47](8,null,".",0,"fill",function(N){return N?N:Array.prototype.fill}),this||self),dj=dj||{},Md=(qA(),BF(),function(N){return K[10].call(this, +16,N)}),$_=((nn(),typeof Symbol)==="function"&&GX(),function(N){return P[1].call(this,8,N)}),YQ=function(){return l[33].call(this,32)},EN="closure_uid_"+(Vn()*1E9>>>0),z0=0,Pe=function(N,C,e){var L=[null,"apply","prototype"];return(Pe=Function[L[2]].bind&&Function[L[2]].bind.toString().indexOf(q6())!=-1?x$:Wq,Pe)[L[1]](L[0],arguments)},gd=(ZD(),null),CM=null,nX=null,lY=[2,3,(T[40](27,IH,Error),4)],AF=new Map,NC=function(N,C){return T[17].call(this,41,N,C)},kU=(b6.prototype.substring=function(N,C, +e,L,h){for(L=(e-=C,h=new gd(e),0);L<e;L++)h[L]=U[39](2,3,this,N,C+L);return h},globalThis),FI=function(){return S[48].call(this,4)},aI=function(N,C,e,L){return K[5].call(this,2,N,C,e,L)},m5=function(N){return y[42].call(this,22,N)},Cf=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y){return y[3].call(this,69,N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y)},eM=function(){return I[8].call(this,1)},bw=function(N){return y[14].call(this,73,N)},sO=function(N,C,e,L,h,Q){return f[1].call(this,16,N,C,e, +L,h,Q)},iR=new Map,Lf=((((((((I[23](41),y[28](2),H)[46](57),f)[15](24),S)[43](5),U)[21](41),K)[38](10),T[22](55),f)[23](4),v)[34](2),K[33](24),P[33](3),I[6](25),U[48](10),K[47](49),T[30](1),W[6](7),{}),pB=((H[29](3),H[7](6),f)[11](1),H[3](1),f[33](1),function(N){return l[12].call(this,8,N)}),ON=Promise.resolve(),rk=function(N,C,e,L,h){return K[49].call(this,26,e,N,h,C,L)},iI=function(N){return y[44].call(this,43,N)};function sH(N,C,e){return U[3].call(this,81,N,C,e)} +(T[0](88,sH,Error),sH.prototype).name=wP();var kv;I0(); +var oq,ss=function(N){return v[25].call(this,68,N)},UL=function(N,C,e,L,h,Q,m,O){return H[32].call(this,30,N,C,e,L,h,Q,m,O)},ZX,P9=void 0,jD,T6=typeof TextDecoder!=="undefined",cQ=function(N,C){return K[14].call(this,2,N,C)},Bo=DT(),qs=typeof TextEncoder!=="undefined",uI=typeof String.prototype[Bo]==="function",n6=function(){return f[21].call(this,19)},By=String.prototype.trim?function(N){return N.trim()}:function(N){return/^[\s\xa0]*([\s\S]*?)[\s\xa0]*$/.exec(N)[1]},h2=((((P[31](16,61,P[46].bind(null, +50)),lO)(),bB)(),Tl)(),Gu(),S)[9](10,1,!1),ER=function(N){return U[14].call(this,1,N)},eZ=S[9](18,610401301,!1),q0=(S[9](19,899588437,!1),function(N){return l[47].call(this,33,N)}),Ew=(((S[9](12,772657768,!0),S)[9](11,513659523,!1),S[9](9,568333945,!0),S[9](13,1331761403,!0),S)[9](12,651175828,!1),function(){return P[48].call(this,1)}),fy=((S[9](18,722764542,!1),S)[9](19,748402145,!1),S[9](13,748402146,!1),S)[9](17,748402147,!0),Q3=((((((S[9](17,1602613185,!0),S[9](10,861377723,!1),S[9](11,861377724, +!1),S[9](14,869336903,!1),S)[9](15,882674507,!1),S[9](20,869336904,h2),S[9](14,869336905,h2),S[9](9,283953155,!1),S)[9](16,919444824,!0),S)[9](20,928875398,!0),S)[9](15,683749201,!1),S)[9](16,2147483644,!1),S[9](11,2147483645,!1),S[9](9,2147483646,h2),S[9](10,2147483647,!0),Zf.navigator),Ie,z6=(Ie=Q3?Q3.userAgentData||null:null,function(N,C,e,L,h,Q,m,O,t,D){return y[9].call(this,6,N,C,e,L,h,Q,m,O,t,D)}),xs={},xD=p8(),EH=Ls(),vQ=Gu(),V5=ef(),YU=function(N,C){return P[16].call(this,8,N,C)},dR=nY(), +wR=Tl(),Km=Cn(),A4=wO(),Yw=function(){return P[3].call(this,48)},Gk=function(N,C){return v[27].call(this,88,N,C)},RX=function(N,C,e,L,h,Q,m){return K[16].call(this,1,N,C,e,L,h,Q,m)},j5=Array.prototype.some?function(N,C){return Array.prototype.some.call(N,C,void 0)}:function(N,C,e,L,h,Q){for(L=(h=(Q=["","call",(e=N.length,"split")],typeof N==="string"?N[Q[2]](Q[0]):N),0);L<e;L++)if(L in h&&C[Q[1]](void 0,h[L],L,N))return!0;return!1},LM=function(N,C,e){return l[23](89,0,"aria-",document,arguments)}, +mA=Array.prototype.lastIndexOf?function(N,C){return Array.prototype.lastIndexOf.call(N,C,N.length-1)}:function(N,C,e,L,h){if((h=["lastIndexOf",0,1],L=N.length-h[2],L<h[1]&&(L=vh(h[1],N.length+L)),typeof N)==="string")return typeof C!=="string"||C.length!=h[2]?-1:N[h[0]](C,L);for(e=L;e>=h[1];e--)if(e in N&&N[e]===C)return e;return-1},QU=Array.prototype.forEach?function(N,C,e){Array.prototype.forEach.call(N,C,e)}:function(N,C,e,L,h,Q){for(h=(Q=(L=typeof N==="string"?N.split(""):N,N.length),0);h<Q;h++)h in +L&&C.call(e,L[h],h,N)},Zx=Array.prototype.indexOf?function(N,C){return Array.prototype.indexOf.call(N,C,void 0)}:function(N,C,e){if(typeof N==="string")return typeof C!=="string"||C.length!=1?-1:N.indexOf(C,0);for(e=0;e<N.length;e++)if(e in N&&N[e]===C)return e;return-1};function qc(N,C){for(var e=[9,0,22],L=1;L<arguments.length;L++){var h=arguments[L];if(l[e[2]](e[0],"object",h)){var Q=h.length||e[1],m=N.length||e[1];for(var O=(N.length=m+Q,e[1]);O<Q;O++)N[m+O]=h[O]}else N.push(h)}} +function mk(N,C,e,L){Array.prototype.splice.apply(N,Og(arguments,1))}function Og(N,C,e){var L=["prototype","slice","call"];return arguments.length<=2?Array[L[0]][L[1]][L[2]](N,C):Array[L[0]][L[1]][L[2]](N,C,e)} +var t2=(GZ[OY()]=function(){},S[20](71,"Opera")),qH=function(N,C,e,L,h,Q){return W[13].call(this,2,L,N,e,C,h,Q)},Ug=l[43](1,"MSIE"),DP=I[1](92,"Edge"),bj=I[1](91,"Gecko")&&!(y[48](55,"webkit",S[16](14).toLowerCase())&&!I[1](75,"Edge"))&&!(I[1](91,"Trident")||I[1](76,"MSIE"))&&!I[1](76,"Edge"),M3=y[48](48,"webkit",S[16](47).toLowerCase())&&!I[1](79,"Edge"),i0=M3&&I[1](78,"Mobile"),gw=(gs(),S[22](3)),TM=I[27](6),vy=S[47](57),At=W[37](1,"iPod","iPhone"),yc=I[1](79,"iPad"),qC=I[1](89,"iPod"),uv=P[35](24, +"iPod"),na=(((function(N,C){if(N=(C=["exec",16,46],S[C[1]](C[2])),bj)return/rv:([^\);]+)(\)|;)/[C[0]](N);if(DP)return/Edge\/([\d\.]+)/[C[0]](N);if(Ug)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/[C[0]](N);if(M3)return/WebKit\/(\S+)/[C[0]](N);if(t2)return/(?:Version)[ \/]?(\S+)/[C[0]](N)}(),Ug)&&Zf[eC()]&&Q6(),Zf[eC()])&&Ug&&Zf[eC()]&&Q6(),S)[1](20,"CriOS"),BG=T[45](16,"Safari")&&!P[35](9,"iPod"),od=BA(),jM=bj||M3,ue=function(N){return f[4].call(this,30,N)},MY=jM||!BG&&typeof Zf.atob=="function",xd=null, +v9=jM||typeof Zf.btoa=="function",Ed=[1,7],Ae=typeof Uint8Array!=="undefined",jJ=!Ug&&typeof btoa==="function",ew={"-":n_(),_:Wz(),".":js()},mf={he:{value:0,configurable:!0,writable:!0,enumerable:!1}},nh,H9=function(N,C){return U[16].call(this,32,N,C)},hw=Rv(),Cy=void 0,x1,$l=0,n2=!0,Jp=!1,F2=2,OP=2,Jd=typeof Symbol==="function"&&typeof Symbol()==="symbol",GV,cG=wC(),Kf=(GV=K[3](10,cG,void 0,!0),Nl(),jx()),NM=K[3](29,void 0,Kf),A2=(CW(),q8()),Cb=K[3](32,void 0,A2),ro=((((oP(),I2)(),ka)(),Mv)(),QS(), +K[3](11,void 0,Symbol())),y3,o5=(UX(),function(N){return I[19].call(this,6,N)}),iv=qq(),vG=(y3=K[3](30,void 0,iv),UX(),HO)(),k1=K[3](31,void 0,vG),mK,nf=(j7(),fG()),Ib={WG:!0,gW:!((mK=K[3](8,void 0,nf),k9)(),1),Wt:null},Rb=Tq(),X9=K[3](9,void 0,Rb),F7=eQ(),MI=K[3](38,F7,"ao",!0),VG,lv=(Vb(),PO()),TV=(VG=K[3](37,void 0,lv),vM(),K)[3](12),ZP=(Pm(),Pm(),$2(),function(N){return W[32].call(this,1,N)}),Qg=(($2(),ae)(Math.log2(vh.apply(null,T[5](25,Object.values({LG:1,UL:2,QX:4,lL:8,XY:16,Jq:32,ql:64,pG:128, +Y0:256,M2:512,Su:1024,QS:2048,B1:4096,CZ:8192}))))),Object).defineProperties,Rw=Jd?GV:"Fn",Fq=(W[32](16,7,qD),$4(qD)),i9=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){return S[7].call(this,80,N,C,e,L,h,Q,m,O,t,D,q,u,B,G)},$r={},NR={},ob=typeof Symbol!="undefined"&&typeof Symbol.hasInstance!="undefined",ri=(ZF.prototype.next=(ZF.prototype[Symbol.iterator]=function(){return this},function(N){return N=this.i.next(),N.done||(N.value=this.B.call(this.G,N.value)),N}),$4)({}),Ff=$4({}),rY={},kD=(Wm(),P[0](1,!0, +function(N){return typeof N==="number"})),HH=P[0](59,!0,function(N){return typeof N==="string"}),rR=P[0](2,!0,function(N){return typeof N==="boolean"}),PG=P[0](2,!0,function(N){return typeof N==="bigint"}),Vg=function(N){return S[34].call(this,16,N)},B_=typeof Zf.BigInt==="function"&&typeof Zf.BigInt(0)==="bigint",ZW=P[0](59,!0,function(N){return B_?PG(N):HH(N)&&/^(?:-?[1-9]\d*|0)$/.test(N)}),oH=P[0](60,!0,function(N,C){return(C=[!1,9,!0],B_)?N>=sg&&N<=ff:N[0]==="-"?W[C[1]](2,C[2],C[0],X7,N):W[C[1]](1, +C[2],C[0],SM,N)}),X7=Number.MIN_SAFE_INTEGER.toString(),sg=B_?BigInt(Number.MIN_SAFE_INTEGER):void 0,SM=Number.MAX_SAFE_INTEGER.toString(),ff=B_?BigInt(Number.MAX_SAFE_INTEGER):void 0,TU=0,l5=0,g3=typeof Uint8Array.prototype.slice==="function",aV,P0=(P[31](8,7,function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){for(t=!(u=(D=[89,(c=26,B=undefined,"call"),2],D)[0],1);;)try{if(c==63)break;else if(c==64)c=--L<=0?67:55;else if(c==38)B!==undefined?(c=B,B=undefined):c=23;else if(c==67)c=16;else if(c==16)u=D[0],Q&&!Q.done&& +(O=m.return)&&O[D[1]](m),c=38;else if(c==55)Q=m.next(),c=93;else if(c==22)u=43,c=50;else if(c==93)c=Q.done?16:46;else if(c==26)C=H[40](11,"g"+e,C),h=void 0,m=P[4](14,(""+N)[YB+WG](C)),Q=m.next(),c=22;else{if(c==23)return u=D[0],h&&h.length>=D[2]?h[1]:"";if(c==46)h=Q.value,c=64;else if(c==50)c=93;else if(c==25)throw G;}}catch(A){if(u==D[G=A,0])throw A;u==43&&(B=25,c=16)}}),Number.isSafeInteger),oE=Math.trunc,Ro=typeof BigInt==="function"?BigInt.asUintN:void 0,sR=typeof BigInt==="function"?BigInt.asIntN: +void 0,th=Number.isFinite,Pi=function(N,C,e){return S[22].call(this,4,N,C,e)},d6=function(N){return l[20].call(this,5,N)},vL=function(N){return T[47].call(this,2,N)},RV=MF(),IV=RV.length,kQ=function(N){return f[3].call(this,14,N)},ny=um(),vV=ny.length,F9=Y2(),gf=function(N,C,e,L){return I[37].call(this,56,N,C,e,L)},RF=F9.length,qt=function(N){return v[25].call(this,7,N)},Xo=function(N,C){return S[30].call(this,4,N,C)},af="",fq=function(N,C){return T[47].call(this,81,N,C)}; +function gR(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g){if((X=(a=K[32].bind(null,(g=[2,64,(Z=[1E3,0,1],65)],4)),y[40].bind(null,8)),e).length||L){for(E=(r=Z[1],n=Z[c=e.length-Z[g[0]],k=Z[1],1],Z)[1],x=Z[1];c>=Z[1];c--)G=e[c],L&&c===e.length-Z[g[0]]&&G===L||(x++,G!=null&&n++);if(L)for(O in L)Q=+O,isNaN(Q)||(k+=T[41](g[1],100,Z[0],Q),r++,Q>E&&(E=Q));for(z=(R=(w=(q=(u=X(x,(t=N,n))+a(r,E,k),r),e.length-Z[g[0]]),F=k,E),n);w>=Z[1];w--)d=e[w],d==null||L&&w===e.length-Z[g[0]]&&d===L|| +(Y=w-C,D=X(Y,z)+a(q,R,F),D<u&&(u=D,t=Z[g[0]]+Y),q++,z--,F+=T[41](g[2],100,Z[0],Y),R=vh(R,Y));if(m=X(Z[1],Z[1])+a(q,R,F),m<u&&(t=Z[g[0]],u=m),L)for(A in q=r,z=n,R=E,F=k,L)h=+A,isNaN(h)||h>=1024||(q--,z++,F-=A.length,J=X(h,z)+a(q,R,F),J<u&&(u=J,t=Z[g[0]]+h));B=t}else B=Z[g[0]];return B} +var La=(gR[VG]=xq,function(){return U[16].call(this,14)}),ZE=function(N){return H[15].call(this,10,N)},wo=l[30].bind(null,2),HG=function(N){try{return N=function(){return dt(Map,[],this.constructor)},T[40](3,N,Map),GZ(new N),!1}catch(C){return!0}}(),kB=(((V=WS.prototype,V).get=function(N){return this.i.get(N)},V).set=function(N,C){return this.size=(this.i.set(N,C),this.i).size,this},function(N){return f[13].call(this,12,N)}),Js=(V.forEach=function(N,C){return this.i.forEach(N,C)},V.values=function(){return this.i.values()}, +((V[V.keys=function(){return this.i.keys()},V.clear=function(){(this.i.clear(),this).size=this.i.size},"delete"]=function(N,C){return this.size=(C=this.i["delete"](N),this.i.size),C},V).has=function(N){return this.i.has(N)},V).entries=function(){return this.i.entries()},function(N){return l[24].call(this,1,N)}),Wi=(WS.prototype[Symbol.iterator]=function(){return this.entries()},function(N,C){if(C=["prototype",2,"setPrototypeOf"],HG)return Object[C[2]](WS[C[0]],Map[C[0]]),sm(WS[C[0]],{size:{value:0, +configurable:!0,enumerable:!0,writable:!0}}),WS;return T[N=function(){return dt(Map,[],this.constructor)},40](C[1],N,Map),N}()),qh=(((((((((T[40](28,z6,Wi),z6).prototype.clear=function(N){N=["call",26,2],K[N[1]](61,N[2],this),Wi.prototype.clear[N[0]](this)},z6.prototype["delete"]=function(N,C){return((C=["delete","Zs","prototype"],K)[26](59,2,this),Wi[C[2]][C[0]]).call(this,this[C[1]](N,!0,!1))},z6).prototype.entries=function(N,C,e){return this[e=["entries","call","KD"],e[2]]?(C=Wi.prototype.keys[e[1]](this), +N=new ZF(this,r2,C)):N=Wi.prototype[e[0]][e[1]](this),N},z6.prototype.values=function(N,C,e){return(e=["KD","prototype","call"],this[e[0]])?(N=Wi[e[1]].keys[e[2]](this),C=new ZF(this,z6[e[1]].get,N)):C=Wi[e[1]][VH()][e[2]](this),C},z6).prototype.forEach=function(N,C,e){e=["forEach","prototype","call"],this.KD?Wi[e[1]][e[0]][e[2]](this,function(L,h,Q){N.call(C,Q.get(h),h,Q)}):Wi[e[1]][e[0]][e[2]](this,N,C)},z6.prototype).set=function(N,C,e,L){return(N=(K[L=[(e=[null,!0,2],0),2,1],26](60,e[L[1]],this), +this).Zs(N,e[L[2]],!1),N==e[L[0]])?this:C==e[L[0]]?(Wi.prototype["delete"].call(this,N),this):Wi.prototype.set.call(this,N,this.Wn(C,e[L[2]],e[L[2]],this.KD,!1,this.Nd))},z6).prototype.has=function(N,C){return(C=["Zs","prototype",!1],Wi[C[1]].has).call(this,this[C[0]](N,C[2],C[2]))},z6.prototype).get=function(N,C,e,L,h){if(e=(N=(h=[!0,"Zs","Nd"],this[h[1]](N,!1,!1)),Wi.prototype.get).call(this,N),e!==void 0)return(L=this.KD)?(C=this.Wn(e,!1,h[0],L,this.KV,this[h[2]]),C!==e&&Wi.prototype.set.call(this, +N,C),C):e},z6).prototype[Symbol.iterator]=function(){return this.entries()},z6.prototype).toJSON=void 0,{});if(ob){var pf={};sm(l[36].bind(null,4),(pf[Symbol.hasInstance]={value:function(){throw Error(void 0);},configurable:!1,writable:!1,enumerable:!1},pf))}var bS=function(N){return U[37].call(this,4,N)};function r2(N){return y[28].call(this,13,N)} +var fv,FG={},zQ,Sr=function(N,C){return I[1].call(this,8,N,C)},AI,Kc,py=l[46](48,0),L1=function(N){return W[22].call(this,12,N)},gE=function(N){return f[27].call(this,1,N)},J2=(hl.prototype.clear=(hl.prototype.init=function(N,C,e,L,h,Q,m){this.bK=(m=(Q=(h=L===void 0?{}:L,h.eR),this.eR=Q===void 0?!1:Q,h.bK),m===void 0)?!1:m,N&&T[10](3,3,N,this,C,e)},function(N,C){(((C=(N=[0,null,!1],[2,"eR",0]),this).B=N[1],this[C[1]]=N[C[0]],this).K=N[C[0]],this).o=N[C[2]],this.i=N[C[2]],this.G=N[C[2]]}),hl.prototype.reset= +function(){this.i=this.o},/#/g),M0=function(N){return T[37].call(this,24,N)},eX=(qH.prototype.reset=function(N){(this[(this[this.G=((N=["K","i","o"],this)[N[1]].reset(),-1),N[2]]=-1,N)[0]]=this[N[1]][N[1]],this).B=-1},function(N){return P[29].call(this,12,N)}),Rf=0,QX=[],PX=/^(?!on|src|(?:action|archive|background|cite|classid|codebase|content|data|dsync|href|http-equiv|longdesc|style|usemap)\s*$)(?:[a-z0-9_$:-]*)$/i,QL=[1,(P[31](12,2,function(N){for(var C=[null,2,56],e=5,L=68,h=undefined,Q=!1,m, +O;;)try{if(e==82)break;else if(e==86)e=u.done?52:12;else if(e==12)var t=(e=11,u.value);else{if(e==36)return O;if(e==33)L=41,O=C[0],h=55,e=52;else if(e==C[2])h!==undefined?(e=h,h=undefined):e=53;else if(e==52)L=68,u&&!u.done&&(B=q.return)&&B.call(q),e=C[2];else if(e==5){var D=["","number",9434],q=P[4](11,aq.apply(1,arguments)),u=q.next(),B;e=44}else if(e==16)e=c instanceof EA?62:24;else if(e==0)e=86;else if(e==62)O=c,h=36,e=52;else{if(e==55)return O;if(e==11){var G=typeof t==(L=21,D)[1]?y[14](58,8105, +t):t,c=I[35](80,D[0],N,G);e=16}else{if(e==53)return L=68,U[4](26,D[C[1]])(N);if(e==24)N=N[G],e=30;else if(e==30)u=q.next(),e=86;else if(e==44)L=41,e=0;else if(e==10)throw m;}}}}catch(n){if(L==(m=n,68))throw n;if(L==21)var A=(e=33,n);else L==41&&(h=10,e=52)}}),2)],dk,Dy,U6,O6,ml,q1,ud,xW=function(N,C){return W[21].call(this,4,N,C)},tp,Do=[],zB,yX=((Lc.prototype.end=function(N){return this.i=(N=this.i,[]),N},Lc.prototype).length=function(){return this.i.length},function(N,C,e){var L=[null,3,71];return B8.Hn.apply(L[0], +[N,C,Sv.bind(Eg,e),e].concat(T[5](L[2],aq.apply(L[1],arguments))))}),Ht=[2,3,6],bA=f[12](15),zV=f[12](16),d2=f[12](18),XZ=function(N){return K[1].call(this,81,N)},w2=f[12](15),V3=f[12](22),xB=f[12](16),ab=f[12](18),g2=f[12](21),bv=f[12](22),MC=f[12](21),$B=f[12](17),NG=f[12](19),CV=f[12](19),e9=f[12](20),LV=f[12](20),hV=f[12](17),Py=(tv.prototype.toString=(tv.prototype[tv.prototype.G2=function(N){return QI(S[31](20,this,N))},tv.prototype.toJSON=function(){return S[31](36,this)},MI]=$r,function(){return this.z2.toString()}), +v[21](11,f[34].bind(null,27),function(N,C,e,L,h,Q){if(N[(Q=["B",!0,5],Q)[0]]!==2)return!1;return f[25](Q[2],0,h,l[7](10,Q[1],e,L,C),N),Q[1]})),ZB=v[21](10,f[34].bind(null,28),function(N,C,e,L,h,Q){if(Q=[7,14,!0],N.B!==2)return!1;return(f[25](1,0,h,l[Q[0]](Q[1],Q[2],e,L,C),N),Q)[2]}),Wf=Symbol(),FN=Symbol(),hG=Symbol(),gr=Symbol(),If=Symbol(),og,n5;P[31](24,25,function(){return aq.apply(0,arguments).map(function(N,C){return C=[56,14,8105],U[4](26,4155)(y[C[1]](C[0],C[2],N))})}); +function Fp(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){return S[6].call(this,24,N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A)} +var QF=l[46](32,0),mB=K[9](90,LV,U[36].bind(null,1),function(N,C,e,L,h,Q,m){if(Q=[3,(m=[0,"isArray",2],1),null],C!=Q[m[2]]){if(C instanceof tv){if(L=C.CU)h=L(C),h!=Q[m[2]]&&K[47](32,127,T[23](50,Q[m[0]],h,!0).buffer,e,N);else f[21](10,Q[1],Q[m[0]],mK,void 0,fG());return}if(Array[m[1]](C)){f[21](6,Q[1],Q[m[0]],mK,void 0,fG());return}}P[10](35,N,C,e)}),OI=v[21](1,function(N,C,e,L,h,Q,m,O){if(C instanceof(O=[1,38,10],z6))C.forEach(function(t,D,q){f[32](33,(q=[54,127,10],q[1]),h,e,N,v[q[2]](q[0],1,[D, +t],L))});else if(Array.isArray(C)){for(Q=0;Q<C.length;Q++)m=C[Q],Array.isArray(m)&&f[32](9,127,h,e,N,v[O[2]](O[1],O[0],m,L));y[5](O[0],8192,C)}},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){if(N.B!==(n=[!1,1,(q=[8192,0,!0],"KD")],2))return n[0];if(G=(m=(m=f[25](4,q[n[1]],h,v[10](71,n[1],[void 0,void 0],L),N),v[27](32,m)),C[Rw]|q[n[1]]),u=y[30](31,128,G),G&2)throw Error();if(t=l[14](12,u,C,e),t instanceof z6)(t.Nd&2)!=q[n[1]]?(t=K[42](56,q[0],t),t.push(m),W[26](11,G,e,C,t,u)):(D=m,A=t,O=A.Zs(D[q[n[1]]], +n[0],q[2]),c=D[n[1]],B=A[n[2]]?c===void 0?null:c:A.Wn(c,n[0],q[2],void 0,n[0],A.Nd),Wi.prototype.set.call(A,O,B));else if(Array.isArray(t))Q=t[Rw]|q[n[1]],Q&q[0]||W[32](32,Q|=q[0],t),Q&2&&(t=S[13](5,34,n[1],t),W[26](23,G,e,C,t,u)),t.push(m);else W[26](9,G,e,C,y[5](n[1],q[0],[m]),u);return q[2]}),d3=function(N){return y[42].call(this,48,N)},Cz=function(N,C){return S[26].call(this,1,N,C)},tV=K[9](90,e9,function(N,C,e,L){if(L=[11,20,15],N.B!==1)return!1;return!(H[33](30,e,K[L[0]](L[2],L[1],N.i),C),0)}, +U[1].bind(null,3)),ni=function(N,C){return K[33].call(this,2,N,C)},UI=K[9](10,e9,function(N,C,e,L,h){if(N.B!==(h=[!1,11,12],1))return h[0];return K[1](70,K[h[1]](h[2],20,N.i),L,C,e),!0},U[1].bind(null,19)),DU=K[9](82,CV,function(N,C,e,L,h,Q,m,O,t,D){if(N.B!==(D=[255,42,!1],Q=[23,8388607,2],5))return D[2];return!((m=(O=(h=(t=(L=W[0](D[1],16,N.i),L&Q[1]),(L>>31)*Q[2]+1),L>>>Q[0]&D[0]),O)==D[0]?t?NaN:h*Infinity:O==0?h*oM(Q[2],-149)*t:h*oM(Q[2],O-150)*(t+oM(Q[2],Q[0])),H)[33](30,e,m,C),0)},function(N, +C,e,L,h,Q,m,O){(L=(O=["setFloat32",22,(m=y[49](47,C),0)],[0,16,5]),m!=null)&&(v[O[1]](2,N,e,L[2]),Q=N.i,h=aV||(aV=new DataView(new ArrayBuffer(8))),h[O[0]](L[O[2]],+m,!0),TU=L[O[2]],l5=h.getUint32(L[O[2]],!0),P[8](11,L[1],l5,Q))}),qG=K[9](10,g2,function(N,C,e){return y[30](43,!0,!1,e,N,C)},P[24].bind(null,21)),u_=K[9](10,g2,function(N,C,e,L){return S[2](60,!1,!0,L,C,N,e)},P[24].bind(null,22)),Bg=K[9](74,g2,function(N,C,e){return y[30](42,!0,!1,e,N,C)},P[24].bind(null,26)),j9=U[27](51,g2,function(N, +C,e,L,h,Q){if((L=(Q=[32,31,0],v)[Q[0]](24,!1,H[3].bind(null,36),C),L)!=null)for(h=Q[2];h<L.length;h++)P[Q[1]](49,6,"number",L[h],N,e)},function(N,C,e,L,h,Q){return N.B!==(Q=[92,null,0],0)&&N.B!==2?h=!1:(L=W[18](Q[0],128,C,C[Rw]|Q[2],e),N.B==2?P[2](8,l[21].bind(Q[1],1),L,N):L.push(l[21](64,N.i)),h=!0),h}),Gy=K[9](82,g2,function(N,C,e,L,h,Q){return N.B!==(Q=[!1,33,21],0)?h=Q[0]:(L=l[Q[2]](65,N.i),H[Q[1]](30,e,L===QF?void 0:L,C),h=!0),h},P[24].bind(null,27)),cg=K[9](90,g2,function(N,C,e,L){return S[2](56, +!1,!0,L,C,N,e)},P[24].bind(null,28)),yI=function(N,C){return H[17].call(this,15,N,C)},KV=K[9](66,bv,function(N,C,e,L,h,Q){return N.B!==(Q=[!1,"i",68],0)?h=Q[0]:(K[1](Q[2],W[28](4,32,v[12].bind(null,48),N[Q[1]]),L,C,e),h=!0),h},W[43].bind(null,64)),AV=K[9](74,bv,function(N,C,e,L,h){return(h=["i",6,28],N.B)!==0?L=!1:(H[33](27,e,W[h[2]](h[1],32,v[12].bind(null,49),N[h[0]]),C),L=!0),L},W[43].bind(null,66)),yF=K[9](82,bv,function(N,C,e,L,h,Q){return(Q=[null,32,!0],N.B)!==0?L=!1:(h=W[28](7,Q[1],v[12].bind(Q[0], +52),N.i),H[33](26,e,h===QF?void 0:h,C),L=Q[2]),L},W[43].bind(null,68)),i_=K[9](10,w2,function(N,C,e,L){if(N.B!==(L=[28,!0,"i"],0))return!1;return(H[33](L[0],e,I[22](4,N[L[2]]),C),L)[1]},S[32].bind(null,41)),vg=U[27](54,w2,function(N,C,e,L,h,Q,m,O,t,D){if(L=v[D=[36,32,(t=[0,7,null],75)],D[1]](28,!0,l[D[0]].bind(null,D[2]),C),L!=t[2])for(m=t[0];m<L.length;m++)h=e,O=N,Q=L[m],Q!=t[2]&&(TH(Q),v[22](8,O,h,t[0]),W[23](1,t[1],O.i,Q))},f[36].bind(null,3)),nV=U[27](50,w2,function(N,C,e,L,h,Q,m,O){if((m=(h= +[2,(O=[!0,0,37],0),null],v[32](16,O[0],l[36].bind(null,77),C)),m)!=h[2]&&m.length){for(L=(Q=I[4](18,h[O[1]],N,e),h[1]);L<m.length;L++)TH(m[L]),W[23](4,7,N.i,m[L]);v[O[2]](38,127,N,Q)}},f[36].bind(null,7)),Iu=K[9](66,w2,function(N,C,e,L,h){if(N[h=[33,"B",26],h[1]]!==0)return!1;return L=I[22](12,N.i),H[h[0]](h[2],e,L===0?void 0:L,C),!0},S[32].bind(null,42)),RE=function(N){return l[20].call(this,1,N)},Ru=K[9](90,w2,function(N,C,e,L,h){if((h=[!1,1,!0],N.B)!==0)return h[0];return(K[h[1]](4,I[22](12,N.i), +L,C,e),h)[2]},S[32].bind(null,43)),F_=K[9](82,$B,function(N,C,e,L,h,Q,m,O){return(O=["B",!1,28],N[O[0]])!==1?Q=O[1]:(m=N.i,h=W[0](27,16,m),L=W[0](26,16,m),H[33](O[2],e,v[12](53,h,L),C),Q=!0),Q},function(N,C,e,L,h,Q,m,O,t){if(O=K[47](5,(t=[57,"number",(h=[64,"bigint",null],!1)],h[0]),t[2],C),O!=h[2])switch(W[30](81,"string",h[2],O),v[22](6,N,e,1),typeof O){case t[1]:((TH((m=N.i,O)),H[46](7,0,O),P)[8](9,16,l5,m),P)[8](10,16,TU,m);break;case h[1]:L=y[3](26,0,H9,U[33].bind(null,23),O),U[37](t[0],16,N.i, +L.i,L.B);break;default:Q=S[30](58,h[2],O),U[37](58,16,N.i,Q.i,Q.B)}}),l_=K[9](66,xB,function(N,C,e,L){if(N.B!==(L=["i",!1,43],5))return L[1];return H[33](31,e,W[0](L[2],16,N[L[0]]),C),!0},function(N,C,e,L,h){(L=P[17](28,(h=[null,22,"i"],C)),L)!=h[0]&&(v[h[1]](11,N,e,5),P[8](9,16,L,N[h[2]]))}),Ty=K[9](10,zV,function(N,C,e,L){if(N[L=["B",!0,31],L[0]]!==0)return!1;return H[33](L[2],e,f[6](58,N.i),C),L[1]},K[8].bind(null,8)),ZU=U[27](56,zV,function(N,C,e,L,h,Q){if(h=(Q=["push",null,32],v)[Q[2]](12,!0, +S[16].bind(Q[1],18),C),h!=Q[1]&&h.length)for(v[22](14,N,e,2),S[6](60,127,N.i,h.length),L=0;L<h.length;L++)N.i.i[Q[0]](h[L]?1:0)},function(N,C,e,L,h){if((h=[49,57,"B"],N[h[2]]!==0)&&N[h[2]]!==2)return!1;return N[L=W[18](94,128,C,C[Rw]|0,e),h[2]]==2?P[2](9,f[6].bind(null,h[0]),L,N):L.push(f[6](h[1],N.i)),!0}),ou=K[9](66,zV,function(N,C,e,L,h){if(N[h=[!0,"B","i"],h[1]]!==0)return!1;return((L=f[6](60,N[h[2]]),H)[33](26,e,L===!1?void 0:L,C),h)[0]},K[8].bind(null,10)),Pg=K[9](74,zV,function(N,C,e,L,h){if((h= +[6,"i",!1],N).B!==0)return h[2];return!(K[1](h[0],f[h[0]](61,N[h[1]]),L,C,e),0)},K[8].bind(null,12)),sI=K[9](74,d2,function(N,C,e,L){if(N[L=[32,!0,"B"],L[2]]!==2)return!1;return(H[33](26,e,l[39](L[0],L[1],N),C),L)[1]},T[5].bind(null,16)),fV=K[9](82,d2,function(N,C,e,L,h){if(h=[35,39,!0],N.B!==2)return!1;return L=l[h[1]](h[0],h[2],N),H[33](28,e,L===""?void 0:L,C),h[2]},T[5].bind(null,17)),X_=U[27](49,d2,function(N,C,e,L,h,Q,m,O,t,D){if((O=(L=[63,(D=[22,0,null],127),192],v)[32](8,!0,l[D[0]].bind(D[2], +12),C),O)!=D[2])for(m=D[1];m<O.length;m++)t=N,Q=e,h=O[m],h!=D[2]&&K[47](20,L[1],T[28](5,L[D[1]],L[2],h),Q,t)},function(N,C,e,L,h){if(h=[!1,91,39],N.B!==2)return h[0];return L=l[h[2]](34,!0,N),W[18](h[1],128,C,C[Rw]|0,e).push(L),!0}),S9=K[9](66,d2,function(N,C,e,L,h){if(N.B!==(h=[!0,36,39],2))return!1;return(K[1](h[1],l[h[2]](h[1],h[0],N),L,C,e),h)[0]},T[5].bind(null,18)),YF,Wg=void 0,qf=(YF=new (Wg=Wg===void 0?bA:Wg,M$)(Wg,function(N,C,e,L,h,Q,m,O){if(m=[(O=[!1,92,1],128),0,1],N.B!==2)return O[0]; +return!((Q=v[10](23,m[2],void 0,L),W[18](O[1],m[0],C,C[Rw]|m[O[2]],e)).push(Q),f[25](16,m[O[2]],h,Q,N),0)},function(N,C,e,L,h,Q,m,O){if(O=["isArray",49,0],Array[O[0]](C)){for(Q=O[2];Q<C.length;Q++)y[O[1]](18,N,C[Q],e,L,h);m=C[Rw]|O[2],m&1||W[32](24,m|1,C)}}),function(){return H[17].call(this,11)}),Hg=v[21](3,y[49].bind(null,2),function(N,C,e,L,h,Q,m,O,t,D){if(D=[68,(m=[null,0,!0],!1),30],N.B!==2)return D[1];return t=(O=C[Rw]|m[1],H[4](D[0],m[0],O,Q,y[D[2]](D[2],128,O),e,C),l[7](11,m[2],e,L,C)),f[25](20, +m[1],h,t,N),m[2]}),kF=K[9](90,LV,function(N,C,e,L){if((L=[0,!1,33],N.B)!==2)return L[1];return H[L[2]](31,e,l[39](76,L[0],N),C),!0},P[10].bind(null,32)),rv=U[27](52,LV,function(N,C,e,L,h,Q,m,O,t,D){if(L=v[h=(D=[0,1,null],[null,!1,0]),32](8,h[D[1]],H[24].bind(D[2],9),C),L!=h[D[0]])for(O=h[2];O<L.length;O++)Q=N,m=L[O],t=e,m!=h[D[0]]&&K[47](24,127,T[23](48,3,m,!0).buffer,t,Q)},function(N,C,e,L,h){if(N.B!==(h=[!0,18,0],2))return!1;return((L=l[39](75,h[2],N),W[h[1]](93,128,C,C[Rw]|h[2],e)).push(L),h)[0]}), +pV=K[9](74,LV,U[36].bind(null,8),P[10].bind(null,33)),JV=K[9](82,LV,function(N,C,e,L,h){if(h=[!1,1,"B"],N[h[2]]!==2)return h[0];return K[h[1]](6,l[39](74,0,N),L,C,e),!0},P[10].bind(null,34)),EI=K[9](66,V3,function(N,C,e,L){if(N[L=[!0,!1,"B"],L[2]]!==0)return L[1];return(H[33](27,e,y[35](22,N.i),C),L)[0]},U[16].bind(null,68)),zy=U[27](48,V3,function(N,C,e,L,h,Q,m,O){if(h=v[32]((Q=[2,0,!(O=[4,12,null],0)],O[1]),Q[2],P[17].bind(O[2],O[0]),C),h!=O[2]&&h.length){for(m=(L=I[O[0]](21,Q[0],N,e),Q)[1];m<h.length;m++)S[6](61, +127,N.i,h[m]);v[37](37,127,N,L)}},function(N,C,e,L,h){if((h=["B",null,91],N[h[0]])!==0&&N[h[0]]!==2)return!1;return!((L=W[18](h[2],128,C,C[Rw]|0,e),N[h[0]])==2?P[2](4,y[35].bind(h[1],4),L,N):L.push(y[35](31,N.i)),0)}),dv=K[9](10,V3,function(N,C,e,L,h){if(N.B!==(h=[7,!1,"i"],0))return h[1];return!(K[1](4,y[35](h[0],N[h[2]]),L,C,e),0)},U[16].bind(null,69)),fz=function(N){return v[31].call(this,4,N)},Pv=function(N){return T[31].call(this,4,N)},wv=K[9](90,hV,function(N,C,e,L){if(N[(L=["B",!1,!0],L)[0]]!== +0)return L[1];return(H[33](28,e,I[22](16,N.i),C),L)[2]},l[37].bind(null,1)),VF=U[27](53,hV,function(N,C,e,L,h,Q){if(Q=[2,0,null],L=v[32](32,!0,l[36].bind(Q[2],78),C),L!=Q[2])for(h=Q[1];h<L.length;h++)W[Q[0]](9,7,10,e,L[h],N)},f[18].bind(null,23)),xF=U[27](55,hV,function(N,C,e,L,h,Q,m,O,t,D){if((Q=[0,(D=[20,null,7],127),!0],t=v[32](D[0],Q[2],l[36].bind(D[1],79),C),t)!=D[1]&&t.length){for(L=(m=I[4](19,2,N,e),Q)[0];L<t.length;L++)O=N.i,h=t[L],TH(h),W[23](5,D[2],O,h);v[37](21,Q[1],N,m)}},f[18].bind(null, +25)),UK=function(){return W[29].call(this,25)},au=K[9](74,hV,function(N,C,e,L,h){if(N[h=[20,27,"B"],h[2]]!==0)return!1;return!(L=I[22](h[0],N.i),H[33](h[1],e,L===0?void 0:L,C),0)},l[37].bind(null,2)),DN=function(){return P[13].call(this,18)},gv=K[9](66,ab,function(N,C,e,L,h){if(N.B!==(h=[60,24,"i"],5))return!1;return!(K[1](h[0],v[35](31,h[1],N[h[2]]),L,C,e),0)},function(N,C,e,L,h,Q,m){(h=(Q=[255,(m=["i",0,5],0),16],l)[36](78,C),h)!=null&&(v[22](4,N,e,m[2]),L=N[m[0]],TH(h),L[m[0]].push(h>>>Q[1]&Q[m[1]]), +L[m[0]].push(h>>>8&Q[m[1]]),L[m[0]].push(h>>>Q[2]&Q[m[1]]),L[m[0]].push(h>>>24&Q[m[1]]))}),fC=function(N,C){return S[10].call(this,88,N,C)},b_=K[9](74,NG,function(N,C,e,L,h,Q,m,O,t){return(t=[59,30,"i"],N).B!==1?m=!1:(h=N[t[2]],O=W[0](11,16,h),L=W[0](t[0],16,h),Q=U[48](24,O,L),H[33](t[1],e,Q,C),m=!0),m},function(N,C,e,L,h,Q,m,O,t){if((O=H[3](38,(t=[null,"B",(m=[6,16,0],56)],C)),O)!=t[0])switch(K[12](12,m[0],O),v[22](5,N,e,1),typeof O){case "number":(TH((h=N.i,O)),v)[39](50,m[2],O),U[37](t[2],m[1], +h,TU,l5);break;case "bigint":L=y[3](25,m[2],my,W[14].bind(t[0],2),O),U[37](59,m[1],N.i,L.i,L[t[1]]);break;default:Q=S[30](72,m[0],O),U[37](60,m[1],N.i,Q.i,Q[t[1]])}}),MG=K[9](10,MC,function(N,C,e,L,h){return(h=["i",27,35],N.B!==0)?L=!1:(H[33](h[1],e,K[h[2]](63,32,1,31,N[h[0]]),C),L=!0),L},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((h=H[(O=(B=[3,"asUintN",0],[0,1,"bigint"]),B)[0]](37,C),h)!=null&&(K[12](10,6,h),h!=null))switch(v[22](4,N,e,O[B[2]]),typeof h){case "number":(TU=(l5=(D=(u=(t=(TH((Q=N.i,h)), +u=h,u<O[B[2]]),Vc(u))*2,H[46](15,O[B[2]],u),m=TU,l5),t&&(D==O[B[2]]?m==O[B[2]]?m=D=4294967295:(m--,D=4294967295):D--),D),m),y)[49](B[0],l5,TU,Q);break;case O[2]:y[49](35,(TU=Number(BigInt[B[1]](32,(l5=Number(BigInt[B[1]](32,(L=h<<BigInt((q=N.i,O[1]))^h>>BigInt(63),L))),L>>BigInt(32)))),l5),TU,q);break;default:W[14](33,O[B[2]],31,6,O[1],N.i,h)}}),eB=function(N,C,e,L,h,Q,m){return H[48].call(this,1,N,C,e,L,h,Q,m)},bf={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},dE=function(){return v[46].call(this,18)}, +fh=function(){return W[43].call(this,26)},IY=(P[31](8,31,l[10].bind(null,1)),function(N,C,e,L){return y[49].call(this,1,N,C,e,L)}),Np=(IN.prototype.register=function(){GZ(this)},function(N){return H[26].call(this,4,N)}),p=tv,ts=/buy|pay|place|order|donate|purchase/i,wE=function(){return T[17].call(this,16)},$F=[0,wv],Nj=[(((T[40](59,eX,p),eX.prototype).getSeconds=function(){return f[29](2,this,1)},eX.prototype).setSeconds=function(N){return U[9](2,"bigint",N,1,this)},0),Gy,Iu],Cp=[0,YF,$F,Nj,sI,Ty, +(eX.prototype.D=f[38](67,Nj),-2),wv],eA=[(T[40](6,ER,p),0),Cp,sI],YK=(ER.prototype.D=f[38](73,eA),function(N,C,e){return l[5].call(this,44,N,C,e)}),Lp=[0,kF,rv,Ty,sI],EA=function(N){return T[33].call(this,24,N)},bR=function(N){return I[15].call(this,16,N)},hz=[0,sI,YF,[0,sI,-1,ZU],DU,i_,-4,YF,[0,sI,i_],Ty,F_],QQ=[0,sI,OI,[!0,sI,hz],wv,OI,[!0,i_,hz]],mq=[0,((T[40](2,eY,p),eY.prototype).getValue=function(N,C){if((N=W[C=[1,2,"Cannot access the Any.value field on Any protos encoded using the jspb format, call unpackJspb instead"], +33](13,this,C[1]),Array.isArray(N))||N instanceof tv)throw Error(C[2]);return l[48](C[0],null,C[1],this)},fV),mB],Dw=[1,3],Oa=[0,(P[31](4,17,((eY.prototype.D=f[38](27,mq),uU).prototype.ctor=function(N){return typeof N==="boolean"?N:this.defaultValue},T)[28].bind(null,1)),T[40](26,hp,p),hp.prototype.clearValue=function(){return y[34](24,null,QL,this)},QL),S9,JV],tz=[((T[40]((hp.prototype.D=f[38](75,Oa),56),CC,p),CC).prototype.clearValue=function(){return y[34](26,null,LC,this)},0),LC,Bg,cg,Pg,UI,S9, +Hg,mq,sI,Hg,Oa],Ua="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split((CC.prototype.D=f[38](26,tz)," ")),D7=[0,sI],qj=[0,(T[40](60,MB,p),MB.prototype.H2=function(){return l[48](2,null,3,this)},D7),YF,tz,kF,-1],xw=(T[40](3,Ks,(MB.prototype.D=f[38](67,qj),p)),function(){return I[44].call(this,7)}),N1=l[12](65,"",Ks),up=[0,YF,qj],bs=T[3](9,(Ks.prototype.D=f[38](26,up),null),up,Ks),Bd=((((P[31](8,15,P[7].bind(null,33)),mu).prototype.isSafeInteger=function(N, +C){return(N=this[C=["m",0,21],C[0]]>>C[2],N)==C[1]||N==-1&&!(this.tO==C[1]&&this[C[0]]==-2097152)},mu.prototype.toString=function(N,C,e,L,h,Q,m,O,t,D,q){if((D=(L=["radix out of range: ",(q=["multiply",2,"slice"],36),0],N)||10,D)<q[1]||L[1]<D)throw Error(L[0]+D);if(this.isSafeInteger())return h=l[13](14,L[q[1]],this),D==10?""+h:h.toString(D);return m=(O=(m=(Q=(e=(t=oM(D,(C=14-(D>>q[1]),C)),v[15](20,t/4294967296,t)),this).div(e),Vc(l[13](4,L[q[1]],H[30](56,this,Q[q[0]](e))))),D==10?""+m:m.toString(D)), +O.length<C&&(O="0000000000000"[q[2]](O.length-C)+O),l)[13](10,L[q[1]],Q),(D==10?m:m.toString(D))+O},mu.prototype).Om=function(){return this.tO==0&&this.m==0},mu.prototype).equals=function(N){return N==null?!1:this.tO==N.tO&&this.m==N.m},function(N,C,e){return S[25].call(this,2,N,C,e)}),cJ=((mu.prototype.or=function(N,C){return v[(C=["tO","m",15],C)[2]](24,this[C[1]]|N[C[1]],this[C[0]]|N[C[0]])},mu).prototype.multiply=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if(G=(c=["m",0,1],[65535,16]),this.Om())return this; +if(N.Om())return N;return v[15](4,(Q=((O=(D=((Q=(D=(m=(e=(u=N[c[0]]&G[c[1]],N.tO)>>>(q=this.tO>>>(t=(C=(h=this.tO&G[c[1]],N[c[0]])>>>G[c[2]],this[c[L=this[c[0]]&G[c[1]],0]]>>>G[c[2]]),G[c[B=N.tO&G[c[1]],2]]),G[c[2]]),h*B),(m>>>G[c[2]])+q*B),D)>>>G[c[2]],D)&G[c[1]])+h*e,Q+=D>>>G[c[2]],Q+=L*B,Q>>>G[c[2]]),Q=(Q&G[c[1]])+q*e,O+=Q>>>G[c[2]],Q)&G[c[1]])+h*u,O=O+(Q>>>G[c[2]])+(t*B+L*e+q*u+h*C)&G[c[1]],O<<G[c[2]]|Q&G[c[1]]),(D&G[c[1]])<<G[c[2]]|m&G[c[1]])},(mu.prototype.xor=function(N,C){return C=["tO",20, +15],v[C[2]](C[1],this.m^N.m,this[C[0]]^N[C[0]])},(mu.prototype.div=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(G=["division by zero","m",(O=[2,0,31],27)],N.Om())throw Error(G[0]);if(this[G[1]]<O[1]){if(this.equals(kx)){if(N.equals(v1)||N.equals(jA))return kx;if(N.equals(kx))return v1;if((u=(C=v[15](16,(Q=this[G[1]],Q>>1),this.tO>>>1|Q<<O[2]),C.div(N).shiftLeft(1)),u).equals(iC))return N[G[1]]<O[1]?v1:jA;return(L=H[30](58,this,N.multiply(u)),u).add(L.div(N))}return N[G[1]]<O[1]?S[G[2]](6,this).div(S[G[2]](3, +N)):S[G[2]](2,S[G[2]](1,this).div(N))}if(this.Om())return iC;if(N[G[1]]<O[1])return N.equals(kx)?iC:S[G[2]](7,this.div(S[G[2]](5,N)));for(t=(D=iC,this);t.compare(N)>=O[1];){for(m=(B=(q=(e=(h=vh(1,TH(l[13](6,O[1],t)/l[13](12,O[1],N))),wq(pO(h)/Math.LN2)),e<=48?1:oM(O[0],e-48)),H)[12](37,h),B.multiply(N));m[G[1]]<O[1]||m.compare(t)>O[1];)h-=q,B=H[12](39,h),m=B.multiply(N);D=D.add((B.Om()&&(B=v1),B)),t=H[30](31,t,m)}return D},mu).prototype.compare=function(N,C){return(C=["m","tO",0],this[C[0]]==N[C[0]])? +this[C[1]]==N[C[1]]?0:this[C[1]]>>>C[2]>N[C[1]]>>>C[2]?1:-1:this[C[0]]>N[C[0]]?1:-1},mu.prototype.and=function(N,C){return C=["m","tO",16],v[15](C[2],this[C[0]]&N[C[0]],this[C[1]]&N[C[1]])},(mu.prototype.shiftLeft=function(N,C,e,L){if((C=[63,(L=[1,0,"m"],32),0],N&=C[L[1]],N)==C[2])return this;return(e=this.tO,N<C[L[0]])?v[15](4,this[L[2]]<<N|e>>>C[L[0]]-N,e<<N):v[15](16,e<<N-C[L[0]],C[2])},mu).prototype).add=function(N,C,e,L,h,Q,m,O,t,D,q,u){return v[15](16,(O=(C=((t=(e=(h=(L=N[q=this.m>>>(m=(this[Q= +this[D=[65535,(u=[0,1,"tO"],16)],u[2]]>>>D[u[1]],u[2]]&D[u[0]])+(N[u[2]]&D[u[0]]),D)[u[1]],u[2]]>>>D[u[1]],N).m>>>D[u[1]],N.m)&D[u[0]],this.m)&D[u[0]],m)>>>D[u[1]])+(Q+L),(C>>>D[u[1]])+(t+e)),((O>>>D[u[1]])+(q+h)&D[u[0]])<<D[u[1]]|O&D[u[0]]),(C&D[u[0]])<<D[u[1]]|m&D[u[0]])},32),QO={},iC=v[15](4,0,0),$s=function(N){return T[29].call(this,2,N)},v1=v[15](24,0,1),jA=v[15](24,-1,-1),HR=v[15](28,2147483647,4294967295),kx=v[15](4,2147483648,0),Lo=function(N){return l[22].call(this,59,N)},$d=(ZD(),IK()), +Gi=[0,fV,[0,au,Nj,(Cf.prototype.H2=function(){return this.Tm},au),-1,[0,wv],au,-1],pV],cd=[0,Gy,(((T[40](2,Yl,p),Yl).prototype.getSeconds=function(){return f[29](1,this,1)},Yl.prototype).setSeconds=function(N){return U[9](3,"bigint",N,1,this)},Iu)],BQ=function(N,C){return v[31].call(this,18,N,C)},Kp=new uU((T[40](35,tC,(Yl.prototype.D=f[38](26,cd),p)),tC.prototype.D=f[38](73,[0,Iu,fV,YF,mq]),"117100334")),Az=new uU("118980023"),TY=new uU("115490442"); +function B1(N,C){return I[3].call(this,3,N,C)} +var Ky=(B1.prototype.reset=function(){this.i=(this.G=!1,this.K)},function(N){return f[24].call(this,4,N)}),cc,ec,Es=globalThis.trustedTypes,yQ=l[9](37,(u5.prototype.toString=function(){return this.i+""},[""])),ip=f[12](14,["\x00"],["\\0"]),vd=f[12](46,["\n"],["\\n"]),np=f[12](30,["\x00"],["\\u0000"]),Nt=function(){return l[49].call(this,1)},Mh=[(T[15](77,yQ)&&T[15](75,ip)&&T[15](73,vd)&&T[15](88,np),O$.prototype.toString=function(){return this.i},S[47](83,0,"data")),S[47](19,0,"http"),S[47](51,0, +"https"),S[47](55,0,"mailto"),S[47](23,0,"ftp"),new ZL(function(N){return/^[^:]*([/?#]|$)/.test(N)})],RB=function(){return v[35].call(this,14)},ww=((Zj.prototype.toString=function(){return this.i+""},ls.prototype).toString=function(){return this.i+""},dr.prototype.toString=function(){return this.i},function(){return v[8].call(this,8)}),$5=(((((((((iJ(),BD)(),WK)(),J6)(),on)(),Hp(),qu(),P5)(),ED)(),UF)(),B$(),AT(),EM)(),String.prototype.repeat)?function(N,C){return N.repeat(C)}:function(N,C){return Array(C+ +1).join(N)};Vn();function dq(N){return T[8].call(this,34,N)} +var IA=gD(),RA=Ud(),R5=(V=dq.prototype,function(N){return y[8].call(this,6,N)}),aE=(V.remove=(dq.prototype.clear=function(N,C,e){for(C=(N=(e=[1,28,"remove"],y[e[1]](59,0,this).keys),N.length)-e[0];C>=0;C--)this[e[2]](N[C])},function(N,C,e,L){return L=this.get(N)!==void 0,this.set(N,"",{T4:0,path:C,domain:e}),L}),V.set=(dq.prototype.e2=(V.lX=function(){return y[28](27,0,this).values},function(){return y[28](31,0,this).keys}),(V.get=function(N,C,e,L,h,Q,m,O){for(Q=(m=((L=["",(O=[1,"i",0],0),"="],e= +N+L[2],this)[O[1]].cookie||L[O[2]]).split(u0()),L[O[0]]);Q<m.length;Q++){if((h=By(m[Q]),h.lastIndexOf(e,L[O[0]]))==L[O[0]])return h.slice(e.length);if(h==N)return L[O[2]]}return C},V).isEnabled=function(N){if(!(N=[!0,!1,"i"],Zf).navigator.cookieEnabled)return N[1];if(this[N[2]].cookie)return N[0];if((this.set(IA,RA,{T4:60}),this.get(IA))!==RA)return N[1];return(this.remove(IA),N)[0]},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){if(typeof e===(G=[";expires=","toUTCString",(D=["=",0,(u=!1,null)],";samesite=")], +"object")&&(q=e.sameSite,u=e.secure||!1,B=e.domain||void 0,Q=e.T4,O=e.path||void 0),/[;=\s]/.test(N))throw Error('Invalid cookie name "'+N+'"');if(/[;\r\n]/.test(C))throw Error('Invalid cookie value "'+C+'"');(t=(m=(L=(Q===(h=B?";domain="+B:"",void 0)&&(Q=-1),O?";path="+O:""),u)?L8():"",Q)<D[1]?"":Q==D[1]?G[0]+(new Date(1970,1,1))[G[1]]():G[0]+(new Date(Date.now()+Q*1E3))[G[1]](),this).i.cookie=N+D[0]+C+h+L+t+m+(q!=D[2]?G[2]+q:"")}),function(N,C,e,L,h,Q,m,O,t){return W[22].call(this,44,N,C,e,L,h, +Q,m,O,t)}),Hz=(vn(),sh(),uy()),SZ=new dq(typeof document=="undefined"?null:document),Dm=Mo(),Fn=function(N,C,e){return l[32].call(this,24,N,C,e)},qm=YS(),t_=tT(),cZ=vw(),yi=sU(),A_=Jc(),UT=h7(),Ki=dS(),OT=iB(),Li=J$(),m2=rW(),Qi=FJ(),h_=q2(),B8=(T[40](26,ss,p),{}),FO=[0,i_,wv,Bg],lp=(T[40](34,Wt,(ss.prototype.D=f[38](27,FO),p)),[0,pc,Pg,-1,cg,11,Pg]),$z=[1,2,((T[40](2,(Wt.prototype.D=f[38](67,lp),Mt),p),Mt.prototype.D=f[38](75,SO),T)[40](38,be,p),3),4,5,6,7,8,9,10,11,12,13],Ti=[0,$z,S9,u_,S9,u_,JV, +KV,JV,KV,UI,-1,Hg,Nj,-1,Hg,SO],Z7=[0,(T[40](60,(be.prototype.D=f[38](27,Ti),gu),p),P[31](4,39,I[48].bind(null,13)),YF),Ti],oA=[0,((T[40](56,(gu.prototype.D=f[38](75,Z7),Yg),p),Yg.prototype).getName=function(){return S[49](31,T[33](59,this,void 0,1,sF),this)},sF),S9,Pg],Pd=[(T[40](60,SP,(Yg.prototype.D=f[38](75,oA),p)),0),oA,lp,Z7],UR=(SP.prototype.D=f[38](26,Pd),function(N,C){return W[8].call(this,48,N,C)}),sa=(T[40](58,kg,p),[0,oA,lp,Z7]),fp=[0,1,(T[40]((kg.prototype.D=f[38](75,sa),38),Wr,p),kF), +qG,b_,1,Z7,Ty,-1],oI=function(){return H[44].call(this,4)},X1=(Wr.prototype.D=f[38](26,fp),function(N,C){return U[43].call(this,19,N,C)}),XO=[0,2,oA,lp,Z7,-1],SA=[0,wv],Ym=[0,(T[40](6,Pt,p),Ht),b_,Hg,Pd,Hg,XO,FO,sI,Hg,sa,1,Ty,wv],Wd=[((((T[Pt.prototype.D=f[38](75,Ym),40](3,gV,p),gV.prototype.D=f[38](67,[0,Ym,tV,Bg,i_,-1]),T[40](34,bS,p),bS).prototype.D=f[38](27,[0,sI,wv,i_,Bg,-1]),T)[40](58,Pv,p),Pv).prototype.D=f[38](27,kc),T[40](6,o$,p),0),s_,qG,Hg,Ym,Hg,kc,wv],Hd=[(((T[o$.prototype.D=f[38](73, +Wd),40](27,Z6,p),Z6.prototype).D=f[38](67,[0,YF,Wd]),T)[40](27,rA,p),0),sI],Us=((T[40](2,Tn,(rA.prototype.D=f[38](26,Hd),p)),T)[40](27,FP,p),[]),km=[0,i_,sI,-1,1,[-1,Lf,function(N,C,e,L,h,Q,m,O,t){t=[2,14,(Q=[0,!1,4],"K")],H[34](17,100);try{for(O=(h={},e.iA);I[13](87,Q[1],C)&&C.B!=Q[t[0]];h={bQ:void 0,Ry:void 0})if(C.o===11)h.bQ=void 0,m=C[t[2]],h.Ry=Q[1],v[30](8,Q[t[0]],Q[1],Q[0],t[0],function(D){return function(q,u,B,G,c,A,n,R){B=e[G=[null,!0,2],D.bQ=(R=["i",0,40],q),D.bQ],B==G[R[1]]&&(A=O==G[R[1]]? +void 0:O[D.bQ])&&(c=S[R[2]](32,G[R[1]],A),n=y[31](9,G[2],H[1].bind(null,45),f[37].bind(null,21),A,FN).LD,B=e[D.bQ]=function(F,Z,X){return c(l[7](13,!0,X,n,Z),F)}),B!=G[R[1]]?B(u,N,D.bQ):(u[R[0]][R[0]]=u[R[0]].G,D.Ry=G[1])}}(h),C),h.Ry&&H[17](3,null,N,h.bQ,P[t[1]](20,Q[0],m,C));else H[17](t[0],null,N,C.G,U[10](9,Q[t[0]],Q[0],C));if(L=T[1](4,N))L.Dn=e.VU[If];return!0}catch(D){if(D instanceof RangeError)throw new SyntaxError;throw D;}finally{Rf>Q[0]&&Rf--}},function(N,C){return function(e,L,h,Q,m,O, +t){(m=(Q=[null,4,(t=[23,2,7],1)],T[t[0]](3,Q[t[1]],N,L)),m!=Q[0])&&(v[22](3,e,Q[t[1]],3),v[22](t[2],e,t[1],0),W[t[0]](t[1],t[2],e.i,h),O=I[4](20,t[1],e,3),C(m,e),v[37](22,127,e,O),v[22](t[1],e,Q[t[1]],Q[1]))}}],i_],rQ=(Tn.prototype.D=f[38](27,km),[0,km]),$1=(FP.prototype.D=f[38](67,rQ),function(){return P[28].call(this,25)}),pp=[(T[40](28,fj,p),0),qG],T_=function(N){return U[4].call(this,1,N)},QT=(T[40]((fj.prototype.D=f[38](27,pp),28),SG,p),255),Jz=[0,YF,fp],Ea=[0,(SG.prototype.D=f[38](73,Jz),SA)], +zi=(T[40](59,sd,p),[0,b_]),dQ=function(N){return f[23].call(this,6,N)},wQ=(T[40]((sd.prototype.D=f[38](67,zi),28),o5,p),[0,Pr,Hg,zi,Hg,Jz,Hg,pp,1,Hg,Ea]),us=(T[40](59,R5,(o5.prototype.D=f[38](27,wQ),p)),function(N){return f[23].call(this,2,N)}),kn=function(N){return y[38].call(this,1,N)},CN=function(N,C){return f[37].call(this,4,N,C)},VQ=[0,lY,qG,Hg,wQ,Hg,rQ,Hg,[0]],xm=[0,YF,[(R5.prototype.D=f[38](73,VQ),0),qG,kF,X_,wv,-1]],aA=[0,wv,(T[40](56,kQ,p),xm)],Kh=(((T[40](6,qt,(kQ.prototype.D=f[38](26,aA), +p)),P)[31](16,4,f[37].bind(null,11)),qt).prototype.D=f[38](75,[0,YF,VQ,aA,Hd]),function(N,C,e,L){return y[45].call(this,32,N,C,e,L)}),BL=((T[40](27,yD,p),yD).prototype.D=f[38](27,[0,sI]),function(N){return T[40].call(this,7,N)}),pd=((T[40](32,iI,p),iI).prototype.D=f[38](27,[0]),function(N,C){return P[21].call(this,1,N,C)});function K2(){return H[18].call(this,6)} +var te=(K2.prototype[(xW.prototype.preventDefault=function(){this.defaultPrevented=!0},K2.prototype.U=function(){if(this.Z)for(;this.Z.length;)this.Z.shift()()},xW.prototype.i=function(){this.G=!0},K2.prototype.dispose=(K2.prototype.J=!1,function(){this.J||(this.J=!0,this.U())}),Symbol).dispose]=function(){this.dispose()},!1),Ld=function(N,C,e,L){if((L=["defineProperty","test",!1],!Zf.addEventListener)||!Object[L[0]])return L[2];e=(N=L[2],fu({},O2(),{get:function(){N=!0}}));try{C=function(){},Zf.addEventListener(L[1], +C,e),Zf.removeEventListener(L[1],C,e)}catch(h){}return N}(),PV=Sf(),gQ=(((CZ(),lZ)(),gK)(),k_)(),bp=PY(),lb=$$(),TP=Ln(),Mj=Ic(),VL=uZ(),bd=wK(),$m=SU(),q$=(((M8(),HK)(),TK)(),j1)(),oF=$e(),uA=v$(),NU=c5(),CR=xA(),eF=function(N,C,e,L){return H[13].call(this,9,e,C,L,N)},ZK=function(N,C,e){return W[39].call(this,31,N,C,e)},nu=((((FE(),Ab)(),F8)(),dI(),BE)(),It(),rB)(),LR=MW(),PQ=((A$(),ym(),oh(),Vw(),bk)(),B5(),Fh(),Tg(),sS)(),mT=(Yu(),function(N,C,e){return K[30].call(this,1,N,C,e)}),jW=function(N, +C,e,L){return H[5].call(this,1,N,C,e,L)},s1=A7(),Zw=(rg(),DG(),Xt(),tb)(),Y3=((wW(),Ul)(),oa(),JT(),HA(),DV(),cD)(),$Q=((((ei(),Vd)(),L3)(),$G)(),pD()),lz=(((bg(),e7)(),Vo(),dG)(),$P(),tk(),function(){gX.apply(this,arguments)}),GA=((((((((((((ba(),oR)(),y1)(),ZG(),pW(),H$(),sx)(),u3)(),gC(),RR)(),$S(),fL)(),O0)(),pI)(),TX)(),T$(),XT)(),Go(),G4(),KZ)(),aU(),bN(),oO()),hR=(((((o_(),El)(),OM)(),Gg(),XX)(),XS(),T9(),bK)(),Ya)(),nM=((Gp(),P)[31](16,42,function(N){return function(){return v[12](35,0,function(){return N}, +bH)}}),v_()),j6=((((((((((((((((((((((((((((TI(),tm)(),Un(),$p(),ju(),bu(),V7)(),kX)(),LT(),mO(),zs(),Bb(),d9(),Sy)(),rU)(),K4(),Dv(),gI(),aK(),UQ)(),pK)(),fI(),ky)(),mF)(),xS)(),ID)(),US)(),xG)(),za)(),f_(),lB(),AH)(),w9)(),iu)(),iQ(),vA(),fe)(),zZ)(),e0(),el(),zf)(),cb(),Qf)(),M5(),WE)(),lL)(),uh)(),Ih(),kG(),AB)(),Tp(),gz(),EJ)(),cK)(),L7)(),wr=kH();((qb(),YT(),PK(),hg)(),SQ(),IZ)(),n4();function hP(N,C,e){return P[35].call(this,11,N,C,e)} +var Qc=(((T[0](93,hP,xW),xL(),W6(),NJ(),hP).prototype.init=function(N,C,e,L,h,Q,m){(this[(this.pointerId=(this.K=(this[(this.keyCode=((this.shiftKey=N.shiftKey,this.relatedTarget=(this.state=N.state,(e=(m=[(this.ctrlKey=N.ctrlKey,"timeStamp"),(h=[0,""],"changedTouches"),(L=this.type=N.type,"altKey")],(this.metaKey=N.metaKey,N[Q=N.relatedTarget,this.B=C,m[1]])&&N[m[1]].length?N[m[1]][h[0]]:null),this.target=N.target||N.srcElement,Q)||(L==lb?Q=N.fromElement:L==TP&&(Q=N.toElement)),Q),this.button=N.button, +e)?(this.clientX=e.clientX!==void 0?e.clientX:e.pageX,this.clientY=e.clientY!==void 0?e.clientY:e.pageY,this.screenX=e.screenX||h[0],this.screenY=e.screenY||h[0]):(this.clientX=N.clientX!==void 0?N.clientX:N.pageX,this.clientY=N.clientY!==void 0?N.clientY:N.pageY,this.screenX=N.screenX||h[0],this.screenY=N.screenY||h[0]),N.keyCode||h[0]),this.key=(this.pointerType=N.pointerType,(this.O5=N,N.key)||h[1]),m)[2]]=N[m[2]],gw)?N.metaKey:N.ctrlKey,N).pointerId||h[0],m)[0]]=N[m[0]],N).defaultPrevented&&hP.L.preventDefault.call(this)}, +hP.prototype).i=function(N){hP[N=["i","O5","L"],N[2]][N[0]].call(this),this[N[1]].stopPropagation?this[N[1]].stopPropagation():this[N[1]].cancelBubble=!0},hP.prototype.preventDefault=function(N,C){(N=((C=["L","preventDefault",!1],hP[C[0]])[C[1]].call(this),this.O5),N)[C[1]]?N[C[1]]():N.returnValue=C[2]},function(N,C,e){return l[11].call(this,26,e,N,C)}),Qt=function(N,C,e,L,h,Q,m,O,t,D){return l[21].call(this,2,N,C,e,L,h,Q,m,O,t,D)},Ri="closure_listenable_"+(Vn()*1E6|0),FW=0; +function m4(N,C,e,L,h){return K[23].call(this,41,C,e,N,h,L)}var R9=function(){return K[8].call(this,18)},li=function(N,C,e){return K[20].call(this,2,N,C,e)},W0=function(N){return v[2].call(this,40,N)},O9=function(N){return v[36].call(this,32,N)};function yO(N,C){for(var e,L,h=1;h<arguments.length;h++){for(L in e=arguments[h],e)N[L]=e[L];for(var Q=0;Q<Ua.length;Q++)L=Ua[Q],Object.prototype.hasOwnProperty.call(e,L)&&(N[L]=e[L])}} +function Lx(N){var C=["isArray",1,"apply"],e=[0,1,2],L=arguments.length;if(L==e[C[1]]&&Array[C[0]](arguments[e[0]]))return Lx[C[2]](null,arguments[e[0]]);if(L%e[2])throw Error("Uneven number of arguments");for(var h=e[0],Q={};h<L;h+=e[2])Q[arguments[h]]=arguments[h+e[C[1]]];return Q}function AC(N){return y[43].call(this,13,N)} +var g7="closure_lm_"+((AC.prototype.add=function(N,C,e,L,h,Q,m,O,t,D){return m=v[(t=(Q=(D=[0,37,"i"],N.toString()),this[D[2]][Q]),t||(t=this[D[2]][Q]=[],this.B++),D)[1]](9,D[0],C,h,L,t),m>-1?(O=t[m],e||(O.bx=!1)):(O=new m4(Q,this.src,!!L,C,h),O.bx=e,t.push(O)),O},AC.prototype).remove=function(N,C,e,L,h,Q,m,O,t){if(!((m=[!1,!0,(t=["prototype",null,(O=N.toString(),1)],0)],O)in this.i))return m[0];return Q=v[h=this.i[O],37](11,m[2],C,L,e,h),Q>-1?(l[38](10,t[1],h[Q]),Array[t[0]].splice.call(h,Q,t[2]), +h.length==m[2]&&(delete this.i[O],this.B--),m[t[2]]):m[0]},Vn()*1E6|0),Rd=Fd(),Ig=function(N,C,e,L,h,Q,m){return m=["listener","handler","src"],N.UV?Q=!0:(L=new hP(C,this),h=N[m[0]],e=N[m[1]]||N[m[2]],N.bx&&y[40](4,N),Q=h.call(e,L)),Q},ag=0,ET="__closure_events_fn_"+(Vn()*1E9>>>0);v[39](37,0,function(N){Ig=N(Ig)});function TN(N){return H[32].call(this,66,N)} +var tR=(((T[0](91,TN,K2),TN.prototype.U=function(){TN.L.U.call(this),v[18](32,this)},TN.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented");},T)[0](87,oI,xW),T)[0](92,co,xW),{}),p6=((((rG(),eu)(),R0(),Iy)(),Ml(),Go)(),cA(),tB(),zK)(),Jq=Na(),aj=Pu(),g5=a0(),U9=t9(),EK=$9(),zj=jh();OL.prototype.close=(OL.prototype.send=function(N,C){(C=N.G2(),this.channel).send(C)},function(){this.state!==2&&this.channel.close()}); +var fM,D0,qU=new ss,N4=((((fM=(D0=K[23](28,1,9,qU),y)[44](10,2,D0,5),rx.prototype.equals=function(N){return this.i===N.i},qr.prototype.update=function(N,C,e){this[N=this[(C=(e=["i","max",3E5],Date.now()),e)[0]]+(C-this.B)/e[2],e[0]]>=N||(this[e[0]]=RY(N,this[e[1]]),this.B=C)},T)[40](26,Zd,Error),Qo)(),BW)(),ja(),function(N){return I[2].call(this,8,N)}),dV=(il.prototype.equals=function(N,C){return(C=["i","o","P"],N[C[2]])==this[C[2]]&&N.K==this.K&&N.B==this.B&&N.G==this.G&&N[C[1]]==this[C[1]]&&N[C[0]]== +this[C[0]]},f7()),VW=hY(),xx=iy(),z3=WO(),Ez=lP(),wV=De(),OV=((V=(il.prototype.add=function(N,C){(this[this.G+=N.G,this.P+=N.P,C=["K","o","i"],C[1]]+=N[C[1]],this)[(this.B+=N.B,C)[2]]+=N[C[2]],this[C[0]]+=N[C[0]]},il.prototype.Om=function(N,C){return(N=(C=["o","i","P"],[0]),this[C[2]]==N[0]&&this.K==N[0]&&this.B==N[0])&&this.G==N[0]&&this[C[0]]==N[0]&&this[C[1]]==N[0]},NS.prototype),V.getFullYear=function(){return this.i.getFullYear()},V.getYear=function(){return this.getFullYear()},V.getMonth=function(){return this.i.getMonth()}, +V.getDate=function(){return this.i.getDate()},V).getTime=function(){return this.i.getTime()},function(N,C,e,L){return U[49].call(this,8,C,N,e,L)}),CS=(V.getDay=function(){return this.i.getDay()},V.getUTCFullYear=((V.getUTCDate=function(){return this.i.getUTCDate()},V).getUTCMonth=function(){return this.i.getUTCMonth()},function(){return this.i.getUTCFullYear()}),function(N){return f[20].call(this,1,N)}),XI=(V=NS.prototype,/[^\{]*\{([\s\S]*)\}$/),tP=(V.getTimezoneOffset=(V.setDate=function(N){this.i.setDate(N)}, +(V.setTime=function(N){this.i.setTime(N)},V).getUTCMinutes=(V.setUTCDate=(NS.prototype.valueOf=function(){return this.i.valueOf()},function(N){this.i.setUTCDate(N)}),function(){return this.i.getUTCMinutes()}),V.add=function(N,C,e,L,h,Q,m,O,t,D){if(Q=[(D=[1,"B",3],12),99,0],N.P||N.K){(h=this.getYear()+TH((t=this.getMonth()+N.K+N.P*Q[0],t/Q[0])),t%=Q[0],t<Q[2])&&(t+=Q[0]);a:{switch(t){case D[0]:m=h%4!=Q[2]||h%100==Q[2]&&h%400!=Q[2]?28:29;break a;case 5:case 8:case 10:case D[2]:m=30;break a}m=31}(L= +RY(m,this.getDate()),this).setDate(D[0]),this.setFullYear(h),this.setMonth(t),this.setDate(L)}N[D[1]]&&(e=this.getYear(),C=e>=Q[2]&&e<=Q[D[0]]?-1900:0,O=new Date((new Date(e,this.getMonth(),this.getDate(),12)).getTime()+N[D[1]]*864E5),this.setDate(D[0]),this.setFullYear(O.getFullYear()+C),this.setMonth(O.getMonth()),this.setDate(O.getDate()),T[18](33,O.getDate(),this))},(V.toString=function(){return this.CP()},V).set=function(N){this.i=new Date(N.getFullYear(),N.getMonth(),N.getDate())},V.getUTCHours= +(V.setYear=(V.setMonth=(V.CP=function(N,C,e,L,h){return C=(h=(L=this.getFullYear(),[0,(e=["",1,2],38),"getDate"]),L)<h[0]?yR():L>=1E4?n_():"",[C+H[h[1]](24,C?6:4,Vc(L)),H[h[1]](20,e[2],this.getMonth()+e[1]),H[h[1]](28,e[2],this[h[2]]())].join(N?yR():"")+e[h[0]]},V.setUTCFullYear=function(N){this.i.setUTCFullYear(N)},function(N){this.i.setMonth(N)}),V.equals=function(N,C){return!((C=["getYear","getMonth","getDate"],!N||this[C[0]]()!=N[C[0]]()||this[C[1]]()!=N[C[1]]())||this[C[2]]()!=N[C[2]]())},V.setUTCMonth= +function(N){this.i.setUTCMonth(N)},function(N){this.setFullYear(N)}),V.getUTCDay=function(){return this.i.getDay()},V.setFullYear=function(N){this.i.setFullYear(N)},function(){return this.i.getUTCHours()}),function(){return this.i.getTimezoneOffset()}),function(N,C,e,L,h){return U[27].call(this,10,e,L,N,C,h)}),ux=(((((((((((((((((((((((T[0](90,y5,NS),V=y5.prototype,V).getHours=function(){return this.i.getHours()},V).getMinutes=function(){return this.i.getMinutes()},V).getSeconds=function(){return this.i.getSeconds()}, +V.getMilliseconds=function(){return this.i.getMilliseconds()},V.getUTCDay=function(){return this.i.getUTCDay()},V.getUTCHours=function(){return this.i.getUTCHours()},V=y5.prototype,V.getUTCMinutes=function(){return this.i.getUTCMinutes()},V).getUTCSeconds=function(){return this.i.getUTCSeconds()},V.getUTCMilliseconds=function(){return this.i.getUTCMilliseconds()},V).setHours=function(N){this.i.setHours(N)},V).setMinutes=function(N){this.i.setMinutes(N)},V.setSeconds=function(N){this.i.setSeconds(N)}, +V).setMilliseconds=function(N){this.i.setMilliseconds(N)},V.setUTCHours=function(N){this.i.setUTCHours(N)},V).setUTCMinutes=function(N){this.i.setUTCMinutes(N)},V.setUTCSeconds=function(N){this.i.setUTCSeconds(N)},V).setUTCMilliseconds=function(N){this.i.setUTCMilliseconds(N)},V).add=function(N,C){(((NS.prototype.add.call((C=["G","o","getUTCSeconds"],this),N),N[C[0]])&&this.setUTCHours(this.i.getUTCHours()+N[C[0]]),N[C[1]])&&this.setUTCMinutes(this.i.getUTCMinutes()+N[C[1]]),N.i)&&this.setUTCSeconds(this.i[C[2]]()+ +N.i)},V).CP=function(N,C,e,L){return(C=NS.prototype.CP.call(this,(e=(L=[0,38,22],[2,":","T"]),N)),N)?C+e[2]+H[L[1]](18,e[L[0]],this.getHours())+e[1]+H[L[1]](32,e[L[0]],this.getMinutes())+e[1]+H[L[1]](26,e[L[0]],this.getSeconds()):C+e[2]+H[L[1]](L[2],e[L[0]],this.getHours())+H[L[1]](18,e[L[0]],this.getMinutes())+H[L[1]](30,e[L[0]],this.getSeconds())},V.equals=function(N){return this.getTime()==N.getTime()},V).toString=function(){return this.CP()},Cz.prototype).equals=function(N){return this.i===N.i&& +this.B===N.B},N0.prototype.equals=function(N){return this.value.equals(N.value)},hr).prototype.equals=function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(this.value===(B=(Q=[!1,0,!0],["equals","i",0]),null))u=N.value===null;else{if(this.value instanceof rx)t=N.value instanceof rx?this.value[B[0]](N.value):!1;else{if(this[B[1]]!==N[B[1]])L=Q[B[2]];else{if(typeof this.value==="string"||typeof this.value==="number")m=this.value===N.value;else{if(this.value instanceof mu)O=N.value instanceof mu?this.value[B[0]](N.value): +!1;else{if(this.value instanceof Uint8Array){if(N.value instanceof Uint8Array)a:if(C=this.value,h=N.value,C.length!==h.length)q=Q[B[2]];else{for(D=Q[1];D<C.length;++D)if(C[D]!==h[D]){q=Q[B[2]];break a}q=Q[2]}else q=Q[B[2]];e=q}else e=this.value instanceof Cz?N.value instanceof Cz?this.value[B[0]](N.value):!1:this.value instanceof N0?N.value instanceof N0?this.value[B[0]](N.value):!1:!1;O=e}m=O}L=m}t=L}u=t}return u},Xn).prototype.equals=function(N,C,e,L){if(C=(L=["B","i",!0],this[L[1]].length===N[L[1]].length))a:if(this[L[0]]!== +N[L[0]]||this[L[1]].length>N[L[1]].length)C=!1;else{for(e=0;e<this[L[1]].length;++e)if(!this[L[1]][e].equals(N[L[1]][e])){C=!1;break a}C=L[2]}return C},b0.prototype.equals=function(N){return this.i.equals(N.i)},P)[31](16,32,U[14].bind(null,16)),T)[40](28,bO,Error),V=oo.prototype,V).unsubscribe=function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(!(B=[57,"unsubscribe",3],this.closed)){if(Array.isArray((h=this.B,this.closed=!0,h))){L=P[4](14,h),D=L.next();try{for(;!D.done;D=L.next())D.value.remove(this)}finally{D&& +!D.done&&(O=L.return)&&O.call(L)}}else h==null||h.remove(this);if(K[15]((t=this.o,B)[2],t))try{t()}catch(G){u=G instanceof bO?G.errors:[G]}if(N=this.G){Q=(q=P[4](14,(this.G=null,N)),q.next());try{for(;!Q.done;Q=q.next()){e=Q.value;try{K[15](2,e)?e():e[B[1]]()}catch(G){m=void 0,u=(m=u)!=null?m:[],G instanceof bO?u=[].concat(T[5](39,u),T[5](B[0],G.errors)):u.push(G)}}}finally{Q&&!Q.done&&(C=q.return)&&C.call(q)}}if(u)throw new bO(u);}},V).add=function(N,C,e){if(e=[2,"closed",null],N&&N!==this)if(this[e[1]])K[15](e[0], +N)?N():N.unsubscribe();else{if(N instanceof oo){if(N[e[1]]||N.O8(this))return;N.bU(this)}(this.G=(C=this.G)!=e[2]?C:[]).push(N)}},V.bU=function(N,C){return v[4].call(this,6,N,C)},V).O8=function(N,C){return H[6].call(this,50,N,C)},V).L8=function(N,C){return K[6].call(this,9,N,C)},V).remove=function(N,C){((C=this.G)&&K[45](36,1,C,N),N)instanceof oo&&N.L8(this)},new oo),NI=((((V=((T[40](26,$s,(ux.closed=!0,oo.i=ux,oo)),$s).i=oo.i,$s.create=function(N,C,e){return new iA(N,C,e)},$s.prototype),V.next=function(N){this.i|| +this.rO(N)},V).error=function(N){this.i||(this.i=!0,this.x_(N))},V.complete=function(){this.i||(this.i=!0,this.GD())},V).unsubscribe=function(N){(N=["i","unsubscribe","call"],this).closed||(this[N[0]]=!0,oo.prototype[N[1]][N[2]](this))},V).rO=function(N){this.destination.next(N)},function(N){return v[41].call(this,8,N)}),Ob=((T[40](59,iA,(NI.prototype.error=(NI.prototype.complete=function(N){if((N=this.i,N).complete)try{N.complete()}catch(C){H[10](21,C)}},function(N,C){if(C=this.i,C.error)try{C.error(N)}catch(e){H[10](17, +e)}else H[10](19,N)}),NI.prototype.next=function(N,C){if((C=this.i,C).next)try{C.next(N)}catch(e){H[10](18,e)}},(V.GD=function(){(this.destination.complete(),this).unsubscribe()},V).x_=function(N){(this.destination.error(N),this).unsubscribe()},$s)),iA.i=$s.i,iA).create=$s.create,typeof Symbol==="function")&&Symbol.observable||"@@observable",Pz=(((((((NC.create=((((((V=(((((V=ZE.prototype,V.Sz=function(N,C){return((C=new ZE,C).source=this,C).P=N,C},V.subscribe=(ZE.prototype[ZE.prototype.ix=function(){var N= +aq.apply(0,arguments);return N.length?T[20](10,0,N)(this):this},ZE.create=function(N){return new ZE(N)},Ob]=function(){return this},function(N,C,e,L,h,Q,m){return L=(h=(m=["sb",15,4],N&&N instanceof $s||N&&K[m[1]](1,N.next)&&K[m[1]](3,N.error)&&K[m[1]](m[2],N.complete)&&I[14](m[2],N))?N:new iA(N,C,e),this).P,Q=this.source,h.add(L?L.call(h,Q):Q?this.VY(h):this[m[0]](h)),h}),V).sb=function(N){try{return this.VY(N)}catch(C){N.error(C)}},V).forEach=function(N,C,e){return C=T[26](16,null,(e=this,C)),new C(function(L, +h,Q){Q=e.subscribe(function(m){try{N(m)}catch(O){h(O),Q==null||Q.unsubscribe()}},h,L)})},V).VY=function(N,C){return(C=this.source)==null?void 0:C.subscribe(N)},T[40](60,Nc,Error),T)[40](28,UK,ZE),UK).prototype,V).Sz=function(N,C){return C=new NC(this,this),C.P=N,C},V.Um=function(){return y[21].call(this,8)},V).next=function(N,C,e,L,h){if(h=[10,"slice","call"],this.Um(),!this.i){e=(L=P[4](h[0],this.B[h[1]]()),L.next());try{for(;!e.done;e=L.next())e.value.next(N)}finally{e&&!e.done&&(C=L.return)&&C[h[2]](L)}}}, +V).error=function(N,C,e){if(!this[this[(e=["K","Um","i"],e)[1]](),e[2]])for(this.G=this[e[2]]=!0,C=this.B,this[e[0]]=N;C.length;)C.shift().error(N)},V.complete=function(N,C){if((C=["B","i",!0],this).Um(),!this[C[1]])for(this[C[1]]=C[2],N=this[C[0]];N.length;)N.shift().complete()},V.unsubscribe=function(){this.B=null,this.i=this.closed=!0},V.p8=function(N,C,e,L){return U[42].call(this,30,N,C,e,L)},UK.prototype.V=function(N,C,e){(C=(e=this.K,this).i,this.G)?N.error(e):C&&N.complete()},V.VY=function(N){return(this.Um(), +this).V(N),this.p8(N)},UK.prototype.sb=function(N){return(this.Um(),ZE.prototype).sb.call(this,N)},UK).create=function(N,C){return new NC(N,C)},T)[40](6,NC,UK),UK.create),NC).prototype.next=function(N,C,e){(C=this.destination)==null||(e=C.next)==null||e.call(C,N)},NC.prototype).error=function(N,C,e){(e=this.destination)==null||(C=e.error)==null||C.call(e,N)},NC.prototype.complete=function(N,C){(N=this.destination)==null||(C=N.complete)==null||C.call(N)},NC.prototype.VY=function(N,C,e){return(C=(e= +this.source)==null?void 0:e.subscribe(N))!=null?C:oo.i},T)[40](32,DR,UK),DR).create=UK.create,SE.Object.defineProperties(DR.prototype,{value:{configurable:!0,enumerable:!0,get:function(){return this.getValue()}}}),DR.prototype.VY=function(N,C){return!(C=UK.prototype.VY.call(this,N),C).closed&&N.next(this.o),C},DR.prototype).getValue=function(N,C){if((N=(C=this.o,this).K,this).G)throw N;return this.Um(),C},DR.prototype).next=function(N){UK.prototype.next.call(this,this.o=N)},typeof Symbol==="function")&& +Symbol.iterator?Symbol.iterator:"@@iterator",jr=new (((T[40](38,ve,Error),T[40](34,zk,$s),zk).i=$s.i,zk.create=$s.create,zk.prototype).unsubscribe=function(N,C){((C=[null,"call","K"],this.closed)||(N=this[C[2]])!=C[0]&&N[C[1]](this),$s).prototype.unsubscribe[C[1]](this)},ZE)(I[38].bind(null,1)),fA=(P[31](8,37,function(N,C){return UR(function(e){return e=[0,"slice","join"],Array.from(N.toString())[e[1]](e[0],C)[e[2]]("")},(C=C===void 0?100:C,""))}),function(N){return U[15].call(this,1,N)}),Pq=function(N, +C){return T[4].call(this,14,N,C)},Av=function(N){return H[44].call(this,15,N)},os=(((ZY.prototype.eZ=(((Pq.prototype.A2=function(N,C,e,L,h,Q,m){return(h=((N=l[e=(m=[2,"split","X-Goog-AuthUser"],Q=[0," ","Authorization"],{}),4](5,[]))?(C=N[m[1]](OY()),L={scheme:C[Q[0]],hash:C[1]}):L=null,L),h)!=null&&(e[Q[m[0]]]=h.scheme+Q[1]+h.hash,e[m[2]]=String(this.B||Q[0])),e},ZY).prototype.Jm=(Pq.prototype.LP=function(){return 0},Pq.prototype.eZ=function(){return!0},Pq.prototype.Jm=function(){return{key:this.i}}, +function(){return{}}),Av.prototype).Jm=function(){return{key:this.i}},function(){return!0}),ZY.prototype).A2=function(N){return N={},N.Authorization="OAuth "+this.i.getValue(),N},Av).prototype.eZ=function(){return!1},function(N,C){return H[13].call(this,59,N,C)}),aF=(os.prototype.LP=(os.prototype.eZ=((Av.prototype.A2=function(){return{}},ZY.prototype).LP=function(){return 1},os.prototype.Jm=function(){return{key:this.i}},function(){return!0}),Av.prototype.LP=function(){return 1},os.prototype.A2=function(){return{Authorization:"Bearer "+ +this.B.getValue()}},function(){return 0}),UD)(),VK=SS(),Zo=HA(),BT=Go(),gq=mU(),wj=L3(),jF=cA(),qL=((mH(),H$(),f8(),gW)(),typeof AsyncContext)!=="undefined"&&typeof AsyncContext.Snapshot==="function"?function(N){return N&&AsyncContext.Snapshot.wrap(N)}:function(N){return N},Y5=function(){return f[29].call(this,21)};function yE(){return I[9].call(this,73)} +(((T[0](88,yE,K2),yE.prototype)[Ri]=!0,yE.prototype.Q7=function(N){this.Ku=N},yE.prototype).removeEventListener=function(N,C,e,L){f[35](35,0,L,e,this,N,C)},yE.prototype).U=function(N){((N=[31,9,"Ku"],yE.L.U).call(this),y[N[1]](N[0],null,0,this),this)[N[2]]=null};function P7(){return l[32].call(this,1)} +var Ll={'"':(P7.prototype.G2=function(N,C){return(l[20]((C=[],27),null,this,C,N),C).join("")},UF()),"\\":B$(),"/":l3(),"\b":J6(),"\f":on(),"\n":Hp(),"\r":qu(),"\t":P5(),"\v":uB()},eK=/\uffff/.test(U2())?/[\\"\x00-\x1f\x7f-\uffff]/g:/[\\"\x00-\x1f\x7f-\xff]/g,Gm,Ge=(T[0](86,oN,P[31].bind(null,34)),oN.prototype.i=function(){return new XMLHttpRequest},Gm=new oN,RegExp)("^(?:([^:/?#.]+):)?(?://(?:([^\\\\/?#]*)@)?([^\\\\/?#]*?)(?::([0-9]+))?(?=[\\\\/?#]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#([\\s\\S]*))?$"), +cH=null,lf=function(){return l[15].call(this,1)};function cT(N,C){var e=[1,"=",2],L=["?",1,0],h=arguments.length==e[2]?l[10](3,e[1],L[e[0]],arguments[L[e[0]]],L[e[2]]):l[10](4,e[1],L[e[0]],arguments,L[e[0]]);return f[5](18,L[0],N,h)}var ZI=gy(),KR=(T[0](84,xK,yE),fe()),AR=(eC(),ne(),t1)(),yt=yT(),ix=(oK(),zG)(); +v[39](5,0,((xK.prototype.getResponse=function(N){N=["mozResponseArrayBuffer","i",""];try{if(!this[N[1]])return null;if("response"in this[N[1]])return this[N[1]].response;switch(this.A){case N[2]:case KR:return this[N[1]].responseText;case AR:if("mozResponseArrayBuffer"in this[N[1]])return this[N[1]][N[0]]}return null}catch(C){return null}},xK.prototype.T=(xK.prototype.I=function(){S[11](9,!0,0,this)},xK.prototype.isActive=function(){return!!this.i},function(N){if(!(N=[8,0,"I"],this.J))if(this.Y|| +this.h||this.P)S[11](N[0],!0,N[1],this);else this[N[2]]()}),(xK.prototype.U=function(N){((N=["L","G","U"],this.i)&&(this[N[1]]&&(this.P=!0,this[N[1]]=!1,this.i.abort(),this.P=!1),v[29](19,null,this,!0)),xK[N[0]][N[2]]).call(this)},xK).prototype.abort=function(N,C){(C=[null,39,38],this.i)&&this.G&&(this.G=!1,this.P=!0,this.i.abort(),this.P=!1,this.B=N||7,v[44](C[1],this,aF),v[44](C[2],this,BT),v[29](21,C[0],this))},((V=xK.prototype,V).h0=function(){return T[9].call(this,74)},V).aW=function(){return this.K}, +V.sC=function(){return this.A},V.send=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y){if(G=[!(Y=[1,"call","Unknown input type for opt_headers: "],1),!0,5],this.i)throw Error("[goog.net.XhrIo] Object is active with another request="+this.l+"; newUri="+N);(this.i=((((Q=C?C.toUpperCase():qO(),this.l=N,this).G=G[Y[0]],this).S=G[0],this).B=0,this.o="",this.F)?this.F.i():Gm.i(),this).i.onreadystatechange=qL(Pe(this.T,this));try{this.Y=G[Y[0]],this.i.open(Q,String(N),G[Y[0]]),this.Y=G[0]}catch(k){v[17](6, +G[Y[0]],G[2],this,k);return}if(F=new Map((u=e||"",this).headers),L)if(Gn(L)===Object.prototype)for(R in L)F.set(R,L[R]);else if(typeof L.keys==="function"&&typeof L.get==="function"){O=(n=P[4](12,L.keys()),n.next());try{for(;!O.done;O=n.next())h=O.value,F.set(h,L.get(h))}finally{O&&!O.done&&(c=n.return)&&c[Y[1]](n)}}else throw Error(Y[2]+String(L));t=(q=((B=(A=Array.from(F.keys()).find(function(k){return yt.toLowerCase()==k.toLowerCase()}),Zf[jz()])&&u instanceof Zf[jz()],!S[9](43,Wl,Q))||A||B||F.set(yt, +ix),P[4](14,F)),q).next();try{for(;!t.done;t=q.next())X=P[4](11,t.value),D=X.next().value,m=X.next().value,this.i.setRequestHeader(D,m)}finally{t&&!t.done&&(Z=q.return)&&Z[Y[1]](q)}("withCredentials"in this.i&&this.i.withCredentials!==this.K&&(this.i.withCredentials=this.K),this).A&&(this.i.responseType=this.A);try{this.V&&(clearTimeout(this.V),this.V=null),this.X>0&&(this.V=setTimeout(this.VM.bind(this),this.X)),this.h=G[Y[0]],this.i.send(u),this.h=G[0]}catch(k){v[17](2,G[Y[0]],G[2],this,k)}},V).VM= +function(N){N=["i",8,44],typeof dj!="undefined"&&this[N[0]]&&(this.o="Timed out after "+this.X+"ms, aborting",this.B=N[1],v[N[2]](35,this,jF),this.abort(N[1]))},function(N){xK.prototype.I=N(xK.prototype.I)}));function sB(N,C,e){return W[5].call(this,2,N,C,e)} +var Je=((sB.prototype.toString=function(N,C,e,L,h,Q,m,O,t,D){if((O=(C=[!0,null,(D=[0,"i","push"],"file")],t=[],this).B)&&t[D[2]](H[40](29,C[1],I8,O,C[D[0]]),C1()),(m=this[D[1]])||O==C[2])t[D[2]](cv()),(N=this.P)&&t[D[2]](H[40](27,C[1],I8,N,C[D[0]]),AZ()),t[D[2]](P[30](16,m).replace(/%25([0-9a-fA-F]{2})/g,Cl())),Q=this.o,Q!=C[1]&&t[D[2]](C1(),String(Q));if(h=this.G)this[D[1]]&&h.charAt(D[0])!="/"&&t[D[2]](Wz()),t[D[2]](H[40](87,C[1],h.charAt(D[0])=="/"?iU:vm,h,C[D[0]]));return(L=((e=this.K.toString())&& +t[D[2]](CJ(),e),this.A))&&t[D[2]](NY(),H[40](23,C[1],J2,L)),t.join("")},sB).prototype.resolve=function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((h=(L=(B=["G",1,0],["",".",null]),U)[36](15,this),D=!!N.B)?S[20](76,L[B[2]],h,N.B):D=!!N.P,D?h.P=N.P:D=!!N.i,D?S[42](5,!0,h,N.i):D=N.o!=L[2],O=N[B[0]],D)S[12](15,h,N.o);else if(D=!!N[B[0]])if(O.charAt(B[2])!="/"&&(this.i&&!this[B[0]]?O="/"+O:(m=h[B[0]].lastIndexOf(Wz()),m!=-1&&(O=h[B[0]].slice(B[2],m+B[1])+O))),Q=O,Q==".."||Q==L[B[1]])O=L[B[2]];else if(y[48](59,"./", +Q)||y[48](57,"/.",Q)){for(u=(q=(C=Q.split((t=Q.lastIndexOf("/",B[2])==B[2],Wz())),[]),B[2]);u<C.length;)e=C[u++],e==L[B[1]]?t&&u==C.length&&q.push(L[B[2]]):e==".."?((q.length>B[1]||q.length==B[1]&&q[B[2]]!=L[B[2]])&&q.pop(),t&&u==C.length&&q.push(L[B[2]])):(q.push(e),t=!0);O=q.join(Wz())}else O=Q;return D?I[34](5,!0,h,O):D=N.K.toString()!=="",D?l[3](2,L[2],h,y[23](7,N.K)):D=!!N.A,D&&T[25](18,h,N.A),h},function(N,C){return T[2].call(this,1,N,C)}),Rg=function(N){return v[39].call(this,11,N)},hZ=(Je.prototype.remove= +function(N,C){return(N=((C=["B",!1,75],f)[28](78,null,this),K[44](C[2],N,this)),this.i.has(N))?(this.G=null,this[C[0]]-=this.i.get(N).length,this.i["delete"](N)):C[1]},(Je.prototype.clear=(V=Je.prototype,function(N){this[(this.i=(N=["G","B",null],this[N[1]]=0,N[2]),N)[0]]=N[2]}),Je).prototype.add=function(N,C,e,L){return((N=((f[L=["i","G","B"],28](14,null,this),this)[L[1]]=null,K[44](96,N,this)),(e=this[L[0]].get(N))||this[L[0]].set(N,e=[]),e).push(C),this)[L[2]]+=1,this},function(N){return f[15].call(this, +1,N)}),jX=(T[40](34,(V.get=((V.e2=(Je.prototype.toString=function(N,C,e,L,h,Q,m,O,t){if((t=[17,23,"join"],this).G)return this.G;if(!this.i)return"";for(e=(C=Array.from((m=[],this.i).keys()),0);e<C.length;e++)for(Q=C[e],N=P[30](t[0],Q),O=this.lX(Q),L=0;L<O.length;L++)h=N,O[L]!==""&&(h+="="+P[30](t[1],O[L])),m.push(h);return this.G=m[t[2]](lC())},V.forEach=(V.set=function(N,C,e){return this[(this.G=(f[(e=[null,"B",28],e)[2]](14,e[0],this),e[0]),N=K[44](78,N,this),v)[6](4,e[0],N,this)&&(this[e[1]]-= +this.i.get(N).length),this.i.set(N,[C]),e[1]]+=1,this},function(N,C){(f[28](30,null,this),this).i.forEach(function(e,L){e.forEach(function(h){N.call(C,h,L,this)},this)},this)}),function(N,C,e,L,h,Q,m){for(N=(C=(e=(f[(m=[28,0,"from"],m)[0]](63,null,this),[]),Array[m[2]](this.i.values())),L=Array[m[2]](this.i.keys()),m[1]);N<L.length;N++)for(h=C[N],Q=m[1];Q<h.length;Q++)e.push(L[N]);return e}),V).lX=function(N,C,e,L,h){if(typeof N===(e=(f[28]((h=[12,31,74],h[1]),null,this),[]),"string"))v[6](h[0],null, +N,this)&&(e=e.concat(this.i.get(K[44](h[2],N,this))));else for(C=Array.from(this.i.values()),L=0;L<C.length;L++)e=e.concat(C[L]);return e},function(N,C,e){if(!N)return C;return(e=this.lX(N),e.length)>0?String(e[0]):C}),Hf),Error),function(N){return W[12].call(this,3,N)}),rV=(Sc.prototype.request=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){if(((u=(Q=(D={"Content-type":"application/json+protobuf"},A=[78,35,"assign"],this),new sB(this.i)),I)[34](22,!0,u,T[40](5,0,1,u.G,C)),h).L0){B=(O=P[4](10,Object.entries(h.L0)), +O).next();try{for(;!B.done;B=O.next())G=P[4](12,B.value),m=G.next().value,t=G.next().value,U[A[1]](A[0],u,m,t)}finally{B&&!B.done&&(c=O.return)&&c.call(O)}}return q=(Object[A[2]](D,h.bJ),e.G2()),new Promise(function(n,R,F){Q.o7.send(u,function(Z,X,Y){if(K[38]((Y=[(X=[2,": ",1223],"B"),"Failed to deserialize response from ",25],Z=K[24](17,X[0],this)===-1?void 0:K[24](11,X[0],this),Y)[2],X[2],this))try{n(I[9](41,"",P[21](12,"",this),L))}catch(k){R(new Hf(4,Y[1]+u+X[1]+P[21](11,"",this),Z))}else R(new Hf(this[Y[0]], +typeof this.o==="string"?this.o:String(this.o),Z))},N,q,D,(F=h.T2)!=null?F:2E4,h.withCredentials)})},null),Zm=hb();function JP(N){return l[7].call(this,2,N)}var uf=(P[31](8,48,function(N,C,e,L){return(C=H[40](14,e,C),(L=(""+N)[YB+vT](C))&&L.length>=2)?L.index:null}),T[0](92,JP,xW),yo)();function mW(N){return H[39].call(this,14,N)}var a6=(T[0](84,mW,xW),eh)(),eE=function(N){return y[31].call(this,72,N)};function JC(N,C){return f[4].call(this,64,N,C)} +var PJ=((T[0](85,JC,xW),eO.prototype.get=function(N,C){return(C=["B","i",0],this[C[0]]>C[2])?(this[C[0]]--,N=this[C[1]],this[C[1]]=N.next,N.next=null):N=this.o(),N},eO.prototype).put=function(N,C){(this[C=["i","B","G"],C[2]](N),this)[C[1]]<100&&(this[C[1]]++,N.next=this[C[0]],this[C[0]]=N)},function(N){return N}),sb,jm=new (((v[39](36,0,function(N){PJ=N}),eM).prototype.add=function(N,C,e){((e=jm.get(),e).set(N,C),this).B?this.B=this.B.next=e:this.i=this.B=e},eM).prototype.remove=function(N,C){return(N= +(C=["i",null,"B"],C[1]),this)[C[0]]&&(N=this[C[0]],this[C[0]]=this[C[0]].next,this[C[0]]||(this[C[2]]=C[1]),N.next=C[1]),N},eO)(function(){return new nR},function(N){return N.reset()}),nR=function(){return U[35].call(this,7)},LA=(nR.prototype.reset=function(){this.next=this.B=this.i=null},nR.prototype.set=function(N,C){this.i=(this.next=null,this.B=N,C)},function(){return I[29].call(this,32)}),dH,wH=!1,V4=new eM,Dk=function(N,C,e,L,h,Q,m){return H[27].call(this,8,N,C,e,L,h,Q,m)},tJ=Vl(),P2=new (v5.prototype.reset= +function(N){this.B=(this[this.G=(this.i=(this.K=(N=["o",!1,null],N[1]),N[2]),N[2]),N[0]]=N[2],N)[2]},eO)(function(){return new v5},function(N){N.reset()}),Rj=(wu.prototype.catch=(wu.prototype[tJ]=!(wu.prototype.then=function(N,C,e){return v[32](6,null,qL(typeof N==="function"?N:null),this,qL(typeof C==="function"?C:null),e)},0),wu.prototype[wu.prototype.X=function(N,C){this[C=[3,"i",2],C[1]]=0,v[45](C[0],null,C[2],N,this)},wu.prototype.V=function(N,C){return v[32](5,null,null,this,qL(N),C)},"finally"]= +function(N,C){return new (C=this,N=qL(N),wu)(function(e,L){y[44](1,null,3,function(h){N(),e(h)},function(h){(N(),L)(h)},C)})},wu).prototype.V,wu.prototype.j=function(N,C){for(C=[null,2,"P"];N=T[21](5,C[0],this);)K[23](7,C[1],C[0],this.A,this,this.i,N);this[C[2]]=!1},wu.prototype.cancel=(wu.prototype.h=function(N,C){(this.i=(C=[null,45,0],C[2]),v)[C[1]](2,C[0],3,N,this)},function(N,C){this.i==0&&(C=new Vg(N),v[3](20,!0,function(){P[49](22,null,0,this,C)},this))}),T)[0].bind(null,69),E6=((T[0](90,Vg, +sH),Vg).prototype.name=SQ(),function(N,C,e){return U[19].call(this,18,e,N,C)});(((Pn(),T[40](58,As,K2),As).prototype.V=function(N){var C=[4,null,(this.B=arguments,!1)];this.i||this.o?this.G=!0:y[C[0]](7,C[2],C[1],this)},As.prototype).pause=function(){this.o++},As.prototype.U=function(N){N=[null,"call","U"],K2.prototype[N[2]][N[1]](this),this.i&&(S[3](1,this.i),this.i=N[0],this.B=N[0],this.G=!1)},pk)();function j8(){return l[17].call(this,41)} +j8.prototype.Y_=(j8.prototype.info=function(){},function(){return P[21].call(this,16)});function xY(N,C,e,L,h){return f[4].call(this,18,e,C,L,N,h)} +var M4=(xY.prototype.setTimeout=function(N){this.VM=N},function(){return H[13].call(this,8)}),tG=(xY.prototype.Ku=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){c=[8,"O",(m=[14,!1,2],"F")];try{if(N==this.i)a:if(q=W[1](11,this.i),B=this.i.B,Q=K[24](27,m[2],this.i),!(q<3||q==3&&!l[40](30,"",this)))if(this.I||q!=4||B==7||(B==c[0]||Q<=0?l[47](18,3):l[47](17,m[2])),l[5](20,null,this),this.W=t=K[24](16,m[2],this.i),G=I[40](14,!0,m[2],1,"",this),l[40](32,"",this),this.P=t==200,y[16](49," ","\n","]: ",this.K,this[c[1]], +this.j,this.G,t,q,this.J),this.P){if(this.rq&&!this[c[2]]){b:{if(this.i&&(h=this.i,(u=h.i?h.i.getResponseHeader(U9):null)&&!S[23](31,u))){D=u;break b}D=null}if(O=D)v[20](2,m[2],O,this.G,this.K,"Initial handshake response via "+U9),this[c[2]]=!0,K[36](90,"ms",this,O);else{H[c[0]](3,(this.P=(this.V=3,m[1]),12)),f[7](12,null,this),l[14](29,0,this);break a}}if(this.C){for(e=!0;!this.I&&this.X<G.length;)if(C=v[40](42,1,this,G),C==D_){q==4&&(this.V=4,H[c[0]](15,m[0]),e=m[1]),v[20](61,m[2],null,this.G,this.K, +Mk());break}else if(C==qM){e=(this.V=4,H[c[0]](12,15),v[20](34,m[2],G,this.G,this.K,t6()),m[1]);break}else v[20](29,m[2],C,this.G,this.K,null),K[36](88,"ms",this,C);this.P=((l[1](81,"GET",m[2],this)&&this.X!=0&&(this.B.i=this.B.i.slice(this.X),this.X=0),q!=4||G.length!=0)||this.B.B||(this.V=1,H[c[0]](10,16),e=m[1]),this.P&&e),e?G.length>0&&!this.o6&&(this.o6=!0,L=this.o,L.i==this&&L.Hm&&!L.W&&(L.K.info("Great, no buffering proxy detected. Bytes received: "+G.length),U[44](22,null,L),L.W=!0,H[c[0]](2, +11))):(v[20](62,m[2],G,this.G,this.K,s7()),f[7](12,null,this),l[14](27,0,this))}else v[20](30,m[2],G,this.G,this.K,null),K[36](89,"ms",this,G);if((q==4&&f[7](44,null,this),this.P)&&!this.I)if(q==4)I[19](30,3,1,this.o,this);else this.P=m[1],S[2](64,this)}else l[4](24,", ",m[2],"",":",this.i),t==400&&G.indexOf(kh())>0?(this.V=3,H[c[0]](5,12)):(this.V=0,H[c[0]](9,13)),f[7](36,null,this),l[14](25,0,this)}catch(A){FR(),l[40](31,"",this)||uk()}finally{}},/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:\/?#]*(?:[\/?#]|$))/i), +Yv=(xY.prototype.Xe=function(N,C,e,L){(e=(C=N[L=[15,3,"target"],L[2]],this).u)&&W[1](L[0],C)==L[1]?(S7(),e.V()):this.Ku(C)},function(N,C,e,L,h){return I[37].call(this,3,N,e,C,h,L)}),fa=(xY.prototype.cancel=(xY.prototype.hO=function(N,C,e){C=((N=[17,(e=[42,2,5],3),null],this).S=N[e[1]],Date.now()),C-this.iI>=0?(this.P&&yd(),P[e[2]](e[1],this.G,this.J),this.T!=e[1]&&(l[47](16,N[1]),H[8](8,N[0])),f[7](13,N[e[1]],this),this.V=e[1],l[14](31,0,this)):(p3(),v[e[0]](12,N[e[1]],this.iI-C,this))},function(){f[7](45, +(this.I=!0,null),this)}),function(){return U[1].call(this,8)}),Im=pY(),Rm=function(N){return K[16].call(this,72,N)}; +(Vj.prototype.stringify=function(N){return Zf[c9()].stringify(N,void 0)},IY.prototype).cancel=(Vj.prototype.parse=function(N){return Zf[c9()].parse(N,void 0)},function(N,C,e,L){if(this[(L=["B","i","call"],this.G=S[17](58,null,this),L)[0]])this[L[0]].cancel(),this[L[0]]=null;else if(this[L[1]]&&this[L[1]].size!==0){N=P[4](12,this[L[1]].values()),C=N.next();try{for(;!C.done;C=N.next())C.value.cancel()}finally{C&&!C.done&&(e=N.return)&&e[L[2]](N)}this[L[1]].clear()}}); +function F$(){return y[1].call(this,7)} +var Fi=((((((((((T[0](95,iH,P[31].bind(null,35)),iH.prototype).i=function(){return new LL(this.G,this.B)},T[0](91,LL,yE),LL).prototype.open=function(N,C,e){if(this.readyState!=(e=["abort","S","Y"],0))throw this[e[0]](),Error("Error reopening a connection");v[this[this[e[this.readyState=1,1]]=N,e[2]]=C,45](24,this)},LL.prototype).send=function(N,C,e){if(this.readyState!=(e=["Y","A","u"],1))throw this.abort(),Error("need to call open() first. ");if(this[e[1]].signal.aborted)throw this.abort(),Error("Request was aborted."); +((C={headers:this.X,method:this.S,credentials:this.P,cache:void 0,signal:(this.i=!0,this[e[1]].signal)},N)&&(C[$V()]=N),(this.l||Zf).fetch(new Request(this[e[0]],C))).then(this[e[2]].bind(this),this.K.bind(this))},LL).prototype.abort=function(N,C){this.readyState=((((C=["responseText","abort",(N=[4,0,""],38)],this.response=this[C[0]]=N[2],this.X=new Headers,this.status=N[1],this.A)[C[1]](Dt()),this).G&&this.G.cancel(Dt()).catch(function(){}),this.readyState)>=1&&this.i&&this.readyState!=N[0]&&(this.i= +!1,P[C[2]](2,N[0],this)),N[1])},LL).prototype.F=function(N){this.i&&(this.response=N,P[38](11,4,this))},LL.prototype).I=function(N,C,e,L){if(this[(L=[48,"push","i"],L)[2]]){if(this.V&&N.value)this.response[L[1]](N.value);else!this.V&&(e=N.value?N.value:new Uint8Array(0),C=this.h.decode(e,{stream:!N.done}))&&(this.response=this.responseText+=C);(N.done?P[38](3,4,this):v[45](25,this),this.readyState)==3&&I[L[0]](57,this)}},LL.prototype.u=function(N,C){if((C=["T",27,56],this).i&&(this.o=N,this.B||(this.status= +this.o.status,this.statusText=this.o.statusText,this.B=N.headers,this.readyState=2,v[45](C[1],this)),this.i&&(this.readyState=3,v[45](28,this),this.i)))if(this.responseType==="arraybuffer")N.arrayBuffer().then(this.F.bind(this),this.K.bind(this));else if(N.body&&Zf.ReadableStream){if((this.G=N.body.getReader(),this).V){if(this.responseType)throw Error('responseType must be empty for "streamBinaryChunks" mode responses.');this.response=[]}else this.response=this.responseText="",this.h=new TextDecoder; +I[48](C[2],this)}else N.text().then(this[C[0]].bind(this),this.K.bind(this))},LL.prototype).K=function(){this.i&&P[38](10,4,this)},P)[31](20,43,function(N){return H[2](3,!1,function(C){return C.Object.hasOwnProperty.call(N,uD())?"":N.value})}),LL).prototype.T=function(N,C){(C=["responseText",16,4],this.i)&&(this.response=this[C[0]]=N,P[38](C[1],C[2],this))},LL.prototype.setRequestHeader=function(N,C){this.X.append(N,C)},LL.prototype.getResponseHeader=function(N){return this.B?this.B.get(N.toLowerCase())|| +"":""},function(N){return W[15].call(this,1,N)});(LL.prototype.getAllResponseHeaders=function(N,C,e,L,h){if(!this[(h=["join","B","push"],h)[1]])return"";for(L=(e=(N=[],this)[h[1]].entries(),e.next());!L.done;)C=L.value,N[h[2]](C[0]+": "+C[1]),L=e.next();return N[h[0]](vZ())},fu(LL.prototype,Oj(),{get:function(){return this.P==="include"},set:function(N){this.P=N?xb():FT()}}),KT(),Nd)();function ra(N,C){return f[14].call(this,66,N,C)} +var Tj=(((ra.prototype.ks=(ra.prototype.bI=function(N,C,e){P[this.X=(e=(C=[1,"BP detection timer enabled: ",null],[46,"i",4]),C[2]),e[0]](8,C[0],C[2],this),!this.Hm||this.W||this[e[1]]==C[2]||this.j_<=0||(N=e[2]*this.j_,this.K.info(C[1]+N),this.S=y[9](18,Pe(this.ZR,this),N))},function(N,C){(C=["K",14,13],N)?(this[C[0]].info(xV()),H[8](C[1],2)):(this[C[0]].info(fn()),H[8](C[2],1))}),(ra.prototype.ZR=function(N,C){this[C=[(N=[10,null,!0],1),"S",2],C[1]]?(this[C[1]]=N[C[0]],this.K.info(ku()),this.K.info(IC()), +this.W=N[C[2]],this.l=!1,H[8](C[2],N[0]),v[16](16,N[C[0]],this),P[46](10,C[0],N[C[0]],this)):Oy()},ra).prototype).S_=8,ra.prototype.Fd=function(N){this[N=["h",3,null],N[0]]!=N[2]&&(this[N[0]]=N[2],v[16](48,N[2],this),l[9](8,N[1],this),H[8](11,19))},(ra.prototype.iz=(ra.prototype.isActive=function(){return!!this.P&&this.P.isActive(this)},ra.prototype.SW=function(N){S[9](45,arguments,this.B)},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if((L=(c=[4096,"iI",0],[":",1E5,0]),this).V)if(this.V=null,ji(),this.B== +1)if(N)Dn();else{if(((t=(Ta(),this.o6=TH(Vn()*L[1]),O=this.o6++,new xY(O,this,void 0,this.K)),D=this.j,this).rq&&(D?(D=l[15](36,D),yO(D,this.rq)):D=this.rq),this.A!==null||this.O)||(t.l=D,D=null),this[c[1]])a:{for(u=(m=L[2],L)[2];u<this.o.length;u++){b:{if((B=this.o[u],Im)in B.map&&(Q=B.map[Im],typeof Q==="string")){h=Q.length;break b}h=void 0}if(G=h,G===void 0)break;if(m+=G,m>c[0]){C=u;break a}if(m===4096||u===this.o.length-1){C=u+1;break a}}C=this.JO}else C=this.JO;if(this[((((e=P[44](1,!1,"",this, +C,t),q=U[36](23,this.F),U)[35](78,q,wd(),O),U)[35](78,q,z1(),22),this.Z&&U[35](73,q,g5,this.Z),W[24](8,q,this),D&&(this.O?e="headers="+P[30](19,f[1](1,"\r\n",L[c[2]],D))+"&"+e:this.A&&W[41](80,L[c[2]],this.A,D,q)),U[10](56,t,this.G),this.hj)&&U[35](74,q,mV(),rG()),c)[1]])U[35](75,q,jy(),e),U[35](72,q,dd(),Sq()),t.rq=!0,W[33](3,null,null,q,t);else W[33](4,null,e,q,t);this.B=2}else if(this.B==3)if(N)I[35](8,L[c[2]],null,this,N);else this.o.length==L[2]||v[24](72,this.G)||(I[35](9,L[c[2]],null,this), +xy())}),ra).prototype.B=1,ra.prototype).connect=function(N,C,e,L,h,Q){this.F=(((this[((this.I=((h=[!0,(Q=["hO",30,"l"],1),0],V2(),H)[8](4,h[2]),C||{}),this.Ku=N,e&&L!==void 0)&&(this.I[k2()]=e,this.I[vb()]=L),Q)[2]]=this[Q[0]],RP)(),this).SW(h[1],h[2]),U)[Q[1]](50,".","",this,this.Ku,null),f[18](10,h[0],this)},function(){return K[41].call(this,16)}); +i$.prototype.K=(i$.prototype.B=function(){},function(){}),i$.prototype.P=function(){},(i$.prototype.isActive=function(){return!0},i$).prototype.G=function(){},i$.prototype.o=function(){};function tt(){return I[38].call(this,22)} +var Jv=(((T[0](93,UL,yE),UL.prototype).close=function(){l[24](18,null,this.i)},UL.prototype).send=function(N,C,e,L,h,Q,m){(L=(C=(m=[18,"K","push"],this.i),typeof N==="string"?(Q={},Q[Im]=N,h=Q):this[m[1]]?(e={},e[Im]=(new P7).G2(N),h=e):h=N,h),C.o[m[2]](new ev(L,C.jW++)),C.B==3)&&f[m[0]](40,!0,C)},function(){return K[40].call(this,48)}),da=(((UL.prototype.U=function(N){(delete this[l[(N=["i","U",24],delete this.G,this[N[0]]).P=null,N[2]](16,null,this[N[0]]),N[0]],UL.L[N[1]]).call(this)},T)[0](86, +dP,oI),T)[0](89,Za,co),function(N){return K[1].call(this,1,N)});((T[0](91,da,i$),da).prototype.B=function(){v[44](34,this.i,"b")},da.prototype.G=function(N){v[44](38,this.i,new Za(N))},da.prototype).o=function(N){v[44](32,this.i,new dP(N))},da.prototype.K=function(){v[44](34,this.i,"a")};function b5(N,C){return K[37].call(this,22,N,C)} +gX.prototype.remove=function(N,C,e,L,h,Q,m,O,t,D,q,u){if(Q=(m=(q=this[(u=["i",0,1],u)[t=[0,1,2],0]],q.length),q[t[u[1]]]),!(m<=t[u[1]])){if(m==t[u[2]])q.length=t[u[1]];else{for(D=(O=(C=this[q[t[u[1]]]=q.pop(),u[0]],C).length,t)[u[1]],h=C[D];D<O>>t[u[2]];){if(C[e=(L=(N=D*t[2]+t[u[2]],D*t[2]+t[2]),L)<O&&C[L][u[0]]<C[N][u[0]]?L:N,e][u[0]]>h[u[0]])break;C[D]=C[e],D=e}C[D]=h}return Q.getValue()}},b5.prototype.getValue=((gX.prototype.e2=function(N,C,e,L){for(N=(e=(C=this.i,0),L=[],C).length;e<N;e++)L.push(C[e].i); +return L},gX.prototype.clear=function(){this.i.length=0},gX).prototype.lX=function(N,C,e,L){for(N=(C=(e=[],L=0,this).i,C).length;L<N;L++)e.push(C[L].getValue());return e},function(){return this.B});function Gj(){var N=[null,"apply",0];return lx[N[1]](N[0],T[5](87,aq[N[1]](N[2],arguments)))} +function lx(){var N=["apply",34,"pop"],C=aq[N[0]](0,arguments),e=W[N[1]](16,C[C.length-1])?C[N[2]]():void 0;return l[27](9,function(L,h,Q,m,O,t){(m=I[11](32,(O=(t=[null,(O=1,41),56],O===void 0?Infinity:O),t[0]),!1,l[5].bind(t[0],62),O),Q=[L].concat(T[5](t[1],C)),m)(e?f[25](t[2],0,e,Q):U[42](24,0,Q)).subscribe(h)})} +var ii=function(N,C,e){var L=[21,"map",39],h=aq.apply(3,arguments)[L[1]](function(Q){return W[0](19,Q)});return P[18](24,W[L[2]](12,S[32](68,new b4,4),N),[W[0](L[0],C),W[0](17,e)].concat(T[5](41,h)))};function D6(N,C){var e=arguments.length>=2;return function(L,h,Q){return L.ix((h=[!0,0,!1],Q=[32,5,8],N?l[Q[2]](Q[0],h[1],function(m,O){return N(m,O,L)}):l[Q[1]].bind(null,63)),y[6](71,1,h[1]),e?K[27](9,h[2],h[0],C):y[42](Q[2],h[2],h[0],function(){return new ve}))}} +function U_(){var N=[0,64,null],C=aq.apply(N[0],arguments);return C.length?l[27](73,function(e,L,h){H[25](8,0,(h=[null,"concat","'"],h[0]),h[2],[e][h[1]](T[5](25,C)))(L)}):l[5].bind(N[2],N[1])} +var Tm={f0:(Dk.prototype.onError=((ru.prototype.start=function(N){return new Co(N,this.i,this.B,this.G,this.o,!0)},YQ.prototype).add=function(N){this.i.push(N)},function(N,C,e,L){(e=(this.B(new $_((L=[47,9,null],N))),H[36](L[0],L[2],new tC,f[L[1]](L[1],403,400,C))),U)[10](5,L[2],2,this,e)}),new sB("https://signaler-pa.clients6.google.com/punctual")),Y7:new sB("https://signaler-pa.googleapis.com/punctual"),BS:!1},Z0={f0:new sB("https://punctual.corp.google.com/punctual"),Y7:new sB,BS:!1},om={f0:new sB("https://punctual-preprod.corp.google.com/punctual"), +Y7:new sB,BS:!1},PT={f0:new sB,Y7:new sB("https://signaler-pa.apis-tpczero.goog/punctual"),BS:!1},s9={f0:new sB("https://punctual-dev.corp.google.com/punctual"),Y7:new sB("https://signaler-staging.sandbox.google.com/punctual"),BS:!1},fR=new Map([["corp",Z0],["prod",Tm],["prod-up",Z0],["preprod-up",om],["tpc-prptst",PT],["preprod-dynamite-alpha-us",I[34](24,"alpha-us")],["preprod-dynamite-alpha-eu",I[34](8,"alpha-eu")],["preprod-dynamite-beta-us",I[34](24,"beta-us")],["preprod-dynamite-beta-eu",I[34](16, +"beta-eu")],["preprod-dynamite-gamma-us",I[34](16,"gamma-us")],["preprod-dynamite-gamma-eu",I[34](16,"gamma-eu")],["preprod-qual-dynamite-perftest",S[18](26,"preprod-qual-dynamite-perftest")],["prod-dynamite-prod-00-eu",I[34](32,"prod-00-eu")],["prod-dynamite-prod-01-eu",I[34](16,"prod-01-eu")],["prod-dynamite-prod-00-us",I[34](8,"prod-00-us")],["prod-dynamite-prod-01-us",I[34](8,"prod-01-us")],["prod-dynamite-prod-02-us",I[34](24,"prod-02-us")],["prod-dynamite-prod-03-us",I[34](24,"prod-03-us")], +["prod-dynamite-prod-04-us",I[34](32,"prod-04-us")],["prod-dynamite-prod-05-us",I[34](16,"prod-05-us")],["prod-dynamite-prod-06-us",I[34](24,"prod-06-us")],["prod-dynamite-prod-07-us",I[34](8,"prod-07-us")],["prod-dynamite-prod-08-us",I[34](8,"prod-08-us")],["prod-dynamite-prod-09-us",I[34](32,"prod-09-us")],["prod-dynamite-prod-00-xx",I[34](32,"prod-00-xx")],["dynamite-alpha-us",K[11](9,"alpha-us","preprod")],["dynamite-alpha-eu",K[11](29,"alpha-eu","preprod")],["dynamite-beta-us",K[11](9,"beta-us", +"preprod")],["dynamite-beta-eu",K[11](41,"beta-eu","preprod")],["dynamite-gamma-us",K[11](41,"gamma-us","preprod")],["dynamite-gamma-eu",K[11](1,"gamma-eu","preprod")],["dynamite-prod-00-us",K[11](33,"prod-00-us","prod")],["dynamite-prod-00-eu",K[11](1,"prod-00-eu","prod")],["dynamite-prod-00-xx",K[11](33,"prod-00-xx","prod")],["dynamite-prod-01-us",K[11](1,"prod-01-us","prod")],["dynamite-prod-01-eu",K[11](33,"prod-01-eu","prod")],["dynamite-prod-02-us",K[11](29,"prod-02-us","prod")],["dynamite-prod-03-us", +K[11](9,"prod-03-us","prod")],["dynamite-prod-04-us",K[11](29,"prod-04-us","prod")],["dynamite-prod-05-us",K[11](33,"prod-05-us","prod")],["dynamite-prod-06-us",K[11](41,"prod-06-us","prod")],["dynamite-prod-07-us",K[11](9,"prod-07-us","prod")],["dynamite-prod-08-us",K[11](29,"prod-08-us","prod")],["dynamite-prod-09-us",K[11](1,"prod-09-us","prod")],["prod-asia-east1",S[18](29,"asia-east1")],["prod-asia-southeast1",S[18](29,"asia-southeast1")],["prod-europe-north1",S[18](30,"europe-north1")],["prod-europe-west1", +S[18](30,"europe-west1")],["prod-europe-west4",S[18](31,"europe-west4")],["prod-southamerica-west1",S[18](28,"southamerica-west1")],["prod-us-central1",S[18](28,"us-central1")],["prod-us-central2",S[18](27,"us-central2")],["prod-us-east1",S[18](27,"us-east1")],["prod-us-west1",S[18](26,"us-west1")],["ytprod",{f0:new sB("https://signaler-pa.youtube.com/punctual"),Y7:new sB("https://signaler-pa.googleapis.com/punctual"),BS:!1}],["dev",s9]]),ej=function(N){return K[6].call(this,16,N)},Hi=(P[31](24,52, +l[3].bind(null,12)),function(N){return y[10].call(this,4,N)}),e3=S[42](61,S[42](98,68,66,69,14,15,10),S[42](36,S[42](39,S[42](32,60,58,61,7,10,3),S[42](46,S[42](49,36,37,38,7,25,2),35,41,35,35,16)),S[42](47,S[42](34,28,30,54,-175,-115,-22),S[42](53,S[42](60,53,45),42),33,7)),55),Xi=[0,(T[40](6,vL,p),sI)],SF=[0,wv,i_,(((T[40]((vL.prototype.D=f[38](67,Xi),26),is,p),is).prototype.getValue=function(){return T[8](49,2,this)},is).prototype.clearValue=function(){return H[38](8,this,void 0,2)},sI),i_],YN= +[0,(T[40](35,(is.prototype.D=f[38](26,SF),A3),p),Ty),sI],RS=(T[40](60,(A3.prototype.D=f[38](26,YN),bQ),p),l[12](1,"",bQ)),Ow=(bQ.prototype.D=f[38](67,[0,yj,wv,Hg,[0],Hg,[0],Hg,YN,Hg,SF,Hg,Xi]),Promise),t0=(bi.prototype.send=function(N,C,e,L,h){(L=(e=e===void 0?[]:e,h=[0,19,"port1"],new MessageChannel),H)[h[1]](h[1],h[0],L[h[2]],C),this.i.postMessage(N,[L.port2].concat(e))},lP()),Uw=Kj(),IS=[104,97,110,100,45,103,101,115,116,117,114,101,115,45,105,102,114,97,109,101].map(function(N){return String.fromCharCode(N)}).join(""), +F3=ri,WT=[0,12,i_,10,(T[40](26,QZ,((BQ.prototype.setInterval=function(N,C){(C=[13,"G","i"],this[C[1]]=N,this[C[2]]&&this.B)?(T[C[0]](72,!1,this),this.start()):this[C[2]]&&T[C[0]](69,!1,this)},BQ).prototype.start=function(N,C){this[C=[!0,"i",(N=this,"o")],this.B=C[0],C[1]]||(this[C[1]]=setTimeout(function(){P[30](32,.8,0,N)},this.G),this.K=this[C[2]]())},p)),Ty)],HT=[0,1,WT,(T[40](59,(QZ.prototype.D=f[38](75,WT),mI),p),[0,7,[0,i_,-1]])],wY=(mI.prototype.D=f[38](73,HT),pL()),$J=((((((((BC(),U0(),pZ(), +wc(),ZM)(),DC)(),WM(),ea)(),Uj)(),Jk(),RK)(),wT(),IR)(),S_(),vO)(),NN)(),$n=(m6(),K8)(),kN=(((((lq(),iT(),ee)(),Gq(),JY(),N5(),yw)(),Jn(),m3)(),Ww)(),function(){return T[5].call(this,51)}),Kv=(ql(),nk(),jn(),YX(),MD)(),EC=(Cr(),aP()),qX=(((((t$(),Le)(),Yp(),XB(),Wx(),WW)(),YH)(),wS(),zo)(),nr()),MP=((((vs(),Xg(),LY)(),fw(),No(),OU)(),JH)(),FM(),z9()),HJ=(((((Oo(),Su)(),Ak)(),UM)(),fk)(),uL()),xn=(sJ(),S2)(),bl=((((((YP(),vp)(),ZC)(),uF(),aZ)(),ot(),RW(),PE)(),r$)(),CG(),2654435761),Iq=((((((((((((((Ag(), +h$)(),vW)(),LG)(),Zr(),wU(),pt)(),Ql)(),iN(),JU(),TR)(),md)(),Ej(),OD(),Kr(),Zt(),rP(),Ga)(),Xh)(),zR)(),gB)(),C0)(),bJ(),yu)(),tY(),aQ(),gg()),gY=(IU(),h6)(),he=(Rk(),LI(),GR()),zv=($T(),E3()),Nf=Yy(),hI=(Pw(),a2(),aR(),qk(),fK()),E$=(C3(),rT(),dU)(),aY=dg();((((Vr(),Q8(),oZ)(),ah(),d1(),mb)(),hB(),Ev)(),Ts(),n0)(),JB(),eI(),Hn(),XD();function aw(N,C){return I[32].call(this,1,N,C)} +((aw.prototype.round=function(){return this.y=(this.x=ae(this.x),ae(this.y)),this},aw.prototype).floor=function(){return this.y=(this.x=TH(this.x),TH)(this.y),this},aw.prototype.ceil=function(){return this.y=(this.x=wq(this.x),wq(this.y)),this},aw).prototype.equals=function(N){return N instanceof aw&&(this==N?!0:this&&N?this.x==N.x&&this.y==N.y:!1)};function B2(N,C){return f[40].call(this,2,N,C)} +var uR={cellpadding:(P[31](4,(B2.prototype.floor=((B2.prototype.round=function(){return this.height=(this.width=ae(this.width),ae)(this.height),this},B2).prototype.aspectRatio=function(){return this.width/this.height},B2.prototype.ceil=function(){return this.height=(this.width=wq(this.width),wq(this.height)),this},function(){return this.height=(this.width=TH(this.width),TH)(this.height),this}),0),S[16].bind(null,8)),lT)(),cellspacing:Uy(),colspan:UU(),frameborder:Yb(),height:XU(),maxlength:dC(),nonce:Cq(), +role:se(),rowspan:HN(),type:Pk(),usemap:Z$(),valign:To(),width:S1()},Mr={IMG:OY(),BR:k4()},no=function(N){return l[28].call(this,1,N)},rl=[0,(no.prototype.B=W[49].bind(null,((((V=no.prototype,V).v=function(N){return I[17](58,N,this.i)},V.getElementsByTagName=function(N,C){return(C||this.i).getElementsByTagName(String(N))},V).ZS=function(N,C,e){return l[23](88,0,"aria-",this.i,arguments)},V.createElement=function(N){return y[41](16,this.i,N)},V).createTextNode=function(N){return this.i.createTextNode(String(N))}, +8)),T[40](35,Lo,p),wv),Ty,i_,-2],pR=[(T[40](2,(Lo.prototype.D=(Lo.prototype.K6=function(){return W[4](1,this,1)},f[38](73,rl)),vk),p),0),sI,-1],L2=(T[40](38,hC,(vk.prototype.D=f[38](75,pR),p)),l)[12](1,"",hC),JR=[0,YF,pR,Ty,sI,-5],E9=(T[40](28,JJ,(hC.prototype.D=f[38](73,JR),p)),P[31](28,5,function(N,C,e){return function D(h,Q,m,O,t){return P[44](6,D,function(q,u,B){u=[4,9,(B=[1,34,"Z"],7313)];switch(q.B){case B[0]:q[B[2]](2),t=P[4](14,C(N(),6).split(u0())),Q=t.next(),q[B[2]](u[0]);case 6:if(Q.done){q.js(u[0]); +break}return h=U[O=Q.value,0].bind(null,81),q.i(e(U[4](B[1],u[2])(U[4](10,1993)(O).trim())),u[B[0]]);case u[B[0]]:(Q=(h(q.G),t.next()),q).js(6);break;case u[0]:(q.J(0,2),Q&&!Q.done)&&(m=t.return)&&m.call(t),q.S(2);break;case 2:q.J(),q.S(0)}})}()}),S[42](35,S[42](36,138,S[42](39,33,20,89,-63,10,25),148,119,215,63),S[42](48,18,0),223,133,95)),zm=[0,sI,-1,wv,sI,-1,wv,sI,-1,JR,rl],ie=(JJ.prototype.D=f[38](75,zm),new hC),KS=null,Gh=function(N,C){return S[34].call(this,1,N,C)},dl=[0,sI,wv,1,sI,-1,wv,(P[31](16, +51,U[35].bind(null,32)),1),wv,1,Bg],sL=function(N,C,e,L){return l[18].call(this,2,N,C,e,L)},wl=[0,wv,sI,-1],Vt=[0,sI,-3],xN=[0,wv,sI,-2],am=[0,sI,wv],gl=[0,sI,-6,Bg,i_,sI,-1,Bg],bx=[0,sI,wv],MU=[0,sI,-6,wv,sI,1,sI,Ty,wv,-(P[31](28,34,function(N,C,e){return N=N[e=[1,15,"replace"],e[2]](/(["'`])(?:\\\1|.)*?\1/g,"")[e[2]](/[^a-zA-Z]/g,""),T[e[1]](e[0],!1,16,C)?v[38](19,N)+","+N:v[38](11,N)}),1),Ty,sI,-2,wv,sI,wv,sI,i_,-1],le=function(){return y[35].call(this,2)},$N=[0,sI,-3,Bg,i_,sI,-1],Nn=[0,Ty,-3], +CH=[0,sI,-4],W4=function(N){return T[36].call(this,1,N)},v0=function(N){return l[3].call(this,6,N)},l0=function(N,C,e,L){return y[19].call(this,6,N,C,e,L)},e4=[0,[0,wv,sI,-1,Bg,i_,-1,sI,-4,YF,[0,sI,-4],-1,1,Nn],[0,wv,sI,-1,Bg,i_,-1,sI,-4,Nn]],LH=(P[31](8,50,E9),[0,sI,wv,sI,-2]),hN=[0,sI,wv,sI,-1,Bg,wv,sI,-1,wv,i_,-1],Q9=[0,Ty,-3],ms=[0,wv],Or=[0,sI,1,sI,-5],MH=function(){var N=[2,1,24],C=[2,0,1],e=aq.apply(C[N[1]],arguments).flat(Infinity),L=f[40](9,C[N[1]],e);return(L=(e=L.filter(function(h){return W[4](2, +h,1)===7}).length,S[11](48,C[0],l[8](66,C[0],N[2],3,C[N[1]],L),C[0])),K)[13](N[1],C[0],C[N[1]],"",C[N[0]],L,e)},tN=[0,sI,-(P[31](28,8,K[4].bind(null,2)),4)],Ur=[0,sI,-(P[31](28,53,W[23].bind(null,24)),9)],Di=[0,wv],qn=[0,wv,sI,-1,Bg,i_,-1,sI,-5,YF,tN,-1,Ty,Q9,wv],uW=[0,sI,[0,i_,-3,wv],wv,-2,[0,i_,-1],Ty],Ba=[0,wv,sI,-8],LX=function(N){return K[42].call(this,66,N)},zJ=function(N,C){return S[39].call(this,32,N,C)},b4=function(N){return f[27].call(this,88,N)},j4=[0,[1,2,3,4,5,6],Hg,dl,Hg,am,Hg,bx,Hg, +ms,Hg,qn,Hg,xN],Ss=(T[40](32,pP,p),function(N,C,e){return P[29].call(this,1,N,C,e)}),Gd=[0,wv,1,gl,1,(P[31](28,12,function(N,C,e,L){return(L=(C=H[40](10,e,C),""+N)[YB+vT](C))&&L.length>=2?L[1]:""}),Or),sI,-1,Ba,Vt,LH,zm,Bg,$N,wl,Ur,MU,1,Di,1,CH,1,dl,j4,am,bx,qn,e4,xN,uW,4,hN],rr=function(N){return S[12].call(this,1,N)},ca=[0,(Lf[pP.prototype.D=f[38](27,Gd),66321687]=Gd,DU)],KH=[0,wv,Bg],c7=function(){AN.apply(this,arguments)},y9=[0,qG,Ty,Bg],iW=[0,Ty,-1,wv,Ty],va=[0,DU,i_,-2],nH=[0,Bg,-1,sI],I7=(P[31](8, +23,P[46].bind(null,73)),[0,wv,va,ca]),R7=[0,sI,(P[31](12,36,l[19].bind(null,6)),-1)],FY=function(N){return f[26].call(this,22,N)},lW=[0,X_,-1,vg,j9,-1],Td=[0,i_,sI,-1],Zi=[0,wv,-1],B0=((T[40](2,OH,p),P[31](20,19,l[41].bind(null,17)),T)[40](32,hZ,p),function(){return l[25].call(this,24)}),o7=[-4,{},HT,wv,Gi],Pa=[-37,{},qG,sI,YF,R7,kF,1,kF,lW,sI,Td,Ty,i_,Bg,sI,-1,MG,Lp,qG,kF,wv,vg,Bg,-1,Zi,sI,Ty,sI,nV,sI,-1,(OH.prototype.D=f[38](73,o7),tV),1,tV,o7,Ty,I7,KH],I6=(((T[hZ.prototype.D=f[38](26,Pa),40](56, +BL,p),BL).prototype.a7=function(N){return y[44](13,2,this,N)},BL.prototype).D=f[38](67,[-19,{},Gd,wv,YF,Pa,qG,rv,sI,-1,qG,wv,-1,iW,nH,y9,Bg,1,EI,1,o7]),Dg.prototype.a7=function(N){return this.i.a7(N),this},function(N,C,e,L){return T[3].call(this,1,N,C,e,L)}),un=function(N,C,e,L,h){return U[13].call(this,72,h,L,N,C,e)};function q9(N){return f[27].call(this,56,N)} +var sr=[0,(P[31](4,57,P[q9.prototype.reset=(q9.prototype.getValue=function(){return this.B},function(){this.i=this.B=this.G}),40].bind(null,1)),i_),sI],fH=[0,X_],XY=[0,X_],S4=[0,i_,wv],Yi=[0,sI,wv,-1],Wa=[0,(P[31](16,3,function(N,C,e){return((""+N)[C=H[40](9,"g"+e,C),YB+vT](C)||[]).length}),P[31](28,21,l[3].bind(null,3)),YF),Yi,Bg],Ha=[0,sI,-1],ki=(T[40](2,w3,p),P[31](8,24,P[6].bind(null,2)),l)[12](32,"",w3),rh=(T[40]((w3.prototype.D=f[38](67,[-8,dW,qG,fH,Wa,XY,YF,S4,YF,sr,YF,Ha]),3),d3,p),[0,i_]); +d3.prototype.D=f[38](75,rh); +var pH,MR=((((dW[pH=new IN,175237375]=rh,T)[40](38,RX,K2),RX.prototype).U=function(N){(T[35](8,(N=[!1,!0,"U"],N[1]),this),T[13](68,N[0],this.i),T[13](71,N[0],this.h),K2.prototype)[N[2]].call(this)},RX).prototype.log=function(N,C,e,L,h,Q,m,O,t,D){(T[46](20,(L=[21,3,(D=["K","splice",null],0)],D[2]),this,2,1),this.S)&&(Q=y[39](2,34,N),O=this.I++,m=N=T[21](88,Q,L[0],O),U[47](44,D[2],64,W[33](25,m,1))==D[2]&&(h=Date.now(),t=Number.isFinite(h)?h.toString():"0",f[13](57,"bigint",m,t,1)),y[15](32,!1,"-", +64,D[2],W[33](21,m,15,void 0,void 0,P[0].bind(D[2],45)))!=D[2]||T[21](56,m,15,(new Date).getTimezoneOffset()*60),e=N,T[46](22,D[2],this,1,1),C=this.B.length-1E3+1,C>L[2]&&(this.B[D[1]](L[2],C),this[D[0]]+=C,T[46](19,D[2],this,L[1],C)),this.B.push(e),this.B3||this.i.B||this.i.start())},RX.prototype.flush=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){this.B.length===(h=(c=[(O=this,"l"),"i","V"],[!1,"throttled",5]),0)?N&&N():(m=Date.now(),this[c[0]]>m&&this.X<m?C&&C(h[1]):(this.hc&&(typeof this.hc.K6==="function"? +v[24](5,this.o,this.hc.K6()):this.o.o=0),G=this.B.length,u=W[35](4,9,h[0],h[2],3,this.K,this.BE,this.j,this.B,this.o),(q=this.jP())&&this.Y===q?C&&C("stale-auth-token"):(this.B=[],this[c[1]].B&&T[13](70,h[0],this[c[1]]),this.K=0,e=u.G2(),L=function(){O.hc&&O.hc.send(Q,B,t)},this[c[2]]&&(e.length<this[c[2]].Za?0:typeof CompressionStream!=="undefined")&&(D=W[38](1,2,3,1,4,e)),B=function(A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA){if((hA=[46,(X=[null,0,175237375],"X"),0],O).G.reset(),O.i.setInterval(O.G.getValue()), +A){w=X[hA[2]];try{M=QI(GH(A.replace(")]}'\n",""))),w=ki(M)}catch(mQ){}if(w){x=((k=Number(f[29](1,w,1,l[hA[0]](48,ay()))),k>X[1])&&(O[hA[1]]=Date.now(),O.l=O[hA[1]]+k),z=w,P[18](54,ro)),Jd&&x&&((n=z.z2[x])==X[hA[2]]?void 0:n[X[2]])!=X[hA[2]]&&f[21](11,1,3,y3);a:{if(P[18](38,(g=g===void 0?!1:g,TV))&&P[18](hA[0],ro)&&void 0===TV){if(Y=(d=z.z2,d[ro]),!Y)break a;if(F=Y.Dn)try{F(d,X[2],CY);break a}catch(mQ){T[hA[2]](69,mQ)}}g&&(E=z.z2,(J=P[18](14,ro))&&J in E&&(Z=E[J])&&delete Z[X[2]])}if(R=(a=pH.ctor? +pH.i(z,pH.ctor,X[2],pH.B):pH.i(z,X[2],X[hA[2]],pH.B),a)===null?void 0:a)r=T[8](16,1,R,-1),r!==-1&&(O.G=new q9(r<1?1:r),O.i.setInterval(O.G.getValue()))}}(N&&N(),O).j=X[1]},t=function(A,n,R,F,Z,X,Y,k,E){(((A===((R=(k=(Z=(Y=y[48]((E=(F=["net-send-failed",null,14],[2,500,"G"]),E[0]),3,u,y[11](35),hZ),Number(f[29](E[0],u,F[E[0]]))),X=O[E[2]],n),X.i=RY(3E5,X.i*E[0]),ae(.1*(Vn()-.5)*E[0]*X.i)),X.B=RY(3E5,X.i+R),O).i.setInterval(O[E[2]].getValue()),401)&&q&&(O.Y=q),Z)&&(O.K+=Z),k===void 0&&(k=E[1]<=A&&A< +600||A===401||A===0),k&&(O.B=Y.concat(O.B),O.B3||O.i.B||O.i.start()),T)[46](18,F[1],O,7,1),C)&&C(F[0],A),++O.j},Q=P[47](1,q,this,e),D?D.then(function(A,n,R){((((T[46](17,null,O,(n=(R=[0,"Content-Encoding",2],["Content-Type",2,5]),n[R[2]]),G),Q.wz)[R[1]]="gzip",Q).wz[n[R[0]]]="application/binary",Q).body=A,Q.UZ=n[1],L)()},function(){T[46](16,null,O,6,G),L()}):L())))},function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){return H[31].call(this,16,N,C,e,L,h,Q,m,O,t,D,q,u,B,G)}),l9=((((((((T[40](32,((IX.prototype.K6= +function(){return 4},IX).prototype.send=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G){return P[44](13,(q=this,function(c,A,n){A=[0,(n=["J",2,8],408),null];switch(c.B){case 1:return B=(D=q.za?new AbortController:void 0)&&N.SP>A[0]?setTimeout(function(){D.abort()},N.SP):void 0,c.K(n[1],3),t=Object.assign({},{method:N.oF,headers:Object.assign({},N.wz)},N.body&&{body:N.body},N.withCredentials&&{credentials:"include"},{signal:N.SP&&D?D.signal:null}),c.i(fetch(N.url,t),5);case 5:if((O=c.G,O.status)!==200){(m=e)== +A[n[1]]||m(O.status),c.js(3);break}if((h=C)==A[n[1]]){c.js(7);break}return c.i(O.text(),n[2]);case n[2]:h(c.G);case 7:case 3:((c[n[0]](),clearTimeout)(B),c).S(A[0]);break;case n[1]:L=c.o();switch((G=L)==A[n[1]]?void 0:G.name){case "AbortError":(u=e)==A[n[1]]||u(A[1]);break;default:(Q=e)==A[n[1]]||Q(400)}c.js(3)}}))},ni),K2),ni.prototype.Ec=function(){return this.i=!0,this},oM(1024,-3),oM(1024,-2),oM(1024,2),oM(1024,3),oM)(1024,4),oM)(1024,5),oM(1024,6),oM)(1024,7),oM(1024,8),lk(),uq)(),bF)(),In(), +Bp(),b3)(),wx(),xt)(),{}),TS=(Tk.prototype.U5=(Tk.prototype.f8=function(){return P[32].call(this,2)},function(){return this.B}),Tk.prototype.toString=function(){return this.B},Tk.prototype.v2=null,{}),QK={},oi={},qw={},P8=(T[0](85,kN,Tk),kN.prototype.sm=TS,function(N){function C(e){this.B=e}return C.prototype=N.prototype,function(e,L,h){return L!==(h=new C(String(e)),void 0)&&(h.v2=L),h}}(kN)),JF=RegExp.prototype.hasOwnProperty(t7()),E1=new RegExp((JF?"":bn())+"(?:!|/?([a-zA-Z][a-zA-Z0-9:-]*))",JF? +eS():LW()),fJ=((T[40](38,LA,kN),LA.prototype).U5=function(N,C,e,L,h){if((h=["i","B",""],this[h[1]])!==void 0)return this[h[1]];N=P[C=h[2],4](12,this[h[0]]),e=N.next();try{for(;!e.done;e=N.next())C+=e.value}finally{e&&!e.done&&(L=N.return)&&L.call(N)}return C},LA.prototype.toString=function(){return this.U5()},function(){function N(){this.B=""}return N.prototype=LA.prototype,function(){return new N}}()),TJ={"\x00":yH(),"\t":Ct(),"\n":yf(),"\v":zL(),"\f":Ov(),"\r":U7()," ":N8(),'"':TG(),"&":zI(),"'":D3(), +"-":PD(),"/":Zq(),"<":ut(),"=":JQ(),">":z8(),"`":jo(),"…":M6()," ":o2(),"\u2028":Si(),"\u2029":H6()},uw={"\x00":((((((((((((((((((((((((((((((Xv(),pr)(),P5)(),Hp(),bq)(),on(),qu(),wy)(),kV)(),E7(),AU(),Ik)(),uV)(),rs)(),uP(),AO)(),M2)(),MA)(),l3(),hj)(),nK)(),fZ)(),kP)(),vD(),m9(),B$(),gO(),cY(),GD(),D1(),a8(),rS)(),tc(),f4)(),yr)(),tU(),AY)(),Bm(),H5(),Se(),iF(),L0)(),Y$)(),Nb(),d$)(),hL(),E8(),dz(),Qs)(),FB)(),hT(),so(),CD)(),hn)(),cN)(),Jm)(),cM(),xT)(),zq(),E2(),wI(),vu)(),"":Hs(),"":YG(),"":J1(), +"":aW(),"":J9(),"":bh(),"":by(),"\b":ZT(),"\t":Qd(),"\n":MJ(),"\v":Z2(),"\f":l7(),"\r":TL(),"":Qu(),"":qF(),"":Ia(),"":ho(),"":yz(),"":lJ(),"":ac(),"":s8(),"":sX(),"":g9(),"":Z4(),"":RZ(),"":j_(),"":T4(),"":rI(),"":GI(),"":y7(),"":IW()," ":qe(),'"':zX(),"'":Zl(),"(":lQ(),")":AL(),"<":sp(),">":Fg(),"\\":RO(),"{":st(),"}":ik(),"":i3(),"…":$u()," ":cm(),"\u2028":i7(),"\u2029":iL(),"!":wz(),"#":Wu(),"$":l$(),"&":Lr(),"'":O8(),"(":CI(),")":Oe(),"*":Xb(),"+":lK(),",":Ne(),"/":F6(), +":":MS(),";":OJ(),"=":wB(),"?":s0(),"@":vx(),"[":Wb(),"]":zx()},JN=[0,au,fV,Iu],op=/[\x00\x22\x26\x27\x3c\x3e]/g,qy=/</g,Er=[0,Iu],zd=[0,(P[31](4,55,U[18].bind(null,1)),au),fV],dh=[0,Gy,-2],wh=[0,((T[40](38,Th,p),Th.prototype.kx=function(){return f[29](2,this,5)},Th.prototype).D=f[38](67,[0,fV,-1,au,yF,Gy,fV,JN,zd,dh,Er]),T[40](27,L1,p),wv),i_],V9=[0,Bg,i_,(T[L1.prototype.D=f[38](26,wh),40](58,us,p),Bg)],xi=[0,wv,AV,-1,(T[us.prototype.D=f[38](75,((us.prototype.kx=function(){return f[29](1,this,1)}, +us.prototype).y7=function(){return f[29](8,this,3)},V9)),40](60,u4,p),Ty),V9,sI,-1],a7=[(T[40](34,(u4.prototype.D=f[38](67,xi),UV),p),0),YF,xi,YF,wh],gh=[0,wv,(((T[40](60,(UV.prototype.D=f[38](27,a7),q0),p),q0.prototype).getValue=function(){return T[8](17,2,this)},q0).prototype.clearValue=function(){return H[38](5,this,void 0,2)},i_),sI,i_],bW=[(((q0.prototype.D=f[38](26,gh),T)[40](3,jX,p),P[31](20,10,I[15].bind(null,9)),P)[31](12,38,K[36].bind(null,2)),0),AV,Bg,Ty,i_,a7,gh,wv,i_,-1],Mn=[0,i_,((T[40](27, +(jX.prototype.D=f[38](27,(jX.prototype.kx=function(){return f[29](2,this,2)},bW)),Du),p),P)[31](8,60,y[20].bind(null,58)),-1)],$i=[(P[31]((Du.prototype.D=f[38](67,Mn),4),35,function(N){return H[2](5,!1,function(C,e,L,h){for(L=(h=[26,"getPrototypeOf",96],h[2]);L!=h[0];){if(L==12)return N.value;if(L==49)return e=C.Object[h[1]](N),I[35](81,"",e,uD())instanceof EA?"":C.Object.getOwnPropertyDescriptor(e,uD()).get.call(N);L==h[2]&&(L=C.Object.hasOwnProperty.call(N,uD())?49:12)}})}),T[40](3,UO,p),0),wv, +DU,-1],Ng=[0,i_,(T[40](3,(UO.prototype.D=f[38](75,$i),TC),p),DU),-1,i_],CQ=[0,i_,DU,-1,Ng,(T[40](2,(TC.prototype.D=f[38](73,Ng),lH),p),-1),i_,-2],JG=((lH.prototype.D=f[38](27,CQ),T[40](26,OA,p),OA).prototype.D=f[38](27,[0,YF,$i,-1,CQ,X_,Mn]),Symbol)(Px()),JA={},fS=(T[0](93,oj,yE),Qw()),Lv=Rc(),Aa=(T[0](93,Js,((oj.prototype.G=function(N){P[12](57,N,this)},oj.prototype).U=(oj.prototype.B=function(N,C){(C=[3,13,12],N.keyCode==C[1]||M3&&N.keyCode==C[0])&&P[C[2]](56,N,this)},function(N){delete ((oj.L.U.call((N= +[!1,35,0],this)),f[N[1]](34,N[2],this,N[0],this.i,oF,this.B),f)[N[1]](32,N[2],this,N[0],this.i,PV,this.G),this).i}),hP)),[]),pj=function(N){return U[7].call(this,4,N)},O5=((((T[0](85,pj,hP),T)[40](32,mT,yE),mT.prototype.B=function(N,C,e,L){if((e=Date[(L=["now",1E3,"preventDefault"],L)[0]]()-this.G,C)||e>L[1])N.type=O5,v[44](35,this,N),N.i(),this.V||N[L[2]]();return!1},mT.prototype).K=function(N,C,e){if(N.type==(e=["B",!0,!1],PQ))this.G=Date.now(),N.i();else if(N.type==s1&&(C=Date.now()-this.G,N.O5.cancelable!= +e[2]&&C<500))return this[e[0]](N,e[1]);return e[1]},mT.prototype).P=function(N){return N.keyCode==32&&N.type==uA?this.B(N):!0},mT.prototype.U=function(N){f[35](36,(N=[!1,0,"call"],N[1]),this,N[0],this.o,fS,this.B),f[35](38,N[1],this,N[0],this.i,[PQ,s1],this.K),yE.prototype.U[N[2]](this)},Qw()),SJ=(pF(),y_()),YE=Ai(),VM=lg(),t4=tO(),xE=((KL(),ti(),LZ(),Qb)(),Ry)(),W_=ge(),ed=uu(),H_=((A9(),nL)(),SI()),aM=OR(),gL=tH(),Jf=zD(),LQ=(P[31](16,44,I[23].bind(null,16)),KI()),kE=(Rh(),SC)(),rL=Tf(),pm=bL(), +J4=xC(),hD=($A(),qo(),qv()),E5=xp(),zb=Ws(),dL=XL(),Q0=(FS(),HC)(),wL=(s3(),Vv)(),m_=(((((((((((((((($H(),xP)(),h9(),jI)(),FH(),P)[31](20,16,function(N,C,e,L,h,Q,m,O,t,D,q){for(t=!(D=(q=(O=60,Q=undefined,[2817,53,"src"]),q)[1],1);;)try{if(O==80)break;else{if(O==20)return N.nodeType==1&&N[q[2]]&&S[36](40).test(N[q[2]])?!1:!0;if(O==93)O=N.innerHTML.indexOf(e.value)!=-1?82:77;else if(O==60)O=N&&N.nodeType!=3?89:29;else if(O==65)Q!==undefined?(O=Q,Q=undefined):O=20;else if(O==28)D=0,O=57;else if(O==57)O= +31;else{if(O==29)return!1;if(O==82)m=!1,Q=45,O=40;else if(O==77)e=L.next(),O=31;else if(O==89)O=N.innerHTML?49:20;else if(O==40)D=q[1],e&&!e.done&&(C=L.return)&&C.call(L),O=65;else if(O==49)L=P[4](12,U[4](10,q[0])),e=L.next(),O=28;else{if(O==45)return m;if(O==31)O=e.done?40:93;else if(O==26)throw h;}}}}catch(u){if(D==q[h=u,1])throw u;D==0&&(Q=26,O=40)}}),NA(),Qk)(),sh)(),OM)(),n7)(),K_)(),Qa(),OX(),sh(),ND)(),R8)(),Vf(),rC)(),cw(),Qv)(),gN(),fe)(),v6(),D$(),r9)(),sh)(),V6(),FQ)(),Oi=lM(),U5=((((((((Oh(), +QH)(),FQ(),lM(),QH(),FQ)(),lM(),QH)(),lM)(),FQ)(),Ma)(),GK(),FQ(),lM)(),Oh(),QH(),FQ)(),DO=lM();QH(); +var XA,tD=(((vC(),MN)(),BO)(),vK(),Hx(),J7()),Ui=h1(),DA=(((((((((((Q7(),RC(),D4)(),A6(),at)(),Up)(),HD)(),eC(),$L(),Ze)(),Lt(),k$)(),pG(),KY)(),K_(),NA(),y8)(),qE(),YV(),sy(),cF)(),m1(),kb(),c6)(),mZ()),qg=So(),uX=bP(),BI=(((fW(),av)(),L4)(),LJ(),bV(),ov()),jd=((((((jQ(),$C(),uN(),re)(),ES)(),ug(),iP(),w1(),Ey)(),cs)(),Xd)(),UJ(),dy()),GF=(((((((N2(),Z3(),je)(),hi)(),dK(),a_)(),gG)(),FU)(),RD)(),P[31](24,58,P[42].bind(null,56)),Ac)(),fm=HF(),BH=se(); +function vr(N,C,e,L){return f[10].call(this,1,N,e,L,C)} +var $x=(vr.prototype.ceil=(vr.prototype.floor=function(){return(this.bottom=(this.right=(this.top=TH(this.top),TH(this.right)),TH(this.bottom)),this).left=TH(this.left),this},function(){return this.bottom=(this.top=wq(this.top),this.right=wq(this.right),wq)(this.bottom),this.left=wq(this.left),this}),vr.prototype.round=function(){return(this.bottom=(this.top=ae(this.top),this.right=ae(this.right),ae)(this.bottom),this).left=ae(this.left),this},function(N){return f[18].call(this,3,N)}),J5=function(N, +C,e,L){return y[25].call(this,20,N,C,e,L)};function XQ(N,C,e,L){return T[33].call(this,1,e,L,C,N)} +var eb=(XQ.prototype.ceil=((XQ.prototype.round=function(){return this.height=((this.top=(this.left=ae(this.left),ae(this.top)),this).width=ae(this.width),ae(this.height)),this},XQ.prototype).floor=function(){return(this.width=(this.top=(this.left=TH(this.left),TH(this.top)),TH)(this.width),this).height=TH(this.height),this},function(){return this.height=(this.width=(this.top=(this.left=wq(this.left),wq)(this.top),wq)(this.width),wq(this.height)),this}),function(N,C,e,L){return U[11].call(this,1,N, +C,e,L)}),cI=bj?O3():M3||DP?x9():null;function KQ(){return W[31].call(this,8)}(S[42](84,KQ),KQ).prototype.i=0;function QY(N,C){return y[25].call(this,1,N,C)} +var es=((T[0](90,QY,yE),QY).prototype.PK=KQ.M(),null),Pj=(Zp(),sn(),Yh(),Jj()),sP=tL(),fX=NE(),Xk=lm(),SL=Un(),Yr=FE(),Wj=It(),Hj=wG(),kr=Bw(),rm=$y(),pX=xA(),Jh=c5(),EP=Q1(),zC=x0(),AD={Up:38,Down:40,Left:37,Right:39,Enter:13,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,"U+007F":46,Home:36,End:35,PageUp:33,PageDown:34,Insert:45},Bq=YO(),a5=ak(),y0=Qw(),iX=dI(),vI=Sa(),WR=(KD(),kT()),ze=dN(),QD=Ut(),wm=ZQ(),dm=(cC(),yb()),hW=((V=(P[31](24,59,function(N,C, +e,L,h,Q,m,O,t,D,q,u){for(q=(t=[60,21,(u=64,45)],t[0]);;)try{if(u==18)break;else if(u==20)q=t[0],u=18;else if(u==64)return q=82,Q=new Rp,m=U[4](18,4157)(e(f[38](85),41)),O=U[4](34,3273)(m(),h.join(Pp()),ep()),I[22](t[1],2,Q,l[36].bind(null,73),T[t[2]].bind(null,5),1,O),Q.G2()}catch(B){if(q==t[0])throw B;q==82&&(D=B,u=20)}}),QY).prototype,QY.prototype.v=function(){return this.B},V.Q7=function(N){if(this.o&&this.o!=N)throw Error(vI);QY.L.Q7.call(this,N)},V).vm=function(){this.B=this.A.createElement(EC)}, +function(N){return K[28].call(this,16,N)}); +((QY.prototype.Vl=function(){T[38](23,(this.nu=!0,this),function(N){!N.nu&&N.v()&&N.Vl()})},V).bz=(V.render=(V.Yx=function(N){this.B=N},function(N,C){if(C=["B","insertBefore","i"],this.nu)throw Error(WR);((this[C[0]]||this.vm(),N)?N[C[1]](this[C[0]],null):this.A[C[2]].body.appendChild(this[C[0]]),this.o)&&!this.o.nu||this.Vl()}),QY.prototype.s5=function(){return this.B},function(N){this.nu=(this[T[38](24,this,(N=["Y",!1,31],function(C){C.nu&&C.bz()})),N[0]]&&v[18](N[2],this[N[0]]),N[1])}),QY).prototype.U= +function(N){(this.B=this[((N=[48,"K",38],this).nu&&this.bz(),this.Y&&(this.Y.dispose(),delete this.Y),T[N[2]](22,this,function(C){C.dispose()}),this.B)&&W[N[0]](56,this.B),this.o=this.V=null,N[1]]=null,QY).L.U.call(this)};function nQ(N,C,e,L){return H[1].call(this,65,N,C,e,L)}var g0=(T[0](88,nQ,hP),P$());function mS(N,C){return P[13].call(this,7,N,C)} +var I1=(((T[0](94,mS,yE),mS.prototype).G=function(N,C,e){if((C=[91,(e=["handleEvent","shiftKey",17],13),18],M3&&(this.BK==e[2]&&!N.ctrlKey||this.BK==C[2]&&!N.altKey||gw&&this.BK==C[0]&&!N.metaKey)&&(this.t2=this.BK=-1),this.BK)==-1&&(N.ctrlKey&&N.keyCode!=e[2]?this.BK=e[2]:N.altKey&&N.keyCode!=C[2]?this.BK=C[2]:N.metaKey&&N.keyCode!=C[0]&&(this.BK=C[0])),I[3](21,C[1],C[0],N.metaKey,N[e[1]],N.altKey,this.BK,N.keyCode,N.ctrlKey))this.t2=l[1](e[2],173,N.keyCode),I1&&(this.Cs=N.altKey);else this[e[0]](N)}, +mS.prototype).B=null,gw&&bj),Fs={oy:gQ,q4:bp,IF:$m,D3:((((V=mS.prototype,mS.prototype.i=null,V).Cs=!1,(mS.prototype.U=function(N){mS.L.U[N=[null,41,"call"],N[2]](this),W[44](N[1],N[0],this)},V).wo=function(N){return P[47].call(this,12,N)},(mS.prototype.v=function(){return this.i},V).t2=(mS.prototype.handleEvent=function(N,C,e,L,h,Q,m,O,t,D){if(((m=Q=l[1](16,173,(e=(h=(D=[36,(t=N.O5,"t2"),9],[224,25,0]),t.altKey),M3&&N.type==q$?(Q=this[D[1]],O=t.charCode>=h[2]&&t.charCode<63232&&T[5](32,!1,Q)?t.charCode: +0):(N.type==q$?(I1&&(e=this.Cs),t.keyCode==t.charCode?t.keyCode<32?(Q=t.keyCode,O=h[2]):(Q=this[D[1]],O=t.charCode):(Q=t.keyCode||this[D[1]],O=t.charCode||h[2])):(O=t.charCode||h[2],Q=t.keyCode||this[D[1]]),gw&&O==63&&Q==h[0]&&(Q=191)),Q)))?Q>=63232&&Q in Mu?m=Mu[Q]:Q==h[1]&&N.shiftKey&&(m=D[2]):t.keyIdentifier&&t.keyIdentifier in AD&&(m=AD[t.keyIdentifier]),!bj||N.type!=q$)||I[3](5,13,91,N.metaKey,N.shiftKey,e,this.BK,m,N.ctrlKey))L=m==this.BK,this.BK=m,C=new nQ(m,O,L,t),C.altKey=e,v[44](D[0],this, +C)},-1),V).VB=null,V.Dq=null,V).BK=-1,Mj),te:lb,rW:TP,TQ:VL,wy:bd},R1,F5=(S[42](83,La),Lx)(tD,hD,Ui,t4,DA,Q0,qg,t4,uX,t4,BI,t4,jd,Q0,GF,Q0),jG=(La.prototype.cK=(La.prototype.yY=function(N,C,e,L,h,Q,m,O,t,D,q){return((e=(C.Wm=(m=(h=(D=(L=this[Q=((q=(O=[!1," ",'"'],["cK",1,"nextSibling"]),N.id)&&P[39](17,O[2],C,N.id),N&&N.firstChild?l[17](24,C,N.firstChild[q[2]]?v[40](52,N.childNodes):N.firstChild):C.RX=null,0),q[0]](),this[q[0]]()),t=O[0],O)[0],v[40](37,U[19](32,N))),m.forEach(function(u,B,G){(B=[!0, +(G=[2,14,0],0),10],t||u!=L?h||u!=D?Q|=S[38](10,B[G[0]],"-hover",this,u):h=B[G[2]]:(t=B[G[2]],D==L&&(h=B[G[2]])),S[38](G[1],B[G[0]],"-hover",this,u)==1)&&W[G[0]](3,B[1],N)&&I[29](66,B[1],N,!1)},this),Q),t||(m.push(L),D==L&&(h=!0)),h||m.push(D),C.X))&&m.push.apply(m,e),t&&h&&!e)||K[2](21,"string",m.join(O[q[1]]),N),N},La.prototype.C6=(La.prototype.Mk=function(N,C,e){cI&&(e=C?"":sh(),N.style&&(N.style[cI]=e))},La.prototype.m1=function(N,C){K[46](2,N,this.cK()+"-rtl",C)},La.prototype.zm=function(N,C){(N[N[C= +["nu","E5","v"],C[1]]==null&&(N[C[1]]="rtl"==P[13](3,N[C[0]]?N.B:N.A.i.body,"direction")),C[1]]&&this.m1(N[C[2]](),!0),N).isEnabled()&&this.Eb(N,N.isVisible())},function(N,C,e){return N[e=[0,"Cu","v"],e[1]]&32&&(C=N[e[2]]())?W[2](5,e[0],C):!1}),(La.prototype.KP=function(N,C){return C=[36,"A","join"],N[C[1]].ZS(EC,I[C[0]](5,this,N)[C[2]](OY()),N.U5())},La).prototype.Ih=(La.prototype.Eb=function(N,C,e,L){if((L=[null,6,29],N.Cu&32)&&(e=N.v())){if(!C&&N.vL()){try{e.blur()}catch(h){}N.vL()&&N.gO(L[0])}W[2](L[1], +0,e)!=C&&I[L[2]](3,0,e,C)}},La.prototype.Qk=function(N,C,e,L,h,Q,m,O){(m=(h=(R1||(R1={1:xE,8:Q0,16:t4,64:ed}),R1)[C],N.getAttribute(BH))||null)?(L=F5[m]||h,O=h==t4||h==Q0?L:h):O=h,(Q=O)&&K[13](42,Q,N,e)},function(N,C,e,L,h,Q){if(L=(Q=[9,"v",46],N[Q[1]]()))(h=v[Q[0]](40,C,this))&&K[Q[2]](1,N,h,e),this.Qk(L,C,e)}),La.prototype.B9=function(){},function(){return"goog-control"}),{});function jj(N,C,e,L,h,Q,m,O){return P[7].call(this,40,N,C,e,L,h,Q,m,O)} +var lX=(((((((((V=(((((((V=((((T[0](95,jj,QY),jj.prototype).s5=function(){return this.v()},V=jj.prototype,V).Qq=!0,V.Wm=0,V.Cu=39,V.SZ=255,V).RX=null,jj.prototype),V).I7=!0,jj.prototype.Yx=function(N,C){((this.B=N=(C=["Mk","yY","G"],this[C[2]][C[1]](N,this)),l)[29](6,null,this[C[2]],N),this[C[2]][C[0]](N,!1),this).Qq=N.style.display!="none"},V.U=function(N){(delete this[(jj[(N=["G","L","U"],N)[1]][N[2]].call(this),this).l&&(this.l.dispose(),delete this.l),N[0]],this).RX=this.X=null},jj).prototype.X= +null,V.Vl=function(N,C,e,L,h,Q){((((((L=(N=(Q=[33,(h=[8,64,16],"zm"),48],jj.L.Vl.call(this),this.B),this.G),this.isVisible())||K[13](39,aM,N,!this.isVisible()),this).isEnabled()||L.Qk(N,1,!this.isEnabled()),this.Cu)&h[0]&&L.Qk(N,h[0],!!(this.Wm&h[0])),this).Cu&h[2]&&L.Qk(N,h[2],this.gq()),this).Cu&h[1]&&L.Qk(N,h[1],!!(this.Wm&h[1])),this.G)[Q[1]](this),this.Cu&-2&&(this.I7&&U[32](Q[0],!0,this),this.Cu&32&&(C=this.v()))&&(e=this.l||(this.l=new mS),W[Q[2]](49,e,C),y[22](44,y[22](55,y[22](Q[0],y[10](19, +this),e,g0,this.Nh),C,CR,this.qo),C,NU,this.gO))},V).vm=function(N,C){(this.B=N=(C=["G",!1,7],this[C[0]].KP(this)),l[29](C[2],null,this[C[0]],N),this)[C[0]].Mk(N,C[1]),this.isVisible()||(P[49](2,N,C[1]),N&&K[13](58,aM,N,!0))},jj.prototype.bz=function(N){(((N=[44,"isEnabled","L"],jj[N[2]]).bz.call(this),this).l&&W[N[0]](40,null,this.l),this.isVisible()&&this[N[1]]())&&this.G.Eb(this,!1)},V).U5=function(){return this.RX},jj.prototype.isVisible=function(){return this.Qq},jj.prototype).isEnabled=function(){return!(this.Wm& +1)},jj.prototype).I6=function(N,C,e,L){(C=(L=[!1,2,"o"],this)[(e=[4,!0,64],L)[2]],C&&typeof C.isEnabled=="function"&&!C.isEnabled())||!H[47](32,e[L[1]],1,!N,this)||(N||(v[0](14,e[0],L[0],this),v[41](22,L[1],L[0],this)),this.isVisible()&&this.G.Eb(this,N),K[47](76,1,1,!N,this,e[1]))},jj.prototype.isActive=function(){return!!(this.Wm&4)},jj.prototype),V).Iz=function(N,C){(C=[64,48,75],H)[47](C[1],C[0],16,N,this)&&K[47](C[2],1,16,N,this)},V.vL=function(){return!!(this.Wm&32)},V.WE=function(N,C){H[C= +[73,47,16],C[1]](C[2],64,32,N,this)&&K[C[1]](C[0],1,32,N,this)},V).M7=function(N,C,e){(e=[(C=[!0,2,4],41),"G",1],this).isEnabled()&&(P[26](3,this,C[e[2]])&&v[e[0]](21,C[e[2]],C[0],this),N.O5.button!=0||gw&&N.ctrlKey||(P[26](5,this,C[2])&&v[0](12,C[2],C[0],this),this[e[1]]&&this[e[1]].C6(this)&&this.v().focus())),N.O5.button!=0||gw&&N.ctrlKey||N.preventDefault()},V).gq=function(){return!!(this.Wm&16)},V=jj.prototype,V).Xq=function(N){return P[42].call(this,1,N)},jj).prototype.R=function(N,C,e){(C= +[2,4,!(e=[!0,"F",26],1)],this.isEnabled())&&(P[e[2]](3,this,C[0])&&v[41](23,C[0],e[0],this),this.isActive()&&this[e[1]](N)&&P[e[2]](4,this,C[1])&&v[0](28,C[1],C[2],this))},V.qo=function(){return P[17].call(this,9)},V.hu=function(N,C){return P[16].call(this,65,N,C)},jj.prototype).F=function(N,C,e,L,h){return((P[(L=[64,(h=["shiftKey",26,0],8),1],h)[1]](2,this,16)&&this.Iz(!this.gq()),P[h[1]](1,this,L[1])&&H[47](16,L[h[2]],L[1],!0,this)&&K[47](79,L[2],L[1],!0,this),P[h[1]](1,this,L[h[2]])&&(e=!(this.Wm& +L[h[2]]),H[47](23,L[h[2]],L[h[2]],e,this)&&K[47](72,L[2],L[h[2]],e,this)),C=new xW(y0,this),N)&&(C.altKey=N.altKey,C.ctrlKey=N.ctrlKey,C.metaKey=N.metaKey,C[h[0]]=N[h[0]],C.K=N.K,C.timeStamp=N.timeStamp),v)[44](38,this,C)},jj.prototype.Tt=function(N){return N.keyCode==13&&this.F(N)},V).gO=function(){return H[35].call(this,8)},jj.prototype).u=U[22].bind(null,55),jj);if(V.Nh=function(N){return W[30].call(this,57,N)},typeof lX!=="function")throw Error("Invalid component class "+lX); +if(typeof La!=="function")throw Error("Invalid renderer class "+La); +var TF=f[18](12,lX),TA=(((((V=((((V=(U[jG[TF]=La,46](27,function(){return new jj(null)},"goog-control"),T[40](38,J5,jj),J5.prototype),V.uf=function(){this.i==2||this.Md(2)},V.M7=function(N,C){(C=[27,"call",16],jj).prototype.M7[C[1]](this,N),H[C[2]](C[0],this,!0)},V.I6=function(N,C){C=["call","tabIndex","prototype"],jj[C[2]].I6[C[0]](this,N),N&&(this.v()[C[1]]=this[C[1]])},V).vm=function(N){this.B=P[4](2,S[(N=[8,39,":"],N)[0]].bind(null,N[1]),{id:P[9](18,N[2],this),sc:this.X,checked:this.gq(),disabled:!this.isEnabled(), +Uc:this.tabIndex},void 0,this.A)},V).NK=function(N){return(N=["Md",3,"i"],this[N[2]]==N[1])?y[34](2):this[N[0]](N[1])},V).Vl=function(N,C,e,L,h,Q){this[((jj.prototype.Vl.call((Q=["P","Ks",":"],this)),this.I7)&&(h=y[10](23,this),this[Q[0]]&&y[22](44,y[22](32,y[22](48,y[22](33,y[22](28,h,new mT(this[Q[0]]),O5,this[Q[1]]),this[Q[0]],lb,this.Xq),this[Q[0]],TP,this.hu),this[Q[0]],gQ,this.M7),this[Q[0]],bp,this.R),y[22](40,y[22](48,h,new mT(this.v()),O5,this[Q[1]]),new oj(document),fS,this[Q[1]])),Q)[0]]&& +(this[Q[0]].id||(L=this[Q[0]],e=Dl(),N=P[9](13,Q[2],this)+"."+e,L.id=N),C=this.v(),K[13](26,LQ,C,this[Q[0]].id))},J5).prototype,J5.prototype.Iz=function(N){N&&this.gq()||!N&&this.i==1||this.Md(N?0:1)},V).WE=function(N,C){jj[C=[26,!1,"prototype"],C[2]].WE.call(this,N),H[16](C[0],this,C[1])},V.Tt=function(N,C){return(C=[!0,"keyCode",!1],!N||N[C[1]]!=32&&N[C[1]]!=13)?C[2]:(this.Ks(N),C[0])},V).Ks=function(N,C){return K[30].call(this,12,N,C)},V.Md=function(N,C,e,L){if(e=[!1,2,0],L=[1,3,"i"],N==e[2]&& +this.gq()||N==L[0]&&this[L[2]]==L[0]||N==e[L[0]]&&this[L[2]]==e[L[0]]||N==L[1]&&this[L[2]]==L[1])return T[23](34);return(((((N==e[L[0]]&&this.WE(e[0]),this)[L[2]]=N,f)[31](L[0],this,N==e[2],"recaptcha-checkbox-checked"),f)[31](9,this,N==e[L[0]],"recaptcha-checkbox-expired"),f)[31](L[1],this,N==L[1],"recaptcha-checkbox-loading"),(C=this.v())&&K[13](36,t4,C,N==e[2]?m_:Oi),v[44](39,this,iX),T)[23](66)},V).gq=function(){return this.i==0},V).vL=function(N){return(N=["v","recaptcha-checkbox-clearOutline", +36],jj.prototype).vL.call(this)&&!(this.isEnabled()&&this[N[0]]()&&v[N[2]](2,this[N[0]](),N[1]))},nD)(),Zg=HY();function Xp(N,C,e){return v[11].call(this,40,N,C,e)}var ZA=(T[0](95,Xp,K2),Bn()); +((Xp.prototype.V=function(N){(this[((N=["o","i",2],this[N[0]])&&this[N[1]]&&y[40](N[2],this[N[1]]),N)[1]]=null,this).P.call(this.K,P[3](8))},(Xp.prototype.isActive=function(){return this.i!=null},Xp).prototype).HL=function(N,C,e){this[(e=[null,"i","call"],this.isActive())&&(N=W[31](6,e[0],this),C=S[35](1,e[0],this),N&&!C&&this.B.mozRequestAnimationFrame?y[40](2,this[e[1]]):N&&C?C[e[2]](this.B,this[e[1]]):this.B.clearTimeout(this[e[1]])),e[1]]=e[0]},Xp.prototype.U=function(){this.HL(),Xp.L.U.call(this)}, +Xp.prototype).start=function(N,C,e,L){(e=(N=(this.o=(C=[null,!0,20],L=[1,"mozRequestAnimationFrame",0],this.HL(),!1),W[31](11,C[L[2]],this)),S[35](2,C[L[2]],this)),N&&!e&&this.B[L[1]])?(this.i=K[26](13,ZA,this.B,this.G),this.B[L[1]](C[L[2]]),this.o=C[L[0]]):this.i=N&&e?N.call(this.B,this.G):this.B.setTimeout(S[9](7,L[2],this.G),C[2])};function S3(N,C,e){return H[33].call(this,3,N,C,e)} +var sV=((((V=(T[0](91,S3,K2),S3.prototype),V.U=function(N){delete this[(N=["i","call","HL"],S3).L.U[N[1]](this),this[N[2]](),N[0]],delete this.B},V).yy=0,V.start=function(N,C){this[(C=["yy",72,36],this).HL(),C[0]]=W[C[2]](C[1],N!==void 0?N:this.o,this.G)},V).HL=function(N){this.yy=(this[N=[3,"isActive",64],N[1]]()&&S[N[0]](N[2],this.yy),0)},V).isActive=function(){return this.yy!=0},null),f5=null,pC=(V.U8=function(){return W[29].call(this,2)},{}),$g=ZG(),o1=eU(),PI=bT(),JZ=ME(),si=mJ(),Ny=IZ(),fQ= +y1();function Yj(){return P[23].call(this,8)} +var X5=((((T[0](84,Yj,yE),Yj).prototype.P=function(){this.B(Ny)},Yj).prototype.B=function(N){v[44](39,this,N)},T)[0](86,eb,Yj),G1()),Sd=Uo(),Cm=new vS(new ((((((((((((((T[0](89,iK,((eb.prototype.B=function(N){v[44](32,this,new iK(N,this))},eb.prototype.A=function(){this.B(X5)},eb.prototype.play=function(N,C,e,L,h){if(e=[(h=[0,"startTime",3],1),!0,0],N||this.i==e[2])this.progress=e[2],this.coords=this.G;else if(this.i==e[h[0]])return!1;return((C=(this.endTime=this[(L=(y[12](38,e[1],this),P[h[2]](12)), +this)[h[1]]=L,this.i==-1&&(this[h[1]]-=this.duration*this.progress),h[1]]+this.duration,this.progress||this.B(o1),this.B($g),this.i==-1&&this.B(PI),this.i=e[h[0]],f[18](45,this)),C in pC||(pC[C]=this),y)[h[0]](h[2]),T)[11](10,e[1],e[h[0]],L,this),e[1]},(eb.prototype.pause=function(N){(N=[!0,1,"B"],this).i==N[1]&&(y[12](14,N[0],this),this.i=-1,this[N[2]](fQ))},eb).prototype.K=function(N,C){((y[12](30,(C=["progress",25,0],!0),this),this.i=C[2],N&&(this[C[0]]=1),v)[20](C[1],C[2],this[C[0]],this),this).B(si), +this.B(JZ)},eb).prototype.U=function(N){((N=["B",0,"call"],this.i)==N[1]||this.K(!1),this[N[0]](Sd),eb.L.U)[N[2]](this)},xW)),T)[0](86,UP,Yj),UP.prototype.add=function(N,C){S[C=[10,9,"push"],C[1]](43,this.G,N)||(this.G[C[2]](N),K[26](C[0],Ny,N,this.V,!1,this))},UP.prototype).remove=function(N,C){C=[33,!1,20],U[C[2]](14,0,N,this.G)&&f[35](C[0],0,this,C[1],N,Ny,this.V)},UP).prototype.U=function(N){(this[N=["G",0,"call"],this[N[0]].forEach(function(C){C.dispose()}),N[0]].length=N[1],UP.L).U[N[2]](this)}, +T[0](87,vo,UP),vo).prototype.play=function(N,C,e){if(this.G.length==(C=[0,!0,(e=["i","o",1],null)],C[0]))return!1;if(N||this[e[0]]==C[0])this[e[1]]<this.G.length&&this.G[this[e[1]]][e[0]]!=C[0]&&this.G[this[e[1]]].K(!1),this[e[1]]=C[0],this.B(o1);else if(this[e[0]]==e[2])return!1;return((this[(this.endTime=((this.B($g),this)[e[0]]==-1&&this.B(PI),this.startTime=P[3](10),C)[2],e)[0]]=e[2],this).G[this[e[1]]].play(N),C)[e[2]]},vo.prototype).pause=function(N){this[N=["i","G",1],N[0]]==N[2]&&(this[N[1]][this.o].pause(), +this[N[0]]=-1,this.B(fQ))},vo).prototype.V=function(N){if(this.i==(N=["P","play",9],1))if(this.o++,this.o<this.G.length)this.G[this.o][N[1]]();else this.endTime=P[3](N[2]),this.i=0,this[N[0]](),this.B(JZ)},vo.prototype.K=function(N,C,e,L){if(this.endTime=P[L=[!(this.i=0,0),3,"G"],L[1]](2),N)for(e=this.o;e<this[L[2]].length;++e)C=this[L[2]][e],C.i==0&&C.play(),C.i==0||C.K(L[0]);else this.o<this[L[2]].length&&this[L[2]][this.o].K(!1);this.B(si),this.B(JZ)},T[40](28,po,eb),po.prototype).U=function(){(eb.prototype.U.call(this), +this).V=null},po.prototype.P=function(N){this[N=["h","play","prototype"],N[0]]||this[N[1]](!0),eb[N[2]].P.call(this)},po.prototype).A=function(N,C,e){((C=(N=-TH(this.coords[0]/(e=["px ","V","o"],this[e[2]]).width)*this[e[2]].width,-TH(this.coords[1]/this[e[2]].height))*this[e[2]].height,this[e[1]]).style.backgroundPosition=N+e[0]+C+"px",eb.prototype).A.call(this)},T)[40](28,xz,J5),xz.prototype.O=function(N){if(this.T==N)throw Error(IP());this.T=N},xz).prototype.NK=function(N,C){if(this.i==(C=[16, +!0,3],C[2])||this.T)return y[34](C[0]);return(N=y[C[0]](14),S[19](2,C[2],C[1],this,N),N).promise},xz).prototype.vm=function(N){this.B=(N=[":","X",1],P[4](N[2],S[8].bind(null,46),{id:P[9](11,N[0],this),sc:this[N[1]],checked:this.gq(),disabled:!this.isEnabled(),Uc:this.tabIndex,G4:!0},void 0,this.A))},xz).prototype.Vl=function(N){this[(N=["recaptcha-checkbox-spinner-overlay",43,"h"],J5.prototype).Vl.call(this),N[2]]||(this[N[2]]=P[N[1]](15,"recaptcha-checkbox-spinner",this),this.iI=P[N[1]](10,N[0], +this))},xz.prototype.uf=function(N,C,e,L,h,Q,m){(m=[19,(C=[3,!1,2],e=this,!0),1],this.i==C[2]||this.T)||(Q=this.i,N=this.vL(),L=T[32](m[0],C[m[2]],this,m[1]),this.i==C[0]?h=S[m[0]](6,C[0],C[m[2]],this,void 0,m[1]):(h=T[23](97),L.add(this.gq()?W[9](32,m[1],this,C[m[2]]):y[43](37,C[m[2]],this,Q,N,C[m[2]]))),h.then(function(){return e.Md(2)}),L.add(y[43](33,C[m[2]],this,C[2],C[m[2]],m[1])),h.then(function(){L.play()},function(){}))},xz).prototype.Iz=function(N,C,e,L,h,Q,m,O,t,D){(O=(D=[(e=[!1,3,!0], +0),"gq",9],this),N&&this[D[1]]()||!N&&this.i==1||this.T)||(L=this.i,m=N?0:1,C=function(){return O.Md(m)},t=this.vL(),Q=T[32](17,e[D[0]],this,e[2]),this.i==e[1]?h=S[19](3,e[1],e[D[0]],this,void 0,!N):(h=T[23](65),Q.add(this[D[1]]()?W[D[2]](24,e[2],this,e[D[0]]):y[43](35,e[D[0]],this,L,t,e[D[0]]))),N?Q.add(W[D[2]](30,e[2],this,e[2],C)):(h.then(C),Q.add(y[43](32,e[D[0]],this,m,t,e[2]))),h.then(function(){Q.play()},function(){}))},B2)(28,28),"recaptcha-checkbox-borderAnimation",20,new vr(0,560,28,0)), +h4=new vS(new B2(28,28),"recaptcha-checkbox-borderAnimation",10,new vr(0,840,28,560)),eJ=new vS(new B2(28,28),"recaptcha-checkbox-borderAnimation",20,new vr(28,560,56,0)),QM=new vS(new B2(28,28),"recaptcha-checkbox-borderAnimation",10,new vr(28,840,56,560)),NX=new vS(new B2(28,28),"recaptcha-checkbox-borderAnimation",20,new vr(56,560,84,0)),Lm=new vS(new B2(28,28),"recaptcha-checkbox-borderAnimation",10,new vr(56,840,84,560)),b1=new vS(new B2(38,30),"recaptcha-checkbox-checkmark",20,new vr(0,600, +30,0)),MM=new vS(new B2(38,30),"recaptcha-checkbox-checkmark",20,new vr(0,1200,30,600)),Y6=["bgdata",(T[40](32,W9,p),P[31](20,9,function(N){return H[2](19,!1,function(C){return typeof N==="string"?new C.String(N):N})}),W9.yl=B6(),sI),-3];W9.prototype.D=f[38](75,Y6);function Rq(N,C,e){return S[2].call(this,2,N,C,e)} +var WI=((((Rq.prototype.X=((Rq.prototype.cancel=(Rq.prototype.then=function(N,C,e,L,h,Q){return(h=new wu(function(m,O){L=O,Q=m}),I)[43](10,!0,Q,this,function(m){return m instanceof WI?h.cancel():L(m),qh},this),h.then(N,C,e)},function(N,C,e,L){if(this[(L=["cancel","G","i"],L)[1]])this.B instanceof Rq&&this.B[L[0]]();else{if(this[L[2]])if(C=this[L[2]],delete this[L[2]],N)C[L[0]](N);else C.A--,C.A<=0&&C[L[0]]();this[this.J?this.J.call(this.h,this):this.j=!0,L[1]]||(e=new WI(this),H[6](20,!1,this),I[43](45, +!0,this,!1,e))}}),Rq.prototype).aM=function(N,C){(C=[37,21,43],H[6](C[1],!1,this),I)[C[2]](C[0],!0,this,!0,N)},function(N,C){I[43](53,!0,this,(this.V=!1,N),C)}),Rq.prototype)["finally"]=function(N,C){return K[18](2,!1,!0,new (C=this,Promise)(function(e,L){I[43](9,!0,function(h){(N(),e)(h)},C,function(h){L((N(),h))})}))},Rq).prototype[tJ]=!0,T[0](94,hf,sH),hf.prototype).message=N6(),hf.prototype.name=pn(),function(){return W[42].call(this,16)}),Oz=((((((((((T[0](90,WI,sH),WI.prototype).message=gT(), +WI.prototype).name=VS(),Br).prototype.G=function(){delete Dd[this.i];throw this.B;},c$)(),T)[0](95,li,sH),fa).prototype.set=function(N){(this.i=N,this).B=null},fa).prototype.load=function(N,C,e,L,h){T[22](2,(e=(window.botguard&&(window.botguard=null),[3,1,2]),h=["B",32,0],e[h[2]]),this.i,rY)&&(T[22](2,e[1],this.i,rY)||T[22](3,e[2],this.i,rY))?(C=f[10](10,"",v[33](21,T[22](1,e[h[2]],this.i,rY))),T[22](3,e[1],this.i,rY)?(L=f[10](14,"",v[33](37,T[22](4,e[1],this.i,rY))),this[h[0]]=f[h[1]](12,"nonce", +4,5,e[1],U[31](16,null,L)).then(function(){return new window.botguard.bg(C,function(){})})):T[22](2,e[2],this.i,rY)?(N=S[42](22,null,f[10](11,"",v[33](36,T[22](1,e[2],this.i,rY)))),this[h[0]]=new Promise(function(Q){Q((T[13](84,"",N),new window.botguard.bg(C,function(){})))})):this[h[0]]=Promise.reject()):this[h[0]]=Promise.resolve()},fa).prototype.execute=function(N){return this.B.then(function(C){return new Promise(function(e){(N&&N(),C).invoke(e,!1)})})},P[31](24,22,T[16].bind(null,35)),T)[40](38, +r6,p),function(N){return I[47].call(this,36,N)}),HI=[0,i_,-1],oT=[277,4391,(((r6.prototype.D=f[38](26,HI),T)[40](6,Fi,p),P[31](20,14,function(N,C,e,L){for(L=(e=[11,"className",17],45);L!=38;){if(L==e[0])return C=v[38](e[2],N.tagName+N.id+N[e[1]]),N.tagName+","+C;if(L==12)return U[4](34,6347)(N);L==45&&(L=N&&N instanceof Element?e[0]:12)}}),Cw(),T[40](27,M0,p),P)[31](16,11,W[47].bind(null,16)),32779)],gk=(P[31](16,49,f[39].bind(null,66)),P[31](4,41,f[8].bind(null,40)),l[12](33,"",M0)),k6=[0,i_,-2, +(M0.yl=Fv(),sI)],r4=["conf",1,sI,Ty,2,tV,Ty,VF,HI,Ty,["mconf",wv,(Fi.prototype.D=f[38](26,k6),1),sI,kF,xF,-1,k6,sI],Ty,-1,1,Ty,-3,i_,Ty,-2,kF,Ty,-2,1,Ty,i_,Ty,-5,sI],ce=(M0.prototype.D=f[38](75,r4),ex)(),QE=[4,((B0.prototype.init=function(N,C,e){return(this[N=(e=["i","B",23],N===void 0?new M0:N),e[0]]=N,C=W[33](13,this[e[0]],e[2],rY,void 0,f[22].bind(null,76)))&&(this[e[1]]=new Cf(C)),this},B0.prototype).get=function(){return this.i},6)],GU=(S[42](90,B0),Nv)(),pl=Fm(),cV=xX(),qT=bm(),uS=Dr(),BR=JO(), +jT=BN(),nd=AK(),Rl=X8(),lS=XC(),G3=(FL(),Ux)(),cR=pT(),Kd=Ot(),Af=WF(),yW=Q_(),iS=CK(),vR=sj(),Z9=qJ(),pQ=I_(),JD=vF(),Be=((fz.prototype.add=function(N,C,e){(e=this.i.get(N))||this.i.set(N,e=[]),e.push(C)},fz).prototype.set=function(N,C){this.i.set(N,[C])},(fz.prototype.toString=function(N,C){if(C=["B","i","forEach"],this[C[0]])return this[C[0]];return this[this[N=[],C[1]][C[2]](function(e,L,h){h=P[30](22,L),e.forEach(function(Q,m){((m=h,Q)!==""&&(m+="="+P[30](18,Q)),N).push(m)})}),C[0]]=N.join(lC())}, +fz).prototype.remove=function(N){this.i["delete"](N)},K7)(),XN=Nu(),Ei=Pk(),YY=ig(),zF=qQ(),d4=Db(),Fo=Hu(),jt=((WA(),oD)(),tK)(),cX=kp(),W7=XE(),H7=Kj(),Gc=W5(),rd=zl(),w4=GG(),V0=PN(),ul=(x2(),Fr)(),lw=rK(),K1=Q2(),x6=(to(),D9()),a1=(Jg(),De()),AG=(iV(),mY(),ds)(),g4=WN(),bX=rt(),Mg=(m$(),m0()),$6=C7(),NZ=Zv(),Yz=DM(),CU=TD(),GM=jH(),eg=Xy(),AE=Ku(),yK=(nI(),Z5)(),LU=yk(),h8=Op(),EZ=EQ(),JI=r1(),iM=bZ(),vX=EU(),n1=pw(),Ii=D2(),ye=(mt(),D5)(),ci=Mb(),QV=mg(),pz=kY(),NH=mz(),Om=nw(),BX=nZ(),IE=tg(), +EE=zu(),JM=y6(),RH=ey(),Al=s2(),u1=Qz(),hd=kC(),HX=RU(),mL,mX=(mL=Zf.requestIdleCallback)==null?void 0:mL.bind(Zf),Q4=setTimeout.bind(Zf),N9=[1,2],NV=RegExp,YB=cp(),vT=bZ(),WG=O7(),bb=null,bt={stringify:JSON.stringify,parse:JSON.parse},oG=null,AS=function(N,C,e){return I[30].call(this,24,N,C,e)},w6=An(),VU=BY(),c_=0,Oc=performance,pq=Date.now,vj=Oc.timeOrigin,qY=Oc.now.bind(Oc),Qy=Date,fP=((I[35](79,"",Qy,I[47](17,"",87))instanceof EA&&(Qy={},Qy[I[47](16,"",87)]=function(){return 0}),B8).Hn=function(N, +C,e){var L=["apply",1,73],h=aq[L[0]](3,arguments),Q=qY(),m=P[4](25,2,K[44](6,L[1],new u4,C),Q);return h=N[L[0]](null,T[5](L[2],h)),Promise.resolve(h).then(function(O){e(m,(S[28](26,3,m,qY()-Q),O))},function(O,t,D){e(m,(((S[28]((t=(D=[1,0,78],[3,6,": "]),29),t[D[1]],m,qY()-Q),W)[42](5,!0,4,m),O instanceof Error)?P[D[1]](13,m,O.name+t[2]+O.message,t[D[0]]):P[D[1]](D[2],m,""+O,t[D[0]]),O))}),h},B8.Kg=function(N){return I[42].call(this,34,N)},null),sN=[],X$=(B8.cc=function(N){return T[20].call(this,1, +N)},new Map),t8=((P[31](24,54,((B8.KR=function(N,C){return v[25].call(this,16,C,N)},B8.iU=(B8.xg=function(){return S[5].call(this,2)},function(N,C,e){return S[14].call(this,9,N,C,e)}),B8.Ls=function(){return f[17].call(this,16)},KN.prototype.G_=function(){return this.B},B8).En=(B8.tj=function(N,C){var e=["apply","concat","Hn"];return B8[e[2]][e[0]](B8,[N,C,B8.h2][e[1]](T[5](73,aq[e[0]](2,arguments))))},(B8.oB=function(){return H[43].call(this,12)},B8).h2=function(N){return H[21].call(this,64,N)}, +B8.Ga=function(N){return P[17].call(this,55,N)},function(N,C,e,L,h){return U[15].call(this,2,N,C,e,L,h)}),W)[22].bind(null,11)),KN).prototype.U5=function(){return this.Rz?this.Rz:this.i.toString()},j0()),Uc=Rr(),iw=Mq(),Eg=this;function FA(){return K[6].call(this,56)} +(FA.prototype.lX=function(N,C,e,L,h){for(e=(L=[],h=["push",1,"i"],this).B.length-h[1];e>=0;--e)L[h[0]](this.B[e]);for(C=(N=this[h[2]].length,0);C<N;++C)L[h[0]](this[h[2]][C]);return L},(FA.prototype.clear=function(){this.i=(this.B=[],[])},FA).prototype).remove=function(N,C,e,L,h){return(e=(C=(h=[1,0,"prototype"],this).B,mA(C,N)),e>=h[1]?(Array[h[2]].splice.call(C,e,h[0]),L=!0):L=!1,L)||U[20](15,h[1],N,this.i)};function T7(N,C){return K[9].call(this,9,N,C)}var RM=(T[0](93,T7,K2),Nk)(),Ds=jC(); +T[40](27,lz,(T7.prototype.wN=((T7.prototype.V=function(N){return typeof N.yp=="function"?N.yp():!0},T7.prototype.U=function(N,C){if((T7.L.U.call((C=["i",14,null],this)),this[C[0]]).size>0)throw Error(Ds);for(delete this[C[0]],N=this.B;N.B.length!==0||N[C[0]].length!==0;)P[46](17,C[2],f[C[1]](42,N));delete this.B},T7).prototype.Am=(T7.prototype.xZ=function(N,C,e,L){if(C=Date[L=["now",14,"add"],L[0]](),!(this.P!=null&&C-this.P<this.delay)){for(;I[31](45,this)>0&&(N=f[L[1]](40,this.B),!this.V(N));)this.wN(); +if(!N&&I[31](29,this)+this.i.size<this.G&&(N=this.K()),e=N)this.P=C,this.i[L[2]](e);return e}},function(N,C){this.i["delete"]((C=[46,31,null],N)),this.V(N)&&I[C[1]](28,this)+this.i.size<this.G?this.B.i.push(N):P[C[0]](16,C[2],N)}),T7.prototype.K=function(){return{}},function(N,C,e){for(e=["push",1,"B"],N=this[e[2]];I[31](12,this)+this.i.size<this.j;)C=this.K(),N.i[e[0]](C);for(;I[31](13,this)+this.i.size>this.G&&I[31](44,this)>0;)P[46](e[1],null,f[14](41,N))}),gX)); +function J0(N,C){return l[6].call(this,16,N,C)} +(((V=(T[0](88,J0,T7),J0).prototype,V.xZ=function(N,C,e,L){if(!(L=["delay",1,45],N))return(e=J0.L.xZ.call(this))&&this[L[0]]&&(this.A=Zf.setTimeout(Pe(this.yB,this),this[L[0]])),e;f[34](L[2],L[1],N,this.o,C!==void 0?C:100),this.yB()},V.U=function(N){this.o=(((N=["U","clearTimeout","call"],J0.L)[N[0]][N[2]](this),Zf[N[1]](this.A),this).o.clear(),null)},V.Am=function(N){(J0.L.Am.call(this,N),this).yB()},V.wN=function(){(J0.L.wN.call(this),this).yB()},V).yB=function(N,C){return K[6].call(this,32,N,C)}, +T[0](87,I6,J0),I6).prototype.V=function(N){return!N.J&&!N.isActive()},I6.prototype.K=function(N,C){return(N=new xK,(C=this.X)&&C.forEach(function(e,L){N.headers.set(L,e)}),this.h)&&(N.K=!0),N},Gh.prototype[Symbol.iterator]=function(){return this},Gh.prototype).next=function(N){return{value:(N=this.i.next(),N.done)?void 0:this.B.call(void 0,N.value),done:N.done}};function qZ(){return S[29].call(this,9)} +var di=((((SV.prototype.qz=((qZ.prototype.qz=(SV.prototype[Symbol.iterator]=function(){return new di(this.i())},SV.prototype.B=function(){return new di(this.i())},function(){return this}),qZ.prototype).next=function(){return Lw},function(){return new zw(this.i())}),T[40](28,zw,qZ),zw).prototype.next=function(){return this.i.next()},zw.prototype)[Symbol.iterator]=function(){return new di(this.i)},zw.prototype).B=function(){return new di(this.i)},function(N){return I[17].call(this,38,N)}); +T[40](59,di,SV),di.prototype.next=function(){return this.G.next()};function lr(N,C){var e=[(this.i=[],1),"B",0],L=["Uneven number of arguments",0,(this[e[1]]={},2)],h=(this.size=(this.G=L[e[0]],L[e[0]]),arguments).length;if(h>e[0]){if(h%L[2])throw Error(L[e[2]]);for(var Q=L[e[0]];Q<h;Q+=L[2])this.set(arguments[Q],arguments[Q+e[0]])}else if(N)if(N instanceof lr)for(h=N.e2(),Q=L[e[0]];Q<h.length;Q++)this.set(h[Q],N.get(h[Q]));else for(Q in N)this.set(Q,N[Q])} +var uc=(((((((V=(((V=lr.prototype,V.e2=function(){return y[12](39,1,this),this.i.concat()},V.lX=function(N,C,e){for(N=((e=["B",1,"push"],y)[12](23,e[1],this),C=[],0);N<this.i.length;N++)C[e[2]](this[e[0]][this.i[N]]);return C},V.has=function(N){return U[22](16,N,this.B)},V.equals=function(N,C,e,L,h,Q,m){if(L=[1,!1,!0],m=[2,null,1],this===N)return L[m[0]];if(this.size!=N.size)return L[m[2]];for(Q=(h=C||y[13].bind(m[1],m[2]),y[12](47,L[0],this),0);e=this.i[Q];Q++)if(!h(this.get(e),N.get(e)))return L[m[2]]; +return L[m[0]]},V).clear=function(N){this[((this.i.length=(this[N=[0,"B","G"],N[1]]={},N[0]),this).size=N[0],N)[2]]=N[0]},V.remove=function(N){return this["delete"](N)},V)["delete"]=function(N,C){return(C=[!0,22,2],U)[C[1]](34,N,this.B)?(delete this.B[N],--this.size,this.G++,this.i.length>C[2]*this.size&&y[12](31,1,this),C[0]):!1},lr).prototype,V).get=function(N,C){return U[22](18,N,this.B)?this.B[N]:C},V).set=function(N,C,e){this[(U[(e=[22,"B","G"],e)[0]](26,N,this[e[1]])||(this.size+=1,this.i.push(N), +this[e[2]]++),e)[1]][N]=C},V).forEach=function(N,C,e,L,h,Q){for(Q=(e=this.e2(),0);Q<e.length;Q++)h=e[Q],L=this.get(h),N.call(C,L,h,this)},V).keys=function(){return y[18](4,this.qz(!0)).B()},V.values=function(){return y[18](1,this.qz(!1)).B()},V).entries=function(N){return T[29](3,(N=this,function(C){return[C,N.get(C)]}),this.keys())},V.qz=function(N,C,e,L,h){return e=(h=(y[12](15,1,this),this.G),L=this,0),C=new qZ,C.next=function(Q){if(h!=L.G)throw Error("The map has changed since the iterator was created"); +if(e>=L.i.length)return Lw;return{value:(Q=L.i[e++],N)?Q:L.B[Q],done:!1}},C},T)[0](88,sO,yE),C_)(),u8=[gq,aF,VK,Zo,BT,jF],Cj=(sO.prototype.send=(sO.prototype.A=(sO.prototype.U=function(N){this[(this[(((N=["B","G","L"],sO)[N[2]].U.call(this),this[N[0]]).dispose(),N)[0]]=null,this[N[1]]).dispose(),N[1]]=null,this.i.clear(),this.i=null},function(N,C,e,L,h){(e=(h=["abort","A","oW"],this).i.get(N))&&!e.o7?(I[7](34,C,void 0,u8,this.G,e.gJ),C.X=vh(0,this.K),C[h[1]]=e.sC(),C.K=e.aW(),e.o7=C,v[44](39,this, +new FX(gq,this,N,C)),f[14](2,this,N,C),e[h[2]]&&C[h[0]]()):(L=this.B,L.i["delete"](C)&&L.Am(C))}),(sO.prototype.V=function(N,C,e,L,h,Q,m){L=C[m=["i","target","dN"],m[1]];switch(C.type){case gq:f[14](3,this,N,L);break;case aF:a:{if((h=this[m[0]].get(N),L.B==7||K[38](24,1223,L))||h[m[2]]>h.uA)if(v[44](39,this,new FX(aF,this,N,L)),h&&(h.EC=!0,h.lp)){Q=h.lp.call(L,C);break a}Q=null}return Q;case VK:v[44](35,this,new FX(VK,this,N,L));break;case jF:case Zo:(e=this[m[0]].get(N),e[m[2]])>e.uA&&v[44](34,this, +new FX(Zo,this,N,L));break;case BT:v[44](36,this,new FX(BT,this,N,L))}return null},sO.prototype).abort=function(N,C,e,L,h){if(L=this.i.get((h=["G",39,"gJ"],N)))e=L.o7,L.oW=!0,C&&(e&&(H[h[1]](9,this[h[0]],e,u8,L[h[2]]),P[8](29,!0,function(Q){(Q=this.B,Q.i["delete"](e))&&Q.Am(e)},e,gq,!1,this)),this.i.remove(N)),e&&e.abort()},function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if(B=["A","i","P"],this[B[1]].get(N))throw Error(uc);return(q=(u=new BP(e,L,C,Pe(this.V,this,N),h,m,O!==void 0?O:this.o,t,D!==void 0?D:this[B[2]]), +this[B[1]].set(N,u),Pe)(this[B[0]],this,N),this.B).xZ(q,Q),u}),function(){return y[43].call(this,2)}),BP=(T[0](94,FX,xW),function(N,C,e,L,h,Q,m,O,t,D){return v[41].call(this,1,N,L,e,Q,C,h,m,O,t,D)}),lA=(((T[((V=BP.prototype,V.U5=function(){return this.i},V.sC=function(){return this.o},V.S2=function(){return this.K},V).A2=function(){return this.B},V.aW=function(){return this.P},V).G_=function(){return this.G},40](2,F1,K2),F1.prototype).send=function(N,C){return(C=N.G)?yX(this.i.bind(this),C,N):this.i(N)}, +F1.prototype).i=function(N){return new wu(function(C,e,L,h,Q,m){(Q=N[m=[(L=this,"WL"),32,10],h=v[m[2]](m[1]),m[0]]?N[m[0]]:N.Rz?Uc:"")&&h.set(yT(),Q),K[m[1]](82,this).then(function(O){L.B.send(O,N.sn.toString(),N.G_(),N.U5(),h,void 0,function(t,D,q,u,B,G,c){if(K[c=(D=t.target,[24,0,(G=["(",1223,400],38)]),c[2]](28,G[1],D)||N.ah&&K[c[0]](18,2,D)==G[2]){try{if(D.i)b:{if((q=D.i.responseText,t8&&q.indexOf(t8)==c[1]&&(q=q.substring(t8.length)),B=q,Zf).JSON)try{u=Zf.JSON.parse(B);break b}catch(A){}u=W[c[2]](32, +G[c[1]],"",")",B)}else u=void 0}catch(A){u=[]}C((0,N.NW)(u))}else e(new hh(N,D))})})},this)},new lr),hh=function(N,C,e,L){return K[15].call(this,24,N,C,e,L)},jg=[0,(((T[40](58,hh,sH),hh.prototype.y7=function(){return this.G},hh.prototype.kx=function(){return this.errorCode},hh.prototype).name=Va(),T)[40](3,J_,K2),T[40](27,DY,p),wv),-2],GE=[0,sI,(DY.prototype.D=f[38](27,jg),-1)],cP=[0,sI,(T[40](28,lI,p),-2),i_],ZN=function(){return I[2].call(this,24)},AN=(T[40](2,HV,(lI.prototype.D=f[38](27,cP),p)), +function(){return T[9].call(this,16)}),zh=(HV.prototype.kx=function(){return l[43](46,8,this,rY,FG)},function(){return f[38].call(this,34)}),rE=(((HV.yl=ps(),HV.prototype).D=f[38](75,["ainput",Y6,sI,r4,sI,1,jg,sI,wv,1,Ty,Bg,GE,sI,Ty,-1,1,Ty,Bg,Ty,-1,nV,sI,nV,sI,2,i_,-1,YF,cP,sI,Bg,kF]),T)[40](6,$I,J_),function(){return I[29].call(this,25)});function VO(N,C,e,L,h){return U[28].call(this,5,N,C,e,L,h)} +var yh=(T[0](92,VO,QY),PA)(),Zk={2:"rc-anchor-dark",1:"rc-anchor-light"},YI=((((((VO.prototype.wJ=function(){},(V=VO.prototype,V.Gt=(VO.prototype.V7=function(N){(this[N=["Verification challenge expired, check the checkbox again for a new challenge",7,"Gt"],N[2]](!0,"Verification challenge expired. Check the checkbox again."),P)[N[1]](4,this,N[0]),this.QB()},function(){}),V).wO=function(){},V).QM=function(){return this.h},V).QB=function(){},V).es=function(){return this.F},V.Rh=function(){return T[23](34)}, +V.x7=function(){return this.S},V.dJ=function(){},V.Au=function(N){(N=["Verification expired, check the checkbox again for a new challenge",1,"Verification expired. Check the checkbox again."],this).Gt(!0,N[2]),P[7](N[1],this,N[0])},V.qW=function(){return this.l},V).Zn=function(){P[7](3,this,"You are verified")},V).Nm=function(){},V.Vl=function(N){(VO.L.Vl[(N=["call",18,17],N)[0]](this),this).P=I[N[2]](N[1],"recaptcha-accessible-status",document)},wD()),KU=kY(),R$=cE(),Fc=m8(),em=FH(),gA={normal:new B2(304, +78),compact:new B2(164,144),invisible:new B2(256,60)},A8={"background-color":HZ(),border:z4(),"box-shadow":fY(),position:Rs(),transition:we(),opacity:ZJ(),visibility:OR(),"z-index":uK(),left:hm(),top:Ir()},yV={width:Tu(),height:Tu(),position:On(),top:hm(),left:hm(),"z-index":uK(),"background-color":HZ(),opacity:WC(),filter:vY()},ic={border:de(),width:ZJ(),height:ZJ(),position:Rs(),"pointer-events":sh(),"margin-top":$X(),"z-index":uK()},vP={border:Ra(),width:ZJ(),height:ZJ(),position:Rs(),"pointer-events":sh(), +"margin-top":EX(),"z-index":uK()},nU={"z-index":uK(),position:fr()},IJ={visibility:OR(),position:Rs(),width:Tu(),top:Ir(),left:hm(),right:hm(),transition:we(),opacity:ZJ()},RJ={width:Tu(),height:Tu(),position:On(),top:hm(),left:hm(),"z-index":uK(),"background-color":HZ(),opacity:ke(),filter:nG()},Fw={margin:Ee(),top:hm(),left:hm(),right:hm(),position:On(),border:z4(),"z-index":uK(),"background-color":HZ()},lc={width:V_(),height:f0(),border:vE(),margin:Dq(),padding:hm(),resize:sh(),display:sh()},TE= +{margin:hm(),"margin-top":y2(),padding:hm(),background:sv(),border:vE(),"border-radius":cu(),height:ez(),width:sQ()},He=((T[40](56,kJ,TN),kJ.prototype.W=function(N){(N=[46,"Y",10],Date.now())-this[N[1]]>N[2]?(S[N[0]](3,.9,"",this),this[N[1]]=Date.now()):(S[3](32,this.h),this.h=W[36](72,N[2],this.W,this))},kJ.prototype.U=function(N){((N=[18,null,82],S)[32](N[2],N[1],this),H)[N[0]](1,N[1],this),TN.prototype.U.call(this)},kJ.prototype).j=function(N,C,e,L,h,Q,m,O,t,D){(((this[(((e=U[26](41,(D=[(C=(N= +N===void 0?Fc:N,C)===void 0?!1:C,38),29,"i"],0),!0,null,this.o))&&C&&(this.A=e),this).A&&(N=em),this).G=N,D[2]]=LM(EC),N)==Fc?(S[D[1]](51,this[D[2]],IJ),m=LM(EC),S[D[1]](55,m,RJ),this[D[2]].appendChild(m),L=LM(EC),S[D[1]](19,L,Fw),this[D[2]].appendChild(L)):N==R$&&(S[D[1]](7,this[D[2]],A8),Q=LM(EC),S[D[1]](55,Q,yV),this[D[2]].appendChild(Q),h=LM(EC),S[D[1]](19,h,ic),W[22](2,h,YI),this[D[2]].appendChild(h),O=LM(EC),S[D[1]](71,O,vP),W[22](1,O,YI),this[D[2]].appendChild(O),t=LM(EC),S[D[1]](23,t,nU), +this[D[2]].appendChild(t)),this).A||f[D[0]](84)).appendChild(this[D[2]])},q_)(),SX=new a3("sitekey",null,(a3.prototype.getName=function(){return this.B},XN),!0),Zs;if(Zf.window){var oJ=new sB(window.location.href),PP=(oJ.o!=(oJ.P="",null)||(oJ.B=="https"?S[12](6,oJ,443):oJ.B=="http"&&S[12](16,oJ,80)),l[34](8,0,oJ.toString())),sc=PP[3],fU=PP[2],Xw="",Sg=PP[4],YR=PP[1];Zs=(YR&&(Xw+=YR+":"),sc&&(Xw+="//",fU&&(Xw+=fU+"@"),Xw+=sc,Sg&&(Xw+=":"+Sg)),W[39](34,3,Xw))}else Zs=null; +var kd=new a3("origin",Zs,w4),We=new a3("size",function(N){return N.has(Yq)?He:xe()},d4),s6=new a3("badge",null,x6),Qe=new a3("s",null,a1),Cu=new a3("action",null,Mg),eH=new a3("username",null,$6),Lu=new a3("account-token",null,Yz),hE=new a3("verification-history-token",null,CU),mn=new a3("waf",null,eg),OO=new a3("anchor-ms",null,LU),tE=new a3("execute-ms",null,h8),$q=new a3("callback"),NB=new a3("promise-callback"),WP=new a3("expired-callback"),G_=new a3("error-callback"),DB=new a3("tabindex","0"), +Yq=new a3("bind"),Xc=new a3("isolated",null),ai=new a3("container"),Ka=new a3("fast",!1),x5=new a3("twofactor",!1),M1={fZ:SX,YT:kd,rH:new a3("hl","en",YY),TYPE:new a3("type",null,Ei),VERSION:new a3("version","8x-4t2pegToiW8KmThtO4AQt",W7),tX:new a3("theme",null,zF),Ce:We,Cb:s6,Hl:Qe,iG:new a3("pool",null,g4),Y5:new a3("content-binding",null,bX),PC:Cu,Pt:eH,nJ:Lu,Hb:hE,c_:mn,nY:new a3("hpm",null,AE),zO:OO,Tn:tE,Je:$q,GQ:NB,NN:WP,t5:G_,fY:DB,oO:Yq,RV:new a3("preload",function(N){return v[16](90,N)}), +Dc:Xc,IV:ai,k5:Ka,RJ:x5},HP=((fq.prototype.get=(fq.prototype.has=function(N){return!!this.get(N)},function(N,C,e){return(C=(e=["i","getName"],this[e[0]])[N[e[1]]()])||(C=N[e[0]]?typeof N[e[0]]==="function"?N[e[0]](this):N[e[0]]:null),C}),fq).prototype.set=function(N,C){this.i[N.getName()]=C},PW)(),Hk=((aI.prototype.toString=function(N,C,e,L){for(L=[(N=0,"o"),"charAt","join"],C=[];N<this[L[0]];N++)e=v[40](36,this.B[N]).reverse(),C.push(HP[L[1]](parseInt(e[L[2]](""),2)));return C[L[2]]("")},aI).prototype.add= +function(N,C,e,L,h,Q,m){if((C=[!1,(m=[3,!0,0],0),6],this).G<=C[1])return C[m[2]];for(Q=(h=C[1],C[m[2]]);h<this.K;h++)L=y[14](m[0],N),e=(L%this.i+this.i)%this.i,this.B[TH(e/C[2])][e%C[2]]==C[1]&&(this.B[TH(e/C[2])][e%C[2]]=1,Q=m[1]),N=""+L;return(Q&&this.G--,m)[1]},function(N){return W[10].call(this,4,N)});((((T[40](56,Hi,p),Hi).prototype.S2=function(){return T[22](1,3,this,rY)},P)[31](20,20,K[31].bind(null,1)),Hi).yl=xh(),Hi).prototype.D=f[38](26,["fetoken",Bg,sI,-2,wv,sI,Bg,-1,kF,sI,-2]); +function kR(){return H[4].call(this,1)}function k3(N,C){return K[10].call(this,2,N,C)} +var rM=(T[0](89,k3,kR),[]).concat(128,l[39](9,0,63)),ZO=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411, +3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,((k3.prototype.digest=function(N,C,e,L,h,Q,m,O){for(Q=((m=[15,56,63],N=(O=["i",255,8],[]),C=this.K*O[2],this.G)<m[1]?this.update(rM,m[1]-this.G):this.update(rM,this.B-(this.G-m[1])),m)[2];Q>=m[1];Q--)this.o[Q]=C&O[1],C/=256;for(U[46](23,m[0],this),L=e=0;L<this.V;L++)for(h=24;h>=0;h-=O[2])N[e++]=this[O[0]][L]>>h&O[1];return N},k3.prototype.reset=function(N){this[(N=["i",40, +"G"],this).K=this[N[2]]=0,N[0]]=Zf[lR()]?new Int32Array(this.P):v[N[1]](45,this.P)},k3.prototype).update=function(N,C,e,L,h,Q,m){if(typeof N===(e=(Q=(h=[15,(C===void 0&&(C=N.length),0),(m=["G","K",1],"number")],h[m[2]]),this)[m[0]],"string"))for(;Q<C;)this.o[e++]=N.charCodeAt(Q++),e==this.B&&(U[46](15,h[0],this),e=h[m[2]]);else if(l[22](25,"object",N))for(;Q<C;){if(!((L=N[Q++],h[2]==typeof L&&h[m[2]]<=L)&&255>=L&&L==(L|h[m[2]])))throw Error("message must be a byte array");(this.o[e++]=L,e==this.B)&& +(U[46](7,h[0],this),e=h[m[2]])}else throw Error("message must be string or array");this[this[m[1]]+=C,m[0]]=e},1537002063),1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],Tb;function ks(){return K[34].call(this,35)} +var r5=[1779033703,3144134277,1013904242,2773480762,(T[0](91,ks,k3),1359893119),2600822924,528734635,1541459225],gJ=pL(),wk=Dz(),GJ=Uj(),L$=X6(),yJ=ZJ(),w8=fD(),zt=ry(),c0=aC(),p5=EV-J3,pU=((T[40](56,Bx,p),P[31](28,1,f[0].bind(null,1)),Bx.prototype.D=f[38](26,[0,i_,sI,-1]),ZN.prototype.start=function(N){N=[30,"observe","o"],window[ce][Ku()]||(this[N[2]]==null&&(this[N[2]]=new MutationObserver(y[N[0]](10,.5,this))),this[N[2]][N[1]](f[38](84),{attributes:!0,childList:!1,subtree:!0}))},ZN.prototype).flush= +function(N,C,e,L,h){return(this.i=(e=(C=(N=(L=new (h=[3,0,"toString"],Bx),K[23](17,1,this.i,L)),P[h[1]](76,N,this.G[h[2]](),2)),P[h[1]](12,C,this.B[h[2]](),h[0]).G2()),h)[1],this).G=new aI,this.B=new aI,e},S[42](89,ZN),T[40](32,Rp,p),l)[12](64,"",Rp),J8=[0,(P[31](20,56,U[45].bind(null,10)),vg)],Ec=[0,i_,YF,[0,[0,kF,-1],Bg,kF,(Rp.prototype.D=f[38](75,J8),-1)]],Ar=function(N,C,e,L,h,Q,m,O,t,D,q){return I[42].call(this,12,L,N,e,C,h,Q,m,O,t,D,q)},zE=[(T[40](32,hQ,p),0),i_,-1,1,i_,-1,X_,sI,i_,Ec,J8,i_], +mm=function(){return U[3].call(this,2)},dJ=T[3](25,null,zE,(hQ.prototype.D=f[38](73,zE),hQ)),dM=[0,wv,((P[31](12,33,l[42].bind(null,11)),T)[40](27,Jw,p),Jw.prototype.cE=function(){return T[22](1,2,this)},sI),vg],Em=((((T[40](60,rr,(Jw.prototype.D=f[38](67,dM),p)),rr.prototype).D=f[38](75,[0,YF,dM,sI]),T)[40](38,WJ,p),P[31](12,46,I[9].bind(null,21)),WJ.prototype.D=f[38](27,[0,i_,-3]),T)[40](26,N4,p),function(){return U[5].call(this,40)}),wM=[0,sI,(((((P[31](4,26,I[14].bind(null,8)),N4.prototype).D= +f[38](26,[0,i_,vg,sI,-4]),T[40](32,kl,p),kl).prototype.D=f[38](73,[0,Bg,-2]),P[31](12,28,P[3].bind(null,5)),T)[40](58,SW,p),P)[31](4,27,S[22].bind(null,27)),i_),-1],MO=((T[40](59,pi,(SW.prototype.D=f[38](27,wM),p)),pi.prototype.D=f[38](73,[0,i_,-5]),P)[31](24,29,l[11].bind(null,23)),T[40](34,oV,p),P[31](12,30,P[41].bind(null,15)),P[31](12,6,l[16].bind(null,5)),oV.prototype.D=f[38](26,[0,i_,-1,Bg]),void 0),pA=[],bH=new le,xl=H[4](6,U[4](26,9166)),VV=H[4](5,U[4](18,8094),50),cy=H[4](5,U[28](17,0,2697), +void 0,!1),PH=hO(),xR=H[4](5,U[4](2,8805),void 0,!0,K[18].bind(null,84)),aJ=H[4](11,U[4](34,9402),void 0,!0,K[18].bind(null,85)),gM=H[4](7,U[4](34,1890),void 0,!0,K[18].bind(null,86)),ap=H[4](6,U[4](2,4291)),L5=H[4](5,U[4](18,1696),56),bc=typeof window!=="undefined"?window:null,gm=function(){return""},$U=bc&&bc.document?bc.document.currentScript:null,fi,IT,C5=S[42](33,U[4](18,6272),S[42](98,U[4](18,6499),S[42](32,S[42](32,S[42](36,U[4](2,5698),U[4](10,4016)),U[4](34,4588)),S[42](47,S[42](39,S[42](52, +S[42](58,U[4](2,2182),U[4](2,9880)),U[4](26,1632)),S[42](46,S[42](51,U[4](10,6697),S[42](50,U[4](26,1265),S[42](56,function(){return nv()},U[4](2,7949)))),S[42](48,S[42](97,S[42](99,U[4](26,7771),S[42](48,U[4](2,9782),U[4](18,1327))),U[4](2,7634)),U[4](10,3473)))),S[42](50,S[42](53,S[42](97,S[42](57,S[42](37,S[42](49,S[42](51,U[4](2,836),U[4](2,506)),S[42](52,U[4](10,3035),U[4](2,6628))),S[42](96,U[4](18,9521),S[42](35,U[4](26,646),U[4](26,381)))),S[42](62,S[42](34,S[42](33,U[4](26,8711),S[42](99, +U[4](18,9157),U[4](10,6927))),S[42](63,U[4](34,1983),U[4](10,7833))),U[4](2,946))),U[4](2,3397)),S[42](35,U[4](34,1006),U[4](26,3436))),S[42](37,U[4](10,4845),U[4](10,8205))))))),nv,CB,DL,MZ=K[43](10,ye),$R=[0,sI,(((DL=new Map([["recaptcha/"+(MZ.includes(Bi())?jY():Gw()),20],["recaptcha/releases/8x-4t2pegToiW8KmThtO4AQt",18],[MZ,19],[K[43](18,ci),21]]),T)[40](26,XH,p),XH.prototype.D=f[38](26,[0,i_,-2,YF,wM,i_]),T[40](56,VX,p),VX.prototype).S2=function(){return U[13](22,this,SW,4)},i_),sI,wM,sI],Ni= +T[3](9,null,$R,(VX.prototype.D=f[38](73,$R),VX));function p$(N,C,e,L,h,Q){return K[12].call(this,18,N,C,e,L,h,Q)} +var eq=((((T[0](89,p$,kR),p$).prototype.reset=function(){(this.i.reset(),this.i).update(this.G)},p$.prototype).update=function(N,C){this.i.update(N,C)},p$).prototype.digest=function(N,C){return(this[(N=(C=["i","o"],this[C[0]].digest()),this[C[0]].reset(),this[C[0]].update(this[C[1]]),C)[0]].update(N),this)[C[0]].digest()},N_()),$Z=X6(),zY=Hu(),sY=iy(),Cg=Lz(),N$=zg(),e$=WO(),NP=hk(),rZ=Qm(),$v=LW(),Ah,Lg=H[4](6,function(N,C,e,L,h,Q,m,O,t){return N.then=((h=(e=new (Q=new (L=(O=[8,1,(t=[12,18,2],"")], +m=U[25](26,sY)+"-"+Date.now(),v)[38](t[0],H[3](t[1],O[1],U[25](25,zY))||O[t[2]]),Set),XH),v[38](14,O[t[2]]+C||O[t[2]],O[0])),l[27](7),U)[10](t[2],m,T[45](34),0),N.then||function(){}),N.then(function(D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x){for(J=1,E=18,z=[(x=undefined,30),36,24],r=!1;;)try{if(J==63)break;else if(J==41)J=!T[22](4,1,n)||Q.has(Z)||Z.includes(L)?z[1]:9;else if(J==z[1])W[z[2]](4,F[0],Z),J=z[2];else if(J==81)R=(v[12](69,5,e)||F[0])+1,K[23](10,5,R,e),J=64;else if(J==66)Z=q.value,J=25;else if(J== +z[2])q=X.next(),J=73;else if(J==49)J=73;else if(J==11){A=H[3](25,F[0],Z)||"";try{G=Ni(v[33](z[1],A))}catch(w){G=new VX}J=(n=G,41)}else if(J==46)x!==undefined?(J=x,x=undefined):J=87;else if(J==92)E=60,J=49;else if(J==94)E=18,q&&!q.done&&(D=X.return)&&D.call(X),J=46;else if(J==25)J=Z.startsWith(m+F[2])?11:z[2];else if(J==61)J=T[22](2,5,n)=="/L"?81:64;else if(J==64)J=S[41](10,F[1],void 0,n)==h?54:z[1];else if(J==54)c=(T[8](49,F[1],e)||F[0])+1,K[23](33,F[1],c,e),u=[n.S2()],l[z[1]](35,2,e,SW,u,4),J=z[1]; +else if(J==9)Q.add(Z),B=e,Y=vh(v[12](69,2,e)||F[0],v[12](69,2,n)),K[23](62,2,Y,B),J=61;else if(J==73)J=q.done?94:66;else if(J==1)F=[0,3,"-"],X=P[4](10,H[42](z[1],F[0])),q=X.next(),J=92;else{if(J==87)return E=18,W[z[2]](2,F[0],m),K[23](11,1,Q.size,e).G2();if(J==z[0])throw k;}}catch(w){if(E==(k=w,18))throw w;E==60&&(x=z[0],J=94)}})},52,!1),hu=H[4](10,function(){return W[7](9,1,"0").then(function(N){return(N||new hQ).G2()})},51),QN=H[4](7,function(N,C){return(N=H[42]((C=[34,40,4],35),0),N).length?U[C[2]](C[0], +8479)(N[U[C[1]](57,N.length)]):ay()},59),mx=H[4](7,function(){return H[3](29,1,U[25](25,Cg))},67),Of=H[4](10,function(N,C){return N=(C=[0,3,32],H[C[1]](C[2],C[0],U[25](26,e$))),W[24](1,C[0],U[25](29,e$)),N},76),h3=H[4](11,function(N){return H[3](27,(N=[4,0,"_"],N[1]),S[N[0]](48,N[2]))},70),tu=[0,((T[40](34,O9,p),T)[40](35,Rn,p),6),sI],Uf=[0,fV,Iu,fV,Gy,(O9.prototype.D=f[38](73,tu),tu),1,au],rw=(((((((T[40](34,(Rn.prototype.D=f[38](75,Uf),Hk),p),Hk).prototype.hm=function(){return U[13](31,this,Rn, +3)},Hk.prototype).i=function(){return S[49](21,5,this)},Hk).prototype.kx=function(){return W[4](9,this,1)},Hk).prototype.D=f[38](73,[0,au,fV,Uf,1,fV]),T[40](34,vz,KN),T[40](58,zP,p),zP.prototype).kx=function(){return W[4](2,this,1)},zP.prototype).hm=function(){return U[13](17,this,Rn,5)},function(){return U[41].call(this,4)}),Dh=(T[zP.prototype.D=f[38](75,[0,(zP.prototype.i=(zP.prototype.jZ=function(){return S[49](22,3,this)},function(){return S[49](28,4,this)}),au),fV,-2,Uf]),40](32,Np,KN),[0,wv, +DU,-1]),qi=["rreq",sI,(((T[40](26,kn,p),kn).prototype.tG=function(){return T[22](1,21,this,rY)},kn).prototype.DS=function(){return T[22](1,7,this,rY)},kn.yl=Ep(),-1),1,sI,-14,YF,Dh,sI,-2,1,sI,-3,Bg,-1],uE=[0,(((((((T[40](6,(kn.prototype.D=f[38](75,qi),WV),p),WV.yl=p7(),WV).prototype.D=f[38](26,["breq",qi]),T[40](60,i1,KN),T[40](35,fN,p),fN.prototype).Fa=function(){return T[22](2,3,this,rY)},fN.yl=Bu(),fN.prototype.D=f[38](73,["patreq",sI,-2]),T)[40](59,E_,p),E_).prototype.Fa=function(){return T[22](3, +1,this,rY)},E_.yl=Gl(),E_).prototype.D=f[38](67,["patresp",sI]),T[40](59,Xo,KN),T)[40](35,$E,p),i_),-1],BU=[0,(T[40](27,($E.prototype.D=f[38](73,uE),CS),p),i_),-2],j$=[((CS.prototype.D=f[38](27,BU),T)[40](60,XZ,p),0),N9,Hg,uE,Hg,BU],GT=[0,wv,(T[XZ.prototype.D=f[38](67,j$),40](38,xH,p),i_)],cU=[(T[40]((xH.prototype.D=f[38](27,GT),3),ZP,p),0),Ty,i_],Kg=[((T[40](2,(ZP.prototype.D=f[38](27,cU),tj),p),T)[40](56,Dx,p),Dx.prototype.S2=function(){return U[13](17,this,tj,2)},0),3,sI],Au=[0,(tj.prototype.D= +f[38](26,Kg),eA),Kg],yN=function(N){return function(){return Date.now()-N}}((Dx.prototype.D=f[38](73,Au),Date.now())),iE=[0,sI,-1],vU=[0,sI,kF,i_,-2,wv,sI,(T[40](28,s5,p),YF),iE],ng=[(T[40](59,(s5.prototype.D=f[38](27,vU),ej),p),0),sI,1,sI,-1,Ty],Ix=[0,(T[40](58,(ej.prototype.D=f[38](73,ng),kB),p),YF),vU,X_],Rx=(kB.prototype.D=f[38](75,Ix),[0,X_]),F0=[0,(T[40](26,an,p),X_),-1],lE=[0,(an.prototype.D=f[38](26,F0),sI),i_,-2],Hv=(T[40](60,UA,p),function(){return S[44].call(this,16)}),IB=function(N){return l[21].call(this, +9,N)},TT=function(N){return P[0](1,!0,function(C){return C instanceof N&&!U[22](13,C)})}(UA),Zh=["pmeta",vU,lE,cU,1,Ix,1,F0,(UA.yl=PM(),GT),Rx,Uf,Au,ng],oB=(((T[40](3,fA,(UA.prototype.D=f[38](73,Zh),p)),fA).prototype.getName=function(){return S[49](20,1,this,void 0,rY)},fA).yl=p_(),T[40](26,bw,p),function(N,C,e,L,h,Q){return v[48].call(this,2,N,C,e,L,h,Q)}),ox=["exemco",fV,-2,(bw.yl=((((bw.prototype.qd=function(){return T[22](4,12,this,rY)},V=bw.prototype,bw.prototype.DS=function(){return T[22](2, +8,this,rY)},bw.prototype.fP=function(){return U[13](19,this,fA,11,rY)},V.fu=function(){return T[22](3,1,this,rY)},V.setTimeout=function(N){return T[21](88,this,3,N,void 0,rY)},V).m0=(bw.prototype.tG=function(){return T[22](4,14,this,rY)},function(N){return W[N=[0,46,33],N[2]](21,this,3,rY,void 0,P[N[0]].bind(null,N[1]))}),V).kx=function(){return l[43](43,6,this,rY,FG)},V).jZ=function(){return T[22](4,10,this,rY)},BM)(),1),cd,ou],PU=["rresp",sI,1,Bg,Zh,sI,wv,Y6,sI,-2,ox,sI,Ty,sI,-1,Ty,(fA.prototype.D= +f[38](67,ox),1),j$],KA=(T[40]((bw.prototype.D=f[38](67,PU),27),nA,KN),Sn()),Ap=Pb(),GS=N_(),cz=ep(),yL=ns(),id=hY(),Aw=Kj(),YZ=(zg(),X6(),K3)(); +(((((((rc(),T[40](38,S8,p),S8.yl=gS(),S8.prototype).D=f[38](75,["ubdreq",qi]),T)[40](32,l6,p),l6).prototype.kx=function(){return l[43](59,3,this,rY,FG)},l6.prototype.DS=function(){return T[22](3,1,this,rY)},l6).prototype.qd=function(){return T[22](1,2,this,rY)},l6).yl=n8(),l6).prototype.D=f[38](26,["ubdresp",sI,-1,wv,Ty]),T)[40](3,f$,KN),oM(2,32),oM(2,48),oM(2,48); +var sf,fg,X0=new Fi,Kz={Dx:1,KZ:2,NS:3,lG:4,Xx:5,Ve:6,E4:7,kK:8,Ui:((((((sf=(fg=K[23](61,1,18,X0),K)[23](17,2,4,fg),K)[23](12,3,0,sf),RB.prototype.reset=function(){this.i=T[26](38,255,[])},S)[42](88,RB),AN.prototype.o=function(){var N=["call",4,"apply"],C=P[N[1]](14,aq[N[2]](0,arguments)),e=C.next(),L;try{for(;!e.done;e=C.next())this.B.add(e.value)}finally{e&&!e.done&&(L=C.return)&&L[N[0]](C)}},AN.prototype.i=function(){var N=["call","B",4],C=P[N[2]](11,aq.apply(0,arguments)),e=C.next(),L;try{for(;!e.done;e= +C.next()){var h=e.value;this[N[1]].has(h)&&this[N[1]]["delete"](h)}}finally{e&&!e.done&&(L=C.return)&&L[N[0]](C)}},AN).prototype.reset=function(){this.B.clear(),this.G.clear()},T)[40](26,c7,AN),S)[42](80,c7),9),ye:10,jU:11,li:12},xj=[1,2,(T[40](6,IB,p),IB.prototype.clearValue=function(){return y[34](25,null,xj,this)},3),4,5,6],S$=[0,xj,dv,Pg,Ru,S9,gv,UI],DZ={IJ:0,Pl:122,h6:441,Gw:855,a1:362,s4:445,pZ:104,qN:317,RO:774,ta:452,Wl:28,lU:296,ju:313,dA:863,BC:181,s9:416,CY:112,dM:239,dH:240,mV:121,u0:422, +Ae:555,N2:338,aJ:90,Rl:149,pe:195,cG:351,QW:499,Zc:157,MJ:52,ZG:212,pz:415,MO:1489,M8:942,AO:191,Tw:690,Wi:613,q2:364,IO:583,gt:1825,xp:525,l9:931,W1:103,Fx:345,ha:436,MS:1332,hq:218,Xo:153,yW:372,Ob:306,Ht:298,kb:141,W_:73,Fp:98,ci:939,j1:74,lA:206,S1:51,X2:496,TP:350,SB:246,eD:446,Wb:78,BH:972,LZ:1284,GT:215,us:1231,c1:177,qS:1111,tq:1515,tp:546,cC:1960,fe:489,Hi:1335,O9:1887,y5:1308,k0:331,dT:1352,ZO:408,qu:666,bG:284,rA:884,H1:1324,bs:346,wA:105,xT:803,dt:590,Bt:1704,XO:1524,Ds:617,e1:541,SU:342, +gT:134,fz:696,Ja:517,m5:391,ku:1124,Aa:1613,v1:57,TT:1788,qJ:557,E6:1861,jD:1400,QO:836,Tq:766,nG:2006,bA:268,Il:2004,Ys:1409,bL:130,uG:1351,Ke:793,wt:1578,xD:1639,zq:328,wH:492,OL:639,GO:1023,vl:1044,gM:264,ui:478,vC:356,P1:697,si:247,KY:987,H_:387,Bl:825,xK:428,ne:293,SD:307,Rg:1815,eQ:513,DO:1286,uL:738,Aq:1636,zT:1954,ps:1328,kD:1550,Xp:889,xu:1862,Gn:1363,XX:398,Yp:1787,WC:1876,h5:(((IB.prototype.D=f[38](73,S$),T)[40](32,b4,p),b4).prototype.D=f[38](73,[0,wv,EI,YF,S$,i_]),oM(2,31),1701),Ei:93, +Pi:1940,yX:543,eU:1131,ct:916,B_:2017,pY:891,ag:1216,Bb:1398,i9:1906,Oi:271,YD:1789,o1:1336,O4:265,ml:1518,I1:1372,VO:578,xb:999,BG:1006,I4:37,ii:1725,zw:1054,NO:1965,eu:2020,U9:55,Gq:2015,KG:332,j3:586,zP:1684,GP:944,hX:1635,qO:1011,a6:1850,sL:109,Pb:1219,SC:170,oh:1113,FX:222,eB:1110,kp:689,x5:399,Zx:1004,Kb:933,ls:322,nZ:660,x0:1921,YK:1585,J6:1501,nb:1449,FE:1626,gA:255,dO:1316,U4:1522,AX:2026,iL:1719,v_:1502,CG:548,nz:947,O6:1790,jH:2032,Yu:472,vG:1973,VS:154,HG:1980,gH:201,rT:896,aO:1452,mc:63, +i0:1013,xs:880,PG:871,Bi:872,U6:2061,cl:2050,XE:873,l0:874,Cz:875,Qe:876,E9:129,oJ:832,N8:1556,LY:777,D9:567,og:155,oV:455,HC:2021,ol:22,yS:223,dW:424,P_:285,VW:686,Vr:767,Ap:457,DY:2025,Ig:118,fj:228,V5:29,Z9:203,q8:347,FY:835,Mu:633,SH:837,Q5:733,bi:989,Fo:400,wT:444,nj:842,Lb:214,Kz:80,Lz:40,mA:480,EL:161,fG:19,LJ:2034,b9:2035,t6:1454,aV:1846,yO:1213,zr:417,Ml:2031,b0:727,jB:360,mR:150,A5:604,vt:545,R1:1019,NJ:375,wW:779,uU:659,u9:959,al:895,Le:41,TO:43,VX:1092,MN:549,uc:352,J5:1422,zn:1278,s6:614, +Nl:2033,DG:1313,pb:1994,e3:1310,pJ:291,cb:619},w7=(((((T[40](2,bR,p),bR.prototype).D=f[38](67,[0,sI,vg]),T[40](60,Kh,px),Kh.prototype.i=function(N,C,e,L,h){return(e=(L=C.get((h=[72,"o",56],this.B))-(N+1),H[35](27,5,L)),P)[18](h[2],S[32](h[0],new b4,this.G),[e,y[38](40,this[h[1]]),y[38](8,this.K)])},T)[40](56,a$,px),a$).prototype.i=function(N,C,e,L,h){return L=(e=(h=[1,"G","H"],C).get(this.B)-(N+h[0]),H[35](26,5,e)),P[18](25,W[39](16,S[32](68,new b4,30),this[h[1]]),[L,y[38](8,this[h[2]])])},T[40](58, +FD,px),FD).prototype.i=function(N,C,e,L,h){return(e=(L=C.get((h=[35,40,18],this.B))-(N+1),H)[h[0]](46,5,L),P)[h[2]](59,S[32](76,new b4,32),[e,y[38](h[1],this.H)])},I[21](20)),qV={Z3:0,fb:278,S3:438,JX:341},aT=Ci(),YM=1/((((((((((((((((((((((((((((((((((((((T[40](27,((YK.prototype.A=(YK.prototype.V=function(){return[]},function(){return[]}),YK.prototype).P=(YK.prototype.stringify=function(N,C,e,L,h,Q,m,O){return(L=[(e=(h=(Q=P[4](11,(O=[23,36,1],y)[41](74,c7.M(),O[2])).next().value,T)[39](5,11),I[21](84)), +m=I[21](O[0]),y[O[1]](3,Q)),T[30](50,e,W[0](16,Q),W[0](17,h)),yg(N,h,Q,C),T[30](O[1],m,0,0),e,U[0](91,N,""),m],c7).M().i(Q),L},function(){}),fh),YK),fh.prototype).P=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB,R6,LB,sC,Sp){this.z$=(this.hO=(this.o=(this.Ku=(this.R=((((this.qp=(this.C=(((this.T=(this.K=(this.JO=(((this.hj=(((this.H=(this[(this[(this.Fd=(((Df=(h=(z=(D=(mQ=(G=(L=(a=(LB=(R6=(OC=(d=(k=(B=(M=(n=(u=(UC=(Z=(Q=(R=(C=(sC=(Y=(c=(X=(q=(KB=(w= +(hA=(e=(g=(tA=(A=(O=(t=(F=(Sp=[15,"O","W"],P[4](Sp[0],S[31](2,42,this))),F.next().value),F).next().value,F.next().value),F.next().value),F).next().value,F.next().value),F.next().value),F).next().value,F.next().value),F.next().value),F.next()).value,F.next().value),J=F.next().value,F).next().value,F.next().value),F.next().value),F.next().value),F.next().value),F.next().value),F.next().value),r=F.next().value,F.next().value),F).next().value,F).next().value,m=F.next().value,F).next().value,x=F.next().value, +F.next().value),F).next().value,F.next()).value,E=F.next().value,F).next().value,N=F.next().value,F.next().value),F).next().value,F).next().value,F.next().value),F.next().value),F.next()).value,F.next()).value,F.next().value),F.next().value),this).iI=d,this).mF=J,OC),this).ZM=r,Sp[1]]=E,this.S_=UC,this).B=O,Sp[2]]=u,this.G=A,q),this).Np=h,this.E5=z,this).F=KB,c),this).u=x,this).h=e,M),t),X),this.S=g,this).rq=D,this).X=a,sC),this.iz=LB,Z),this.Y=Q,this).wq=R6,this).Z=L,this.l=R,this).I=w,this.Vk=B, +this.J=C,n),m),this.Fe=hA,this.lI=k,this.Xe=mQ,Y),tA),this.o6=G,this.bI=N,Df)},fh).prototype.i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d){return[(C=(h=(E=(t=(c=(n=(z=(N=(X=(Z=(k=(A=(q=(m=(L=(O=(B=(e=(Q=(D=(R=(J=P[4](12,K[21](33,this,(d=[87,(F=[!0,3,1],30),37],16))),J).next().value,r=J.next().value,J.next()).value,J.next().value),J.next()).value,J.next()).value,J).next().value,J.next().value),J).next().value,J.next()).value,Y=J.next().value,J.next().value),J.next().value),J.next()).value, +J.next().value),I)[21](7),G=I[21](d[0]),I[21](71)),u=I[21](23),I[21](20)),[U[0](90,r,u0()),U[0](94,D,CL()),ii(R,this.Np,D,r),ii(Q,this.B,this.o6),N,ii(e,Q,this.Xe),P[d[2]](d[0],this.rq,e,B),T[d[1]](38,G,W[0](3,B),F[0]),P[d[2]](81,this.E5,e,B),U[0](88,O,0),P[d[2]](80,O,B,O),U[0](90,L,0),P[d[2]](81,this.X,R,m),y[17](11,m,L,[P[d[2]](80,L,R,q),oc(Y,O,this.z$,q),T[d[1]](49,z,W[0](1,Y),F[0]),T[d[1]](51,u,F[2],F[2]),z,U[0](89,A,F[2]),P[d[2]](80,A,B,A),P[d[2]](d[0],A,this.G,k),l[44](26,X,W[0](21,L),F[2]), +U[0](89,Z,4),I[26](38,k,Z,W[0](17,X)),T[d[1]](43,n,F[2],F[2]),u]),n,T[d[1]](48,N,F[2],F[2]),G,y[36](6,R),y[36](6,D),y[36](2,e),y[36](2,O),y[36](2,q),y[36](6,k),y[36](1,X)]),P[4](12,K[21](d[2],this,F[1]))),t.next().value),t.next().value),t.next().value),c),v[31](75,this.W,h),l[44](48,r,W[0](1,this.h),F[2]),ii(r,h,this.JO,r),S[48](1,E,W[0](18,r),4),f[38](20,W[0](2,this.h),r,10),l[44](61,E,W[0](5,E),W[0](18,r)),ii(E,h,this.R,E),Zz(C,this.o,this.K,this.G,this.S,E),this.stringify(C,C),H[0](40,C,this)]}, +fh.prototype.A=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB,R6,LB,sC,Sp,ur,g8,$W,q4,br,o6,VE,Ph,AA,OW,v8,YW,FK,td,d8){return[(UC=(R6=(Df=(G=(F=(h=(tA=(L=(n=(Sp=(N=(Q=(Z=(td=(t=(R=[(AA=(z=(x=(sC=(a=(e=(c=(FK=(g8=(r=(KB=(v8=(X=(E=(OW=(w=(M=(mQ=[(br=(D=(hA=(g=(m=(d=(OC=(J=(B=(u=(q=P[d8=(q4=[1,"",0],[70,17,59]),4](10,K[21](34,this,9)),Y=q.next().value,q).next().value,q.next()).value,q.next()).value,q).next().value,q.next().value),q.next()).value,LB=q.next().value, +q).next().value,Ph=I[21](20),I)[21](23),I[21](84)),I[21](7)),VE=I[21](23),P[37](86,this.Ku,Y,u)),P[37](d8[1],W[0](18,u),B),T[30](42,Ph,W[0](16,B),q4[2]),T[30](57,br,q4[0],q4[0]),Ph,P[37](83,this.u,Y,u),P[37](16,W[0](3,u),B,W[0](1,B)),P[37](80,this.Vk,Y,u),P[37](1,W[0](d8[1],u),B,W[0](19,B)),P[37](83,this.lI,Y,u),P[37](32,W[0](19,u),B,W[0](2,B)),P[37](87,this.iI,Y,u),P[37](33,W[0](18,u),B,W[0](19,B)),P[37](83,this.O,Y,J),U[27](64,Y,OC),U[0](91,d,q4[2]),y[36](1,m),hA,T[30](53,br,W[0](23,J),W[0](23, +m)),P[12](27,2,VE,W[0](1,d)),P[37](85,this.wq,J,g),v[31](71,this.o,LB),ii(LB,LB,this.bI,g),ii(LB,LB,this.iz,OC),P[37](d8[1],W[0](5,LB),B,W[0](2,B)),VE,U[27](80,B,LB),P[37](84,this.Ku,J,u),P[37](16,W[0](7,u),B,W[0](19,B)),T[30](54,D,W[0](6,B),W[0](6,LB)),T[30](41,br,q4[0],q4[0]),D,P[37](81,this.u,J,u),P[37](1,W[0](d8[1],u),B,W[0](19,B)),U[27](19,J,OC),P[37](80,this.O,J,J),l[44](20,d,W[0](21,d),q4[0]),T[30](52,hA,q4[0],q4[0]),br,y[36](5,u),y[36](5,J),y[36](3,OC),y[36](1,g)],P[4](12,K[21](32,this,15))), +M).next().value,C=M.next().value,M.next().value),M).next().value,A=M.next().value,M.next().value),M.next().value),M).next().value,M.next().value),M.next()).value,M.next()).value,M).next().value,M.next()).value,M.next().value),M.next().value),O=I[21](7),I[21](20)),I[21](20)),I[21](84)),P[37](82,this.X,this.K,C)),U[24](25,KB,W[0](1,this.S),W[0](5,C)),l[44](25,KB,W[0](6,KB),q4[0]),U[24](27,C,W[0](23,C),10),Zz(OW,this.o),Zz(E,this.o),v[31](75,this.C,X),sE(A,X),sE(X,X),ii(v8,this.B,this.o6),O,ii(r,v8, +this.Xe),P[37](87,this.rq,r,g8),T[30](d8[2],x,W[0](16,g8),!0),P[37](80,this.E5,r,g8),U[0](94,FK,q4[0]),P[37](84,FK,g8,FK),U[0](88,Y,q4[2]),P[37](80,Y,g8,Y),ii(m,X,this.l,FK,Y),T[30](37,O,q4[0],q4[0]),x,U[0](95,c,q4[2]),U[0](95,d,q4[2]),U[0](89,e,q4[0]),y[d8[1]](10,C,c,[P[37](85,c,this.K,r),P[37](84,d,r,B),P[37](82,B,this.G,B),P[37](82,d,B,B),P[37](85,e,r,a),l[44](56,a,W[0](d8[1],a),W[0](7,c)),l[44](24,a,W[0](5,a),W[0](3,KB)),f[38](7,W[0](21,B),a,W[0](2,a)),U[24](25,this.h,W[0](22,this.h),W[0](18, +a))]),U[0](93,c,q4[2]),U[0](88,e,10),y[36](3,m),y[d8[1]](9,e,c,[l[44](54,a,W[0](5,c),W[0](21,C)),P[37](84,a,this.K,r),P[37](87,d,r,FK),ii(Y,X,this.J,FK),ii(LB,A,this.J,Y),T[30](58,z,W[0](21,LB),W[0](21,m)),T[30](41,AA,q4[0],q4[0]),z,P[37](80,this.X,E,LB),P[37](83,FK,this.G,sC),I[26](34,E,LB,W[0](1,sC)),ii(w,A,this.l,Y,LB),AA,I[26](2,r,d,W[0](d8[1],LB)),ii(w,OW,this.Z,r)]),U[27](87,OW,this.K),U[27](81,E,this.G),U[27](d8[1],A,this.B),y[36](5,OW),y[36](2,E),y[36](2,A),y[36](5,X),y[36](1,Y),y[36](2,sC)], +P[4](12,K[21](33,this,12))),t.next().value),t.next().value),t.next().value),o6=t.next().value,k=t.next().value,t.next().value),t.next().value),t.next().value),t).next().value,t.next().value),YW=t.next().value,t).next().value,I)[21](84),$W=I[21](23),I[21](7)),I[21](87)),ur=I[21](87),I[21](23)),I[21](23)),this.E_),v[31](90,this.Y,w),P[37](85,this.qp,w,Y),K[11](36,k),T[30](57,F,q4[0],q4[0]),this.SW,U[0](91,k,q4[2]),P[37](87,k,this.H,this.H),v[24](10,3,Y,this.H,this.S_),y[36](1,m),T[30](40,w7,W[0](d8[1], +Y),W[0](d8[1],m)),v[24](11,3,k,this.H,this.ZM),T[30](42,w7,W[0](6,k),W[0](22,m)),v[31](88,this.W,h),ii(k,h,this.R,k),F,T[30](55,UC,W[0](16,Y),W[0](16,this.hO)),U[27](81,Y,this.hO),ii(td,this.B,this.J,Y),y[36](2,w),T[30](d8[2],$W,W[0](1,td),W[0](5,w)),T[30](52,G,q4[0],q4[0]),$W,mQ,f[38](20,W[0](1,B),B,1E6),l[44](24,B,W[0](d8[1],B),1E6),f[38](13,W[0](22,B),B,1E6),P[37](83,this.u,Y,Z),P[37](80,Z,this.T,Z),f[9](34,Z,W[0](1,Z),q4[2]),P[37](87,this.lI,Y,Q),f[9](7,Q,W[0](6,Q),q4[1]),P[37](82,Q,this.hj,Q), +f[9](22,Q,W[0](22,Q),q4[2]),P[37](83,this.iI,Y,o6),f[9](7,o6,W[0](22,o6),q4[1]),P[37](85,o6,this.mF,o6),f[9](2,o6,W[0](6,o6),q4[2]),Zz(sC,this.o,B,Z,Q,o6),P[37](86,this.X,this.G,td),ii(w,this.G,this.Z,sC),ii(w,this.B,this.l,Y,td),T[30](55,Df,q4[0],q4[0]),G,P[37](86,td,this.G,sC),U[0](95,a,q4[2]),P[37](84,a,sC,B),Df,Zz(r,this.o,td,k),ii(w,this.K,this.Z,r),l[44](58,this.S,W[0](21,this.S),q4[0]),l[44](50,a,W[0](18,this.S),W[0](1,k)),f[38](5,W[0](19,B),a,W[0](18,a)),l[44](52,this.h,W[0](1,this.h),W[0](d8[1], +a)),P[37](82,this.X,this.K,e),P[12](28,W[0](21,e),UC,d8[1]),R,UC,y[36](1,a),y[36](3,w),y[36](5,Y),y[36](2,td),y[36](5,Z),y[36](3,Q),y[36](6,o6),y[36](6,sC),y[36](6,r),y[36](3,B),y[36](6,k),K[25](22),this.lz,U[0](90,k,q4[2]),P[37](81,k,this.H,this.H),v[24](14,3,N,this.H,this.S_),ii(td,this.B,this.J,N),y[36](1,w),T[30](36,R6,W[0](23,td),W[0](21,w)),P[37](85,td,this.G,n),P[37](81,this.X,n,Q),U[0](90,o6,5),P[12](24,W[0](18,Q),ur,W[0](6,o6)),P[37](81,o6,n,Sp),T[30](57,ur,W[0](21,Sp),W[0](2,w)),l[44](49, +Sp,W[0](22,Sp),q4[0]),I[26](38,n,o6,W[0](16,Sp)),T[30](36,R6,q4[0],q4[0]),ur,I[26](4,n,o6,q4[0]),R6,y[36](5,N),y[36](3,td),y[36](1,Q),y[36](3,o6),y[36](1,Sp),y[36](2,n),K[25](53),this.ZR,y[15](74,1231,L),Zz(w,L,this.Fe),y[36](6,L),y[36](2,this.Fe),K[25](21),this.vK,y[15](d8[0],181,tA),y[15](72,541,YW),y[15](72,2004,Q),v[31](72,this.Y,w),P[37](84,tA,w,tA),ii(w,tA,YW,Q,this.I),y[36](5,tA),y[36](3,YW),y[36](6,Q),y[36](1,w),K[25](22),this.jW,y[15](75,181,tA),y[15](d8[0],541,YW),y[15](71,825,Q),v[31](72, +this.Y,w),P[37](87,tA,w,tA),ii(w,tA,YW,Q,this.F),y[36](2,tA),y[36](6,YW),y[36](5,Q),y[36](2,w),K[25](58)]},fh).prototype.V=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){return[(q=(Q=(O=(B=(m=(N=(h=(D=(e=(t=P[4](10,K[21](39,this,(L=[1335,11,1815],c=[44,"F",71],L[1]))),t.next()).value,t.next().value),t).next().value,t.next()).value,t.next().value),u=t.next().value,G=t.next().value,t.next()).value,C=t.next().value,t.next().value),t.next().value),this.PL)?[S[32](14,this.H,this[c[1]],this.lz),y[15](76,825,u), +ii(e,h,N,u,this[c[1]]),new FD(this.jW,this[c[1]])]:[],y[15](45,78,this.o)),y[15](70,346,this.C),y[15](43,105,this.J),y[15](75,803,this.l),y[15](45,452,this.Y),y[15](c[2],1960,this.qp),y[15](c[0],1861,this.S_),y[15](72,836,this.ZM),y[15](45,191,this.W),y[15](75,690,this.R),y[15](74,583,this.JO),y[15](45,153,this.Ku),y[15](75,218,this.Vk),y[15](c[0],489,this.u),y[15](c[0],L[0],this.lI),y[15](77,51,this.iI),y[15](72,1887,this.Fd),y[15](73,141,this.O),y[15](c[0],331,this.wq),y[15](77,1308,this.bI),y[15](73, +408,this.iz),y[15](70,313,this.X),y[15](76,306,this.Z),y[15](75,57,this.o6),y[15](43,1788,this.Xe),y[15](73,557,this.rq),y[15](72,362,this.E5),y[15](c[2],L[2],this.Np),y[15](43,307,this.z$),v[31](72,this.C,this.B),sE(this.B,this.B),Zz(this.G,this.o),Zz(this.K,this.o),y[36](5,this.hO),U[0](89,this.S,0),U[0](92,this.h,0),U[0](94,B,rX()),U[0](88,C,CL()),y[15](74,1409,O),y[15](c[2],313,Q),l[43](9,1,O,C,590,Q,this,this.T,B),l[43](25,1,O,C,1704,Q,this,this.hj,B),l[43](13,1,O,C,1524,Q,this,this.mF,B),S[32](11, +this.H,this.I,this.SW),y[15](73,181,h),y[15](75,617,N),y[15](43,2004,m),v[31](70,this.Y,e),P[37](80,h,e,h),ii(e,h,N,m,this.I),new FD(this.vK,this.I),q,S[32](10,this.H,G,this.E_),y[15](77,134,D),U[0](94,e,0),Zz(G,D,G,e),y[36](6,e),y[36](6,D),y[36](2,h),y[36](1,N),y[36](3,m),y[36](6,u),y[36](1,G),y[36](6,B),y[36](6,C),y[36](5,O),y[36](2,Q)]},T[40](59,Ms,YK),Ms).prototype.i=function(N,C){return[(N=P[4]((C=[5,38,0],15),K[21](C[1],this,1)).next().value,U[27](67,this.G,N)),y[47](35,W[C[2]](22,N),N),H[C[2]](44, +N,this),y[36](C[0],N)]},Ms).prototype.V=function(N,C,e,L,h,Q,m,O,t){return[(O=(L=(Q=(m=(e=(h=(N=P[4](11,(t=[1980,15,6],K[21](39,this,t[2]))),N.next()).value,N.next().value),C=N.next().value,N.next()).value,N.next()).value,N.next().value),I[21](71)),y[t[1]](76,122,h)),v[31](87,h,e),y[36](2,h),y[t[1]](77,t[0],C),P[37](87,C,e,m),T[30](42,O,W[0](22,m),W[0](18,2048)),ii(m,e,C),y[36](t[2],C),S[32](13,this.H,this.B,this.o),y[t[1]](74,201,Q),ii(m,m,Q,this.B),y[36](t[2],Q),O,y[36](1,e),y[36](t[2],m),y[36](1, +L)]},Ms.prototype.A=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){return[(B=(u=(L=(O=(h=(D=(G=(Q=(m=(C=(t=(q=(N=P[4](12,(e=[896,(c=[15,"o",6],1452),0],K[21](39,this,11))),N.next().value),N.next().value),N.next()).value,N.next().value),N.next().value),N).next().value,N.next()).value,N).next().value,N.next().value),N.next().value),N.next()).value,I)[21](23),this[c[1]]),U[0](88,u,e[2]),P[37](86,u,this.H,q),T[30](36,B,W[0](23,q),W[0](5,2048)),y[c[0]](72,e[0],G),P[37](80,G,q,t),y[36](c[2],G),y[c[0]](70,e[1], +D),P[37](83,D,q,C),y[36](3,D),y[c[0]](44,63,h),P[37](86,h,q,m),y[36](2,h),y[c[0]](76,1013,O),P[37](84,O,q,Q),y[36](5,O),y[c[0]](74,78,L),Zz(this.G,L,t,C,m,Q),y[36](2,L),B,y[36](2,u),y[36](1,q),y[36](c[2],t),y[36](c[2],C),y[36](1,m),y[36](5,Q),K[25](23)]},Ms.prototype.P=function(N,C,e,L,h){this[(this[this.H=(C=(e=P[4](12,(h=[5,"G","B"],S[31](h[0],3,this))),e.next()).value,N=e.next().value,L=e.next().value),h[1]]=N,h)[2]]=C},T)[40](27,$w,YK),$w.prototype).i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){return B= +(q=(Q=(C=(G=(e=(N=(u=(D=(O=(h=(m=(c=[1409,(A=[15,"",0],129),78],L=P[4](11,K[21](35,this,13)),L.next().value),L.next().value),L.next().value),L.next().value),L).next().value,L.next().value),L.next().value),L.next().value),L.next().value),L.next().value),L.next()).value,t=L.next().value,L.next()).value,[y[A[0]](74,871,m),v[31](91,m,h),y[36](6,m),P[18](25,W[39](24,S[32](72,new b4,41),O),[W[A[2]](22,h)]),y[A[0]](76,832,D),v[31](74,D,u),y[36](2,D),f[9](6,u,W[A[2]](17,u),A[1]),y[A[0]](76,c[A[2]],N),v[31](90, +N,e),y[36](2,N),y[A[0]](71,c[1],G),ii(C,e,G,u),y[36](1,G),y[A[0]](43,313,Q),P[37](81,Q,C,q),y[36](2,Q),y[A[0]](72,c[2],t),Zz(B,t,O,q),y[36](2,t),y[47](43,W[A[2]](23,B),B),H[A[2]](52,B,this)]},T[40](2,Lj,YK),Lj.prototype).A=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R){return B=(q=(Q=(C=(A=(e=(O=(n=(u=(c=(t=P[4](11,(h=(G=(N=[19,3,161],R=[76,3,80],[]),G.concat),K[21](38,this,12))),t.next()).value,t.next().value),D=t.next().value,t).next().value,t).next().value,t.next()).value,t).next().value,t.next().value), +t).next().value,t).next().value,m=t.next().value,t.next().value),L=[this.J,l[44](17,this.X,W[0](19,this.X),1),U[0](75,n,0),P[37](84,n,this.H,c),y[36](6,this.H),y[15](71,214,u),v[24](R[1],N[1],D,c,u),y[36](R[1],u),y[36](R[1],c),P[37](83,n,D,this.K),U[0](74,n,1),P[37](81,n,D,B),y[15](72,R[2],O),oc(e,B,O),y[36](1,O),y[36](5,B),U[0](94,n,0),P[37](83,n,e,e),y[15](73,40,q),v[24](15,N[1],this.o,e,q),y[36](1,q),y[15](45,480,A),oc(C,e,A),y[36](1,A),y[36](1,e),y[15](R[0],N[2],Q),v[24](2,N[1],this.G,C,Q),y[36](R[1], +Q),y[15](44,N[0],m),v[24](9,N[1],this.B,C,m),y[36](6,m),y[36](1,C),y[36](1,n)],h.call(G,T[5](87,L))},Lj.prototype.V=function(N,C,e,L,h,Q,m,O,t,D,q){return e=(O=(m=(C=(t=(h=(N=(L=(q=[74,32,2034],P)[4](11,K[21](38,this,1)).next().value,U[0](91,this.X,0)),U[0](95,this.K,ay())),U[0](q[0],this.G,ay())),U)[0](q[0],this.o,ay()),U)[0](93,this.B,ay()),S)[q[1]](9,this.H,this.h,this.J),D=y[15](q[0],q[2],L),Q=W[0](5,this.h),P[18](26,S[q[1]](20,new b4,16),[W[0](17,L),y[38](48,Q)])),[N,h,t,C,m,O,D,e,y[36](1,L)]}, +Lj).prototype.P=function(N,C,e,L,h,Q,m,O,t){(this.H=(this.o=(this.h=(this.K=(h=(O=(C=(Q=(e=(m=(N=(L=P[t=[4,"X",14],t[0]](t[2],S[31](5,7,this)),L.next().value),L.next().value),L.next()).value,L.next().value),L.next()).value,L).next().value,L.next()).value,Q),N),O),m),this.G=C,this[t[1]]=e,this).B=h},Lj.prototype).i=function(N,C,e,L){return C=(N=(e=P[4](15,K[21](33,this,(L=[2,9,5],L[0]))),e.next()).value,e.next()).value,[f[L[1]](L[0],this.K,W[0](7,this.K),ay()),f[L[1]](18,this.G,W[0](7,this.G),ay()), +f[L[1]](3,this.o,W[0](L[0],this.o),ay()),f[L[1]](6,this.B,W[0](L[2],this.B),ay()),y[15](77,78,N),Zz(C,N,this.X,this.K,this.G,this.o,this.B),this.stringify(C,C),H[0](12,C,this),y[36](L[2],C),y[36](L[0],N)]},T[40](59,Wo,YK),Wo.prototype).i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){return[(t=(B=(G=(u=(C=(D=(h=(Q=(c=(m=(e=K[21](33,this,(N=[362,"",445],A=[20,0,2],12)),P[4](14,e)),m).next().value,m.next().value),L=m.next().value,m).next().value,O=m.next().value,m.next().value),q=m.next().value,m.next()).value, +m.next()).value,m.next().value),m.next().value),m.next()).value,y)[15](44,452,c),v[31](72,c,c),y[15](72,104,Q),y[15](43,N[A[2]],L),ii(h,c,Q,L),y[15](75,N[A[1]],O),P[37](80,O,h,D),y[36](A[2],O),y[36](6,L),y[15](74,351,G,OY()),P[22](44,B,W[A[1]](23,G),LW()),y[36](A[2],G),U[A[1]](90,t,N[1]),y[15](74,296,u),ii(D,D,u,B,t),y[36](5,u),y[36](6,B),U[A[1]](91,C,-4),y[15](73,28,q),ii(D,D,q,C),y[36](1,q),H[A[1]](A[0],D,this)]},T)[40](28,Nh,YK),Nh.prototype.P=function(N,C,e,L,h,Q,m){this[this.K=((this[C=(L=(Q= +(N=(e=P[4](15,S[31](9,5,(m=["B","o","G"],this))),e).next().value,h=e.next().value,e).next().value,e.next().value),e.next().value),m[1]]=N,this).H=Q,this[m[0]]=h,C),m[2]]=L},Nh).prototype.i=function(N,C){return N=(C=[1,12,0],P[4](11,K[21](39,this,C[0]))).next().value,[U[27](82,this.B,N),y[47](41,W[C[2]](16,N),N),H[C[2]](C[1],N,this),y[36](3,N)]},Nh.prototype).V=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){return[(L=(F=(m=(A=(N=(t=(n=(q=(h=(e=(D=(O=(u=(c=(G=(B=P[4]((R=[1,201,(Z=[0,6,9],1556)], +12),K[21](38,this,15)),B.next().value),B.next().value),B.next().value),B.next().value),Q=B.next().value,B.next().value),B.next().value),B).next().value,B.next().value),B.next().value),B.next()).value,B.next().value),B).next().value,B.next()).value,B).next().value,I)[21](87),C=I[21](87),y)[15](72,306,this.G),y[15](71,122,G),v[31](70,G,c),y[36](Z[1],G),y[15](45,R[2],u),P[37](86,u,c,O),f[Z[2]](39,O,W[Z[0]](2,O),Z[0]),y[36](1,u),y[15](71,777,Q),P[37](82,Q,c,D),f[Z[2]](38,D,W[Z[0]](3,D),Z[0]),y[36](2, +Q),y[15](75,78,A),Zz(this.B,A,O,D),y[36](2,A),y[15](44,567,e),P[37](80,e,c,h),y[36](2,e),y[36](2,m),T[30](40,L,W[Z[0]](21,h),W[Z[0]](21,m)),y[15](73,155,q),ii(n,h,q),y[36](5,q),T[30](55,L,W[Z[0]](5,n),W[Z[0]](22,m)),S[32](18,this.H,this.o,this.X),S[32](5,this.H,this.K,this.h),y[15](73,R[1],t),ii(N,n,t,this.o,this.K),T[30](54,C,R[Z[0]],R[Z[0]]),L,U[Z[0]](94,F,Z[0]),ii(F,this.B,this.G,F),y[36](1,F),C,y[36](5,c),y[36](3,h),y[36](3,n),y[36](Z[1],t),y[36](Z[1],N),y[36](Z[1],m)]},Nh.prototype).A=function(N, +C,e,L,h,Q,m,O,t){return C=[(e=(h=(O=(m=(Q=(L=(t=["G",4,37],P[t[1]](10,K[21](33,this,t[1]))),N=L.next().value,L).next().value,L.next()).value,L.next()).value,[this.X,U[0](94,N,0),P[t[2]](85,N,this.H,Q),y[15](72,455,m),P[t[2]](86,m,Q,O),y[36](6,m),f[9](23,O,W[0](18,O),-2),ii(N,this.B,this[t[0]],O),y[36](1,N),y[36](2,Q),y[36](6,O),K[25](t[2])]),P[t[1]](10,K[21](t[2],this,1)).next()).value,this).h,U[0](88,e,-1),ii(e,this.B,this[t[0]],e),y[36](2,e),K[25](20)],[h,C]},T[40](38,Cj,YK),Cj.prototype.i=function(N, +C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g){return[(B=(m=(F=(Q=(E=(N=(c=(O=(R=(t=(z=(w=(u=(x=(A=(J=(k=(q=(d=(Y=(D=(e=(C=(r=P[4](11,K[21](33,this,(X=(g=[15,5,93],[223,1,424]),26))),r.next()).value,r.next()).value,r.next()).value,h=r.next().value,n=r.next().value,r).next().value,r.next().value),r.next().value),r.next()).value,L=r.next().value,a=r.next().value,r.next()).value,r.next().value),r.next().value),r.next().value),r.next()).value,r).next().value,Z=r.next().value,r.next().value), +r).next().value,r.next().value),r.next().value),r.next().value),r.next()).value,r).next().value,r.next().value),I[21](71)),G=I[21](87),I[21](7)),y[36](1,F)),U[0](g[2],N,Sq()),y[g[0]](73,452,C),v[31](86,C,e),y[36](6,C),y[g[0]](75,1449,D),y[g[0]](44,2021,h),ii(n,e,D,h),y[36](g[1],e),y[36](2,D),y[36](6,h),T[30](39,m,W[0](1,n),W[0](17,F)),y[g[0]](77,22,Y),y[g[0]](44,X[0],d),ii(q,n,Y,d),y[36](3,n),y[36](g[1],Y),y[36](1,d),T[30](38,m,W[0](6,q),W[0](7,F)),y[g[0]](71,767,J),ii(A,q,J),y[36](2,J),y[g[0]](77, +313,x),P[37](82,x,A,u),y[36](2,A),y[36](g[1],x),y[g[0]](73,X[2],k),y[g[0]](73,285,L),ii(a,q,k,L),y[36](3,k),y[36](3,L),T[30](41,G,W[0](6,a),W[0](3,F)),y[g[0]](44,686,w),y[g[0]](43,457,z),P[37](83,z,a,Z),ii(t,q,w,Z),y[36](1,z),y[36](6,Z),y[g[0]](74,2025,R),P[37](85,R,a,O),ii(c,q,w,O),y[36](2,R),y[36](g[1],O),y[36](2,w),y[36](3,a),T[30](42,B,X[1],X[1]),G,U[27](19,N,t),U[27](96,N,c),T[30](56,B,X[1],X[1]),m,U[27](98,N,t),U[27](65,N,c),U[0](92,u,0),B,y[g[0]](74,78,E),Zz(Q,E,t,c,u),y[36](6,E),y[47](33, +W[0](22,Q),Q),H[0](48,Q,this)]},T[40](3,VD,YK),VD.prototype.A=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB,R6,LB,sC,Sp,ur){return[(c=(k=(M=(J=(hA=(mQ=(sC=(R=(g=(D=(q=(x=(R6=(t=(E=(Q=(OC=(G=(n=(C=(F=(Df=(e=P[4](14,K[21]((m=[(tA=this,u=I[21](23),UC=I[21](87),1),(Sp=I[21](87),Z=I[21](71),X=I[21]((a=I[21](7),O=I[21](84),87)),ur=[50,(d=I[L=I[21](23),21]((B=I[21](84),84)),!(A=I[21](20),0)),36],696),5],r=I[21](20),32),this,28)),e.next().value),e.next().value), +e).next().value,e.next().value),e.next().value),e.next().value),e.next().value),e.next().value),z=e.next().value,e.next().value),e.next().value),e.next().value),e.next().value),e.next().value),LB=e.next().value,N=e.next().value,function(g8,$W,q4){return[P[q4=($W=[2,0,!0],[85,74,48]),22](46,h,W[0](17,tA.rq),LW()),ii(D,D,tA.u,h),U[0](90,N,$W[1]),P[37](82,N,D,R),Zz(R,tA.J,R),U[0](q4[1],N,1),P[37](87,N,D,sC),Zz(sC,tA.J,sC),U[0](75,N,$W[0]),P[37](q4[0],N,D,mQ),Zz(mQ,tA.J,mQ),S[q4[2]](65,Y,W[0](2,sC),$W[0]), +P[12](28,W[0](3,R),g8,W[0](23,Y)),S[q4[2]](65,Y,W[0](3,mQ),$W[0]),P[12](25,W[0](6,R),g8,W[0](19,Y)),l[44](22,k,W[0](22,R),W[0](21,sC)),l[44](28,k,W[0](1,k),W[0](5,mQ)),P[12](25,W[0](6,k),g8,W[0](2,M)),P[12](30,W[0](7,J),g8,W[0](23,k)),U[0](91,KB,$W[2])]}),e.next().value),e).next().value,e.next().value),KB=e.next().value,e.next().value),e.next().value),e.next().value),e.next()).value,Y=e.next().value,h=e.next().value,w=e.next().value,e.next().value),this).E5,l[44](29,this.K,W[0](1,this.K),m[0]),v[31](77, +this.T,F),ii(C,F,this.Ku,this.hO),P[37](83,this.Z,C,G),v[31](74,this.R,E),U[0](90,z,10),U[0](93,t,0),U[0](94,x,0),U[0](75,LB,0),ii(z,E,this.o6,G,z),y[17](10,z,t,[P[37](84,t,C,n),P[37](84,this.iI,n,R6),T[30](51,r,W[0](18,R6),W[0](21,this.Xe)),T[30](43,A,m[0],m[0]),r,l[44](28,x,W[0](2,x),m[0]),A,Zz(q,this.F,n),U[0](89,hA,2),U[0](92,J,600),U[0](89,M,30),U[0](94,KB,!1),P[37](81,this.I,q,D),g(Z),Z,T[30](52,d,W[0](17,KB),ur[1]),P[37](83,this.l,q,D),g(Sp),Sp,T[30](51,d,W[0](2,KB),ur[1]),P[37](85,this.C, +n,n),Zz(q,this.F,n),P[37](80,this.I,q,D),g(UC),UC,T[30](ur[0],d,W[0](7,KB),ur[1]),P[37](85,this.l,q,D),g(B),B,T[30](57,d,W[0](22,KB),ur[1]),T[30](51,O,m[0],m[0]),d,l[44](ur[0],LB,W[0](19,LB),m[0]),O]),T[30](57,L,W[0](19,x),W[0](7,this.S)),T[30](ur[0],u,m[0],m[0]),L,T[30](55,X,W[0](19,LB),W[0](19,this.Y)),u,U[27](83,x,this.S),U[27](82,LB,this.Y),K[11](38,Df),Zz(OC,this.o,Df,x,LB),ii(F,this.G,this.W,OC),P[37](86,this.Z,this.G,Y),P[12](31,W[0](18,Y),X,11),U[0](95,w,m[2]),U[0](90,c,3),ii(Y,this.G,this.O, +w,c),X,S[48](41,Y,500,W[0](17,this.K)),Zz(this.B,this.h,this.X,Y),y[ur[2]](6,F),y[ur[2]](1,C),y[ur[2]](5,Df),y[ur[2]](2,OC),y[ur[2]](1,n),y[ur[2]](6,G),y[ur[2]](1,E),y[ur[2]](2,z),y[ur[2]](2,t),y[ur[2]](6,R6),y[ur[2]](6,x),y[ur[2]](1,q),y[ur[2]](1,D),y[ur[2]](2,LB),y[ur[2]](2,N),y[ur[2]](5,R),y[ur[2]](3,sC),y[ur[2]](6,mQ),y[ur[2]](5,KB),y[ur[2]](6,hA),y[ur[2]](3,J),y[ur[2]](2,M),y[ur[2]](6,k),y[ur[2]](3,Y),y[ur[2]](5,h),a,K[25](43),this.S_,y[15](76,m[1],Q),Zz(F,Q,this.B),y[ur[2]](3,Q),y[ur[2]](3, +this.B),K[25](39)]},VD).prototype.P=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w){(((this.G=((this.T=((this.C=((this[(this.o6=(this.Xe=(this.Z=(this.W=(this.B=(this.X=(this.S=(this.R=(this.hO=(this.iI=(this.Y=(h=(N=(Y=(q=(n=(Z=(X=(O=(x=(r=(A=(D=(d=(L=(m=(E=(B=(F=(J=(c=(R=(Q=P[4](14,S[31](6,28,(w=["Fe","K","rq"],this))),k=Q.next().value,Q.next().value),Q.next()).value,Q.next().value),Q.next()).value,Q.next()).value,Q).next().value,e=Q.next().value,Q.next().value),Q.next().value), +t=Q.next().value,Q.next()).value,Q.next().value),z=Q.next().value,Q.next().value),Q).next().value,Q).next().value,Q.next()).value,Q).next().value,Q.next().value),Q.next().value),Q.next().value),u=Q.next().value,C=Q.next().value,Q.next()).value,Q.next().value),G=Q.next().value,Q.next().value),Y),z),this.O=N,this.H=J,e),L),C),c),R),D),this[w[0]]=m,this.lI=G,d),A),t),this).l=x,this.o=F,w[2]]=Z,this).u=X,q),this)[w[1]]=u,B),this).I=O,k),this).J=n,this).F=r,this.h=h,this).Ku=E},VD.prototype.V=function(N, +C,e,L,h){return C=(L=P[4]((N=(h=["rq",15,"X"],[660,1110,500]),11),K[21](39,this,2)),e=L.next().value,L.next().value),[y[h[1]](70,78,this.o),y[h[1]](44,452,this.T),y[h[1]](77,317,this.Ku),y[h[1]](74,436,this.hO),y[h[1]](45,836,this.Fe),y[h[1]](77,191,this.R),y[h[1]](75,N[1],this.o6),y[h[1]](73,313,this.Z),y[h[1]](74,306,this.W),y[h[1]](77,689,this.iI),U[0](95,C,!0),T[34](64,this.Xe,W[0](7,C),""),y[h[1]](43,399,this.F),y[h[1]](43,1004,this.l),y[h[1]](71,933,this.I),y[h[1]](73,239,this.u),y[h[1]](45, +322,this[h[0]]),y[h[1]](77,N[0],this.J),y[h[1]](77,141,this.C),y[h[1]](74,195,this.O),y[h[1]](43,28,this.lI),y[h[1]](71,134,this.h),U[0](91,this.K,0),U[0](90,this.S,-1),U[0](90,this.Y,-1),Zz(this.G,this.o),S[32](11,this.H,this[h[2]],this.E5),U[0](93,e,N[2]),Zz(this.B,this.h,this[h[2]],e),new FD(this.S_,e),y[36](5,e)]},VD.prototype).i=function(N,C,e,L,h){return[Zz((L=(e=(C=(h=[16,4,93],P[h[1]](14,K[21](34,this,3))),N=C.next().value,C.next()).value,C.next().value),N),this.o,this.G),this.stringify(N, +N),Zz(this.G,this.o),U[0](75,this.K,0),U[0](90,this.S,-1),U[0](75,this.Y,-1),y[15](73,696,e),Zz(L,e,this.B),U[0](h[2],L,500),Zz(this.B,this.h,this.X,L),y[36](5,e),y[36](5,L),H[0](h[0],N,this)]},T)[40](35,Ho,YK),Ho.prototype.i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB,R6,LB,sC,Sp,ur,g8,$W,q4,br,o6,VE,Ph,AA,OW,v8,YW,FK,td,d8,ir,fB){return OW=[(R=[(tA=(d8=(FK=(e=(sC=(g=[(n=[(J=[(q=(R6=(UC=(YW=[(a=(w=(Q=(ir=(q4=(g8=(o6=(OC=(r=(hA=(Df=(M=(G=(br=(mQ= +(C=(d=(E=(X=(Sp=(O=($W=(c=(t=(A=(VE=(v8=(Ph=(LB=(AA=(m=(KB=(z=(F=(td=K[fB=(ur=[1,100,!0],[2,16,195]),21](34,this,42),P[4](10,td)),F).next().value,F.next().value),F.next().value),F.next().value),F.next()).value,Z=F.next().value,F.next()).value,L=F.next().value,F.next().value),D=F.next().value,F.next().value),F).next().value,F.next()).value,F.next().value),F.next().value),F.next().value),F.next().value),F.next().value),F.next().value),F.next().value),F.next()).value,F.next().value),F).next().value, +F.next()).value,F.next()).value,F.next().value),N=F.next().value,F).next().value,u=F.next().value,F.next().value),F.next().value),F.next().value),Y=F.next().value,B=F.next().value,x=F.next().value,F).next().value,F.next()).value,k=F.next().value,F).next().value,F.next().value),F.next().value),F.next()).value,y[15](71,452,z)),v[31](70,z,z),y[15](74,181,KB),P[37](86,KB,z,KB),y[15](70,112,m),P[37](80,m,KB,m),y[15](71,28,Sp),U[0](74,k,0),U[0](75,ir,5E3),ii(m,m,Sp,k,ir),y[15](76,416,AA),U[0](89,LB,k4()), +ii(Z,m,AA,LB),y[36](5,LB)],I[21](71)),I[21](84)),[U[0](89,w,!1),P[37](84,VE,Z,ir),U[0](95,a,ur[1]),U[0](91,Q,0),ii(a,ir,Sp,Q,a),I[26](fB[0],Z,VE,W[0](7,a)),P[37](84,c,ir,ir),T[30](43,UC,W[0](19,ir),W[0](6,Q)),U[0](93,Q,ur[0]),T[30](40,UC,W[0](22,ir),W[0](22,Q)),U[0](94,Q,fB[0]),T[30](37,UC,W[0](fB[1],ir),W[0](6,Q)),U[0](88,w,ur[fB[0]]),UC,T[30](36,R6,W[0](18,w),W[0](22,$W)),ii(a,Z,g8,VE,k),U[24](40,VE,W[0](17,VE),ur[0]),U[24](24,t,W[0](1,t),ur[0]),R6]),U)[0](89,VE,0),U[0](89,k,ur[0]),U[0](74,$W,ur[fB[0]]), +U[0](92,O,!1),y[15](76,fB[2],g8),y[15](77,313,c),P[37](80,c,Z,t),y[17](15,t,VE,q),y[36](1,g8)],P)[37](81,VE,Z,Ph),ii(v8,D,L,Ph),I[26](36,A,VE,W[0](18,v8))],ii(A,Z,Sp)),U[0](92,VE,0),y[15](76,338,L),P[37](87,c,Z,t),y[15](74,422,D),P[22](40,D,W[0](17,D),ep()),y[17](14,t,VE,n)],h=I[21](23),[P[37](80,mQ,X,Ph),ii(k,br,L,Ph),T[30](56,h,W[0](22,k),W[0](5,O)),U[0](92,d,ur[fB[0]]),h]),I[21](20)),[P[37](86,mQ,X,Ph),ii(k,G,L,Ph),T[30](59,e,W[0](1,k),W[0](5,O)),U[0](90,C,ur[fB[0]]),e]),I)[21](84),I[21](20)), +P)[37](86,VE,A,Ph),T[30](38,d8,W[0](19,Ph),W[0](17,O)),U[24](26,k,W[0](fB[0],VE),3),U[0](75,ir,0),ii(r,N,hA,ir,k),l[44](25,k,W[0](fB[1],VE),4),ii(OC,N,u,t,k),ii(X,Z,Sp,r,OC),P[37](82,c,X,E),U[0](95,d,!1),U[0](92,mQ,0),y[15](44,90,br),P[22](42,br,W[0](19,br),ep()),y[17](9,E,mQ,sC),y[36](1,br),U[24](40,k,W[0](3,VE),4),U[0](93,ir,0),ii(r,N,hA,ir,k),ii(X,Z,Sp,r,VE),P[37](83,c,X,E),U[0](88,C,!1),U[0](89,mQ,0),U[0](88,Q,ur[1]),y[15](43,149,G),P[22](28,G,W[0](17,G),ep()),y[17](13,E,mQ,FK),y[36](3,G),f[26](fB[0], +25,W[0](7,C),C),y[1](24,23,k,W[0](18,d),W[0](5,C)),T[30](40,tA,W[0](3,k),W[0](7,O)),P[37](82,VE,Z,Y),ii(Y,Y,B,D),U[0](74,k,0),P[37](81,k,Y,Y),ii(k,X,q4,Y),ii(k,o6,x,X),l[44](61,M,W[0](18,M),ur[0]),T[30](53,tA,W[0](23,M),W[0](1,Df)),d8],U)[0](93,VE,0),U[0](93,N,Hb()),v[31](72,N,N),U[0](95,hA,aO()),U[0](92,u,oC()),U[0](92,x,qd()),y[15](45,499,q4),y[15](77,239,B),U[0](89,k,""),P[37](83,c,Z,t),ii(o6,k,AA,k),U[0](74,M,0),U[0](74,Df,3),y[17](15,t,VE,R),tA,y[47](37,W[0](6,o6),o6),y[36](1,D),y[36](1,hA), +y[36](1,u),y[36](3,N),y[36](1,AA),y[36](fB[0],L),y[36](fB[0],c),y[36](6,Sp),y[36](6,x),y[36](fB[0],q4),y[36](fB[0],B),H[0](40,o6,this)],[].concat(YW,J,g,OW)},T)[40](58,ph,YK),ph.prototype).i=function(N,C,e,L,h,Q,m,O){return Q=(N=(e=(m=(L=(h=(C=K[21](38,(O=[43,15,16],this),5),P)[4](11,C),h.next().value),h).next().value,h.next().value),h.next().value),h.next().value),[y[O[1]](O[0],122,L),v[31](91,L,N),y[36](1,L),y[O[1]](71,345,m),P[37](82,m,N,Q),y[36](2,m),y[36](6,N),U[0](93,e,""),T[34](70,Q,W[0](6, +e),W[0](O[2],Q)),y[36](3,e),H[0](O[2],Q,this)]},T[40](32,rE,YK),rE).prototype.i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d){return h=[(t=(m=(Z=(q=(N=(L=(G=(R=(Q=(c=(r=(B=(n=(e=(J=(u=(X=K[21](35,this,(E=[212,0,(d=[22,157,75],415)],d[0])),P[4](15,X)),A=u.next().value,u.next().value),u.next()).value,Y=u.next().value,u.next()).value,u.next().value),F=u.next().value,u).next().value,k=u.next().value,u.next().value),D=u.next().value,u.next()).value,u.next()).value,u.next()).value,u.next().value), +u.next()).value,C=u.next().value,u).next().value,u.next()).value,O=u.next().value,u.next().value),z=[y[15](70,452,A),v[31](73,A,A),y[15](d[2],317,J),y[15](71,52,e),ii(Y,A,J,e),y[36](5,J),y[36](6,e),y[15](45,E[0],n),y[15](44,E[2],B),y[15](70,d[1],F),y[15](76,296,r),P[d[0]](26,D,W[0](2,B),LW())],[P[37](81,R,Y,k),P[37](80,n,k,c),ii(c,c,r,D,F),ii(Q,q,N,c)]),U)[0](89,R,E[1]),U[0](93,G,Hb()),v[31](91,G,G),U[0](88,L,oC()),U[0](92,N,qd()),U[0](95,Q,""),y[15](72,313,m),P[37](84,m,Y,C),y[36](5,m),y[15](73, +416,O),ii(q,Q,O,Q),y[36](5,O),U[0](94,Z,5),ii(Z,G,L,Z,C),y[17](10,Z,R,t),this.stringify(q,q),y[36](2,Q),y[36](5,k),y[36](3,Y),y[36](3,c),y[36](2,n),y[36](5,Z),y[36](5,C),y[36](3,B),y[36](2,F),y[36](3,r),y[36](6,D),y[36](2,L),y[36](2,N),y[36](2,G),y[36](1,R),H[0](16,q,this)],[z,h]},T)[40](27,zh,YK),zh.prototype).P=function(N){N=[3,10,4],this.B=P[N[2]](N[1],S[31](N[0],1,this)).next().value},zh).prototype.i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){return[(u=(h=(m=(D=(q=(C=(O=(Q=(B=(N=(L=(e=P[4](10,(c= +[(t=[0,2020,78],21),11,37],K)[c[0]](32,this,10)),e).next().value,e.next().value),e.next()).value,e.next().value),e).next().value,e).next().value,e.next()).value,e.next()).value,e).next().value,e.next().value),I)[c[0]](71),G=I[c[0]](23),y)[36](1,O),y[36](1,C),y[36](3,q),y[36](5,D),y[15](43,1006,L),v[31](87,L,L),T[30](50,G,W[0](2,L),W[0](18,O)),y[15](72,c[2],N),P[c[2]](85,N,L,B),T[30](42,G,W[0](23,B),W[0](23,O)),y[15](76,1725,Q),ii(B,L,N,Q),U[0](88,Q,t[0]),P[c[2]](82,Q,B,B),T[30](55,u,W[0](18,B),W[0](17, +O)),y[15](71,1054,Q),P[c[2]](82,Q,B,C),y[15](44,1965,Q),P[c[2]](85,Q,B,q),u,y[15](72,t[1],Q),ii(B,L,N,Q),U[0](91,Q,t[0]),P[c[2]](86,Q,B,B),T[30](43,G,W[0](7,B),W[0](2,O)),y[15](74,55,Q),P[c[2]](86,Q,B,D),G,K[c[1]](6,m),y[15](73,t[2],Q),Zz(h,Q,this.B,m,C,q,D),this.stringify(h,h),H[0](48,h,this)]},zh).prototype.V=function(){return[K[11](6,this.B)]},T)[40](6,wE,YK),wE.prototype).i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r){return[(n=(L=(D=(h=(Q=(c=(k=(C=(A=(R=(B=(m=(G=(e=P[O=I[E=I[(Y= +(N=[78,284,(r=[37,21,1],36)],I[r[1]](20)),r)[1]](23),r[1]](87),4](10,K[r[1]](34,this,20)),F=e.next().value,e).next().value,J=e.next().value,X=e.next().value,e.next()).value,e).next().value,e.next()).value,e.next().value),e).next().value,e.next()).value,e.next()).value,e.next()).value,Z=e.next().value,t=e.next().value,e.next().value),e.next().value),e.next()).value,q=e.next().value,e.next().value),u=e.next().value,y[15](76,N[0],F)),y[36](6,n),y[15](44,1006,A),v[31](71,A,A),y[36](3,R),T[30](49,Y,W[0](17, +A),W[0](7,R)),y[15](76,r[0],B),P[r[0]](83,B,A,m),T[30](43,Y,W[0](3,m),W[0](19,R)),y[15](45,222,C),ii(m,A,B,C),y[15](77,313,J),P[r[0]](83,J,m,c),P[12](31,W[0](23,c),E,N[2]),U[24](24,c,W[0](23,c),35),y[15](76,28,X),ii(m,m,X,c),E,Zz(n,F),U[0](74,k,0),P[r[0]](85,J,m,c),y[15](77,N[r[2]],G),y[15](45,218,t),y[15](75,55,D),y[17](15,c,k,[P[r[0]](85,k,m,Z),U[0](95,Q,r[2]),P[r[0]](83,t,Z,h),T[30](52,O,W[0](23,h),W[0](2,G)),U[0](92,Q,0),O,P[r[0]](81,D,Z,L),Zz(q,F,Q,L),I[26](34,n,k,W[0](17,q))]),Y,Zz(u,F,n),y[47](49, +W[0](r[2],u),u),H[0](20,u,this)]},T[40](6,gE,YK),gE.prototype).P=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB,R6,LB,sC,Sp,ur,g8,$W,q4,br,o6,VE,Ph,AA,OW,v8,YW,FK){this.rq=((this.SW=(this.T=(this.JO=(this.lI=(this.jW=(this.F=(this.o=((this.Fd=(this.K=(((this.Z=(((this.C=(this.Np=(this.mF=(this.B=(((this.S=(this.X=(this.DM=(this.Nk=((this[(((this.u=(this.ZM=(this.lz=(this.vK=(this.G=(this.S_=(this.wq=(this.Ku=(this[(this.Xe=(this.PL=(this.Ub=(this.z$= +(KB=(M=(sC=($W=(OW=(X=(mQ=(tA=(Sp=(m=(u=(ur=(J=(LB=(G=(z=(t=(q4=(hA=(R=(n=(Ph=(OC=(a=(R6=(x=(h=(F=(d=(L=(E=(g=(Df=(A=(Q=(C=(g8=(Z=(c=(VE=(v8=(D=(B=(N=(br=(k=(r=(O=(Y=(e=P[4](15,(FK=["h","ZR","tu"],S[31](8,55,this))),e).next().value,w=e.next().value,e.next().value),e.next()).value,e.next()).value,e).next().value,e).next().value,e.next()).value,e.next().value),e.next().value),e.next().value),e).next().value,e.next()).value,UC=e.next().value,e.next().value),e.next().value),e.next().value),e.next()).value, +e.next().value),e.next().value),e.next()).value,e.next()).value,e).next().value,e.next().value),e.next().value),e.next()).value,YW=e.next().value,q=e.next().value,e.next().value),AA=e.next().value,o6=e.next().value,e.next()).value,e.next().value),e).next().value,e.next().value),e.next().value),e.next().value),e.next()).value,e).next().value,e.next().value),e.next()).value,e.next()).value,e.next().value),e.next().value),e).next().value,e.next().value),e).next().value,e.next().value),e.next().value), +e).next().value,e.next()).value,e.next()).value,e.next().value),e.next()).value,e.next().value),this.E_=J,G),Sp),a),YW),FK)[0]]=w,L),UC),q),O),$W),m),OW),this.I=k,c),this).R=Df,this).bI=Y,FK)[2]]=OC,this.Vk=t,this.W9=o6,this)[FK[1]]=n,this.hO=g8,ur),F),Q),A),this).Fe=R,this.Y=v8,this.qp=R6,this).W=r,this.O=br,sC),this.iI=VE,AA),N),g),this).o6=d,this).iz=q4,B),this).ns=z,this).J=hA,D),mQ),this).l=C,h),M),KB),this.ks=tA,x),X),this.Gy=u,Z),Ph),this).hj=LB,E)},gE.prototype.V=function(N,C,e,L,h,Q,m,O, +t,D,q,u){return[(O=(Q=(t=(m=(L=(N=(D=P[4](10,K[21](33,this,(e=(u=[56,2,15],[1862,191,0]),6))),q=D.next().value,D.next()).value,h=D.next().value,D).next().value,D).next().value,D.next()).value,C=I[21](7),I[21](20)),I[21](84)),y)[u[2]](75,78,this.J),y[u[2]](70,313,this.JO),y[u[2]](43,e[1],this.ZM),y[u[2]](70,583,this.vK),v[31](77,this.ZM,N),y[u[2]](74,613,h),P[37](81,h,N,this.B),y[u[2]](71,364,h),P[37](87,h,N,this.F),y[u[2]](72,1613,h),P[37](84,h,N,this.jW),U[0](75,this.bI,e[u[1]]),U[0](95,this.h,e[u[1]]), +y[36](u[1],this.G),Zz(this.W,this.J),U[0](74,this.I,e[u[1]]),U[0](94,this.O,e[u[1]]),U[0](88,this.Np,e[u[1]]),U[0](94,this.Z,e[u[1]]),U[0](94,this.K,e[u[1]]),U[0](91,this.Y,e[u[1]]),U[0](75,this.iI,e[u[1]]),U[0](74,this.u,e[u[1]]),U[0](75,this.T,e[u[1]]),y[36](1,this.wq),y[36](3,this.hO),y[36](u[1],this.l),y[36](1,this.X),U[0](95,this.S,e[u[1]]),U[0](93,this.R,e[u[1]]),U[0](93,this.C,e[u[1]]),y[u[2]](71,1954,h),K[17](69,e[u[1]],!1,C,this.o,h),y[u[2]](74,836,h),K[16](13,h,C,this.o,this.lI),y[u[2]](73, +1701,h),K[16](18,h,C,this.o,this.Xe),y[u[2]](45,93,h),K[16](11,h,C,this.o,this.S_),y[u[2]](45,1787,h),K[16](23,h,C,this.o,this.qp),y[u[2]](71,1876,h),K[16](22,h,C,this.o,this.mF),y[u[2]](75,1861,h),K[16](17,h,C,this.o,this.W9),y[u[2]](75,1216,h),K[16](10,h,C,this.o,this.PL),y[u[2]](70,2017,h),K[16](u[2],h,C,this.o,this.tu),y[u[2]](76,891,h),K[16](10,h,C,this.o,this.SW),y[u[2]](73,1363,h),K[16](21,h,C,this.o,this.ZR),y[u[2]](76,1940,h),T[23](27,7,9,h,this.o,this.Fe,Q),Q,y[u[2]](73,774,this.iz),y[u[2]](45, +1398,this.Vk),y[u[2]](75,1352,this.z$),y[u[2]](77,489,this.ns),y[u[2]](44,543,this.hj),y[u[2]](74,1131,this.E_),y[u[2]](77,916,this.Nk),y[u[2]](44,2017,this.Gy),y[u[2]](45,891,this.lz),y[u[2]](43,1111,this.Ub),y[u[2]](75,177,this.ks),y[u[2]](70,398,this.Fd),S[32](13,this.DM,this.rq,this.Gm),S[32](7,this.DM,this.Ku,this.rv),S[32](6,this.DM,this.o6,this.xN),T[30](u[0],O,e[u[1]],e[u[1]]),C,U[0](95,this.bI,1),S[32](5,this.DM,this.rq,this.E5),S[32](19,this.DM,this.Ku,this.E5),S[32](10,this.DM,this.o6, +this.E5),O,y[u[2]](75,452,L),v[31](91,L,L),y[u[2]](73,181,h),P[37](82,h,L,L),y[u[2]](76,617,m),y[u[2]](43,1550,t),ii(h,L,m,t,this.rq),y[u[2]](73,889,t),ii(h,L,m,t,this.Ku),y[u[2]](45,e[0],t),ii(h,L,m,t,this.o6),new FD(this.bp,this.DM),y[36](u[1],q),y[36](1,N),y[36](3,h),y[36](1,L),y[36](6,m),y[36](3,t)]},gE.prototype).i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA){return k=[(u=(J=(B=(N=(Q=(d=(q=(g=(n=(h=(A=(L=(a=(z=(R=(c=(D=(t=(M=(w=P[4]((G=[0,28,(hA=(m=I[21](71), +[36,44,3]),1)],14),K[21](37,this,13)),w.next()).value,w.next().value),w).next().value,w.next().value),w.next()).value,E=w.next().value,O=w.next().value,w.next().value),w.next().value),w.next()).value,w.next()).value,w.next().value),x=w.next().value,X=y[15](77,G[1],t),y[15](43,298,D)),f[38](7,W[0](19,this.I),c,16)),C=ii(R,this.W,t,c),e=U[0](95,E,G[0]),Z=ii(E,this.W,t,E,c),ii)(R,R,D,E),U)[0](90,z,G[0]),U)[0](88,E,6),Y=P[37](86,this.JO,R,c),F=P[37](84,z,R,O),ii(O,O,t)),P[37](86,E,O,a)),this).pR,P)[4](14, +y[41](10,c7.M(),G[2])).next().value,r=I[21](23),y[hA[0]](hA[2],u)),T[30](48,r,W[0](7,u),W[0](23,J.B)),ii(u,J.B,J.J,a),r,U[27](16,u,a)],c7.M().i(u),[X,n,g,C,e,Z,q,d,Q,Y,y[17](11,c,z,[F,N,B,k,I[26](38,O,E,W[0](1,a)),I[26](38,R,z,W[0](22,O))]),yg(h,this.B,this.R),l[hA[1]](62,h,W[0](18,h),W[0](5,this.C)),l[hA[1]](17,E,W[0](23,this.u),G[2]),H[45](19,h,W[0](1,h),W[0](hA[2],E)),l[hA[1]](58,x,W[0](22,h),G[2]),v[31](71,this.ZM,E),ii(x,E,this.vK,x),S[48](9,x,W[0](17,x),4),l[hA[1]](16,h,W[0](hA[2],h),W[0](6, +this.T)),yg(E,this.B,this.S),l[hA[1]](60,h,W[0](5,h),W[0](16,E)),f[38](5,W[0](7,h),h,11),l[hA[1]](57,x,W[0](16,x),W[0](7,h)),yg(x,this.B,x),y[hA[0]](1,h),y[hA[0]](1,E),T[30](38,m,W[0](6,this.Z),G[0]),H[45](13,E,W[0](1,this.iI),W[0](2,this.Z)),S[48](41,E,W[0](6,E),100),yg(E,this.B,E),m,yg(c,this.B,this.K),Zz(L,this.J,this.O,c,E),yg(E,this.B,this.S),yg(c,this.B,this.R),Zz(A,this.J,this.u,E,c,this.T),Zz(M,this.J,this.I,R,L,A,this.bI,this.h,x),this.stringify(M,M),H[0](16,M,this),y[hA[0]](hA[2],t),y[hA[0]](5, +D),y[hA[0]](5,c),y[hA[0]](1,R),y[hA[0]](2,E),y[hA[0]](5,z),y[hA[0]](hA[2],O),y[hA[0]](1,a),y[hA[0]](5,L),y[hA[0]](hA[2],A)]},gE.prototype).A=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB,R6,LB,sC,Sp,ur,g8,$W,q4,br,o6,VE,Ph,AA,OW,v8,YW,FK,td,d8,ir,fB,c8,Nx,Xq,pJ,CP,UW,UN,e8,XK,LP,SN,l4,DI,nJ,x4,c2,hJ,KJ,KP,EW,qx,T0,AJ,Y4,Qq,b8,IF,Ja,EY,mj,eV,oY,Yn,zU,go,nx,W2,H2,Mx,II,zN,Q$,aH,b){return aH=[(EW=(oY=(q=(Mx=(br=(pJ=(Z=(A=(Y4=(L=(R=(n=(q4=(R6=(Ja=(k=(m= +(Ph=(e8=(KB=(qx=(M=(UN=(W2=(J=(mQ=(X=(FK=(UW=(z=((OW=(d=(hA=(G=(nx=(UC=(F=(KP=(CP=(II=(c8=(sC=(Df=(N=(Sp=(x=(v8=(DI=(D=(OC=(H2=($W=(LP=(mj=(o6=(c=(zU=(zN=(C=(Y=(l4=(Yn=(r=(KJ=(B=(IF=(a=(ir=(nJ=(Q$=(AA=[(c2=(g=(YW=(LB=(fB=(go=P[4](15,K[21](32,this,(b=[.1,(e=[1,0,5],37),0],e[b[2]]))).next().value,b8=P[4](11,K[21](35,this,e[2])),b8.next()).value,b8).next().value,x4=b8.next().value,Qq=b8.next().value,b8.next().value),I[21](87)),I[21](20)),this).Gm,U[b[2]](94,fB,e[1]),P[b[1]](80,fB,this.DM,this.G),y[36](5, +this.DM),y[b[1]](22,e[2],this.o,this.G,c2),yg(LB,this.Xe,this.G),yg(x4,this.S_,this.G),y[36](1,fB),T[30](54,g,W[b[2]](17,this.X),W[b[2]](19,fB)),U[24](40,Qq,W[b[2]](1,LB),W[b[2]](6,this.l)),U[24](26,YW,W[b[2]](7,x4),W[b[2]](1,this.X)),S[48](65,Qq,W[b[2]](22,Qq),W[b[2]](21,Qq)),S[48](9,YW,W[b[2]](2,YW),W[b[2]](16,YW)),l[44](58,fB,W[b[2]](2,Qq),W[b[2]](5,YW)),yg(fB,this.F,fB),l[44](20,this.S,W[b[2]](2,this.S),W[b[2]](17,fB)),g,U[27](66,LB,this.l),U[27](18,x4,this.X),y[36](1,fB),y[36](2,LB),y[36](3, +x4),y[36](1,Qq),y[36](2,YW),K[25](36),c2,y[36](2,this.G),l[44](56,this.h,W[b[2]](21,this.h),e[b[2]]),K[25](42)],XK=P[4](10,K[21](32,this,23)),XK.next()).value,XK.next().value),u=XK.next().value,XK.next().value),tA=XK.next().value,XK.next().value),XK.next().value),XK.next()).value,AJ=XK.next().value,XK.next().value),XK.next().value),XK.next().value),XK.next()).value,XK.next().value),XK.next()).value,E=XK.next().value,XK.next()).value,XK.next()).value,w=XK.next().value,XK.next().value),XK.next()).value, +XK).next().value,XK).next().value,I)[21](23),I[21](87)),I[21](7)),I[21](87)),T0=this.rv,U[b[2]](94,Q$,e[1])),O=P[b[1]](87,Q$,this.DM,this.DM),y[b[1]](8,e[2],this.o,this.DM,D)),hJ=y[36](3,Q$),T)[30](54,$W,W[b[2]](16,this.G),W[b[2]](3,Q$)),yg(nJ,this.qp,this.G)),d8=yg(nJ,this.B,nJ),yg(u,this.mF,this.G)),Nx=yg(u,this.B,u),yg(ir,this.lI,this.G)),Xq=yg(ir,this.B,ir),yg)(tA,this.lI,this.DM),U[24](56,tA,W[b[2]](6,tA),W[b[2]](21,ir))),yg(tA,this.B,tA)),eV=S[48](1,a,W[b[2]](7,tA),4),SN=l[44](26,a,W[b[2]](23, +a),W[b[2]](5,ir)),yg(IF,this.W9,this.G)),VE=y[36](2,r),y[36](3,E)),y)[36](5,AJ),T[30](39,H2,W[b[2]](22,IF),W[b[2]](3,r))),h=ii(B,IF,this.iz,this.Vk),f[9](3,B,W[b[2]](5,B),W[b[2]](22,IF))),P[b[1]](80,this.ns,B,E)),this.pR),P)[4](11,y[41](74,c7.M(),e[b[2]])).next().value,I[21](7)),g8=[y[36](3,d),T[30](39,OW,W[b[2]](7,d),W[b[2]](2,hA.T)),P[b[1]](84,E,hA.T,d),f[9](19,d,W[b[2]](6,d),e[1]),OW,U[27](21,d,E)],c7).M().i(d),[T0,DI,O,v8,hJ,x,Sp,d8,N,Nx,Df,Xq,sC,c8,II,eV,SN,CP,VE,KP,F,UC,h,nx,G,g8,ii(KJ,B,this.hj), +T[30](41,H2,W[b[2]](23,r),W[b[2]](19,KJ)),P[b[1]](86,this.E_,KJ,Yn),v[31](74,this.ks,Q$),l[44](22,Yn,W[b[2]](19,Yn),W[b[2]](6,Q$)),yg(Yn,this.B,Yn),P[b[1]](82,this.Nk,KJ,l4),v[31](89,this.Ub,Q$),l[44](53,l4,W[b[2]](23,l4),W[b[2]](3,Q$)),yg(l4,this.B,l4),P[b[1]](82,this.Gy,KJ,Y),yg(Y,this.B,Y),P[b[1]](87,this.lz,KJ,C),yg(C,this.B,C),Zz(r,this.J,Yn,l4,Y,C),l[44](60,Q$,W[b[2]](21,nJ),W[b[2]](18,l4)),l[44](21,Q$,W[b[2]](17,Q$),W[b[2]](17,Y)),S[48](33,a,W[b[2]](2,a),W[b[2]](19,Q$)),l[44](54,Q$,W[b[2]](19, +u),W[b[2]](22,Yn)),l[44](30,Q$,W[b[2]](23,Q$),W[b[2]](17,C)),l[44](16,Q$,W[b[2]](22,Q$),e[b[2]]),H[45](15,a,W[b[2]](23,a),W[b[2]](2,Q$)),P[b[1]](87,this.z$,B,AJ),f[9](35,AJ,W[b[2]](16,AJ),W[b[2]](18,B)),H2,yg(a,this.B,a),l[44](62,this.C,W[b[2]](5,this.C),W[b[2]](3,a)),y[36](5,a),yg(w,this.PL,this.G),S[48](1,w,W[b[2]](16,w),100),yg(w,this.B,w),yg(c,this.qp,this.DM),U[24](26,c,W[b[2]](21,c),W[b[2]](6,nJ)),S[48](33,c,W[b[2]](18,c),W[b[2]](1,c)),yg(o6,this.mF,this.DM),U[24](25,o6,W[b[2]](21,o6),W[b[2]](3, +u)),S[48](1,o6,W[b[2]](2,o6),W[b[2]](5,o6)),l[44](53,mj,W[b[2]](17,c),W[b[2]](23,o6)),yg(mj,this.F,mj),l[44](62,mj,W[b[2]](7,mj),.49),yg(mj,this.B,mj),yg(LP,this.tu,this.G),yg(Q$,this.SW,this.G),S[48](41,LP,W[b[2]](1,LP),W[b[2]](17,Q$)),yg(LP,this.B,LP),Zz(zN,this.J,ir,tA,nJ,u,r,E,AJ,w,mj,LP),f[38](22,W[b[2]](6,this.I),zU,16),I[26](34,this.W,zU,W[b[2]](3,zN)),l[44](21,this.I,W[b[2]](7,this.I),e[b[2]]),y[36](5,this.G),$W,yg(nJ,this.Xe,this.DM),yg(u,this.S_,this.DM),y[36](5,Q$),T[30](36,OC,W[b[2]](19, +this.X),W[b[2]](22,Q$)),U[24](25,c,W[b[2]](3,nJ),W[b[2]](16,this.l)),U[24](58,o6,W[b[2]](23,u),W[b[2]](5,this.X)),S[48](1,c,W[b[2]](16,c),W[b[2]](7,c)),S[48](65,o6,W[b[2]](19,o6),W[b[2]](17,o6)),l[44](18,Q$,W[b[2]](6,c),W[b[2]](2,o6)),yg(Q$,this.F,Q$),l[44](30,this.S,W[b[2]](19,this.S),W[b[2]](5,Q$)),OC,U[27](22,nJ,this.l),U[27](86,u,this.X),y[36](6,Q$),y[36](1,nJ),y[36](2,u),y[36](1,ir),y[36](1,tA),y[36](1,zN),y[36](1,zU),y[36](3,this.DM),K[25](52),D,y[36](6,this.DM),l[44](30,this.h,W[b[2]](21,this.h), +e[b[2]]),K[25](20)]),P[4](10,K[21](b[1],this,14))),UW).next().value,UW.next()).value,UW.next().value),UW.next().value),UW).next().value,UW.next()).value,UW.next().value),UW.next()).value,UW.next()).value,UW).next().value,UW).next().value,UW).next().value,Q=UW.next().value,UW).next().value,I[21](20)),I[21](84)),I)[21](87),EY=I[21](7),ur=I[21](7),I)[21](7),[P[b[1]](87,KB,mQ,X),yg(e8,this.lI,X),U[24](41,Ph,W[b[2]](1,e8),W[b[2]](22,this.Np)),P[12](27,52,q4,W[b[2]](7,Ph)),P[12](30,W[b[2]](1,Ph),q4,e[1]), +T[30](38,q4,W[b[2]](6,Ph),e[1]),P[12](31,W[b[2]](19,this.K),EY,6),P[12](29,W[b[2]](2,Ph),EY,W[b[2]](7,this.K)),H[45](17,FK,W[b[2]](18,Ph),W[b[2]](21,this.K)),yg(FK,this.B,FK),H[45](16,m,W[b[2]](1,Ph),W[b[2]](21,FK)),T[30](39,ur,e[b[2]],e[b[2]]),EY,U[27](97,Ph,m),ur,l[44](49,this.Z,W[b[2]](16,this.Z),e[b[2]]),H[45](20,Q,e[b[2]],W[b[2]](17,this.Z)),P[12](24,b[0],n,W[b[2]](16,Q)),U[b[2]](74,Q,b[0]),n,U[24](58,k,e[b[2]],W[b[2]](18,Q)),S[48](33,this.K,W[b[2]](22,k),W[b[2]](22,this.K)),S[48](9,FK,W[b[2]](21, +Q),W[b[2]](16,m)),l[44](54,this.K,W[b[2]](17,this.K),W[b[2]](19,FK)),S[48](9,this.Y,W[b[2]](6,k),W[b[2]](6,this.Y)),S[48](41,FK,W[b[2]](2,Q),W[b[2]](7,Ph)),l[44](26,this.Y,W[b[2]](18,this.Y),W[b[2]](16,FK)),U[24](59,FK,W[b[2]](1,m),W[b[2]](2,this.K)),yg(FK,this.jW,FK),l[44](50,this.iI,W[b[2]](1,this.iI),W[b[2]](21,FK)),S[48](1,FK,1.5,W[b[2]](7,this.K)),P[12](28,W[b[2]](23,this.Y),q4,W[b[2]](2,FK)),U[27](80,this.Y,this.K),q4,U[27](83,e8,this.Np)]),I[21](23)),I[21](7)),I[21](20)),I[21](87)),I[21](87)), +I[21](84)),t=[this.xN,U[b[2]](75,FK,e[1]),P[b[1]](83,FK,this.DM,X),y[b[1]](7,e[2],this.o,X,br),l[44](21,this.u,W[b[2]](5,this.u),e[b[2]]),yg(FK,this.ZR,X),T[30](48,Ja,W[b[2]](5,FK),W[b[2]](5,this.Fd)),T[30](55,R6,e[1],e[1]),Ja,l[44](52,this.T,W[b[2]](21,this.T),e[b[2]]),R6,yg(J,this.Xe,X),yg(W2,this.S_,X),y[36](2,FK),T[30](38,A,W[b[2]](6,this.X),W[b[2]](21,FK)),T[30](58,Z,e[b[2]],e[b[2]]),A,U[27](84,J,this.l),U[27](17,W2,this.X),Z,T[30](41,pJ,W[b[2]](18,this.hO),W[b[2]](21,FK)),U[24](59,UN,W[b[2]](18, +J),W[b[2]](23,this.wq)),U[24](56,M,W[b[2]](18,W2),W[b[2]](16,this.hO)),S[48](41,UN,W[b[2]](17,UN),W[b[2]](19,UN)),S[48](9,M,W[b[2]](18,M),W[b[2]](16,M)),l[44](24,FK,W[b[2]](23,UN),W[b[2]](16,M)),yg(FK,this.F,FK),l[44](53,this.R,W[b[2]](7,this.R),W[b[2]](22,FK)),pJ,U[27](67,J,this.wq),U[27](65,W2,this.hO),y[36](5,FK),T[30](57,L,W[b[2]](23,FK),W[b[2]](19,this.Fe)),yg(mQ,this.Fe,X),T[30](55,L,W[b[2]](3,FK),W[b[2]](1,mQ)),P[b[1]](82,this.JO,mQ,qx),T[30](40,L,W[b[2]](2,qx),e[1]),P[12](26,W[b[2]](23,qx), +Y4,W[b[2]](16,this.O)),U[27](22,qx,this.O),T[30](58,Y4,e[b[2]],e[b[2]]),L,U[27](20,this.DM,mQ),U[b[2]](93,qx,e[b[2]]),Y4,U[b[2]](91,KB,e[1]),y[17](11,qx,KB,R),y[36](6,FK),y[36](3,X),y[36](5,mQ),y[36](3,qx),y[36](2,KB),y[36](3,e8),y[36](2,Ph),y[36](2,m),y[36](1,Q),y[36](6,k),y[36](1,this.DM),K[25](43),br,y[36](6,this.DM),y[36](1,X),l[44](16,this.h,W[b[2]](7,this.h),e[b[2]]),K[25](54)],P[4](15,K[21](b[1],this,4))),Mx.next().value),td=Mx.next().value,Mx).next().value,Mx).next().value,this).bp,y[15](44, +452,q),v[31](74,q,q),y[15](43,181,EW),P[b[1]](84,EW,q,q),y[15](70,541,td),y[15](70,1550,oY),ii(EW,q,td,oY,this.rq),y[15](72,889,oY),ii(EW,q,td,oY,this.Ku),y[15](45,1862,oY),ii(EW,q,td,oY,this.o6),y[36](2,q),y[36](5,td),y[36](1,oY),y[36](6,EW),K[25](b[1])],[AA,z,t,aH,this.E5,U[b[2]](92,go,e[1]),P[b[1]](82,go,this.DM,this.G),y[36](6,this.DM),K[25](36)]},T)[40](3,dE,YK),dE).prototype.P=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){this.X=(this[this.G=(this.Y=((this[(this.l=(this.I=(this.K=(u=(L=(m=(C=(Q=(q= +(h=(t=(D=P[4]((c=[10,"B","J"],c[0]),S[31](7,13,this)),N=D.next().value,D.next().value),G=D.next().value,O=D.next().value,D.next().value),D.next()).value,D.next().value),D.next()).value,e=D.next().value,D.next()).value,D).next().value,D.next().value),B=D.next().value),C),u),this.S=h,c)[2]]=O,this.Z=L,this).F=e,t),Q),this.o=q,c[1]]=N,m),this.h=G},dE.prototype).i=function(N,C){return[Zz((N=P[4](11,K[21](38,(C=["h",1,"J"],this),C[1])).next().value,N),this.G,this.B,this[C[0]],this[C[2]]),y[47](47,W[0](C[1], +N),N),H[0](48,N,this)]},dE).prototype.A=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){return e=(A=(N=(t=(h=(C=(m=(Q=(D=(O=(q=(u=(L=(G=P[4](11,K[21](35,this,(c=[1,!(n=[70,0,2],1),!0],c[n[1]]))).next().value,[U[24](26,G,W[n[1]](7,G),17),ii(this.B,this.B,this.l,G)]),P[4](11,K[21](33,this,8))),u.next().value),u.next().value),u.next()).value,u.next().value),u.next()).value,u).next().value,u.next().value),u.next().value),I[21](71)),I)[21](7),B=I[21](71),I[21](23)),[this.u,Zz(D,this.G),v[31](86,this.I,q), +v[31](n[0],this.F,O),ii(m,D,this.X,q,O),y[47](39,W[n[1]](16,D),D),T[30](56,N,W[n[1]](1,D),W[n[1]](6,this.Y)),T[30](43,B,W[n[1]](17,O),W[n[1]](1,this.o)),P[12](30,W[n[1]](19,this.o),A,W[n[1]](n[2],O)),U[n[1]](95,t,c[1]),T[30](58,e,c[n[1]],c[n[1]]),A,U[n[1]](74,t,c[n[2]]),e,T[30](57,B,W[n[1]](19,t),W[n[1]](6,this.S)),l[44](56,this.J,W[n[1]](22,this.J),c[n[1]]),U[27](86,t,this.S),B,U[27](23,O,this.o),l[44](61,this.h,W[n[1]](n[2],this.h),c[n[1]]),U[27](23,D,this.Y),Zz(Q,this.G),K[11](7,C),ii(m,Q,this.X, +q,O,C),ii(m,this.B,this.X,Q),P[37](84,this.Z,this.B,G),P[12](29,W[n[1]](7,G),N,26),L,N,y[36](3,D),y[36](n[2],Q),y[36](6,m),y[36](5,q),y[36](1,O),y[36](3,C),y[36](3,G),K[25](38),this.T,y[15](44,1231,h),Zz(m,h,this.K),y[36](5,h),y[36](n[2],m),y[36](6,this.K),K[25](38)]},dE).prototype.V=function(N,C,e,L,h,Q,m,O){return N=(C=(L=(Q=K[21](34,(m=[306,28,(O=["B",36,15],78)],this),4),e=P[4](12,Q),e).next().value,h=e.next().value,e.next().value),e.next()).value,[y[O[1]](2,this.Y),y[O[1]](3,this.o),y[O[2]](72, +m[2],this.G),y[O[2]](77,177,this.I),y[O[2]](43,1111,this.F),y[O[2]](71,m[0],this.X),y[O[2]](44,313,this.Z),y[O[2]](73,m[1],this.l),Zz(this[O[0]],this.G),U[0](75,this.h,0),U[0](89,this.J,0),U[0](74,this.S,!0),U[0](74,this.o,-1),S[32](9,L,C,this.u),y[O[2]](44,215,h),U[0](75,N,100),Zz(this.K,h,C,N),new FD(this.T,this.K),y[O[1]](5,L),y[O[1]](5,h),y[O[1]](5,C),y[O[1]](6,N)]},T[40](59,SD,YK),SD).prototype.i=function(N,C,e){return[(N=(C=(e=[5,4,20],K)[21](32,this,1),P[e[1]](11,C).next().value),K)[11](e[1], +N),H[45](14,N,W[0](e[0],N),10),H[0](e[2],N,this)]},T[40](56,Jv,YK),Jv.prototype.i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB,R6,LB,sC,Sp,ur,g8,$W,q4,br,o6,VE,Ph,AA,OW,v8,YW,FK,td,d8,ir,fB,c8,Nx,Xq,pJ,CP,UW,UN,e8,XK,LP,SN,l4,DI,nJ,x4,c2,hJ,KJ){KJ=[12,81,84],M=[372,246,298];function KP(EW,qx,T0,AJ,Y4,Qq,b8,IF,Ja,EY,mj,eV,oY,Yn,zU,go,nx,W2,H2,Mx,II,zN){return H2=(zU=(oY=(nx=(Qq=(Ja=(eV=(EY=(II=(Mx=P[37](86,(go=(mj=I[21](71),[1,20,!1]),zN=[30,0,85], +c8),Ph,r),U[zN[1]](89,q4,zN[1])),U[zN[1]](75,c2,go[1])),q4),Yn=c2,b8=I[21](87),I)[21](87),I[21](71)),W2=I[21](84),I[21](20)),I)[21](7),[P[37](81,t,r,Xq),P[37](83,$W,r,pJ),P[37](86,d,r,N),P[37](82,x4,r,sC),ii(KB,R6,fB,Xq,pJ,N,sC),T[zN[0]](58,Qq,W[zN[1]](7,AJ),W[zN[1]](3,hJ)),T[zN[0]](42,W2,go[zN[1]],go[zN[1]]),Qq,ii(ir,X,e,KB),T[zN[0]](48,nx,W[zN[1]](3,ir),go[2]),P[37](zN[2],c8,Ph,AJ),T[zN[0]](59,mj,go[zN[1]],go[zN[1]]),W2,nx,T[zN[0]](43,b8,W[zN[1]](6,Y4),W[zN[1]](2,hJ)),T[zN[0]](49,Ja,go[zN[1]],go[zN[1]]), +b8,ii(ir,x,e,KB),T[zN[0]](48,oY,W[zN[1]](17,ir),go[2]),P[37](86,c8,Ph,Y4),T[zN[0]](59,mj,go[zN[1]],go[zN[1]]),Ja,oY,P[37](80,R,r,r),T[zN[0]](40,mj,W[zN[1]](5,hJ),W[zN[1]](18,r))]),y)[17](9,Yn,eV,zU),IF=[Mx,II,EY,H2,mj,y[1](16,23,ir,W[zN[1]](22,Y4),W[zN[1]](16,AJ)),T[zN[0]](39,EW,W[zN[1]](23,ir),!0)],y[17](14,qx,T0,IF)}return(B=(O=[(J=[(o6=(Z=[(Q=(OC=[(Y=(td=(FK=(L=(n=(VE=(AA=(ur=(SN=(e8=(mQ=(h=(Df=(CP=(OW=(l4=(Nx=(XK=(d8=(UN=(hJ=(c=(LP=(UC=(D=(E=(x=(X=(R=(c2=(q=(YW=(ir=(v8=(fB=(KB=(d=(x4=($W=(t=(N= +(sC=(r=(q4=(c8=(R6=(br=(u=(Ph=(w=(e=(a=(m=(tA=(z=(LB=(DI=K[21](35,this,55),A=P[4](11,DI),A).next().value,Sp=A.next().value,A).next().value,A.next().value),A.next().value),A.next().value),A.next()).value,k=A.next().value,A.next().value),A).next().value,A.next().value),A.next().value),A).next().value,A.next().value),A.next().value),A.next().value),Xq=A.next().value,pJ=A.next().value,A).next().value,A.next().value),A.next()).value,A.next().value),A.next().value),A).next().value,A.next().value),A).next().value, +A).next().value,A).next().value,A.next().value),C=A.next().value,A).next().value,A.next().value),A.next().value),A.next().value),A.next()).value,A).next().value,A.next().value),A.next().value),A).next().value,A).next().value,A).next().value,A).next().value,A.next()).value,g=A.next().value,nJ=A.next().value,UW=A.next().value,A).next().value,A).next().value,A.next()).value,A).next().value,A.next().value),A).next().value,A).next().value,A).next().value,A).next().value,hA=I[21](87),g8=I[21](20),I[21](20)), +I[21](20)),I)[21](7),I[21](23)),I[21](20)),I)[21](KJ[2]),G=I[21](20),I[21](20)),I[21](71)),[P[37](83,c8,w,r),P[37](KJ[1],YW,r,C),P[37](80,a,C,q),P[KJ[0]](25,15,hA,W[0](6,q)),P[37](85,t,r,Xq),P[37](KJ[2],$W,r,pJ),P[37](KJ[2],d,r,N),P[37](87,x4,r,sC),ii(KB,R6,fB,Xq,pJ,N,sC),ii(ir,E,e,KB),T[30](49,hA,W[0](6,ir),!1),P[KJ[0]](30,W[0](2,q),hA,1),ii(ir,Ph,k,r),hA]),P)[37](82,c8,UN,r),P[37](82,t,r,Xq),P[37](85,$W,r,pJ),P[37](86,d,r,N),P[37](85,x4,r,sC),ii(KB,R6,fB,Xq,pJ,N,sC),ii(ir,D,e,KB),T[30](53,g8,W[0](19, +ir),0),ii(ir,Ph,k,r),g8],[P[37](KJ[1],c8,d8,r),P[37](80,t,r,Xq),P[37](KJ[2],$W,r,pJ),P[37](82,x4,r,sC),ii(KB,R6,fB,Xq,pJ,sC),ii(ir,UC,e,KB),T[30](53,td,W[0](21,ir),!1),P[37](83,e8,r,mQ),T[30](50,FK,1,1),td]),F=[y[15](74,452,LB),y[15](43,317,Sp),v[31](90,LB,LB),y[15](75,313,a),U[0](75,R6,""),U[0](93,c,OY()),y[15](76,416,v8),ii(Ph,R6,v8,R6),ii(br,R6,v8,R6),y[15](70,218,t),y[15](76,153,$W),y[15](74,51,d),y[15](71,496,x4),y[15](73,M[0],E),y[15](74,338,e),y[15](45,306,k),y[15](71,M[2],fB),y[15](75,362, +YW),y[15](74,141,R),y[15](44,73,X),y[15](43,98,x),y[15](45,206,D),y[15](70,939,UC),y[15](44,239,LP),y[15](77,1921,e8),U[0](75,Nx,Hb()),v[31](77,Nx,Nx),U[0](91,l4,oC()),ii(hJ,R6,LP,c),y[36](6,g),y[36](3,nJ),y[36](5,UW),y[36](6,XK),P[22](72,X,W[0](17,X),ep()),P[22](74,x,W[0](19,x),ep()),P[22](90,E,W[0](3,E),ep()),P[22](30,D,W[0](23,D),ep()),P[22](24,UC,W[0](17,UC),ep())],y)[15](72,436,z),ii(w,LB,Sp,z),P[37](82,a,w,u),U[0](88,ir,30),ii(u,Nx,l4,u,ir),U[0](74,c8,0),y[17](14,u,c8,Y),U[0](90,c8,0),P[37](82, +a,Ph,u),P[KJ[0]](24,4,SN,W[0](23,u)),KP(ur,u,c8,g,nJ),ur],[y[15](75,74,tA),ii(UN,LB,Sp,tA),P[37](87,a,UN,u),U[0](88,c8,0),U[0](90,ir,30),ii(u,Nx,l4,u,ir),ii(Ph,R6,v8,R6),y[17](10,u,c8,OC),U[0](95,c8,0),P[37](87,a,Ph,u),P[KJ[0]](27,4,SN,W[0](5,u)),KP(AA,u,c8,UW,XK),AA]),y)[15](77,1332,m),ii(d8,LB,Sp,m),P[37](83,a,d8,u),U[0](92,c8,0),U[0](90,ir,30),ii(u,Nx,l4,u,ir),ii(Ph,R6,v8,R6),U[0](88,mQ,!1),y[17](11,u,c8,Q),FK],y[15](75,350,OW)),y[15](75,M[1],CP),y[15](45,446,Df),SN,T[30](50,VE,W[0](23,g),W[0](18, +hJ)),P[37](KJ[1],YW,g,g),VE,ii(ir,br,k,g),T[30](37,n,W[0](16,nJ),W[0](22,hJ)),P[37](87,YW,nJ,nJ),n,ii(ir,br,k,nJ),T[30](37,G,W[0](5,UW),W[0](5,hJ)),P[37](86,OW,UW,h),P[37](85,CP,UW,ir),P[37](82,ir,h,UW),P[37](80,Df,UW,UW),G,ii(ir,br,k,UW),T[30](42,L,W[0](21,XK),W[0](2,hJ)),P[37](86,OW,XK,h),P[37](KJ[2],CP,XK,ir),P[37](82,ir,h,XK),P[37](KJ[2],Df,XK,XK),L,ii(ir,br,k,XK),this.stringify(mQ,mQ),ii(ir,br,k,mQ)],[y[36](6,LB),y[36](5,Sp),y[36](1,z),y[36](1,a),y[36](3,t),y[36](2,$W),y[36](3,d),y[36](5,x4), +y[36](5,E),y[36](1,X),y[36](1,x),y[36](2,D),y[36](3,UC),y[36](3,R),y[36](2,fB),y[36](5,k),y[36](5,v8),y[36](3,OW),y[36](5,CP),y[36](1,Df),y[36](6,e),y[36](3,YW),y[36](2,LP),y[36](5,tA),y[36](2,e8),y[36](6,m),this.stringify(br,br),H[0](44,br,this)]),F).concat(Z,o6,J,O,B)},T[40](35,bI,YK),bI).prototype.i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB,R6,LB,sC,Sp,ur,g8,$W,q4,br,o6,VE,Ph,AA,OW,v8,YW,FK,td,d8,ir,fB,c8,Nx,Xq,pJ,CP,UW,UN,e8,XK,LP,SN,l4,DI, +nJ,x4,c2,hJ,KJ,KP,EW,qx,T0,AJ,Y4,Qq,b8,IF,Ja,EY,mj,eV,oY,Yn,zU,go,nx,W2,H2,Mx,II,zN,Q$,aH,b,uC,f9,XV,nB){return[(Ph=(D=(tA=(F=(br=(v8=(g=(L=(q4=(EY=(UW=(G=(OC=(IF=(zU=(Ja=(b=(XV=(eV=(mj=(oY=(mQ=(Qq=(f9=(hA=(Y4=(h=(aH=(LP=(c2=(sC=(KJ=(qx=(td=(UN=(hJ=(UC=(x4=(e=(nx=(X=(c=(AJ=(Yn=(FK=(A=(Sp=($W=(m=(go=(Q$=(Df=(o6=(N=(d8=(XK=(fB=(YW=(e8=(ur=(u=(DI=(g8=(OW=(w=(nJ=(l4=(W2=(Y=(LB=(J=(KB=(x=(CP=(k=(T0=(H2=(R=(EW=(SN=(KP=(d=(AA=(nB=(Z=[!1,!0,41],[21,95,0]),zN=K[nB[0]](33,this,Z[2]),P[4](12,zN)),Nx=AA.next().value, +AA.next().value),pJ=AA.next().value,II=AA.next().value,r=AA.next().value,AA.next().value),AA.next()).value,AA.next().value),AA).next().value,AA).next().value,AA.next()).value,AA.next().value),n=AA.next().value,AA.next()).value,AA.next().value),AA.next().value),AA).next().value,AA).next().value,AA.next()).value,Mx=AA.next().value,AA.next().value),AA.next().value),uC=AA.next().value,C=AA.next().value,Q=AA.next().value,AA).next().value,Xq=AA.next().value,AA.next().value),AA).next().value,AA.next().value), +a=AA.next().value,AA.next()).value,AA.next().value),AA.next()).value,AA.next().value),AA).next().value,AA.next().value),AA.next().value),AA.next().value),AA.next().value),I)[nB[0]](84),I[nB[0]](20)),c8=I[nB[0]](71),I[nB[0]](23)),y)[15](73,452,C),v[31](87,C,C)),y[15](77,317,Q)),O=y[15](45,436,nJ),ii(Xq,C,Q,nJ)),y[36](2,Q)),z=y[36](5,nJ),y)[15](45,78,w),y[15](75,1308,OW)),ir=v[31](87,w,w),ii)(Xq,w,OW,Xq),y)[36](3,OW),y)[15](77,218,W2),t=y[15](77,153,Mx),y[15](72,548,Y)),y)[15](71,947,LB),y[15](70,1973, +fB)),y[15](45,239,XK)),y[15](43,306,pJ)),U[nB[2]](90,g8,"")),U[nB[2]](88,l4,nB[2])),sE(N,w)),P[33](8,1,nB[2],Xq,[U[nB[2]](94,YW,""),P[37](85,W2,a,DI),P[37](83,Mx,a,u),P[37](80,Y,a,ur),P[37](81,LB,a,e8),T[34](71,YW,W[nB[2]](1,DI),""),T[34](65,YW,W[nB[2]](3,YW),W[nB[2]](16,u)),T[34](66,YW,W[nB[2]](2,YW),W[nB[2]](1,ur)),T[34](69,YW,W[nB[2]](23,YW),W[nB[2]](17,e8)),ii(YW,YW,fB),y[15](71,2032,d),P[22](76,d,W[nB[2]](17,d),ep()),ii(J,YW,XK,d),y[36](3,d),f[26](5,25,W[nB[2]](1,J),d8),f[26](6,25,W[nB[2]](19, +d8),d8),T[30](56,o6,W[nB[2]](22,d8),Z[nB[2]]),ii(uC,N,pJ,a),o6],a,l4)),y)[36](3,W2),y)[36](2,Mx),y[36](1,Y)),y[36](2,LB)),y)[36](5,fB),y[36](5,pJ)),y)[36](6,J),y[36](6,uC)),y[36](6,Xq)),y[36](2,w)),y[36](3,DI)),y[36](5,u)),y)[36](2,ur),y[36](2,e8)),y)[36](2,YW),y[36](1,d8)),y[15](76,313,KB)),VE=P[37](81,KB,N,n),y)[36](3,KB),R6=U[nB[2]](92,H2,Z[nB[2]]),U)[nB[2]](92,SN,Z[nB[2]]),M=T[30](58,Q$,W[nB[2]](7,n),nB[2]),U[nB[2]](91,x,Z[nB[2]])),U)[nB[2]](90,CP,Z[1]),T[30](55,Df,W[nB[2]](7,n),1)),E=U[nB[2]](88, +CP,Z[nB[2]]),U[nB[2]](89,l4,nB[2])),q=P[37](85,l4,N,a),y[15](73,863,r)),P[37](85,r,a,T0)),U[nB[2]](nB[1],x,Z[1])),P[33](10,1,nB[2],N,[P[37](83,r,a,k),T[30](50,c8,W[nB[2]](22,k),W[nB[2]](16,T0)),U[nB[2]](75,x,Z[nB[2]]),T[30](37,Df,1,1),c8],a,l4)),b8=y[36](1,r),B=y[36](5,T0),y[36](3,k)),W)[nB[2]](5,CP),W[nB[2]](5,x)),P[18](28,W[39](20,S[32](76,new b4,24),H2),[y[38](16,tA),y[38](32,D)])),go),m,$W,O,Sp,A,z,FK,Yn,ir,AJ,c,X,t,nx,e,x4,UC,hJ,UN,td,qx,KJ,sC,c2,LP,aH,h,Y4,hA,f9,Qq,mQ,oY,mj,eV,XV,b,Ja,zU,VE, +IF,R6,OC,M,G,UW,EY,E,q4,q,L,g,v8,br,Df,b8,B,F,Ph,y[36](2,CP),y[36](5,x),T[30](51,Q$,W[nB[2]](nB[0],H2),Z[nB[2]]),y[15](70,181,EW),P[37](85,EW,C,EW),y[15](43,112,R),P[37](82,R,EW,R),y[36](5,EW),y[15](74,472,Nx),ii(SN,R,XK,Nx),y[36](5,Nx),y[36](2,R),y[36](6,XK),f[26](1,25,W[nB[2]](22,SN),SN),f[26](3,25,W[nB[2]](nB[0],SN),SN),Q$,y[36](6,l4),y[36](6,C),y[36](3,a),y[36](1,n),y[36](5,N),y[1](17,23,KP,W[nB[2]](6,SN),W[nB[2]](5,H2)),y[36](3,H2),T[34](76,II,W[nB[2]](2,KP),W[nB[2]](nB[0],g8)),y[36](6,g8),y[36](3, +KP),y[36](6,SN),H[nB[2]](12,II,this)]},T[40](35,kw,YK),kw.prototype.i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X){return R=(L=(N=(m=(e=(c=(O=(t=(q=(B=(D=(A=(C=(Q=(F=(Z=K[21](38,(u=[240,(X=[36,112,15],1),28],this),16),P[4](14,Z)),h=F.next().value,F.next().value),F.next().value),F.next().value),F.next().value),F.next().value),n=F.next().value,F.next()).value,F).next().value,F.next().value),F.next().value),F.next().value),F.next()).value,F).next().value,G=F.next().value,F).next().value,I[21](87)), +[y[X[2]](73,452,h),v[31](88,h,h),y[X[2]](77,181,Q),P[37](84,Q,h,Q),y[X[0]](5,h),y[X[2]](71,X[1],C),P[37](85,C,Q,C),y[X[0]](1,Q),y[X[2]](76,u[2],A),U[0](74,D,0),U[0](75,B,5E3),ii(C,C,A,D,B),y[X[0]](6,D),y[X[0]](3,B),y[X[2]](43,121,n),y[X[2]](72,422,q),T[34](77,q,ws(),W[0](19,q)),T[34](67,q,W[0](2,q),or()),T[34](68,q,W[0](3,n),W[0](23,q)),y[X[0]](2,n),P[22](88,q,W[0](7,q),Wn()),y[X[2]](74,u[0],t),ii(O,C,t,q),y[X[0]](6,C),y[X[0]](2,t),y[X[0]](5,q),y[X[2]](76,78,c),y[X[2]](77,1308,e),v[31](77,c,m),ii(m, +m,e,O),y[X[0]](6,c),y[X[0]](3,e),y[X[0]](2,O),U[0](74,L,-1),ii(m,m,A,L),y[X[0]](5,A),y[X[2]](74,313,G),P[37](84,G,m,N),P[12](27,W[0](18,N),R,u[1]),U[0](91,L,0),P[37](84,L,m,m),U[0](92,L,u[1]),P[37](87,G,m,N),P[12](24,W[0](2,N),R,2),P[37](86,L,m,m),R,y[X[0]](3,N),y[X[0]](1,G),y[X[0]](5,L),H[0](44,m,this)]},pO(1.4)),WU=[0,wv,i_,((((((((T[40](60,aS,YK),aS).prototype.A=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA,OC,KB,R6,LB){return q=(KB=(D=(d=(Df=(t=(N=[(X= +(R6=(n=(Q=(hA=(R=(k=(c=(a=(OC=(Y=(G=(A=(L=(C=(z=(B=(UC=(r=(J=(w=(x=(m=(h=(tA=(g=(u=(E=(Z=(F=P[4](14,K[21](35,(LB=[(e=[1,3E3,0],18),44,0],this),13)),F.next()).value,F.next().value),F).next().value,F.next()).value,O=F.next().value,F.next().value),F.next()).value,F.next()).value,F.next().value),F).next().value,F.next().value),F.next().value),F.next()).value,mQ=I[21](7),I)[21](7),I[21](23)),[this.Fe,U[LB[2]](75,r,e[2]),P[37](83,r,this.H,this.H),y[37](23,5,this.I,this.H),yg(Z,this.W,this.H),yg(E,this.O, +this.H),l[LB[1]](17,this.u,W[LB[2]](17,this.u),e[LB[2]]),l[LB[1]](25,this.B,W[LB[2]](23,this.B),e[LB[2]]),y[36](1,UC),T[30](50,mQ,W[LB[2]](3,this.Y),W[LB[2]](19,UC)),U[24](24,u,W[LB[2]](LB[0],Z),W[LB[2]](7,this.Y)),P[12](26,e[1],mQ,W[LB[2]](5,u)),l[LB[1]](17,this.G,W[LB[2]](23,this.G),e[LB[2]]),U[24](56,O,W[LB[2]](16,u),W[LB[2]](17,this.S)),H[45](11,O,W[LB[2]](16,O),W[LB[2]](23,this.G)),l[LB[1]](28,tA,W[LB[2]](LB[0],this.S),W[LB[2]](5,O)),U[24](24,h,W[LB[2]](3,u),W[LB[2]](22,tA)),U[24](41,r,W[LB[2]](21, +u),W[LB[2]](21,this.S)),S[48](33,h,W[LB[2]](16,h),W[LB[2]](21,r)),l[LB[1]](57,this.R,W[LB[2]](LB[0],this.R),W[LB[2]](16,h)),U[27](64,tA,this.S),v[31](86,this.T,J),ii(r,J,this.l,u),S[48](9,m,W[LB[2]](17,r),YM),ii(m,J,this.Z,m),P[37](84,m,this.J,r),l[LB[1]](52,r,W[LB[2]](7,r),e[LB[2]]),I[26](34,this.J,m,W[LB[2]](22,r)),y[36](1,UC),T[30](52,B,W[LB[2]](3,this.C),W[LB[2]](6,UC)),P[12](31,e[LB[2]],B,W[LB[2]](2,this.B)),U[24](57,g,W[LB[2]](6,Z),W[LB[2]](3,this.C)),P[12](27,W[LB[2]](16,g),mQ,e[LB[2]]),P[12](24, +e[1],mQ,W[LB[2]](7,g)),ii(r,J,this.l,g),S[48](9,x,W[LB[2]](3,r),YM),ii(x,J,this.Z,x),P[37](86,x,this.K,r),l[LB[1]](48,r,W[LB[2]](16,r),e[LB[2]]),I[26](4,this.K,x,W[LB[2]](3,r)),T[30](54,mQ,e[LB[2]],e[LB[2]]),B,mQ,U[27](LB[0],Z,this.Y),ii(UC,this.F,this.hO,E,this.H),z,y[36](3,Z),y[36](5,E),y[36](6,O),y[36](6,u),y[36](6,g),y[36](5,r),y[36](5,tA),y[36](3,m),y[36](3,x),y[36](6,w),y[36](5,h),K[25](23)]),P)[4](15,K[21](34,this,10)),L.next().value),L).next().value,L.next()).value,L.next()).value,L.next().value), +L.next().value),L).next().value,L).next().value,L).next().value,L.next().value),I[21](7)),I[21](7)),I[21](71)),this).JO,U[LB[2]](91,k,e[2]),P[37](86,k,this.H,this.H),y[37](6,5,this.I,this.H),yg(A,this.W,this.H),yg(G,this.O,this.H),y[36](3,R),T[30](59,X,W[LB[2]](3,G),W[LB[2]](23,R)),ii(G,this.F,this.o6,G),y[36](5,R),T[30](57,X,W[LB[2]](3,G),W[LB[2]](23,R)),yg(Y,this.W,G),U[24](27,OC,W[LB[2]](LB[0],A),W[LB[2]](19,Y)),P[12](26,e[1],R6,W[LB[2]](16,OC)),v[31](89,this.T,c),ii(k,c,this.l,OC),S[48](65,hA, +W[LB[2]](21,k),YM),ii(hA,c,this.Z,hA),P[37](84,hA,this.X,k),l[LB[1]](LB[0],k,W[LB[2]](16,k),e[LB[2]]),I[26](4,this.X,hA,W[LB[2]](22,k)),X,y[36](6,R),T[30](49,R6,W[LB[2]](3,this.Y),W[LB[2]](1,R)),U[LB[2]](90,R,!0),P[12](29,W[LB[2]](6,this.B),R6,2),U[24](41,a,W[LB[2]](16,A),W[LB[2]](1,this.Y)),P[12](25,e[1],R6,W[LB[2]](22,a)),ii(k,c,this.l,a),S[48](33,Q,W[LB[2]](3,k),YM),ii(Q,c,this.Z,Q),P[37](83,Q,this.h,k),l[LB[1]](29,k,W[LB[2]](5,k),e[LB[2]]),I[26](2,this.h,Q,W[LB[2]](1,k)),R6,U[27](16,A,this.C), +P[12](29,W[LB[2]](2,this.B),n,e[LB[2]]),U[24](57,this.B,W[LB[2]](16,this.B),e[LB[2]]),n,y[36](3,G),y[36](1,A),y[36](5,Y),y[36](3,OC),y[36](3,a),y[36](2,c),y[36](5,k),y[36](3,R),y[36](1,hA),y[36](1,Q),K[25](55)],P[4](11,K[21](38,this,5))),t.next()).value,t).next().value,M=t.next().value,t.next().value),t.next()).value,[this.E5,y[15](45,452,M),v[31](73,M,M),y[15](72,181,D),P[37](80,D,M,D),y[15](LB[1],541,KB),y[15](71,793,Df),y[15](72,1578,d),ii(M,D,KB,Df,this.iI),ii(M,D,KB,d,this.rq),y[36](5,D),y[36](3, +M),y[36](6,KB),y[36](6,Df),y[36](5,d),K[25](59)]),[C,N,q]},aS.prototype.i=function(N,C,e,L,h,Q,m,O,t,D,q,u){return[(O=(q=(h=(N=(e=(t=(L=(m=(u=[7,12,"K"],Q=P[4](15,K[21](35,this,8)),Q).next().value,Q).next().value,Q.next().value),Q).next().value,D=Q.next().value,Q.next().value),Q.next().value),Q).next().value,I[21](u[0])),C=I[21](71),U)[27](20,this.S,t),U[27](84,this.J,e),U[27](85,this[u[2]],D),U[27](21,this.X,N),U[27](85,this.h,h),P[u[1]](26,0,O,W[0](u[0],this.G)),y[36](6,t),y[36](3,e),y[36](6,D), +y[36](3,N),y[36](3,h),O,y[36](6,L),P[u[1]](25,W[0](16,this.G),C,2),H[45](u[1],L,W[0](2,this.R),W[0](u[0],this.G)),v[31](86,this.T,q),ii(L,q,this.Xe,L),C,Zz(m,this.o,this.u,t,L,e,D,N,h),this.stringify(m,m),H[0](40,m,this)]},aS.prototype.P=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w){(this.H=((((this.rq=(this[this.F=(this.hO=(this.o6=(this.Xe=(this.Ku=((this.l=((this.o=(this.G=(this.S=((r=(O=(X=(A=(h=(R=(t=(c=(C=(N=(E=(B=(J=(Q=(z=(u=(e=(L=(F=(w=["W",6,"u"],n=P[4](15,S[31](w[1], +28,this)),n.next()).value,n).next().value,n.next()).value,d=n.next().value,m=n.next().value,n).next().value,n.next().value),Z=n.next().value,G=n.next().value,n.next()).value,n.next().value),n).next().value,D=n.next().value,q=n.next().value,n.next().value),n).next().value,n.next()).value,n.next().value),n.next().value),n.next().value),n.next().value),n.next().value),Y=n.next().value,n.next().value),n).next().value,n.next().value),k=n.next().value,x=n.next().value,this).Z=r,u),this.T=X,this.B=B,this[w[0]]= +C,m),t),this).h=J,this.C=L,x),this).lI=k,R),O),this.Y=F,h),A),this.O=c,e),w[2]]=d,this.R=z,q),this).S_=Y,this).K=G,this).I=N,this.X=Q,this.J=Z,E),this).iI=D},aS.prototype).V=function(N,C,e,L,h,Q,m,O,t,D,q,u,B){return[(Q=(L=(u=(e=(m=(t=(N=(O=(C=P[4](12,K[21](39,(q=[0,803,(B=[1,"o","H"],!1)],this),9)),C.next()).value,C.next().value),C.next().value),C.next().value),h=C.next().value,D=C.next().value,C.next().value),C.next().value),C.next().value),I)[21](23),y[15](44,78,this[B[1]])),y[15](45,191,this.T), +y[15](72,364,this.Xe),y[15](73,346,this.Ku),y[15](45,1284,e),y[36](B[0],this.Y),v[31](89,this.Ku,this.F),sE(this.F,this.F),y[36](B[0],this.C),U[0](91,this.u,q[0]),U[0](92,this.G,q[0]),U[0](95,this.S,q[0]),U[0](75,this.R,q[0]),U[0](94,u,25),Zz(this.J,this[B[1]],u),U[0](93,L,q[0]),ii(this.J,this.J,e,L),Zz(this.K,this[B[1]],u),ii(this.K,this.K,e,L),Zz(this.X,this[B[1]],u),ii(this.X,this.X,e,L),Zz(this.h,this[B[1]],u),ii(this.h,this.h,e,L),U[0](93,this.B,q[0]),y[36](2,e),y[15](43,130,L),K[17](68,q[0], +q[2],Q,this.I,L),y[15](76,836,L),K[16](19,L,Q,this.I,this.W),y[15](43,328,L),K[16](14,L,Q,this.I,this.O),y[15](70,313,this.S_),y[15](75,690,this.Z),y[15](75,306,this.lI),y[15](72,583,this.l),y[15](70,q[B[0]],this.hO),y[15](44,105,this.o6),S[32](7,this[B[2]],this.iI,this.Fe),y[15](70,181,t),y[15](76,617,m),y[15](77,793,h),y[15](74,452,O),v[31](89,O,O),P[37](87,t,O,t),ii(O,t,m,h,this.iI),S[32](17,this[B[2]],this.rq,this.JO),y[15](76,1578,D),ii(O,t,m,D,this.rq),new FD(this.E5,this[B[2]]),Q,y[36](B[0], +L),y[36](B[0],O),y[36](6,N),y[36](B[0],t),y[36](5,m),y[36](B[0],h),y[36](B[0],D)]},T[40](56,xw,YK),xw.prototype).A=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X){return u=(c=(O=(R=(L=(e=(F=(h=(C=P[4](15,(m=I[n=I[q=[16,(X=[21,"J",81],0),5],X[0]](87),X[0]](7),K[X[0]](35,this,q[0]))),C.next()).value,t=C.next().value,C.next().value),C.next().value),Q=C.next().value,B=C.next().value,G=C.next().value,D=C.next().value,A=C.next().value,C.next().value),C.next()).value,C.next()).value,Z=C.next().value, +N=C.next().value,C).next().value,C.next().value),[this.W,l[44](48,this.K,W[0](5,this.K),1),v[31](71,this.Y,t),P[37](85,this.T,t,F),y[36](5,t),P[37](X[2],this.R,F,e),y[36](3,F),U[0](94,B,q[1]),U[0](89,G,5E3),ii(e,e,this.I,B,G),y[36](2,B),y[36](3,G),P[22](62,D,W[0](5,this.u),KW()),ii(Q,e,this.Z,D),y[36](2,D),y[36](2,e),U[0](94,R,q[1]),T[30](52,m,W[0](22,Q),W[0](6,e)),P[37](87,this.S,Q,R),m,T[30](48,n,W[0](3,R),W[0](19,this[X[1]])),U[27](66,R,this[X[1]]),K[11](4,h),Zz(A,this.o,h,R),ii(u,this.G,this.l, +A),P[37](X[2],this.S,this.G,O),P[12](28,W[0](22,O),n,11),U[0](75,Z,q[2]),U[0](91,N,3),ii(u,this.G,this.F,Z,N),n,S[48](33,c,500,W[0](X[0],this.K)),Zz(this.B,this.h,this.X,c),y[36](3,h),y[36](5,t),y[36](3,F),y[36](3,e),y[36](6,Q),y[36](5,B),y[36](2,G),y[36](5,D),y[36](3,A),y[36](3,L),y[36](5,R),y[36](1,O),y[36](1,c),y[36](1,u),K[25](X[0]),this.C,y[15](71,696,L),Zz(t,L,this.B),y[36](6,L),y[36](3,this.B),K[25](39)]},xw.prototype.V=function(N,C,e){return N=(C=[239,(e=["C",0,15],500),555],P[4](e[2],K[21](32, +this,1)).next().value),[y[e[2]](76,78,this.o),y[e[2]](44,452,this.Y),y[e[2]](75,313,this.S),y[e[2]](73,C[e[1]],this.Z),y[e[2]](72,181,this.T),y[e[2]](70,112,this.R),y[e[2]](72,836,this.O),y[e[2]](44,306,this.l),y[e[2]](75,195,this.F),y[e[2]](77,134,this.h),y[e[2]](75,28,this.I),y[e[2]](44,C[2],this.u),U[e[1]](92,this.K,e[1]),U[e[1]](89,this.J,-1),Zz(this.G,this.o),S[32](e[2],this.H,this.X,this.W),U[e[1]](95,N,C[1]),Zz(this.B,this.h,this.X,N),new FD(this[e[0]],N),y[36](5,N)]},xw.prototype.i=function(N, +C,e,L,h){return N=(C=(L=P[4](15,K[21]((h=["B",0,52],32),this,3)),L.next()).value,e=L.next().value,L.next().value),[Zz(C,this.o,this.G),this.stringify(C,C),Zz(this.G,this.o),U[h[1]](88,this.J,-1),U[h[1]](91,this.K,h[1]),y[15](73,696,e),Zz(N,e,this[h[0]]),U[h[1]](74,N,500),Zz(this[h[0]],this.h,this.X,N),y[36](6,e),y[36](1,N),H[h[1]](h[2],C,this)]},xw.prototype.P=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z){this.K=((this.B=(this.u=(((this.T=((this[this.o=(this.R=(c=(G=(R=(F=(O=(N=(L=(C=(t=(Q=(e= +(u=(q=(h=(m=(D=(n=P[4](12,(Z=["G","h","J"],S[31](2,18,this))),n.next().value),n.next()).value,n.next().value),n.next().value),A=n.next().value,n.next().value),n.next()).value,n.next().value),B=n.next().value,n.next().value),n.next().value),n).next().value,n.next().value),n.next()).value,n.next().value),n.next()).value,n.next().value),n.next().value),F),this.F=A,t),Z[1]]=e,this[Z[0]]=D,this).S=L,this.l=q,this.Y=C,O),this).O=h,this)[Z[2]]=R,c),m),this).X=Q,this.Z=N,this.I=u,G),this.H=B},T[40](32,Em, +YK),Em.prototype).i=function(N,C,e,L,h,Q,m){return[(C=(Q=(h=(N=(L=K[21](39,this,(m=[15,88,441],4)),P)[4](m[0],L),N).next().value,e=N.next().value,N.next().value),N.next().value),y[m[0]](70,122,Q)),y[m[0]](76,m[2],C),v[31](m[1],Q,h),P[37](81,C,h,e),y[36](3,Q),y[36](2,C),H[0](40,e,this)]},T)[40](56,Yw,YK),Yw).prototype.i=function(N,C,e,L,h,Q,m,O,t,D,q){return e=(L=(m=(C=(t=(D=(h=(Q=K[21](35,this,(q=[31,(O=[5,"",null],37),10],O[0])),N=P[4](14,Q),N.next().value),N.next().value),N.next().value),N).next().value, +N.next().value),H[18](11,O[2],new IB,m)),H[18](q[2],O[2],new IB,t)),[y[15](71,122,h),v[q[0]](75,h,C),y[36](1,h),y[15](75,855,D),P[q[1]](87,D,C,m),y[36](1,D),y[36](2,C),U[0](92,t,O[1]),T[34](72,m,e,L),y[36](1,t),H[0](20,m,this)]},T)[40](60,Md,p),sI)],HU=((Md.prototype.D=f[38](27,WU),T)[40](35,t3,p),[0,QQ,YF,WU]),kM=(T[40](35,Kk,(t3.prototype.D=f[38](27,HU),p)),Kk.prototype.D=f[38](26,[0,i_,-1,OI,[!0,i_,HU]]),function(N){return function(C,e,L){if(e=GH((L=[34,"object",37],C)),!Array.isArray(e))throw Error("Expected jspb data to be an array, got "+ +f[L[2]](67,L[1],e)+": "+e);return y[15](16,L[0],e),new N(e)}}(Kk)),rn,Lq=((T[40](6,eG,YK),eG).prototype.i=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E){return(u=(Q=(c=(R=(n=(B=(m=(L=(N=(k=(O=(h=(Z=(C=(Y=(e=(t=(E=[5,47,15],[633,(F=[],4),2]),A=P[4](E[2],K[21](34,this,12)),A.next()).value,A.next().value),A).next().value,A.next()).value,A.next().value),q=A.next().value,A.next().value),X=A.next().value,A).next().value,A.next().value),A).next().value,A).next().value,rn)||(rn=kM(LK())),T)[8](32, +1,B),D=T[8](32,t[2],B),S[34](6,t[2],!1,B).get(n)),S[34](2,t[2],!1,B).get(D)),R)?y[48](42,t[2],R,y[11](11),Md).length:0,G=c?y[48](10,t[2],c,y[11](50),Md).length:0,t)[1],R)&&y[48](2,t[2],R,y[11](51),Md).forEach(function(J,r){F.push((r=[12,2,4],W[38](r[2],W[r[2]](r[0],J,1),T[8](17,r[1],J),e,O,X,k,Z,h,q,N,L,m,C,u++)))}),c&&y[48](34,t[2],c,y[11](26),Md).forEach(function(J,r){F.push(W[r=[2,8,4],38](5,W[r[2]](14,J,1),T[r[1]](1,r[0],J),e,O,X,k,Z,h,q,N,L,m,C,u++))}),[y[E[2]](43,78,Y),y[E[2]](43,t[0],h),y[E[2]](72, +1518,q),y[E[2]](71,2050,O),y[E[2]](71,1409,Z),U[0](93,m,t[1]+Q+G),Zz(C,Y,m),y[36](6,Y),U[0](89,m,0),I[26](4,C,m,n),U[0](93,m,1),I[26](34,C,m,Q),U[0](91,m,t[2]),I[26](36,C,m,D),U[0](92,m,3),I[26](36,C,m,G),v[31](90,Z,Z)].concat(T[E[0]](57,F),[y[36](E[0],O),y[36](1,h),y[36](6,q),y[36](E[0],Z),y[E[1]](45,W[0](E[0],C),C),H[0](52,C,this)])},$b(),Y_()),QG=yS(),O_=p0(),tM=Sl(),qI=XJ(),uH=dO(),pg=Iv(),ub=((T[40](6,X3,YK),X3.prototype.A=function(N,C,e,L,h,Q){return C=(L=(N=(e=(Q=[27,(h=[],12),"call"],h.concat), +P[4](Q[1],K[21](37,this,1)).next()).value,I)[21](84),[this.K,U[0](94,N,0),P[37](87,N,this.H,N),T[30](52,L,W[0](3,N),W[0](5,2048)),U[Q[0]](87,N,this.B),L,y[36](3,N),K[25](42)]),e[Q[2]](h,T[5](73,C))},X3.prototype.P=function(N,C,e,L,h,Q){this.H=(this[((this.B=(L=(e=(h=(N=P[Q=[15,4,"o"],Q[1]](Q[0],S[31](7,Q[1],this)),N).next().value,N.next().value),N).next().value,C=N.next().value,L),this).G=C,Q)[2]]=h,e)},X3.prototype.i=function(N,C,e,L,h){return L=(N=(e=(C=P[4](14,(h=[3,22,6],K[21](39,this,h[0]))), +C.next().value),C.next().value),C.next()).value,[K[11](36,N),U[24](58,N,W[0](17,N),W[0](18,this.G)),U[0](92,L,h[0]),I[26](36,this.B,L,W[0](h[1],N)),this.stringify(e,this.B),H[0](12,e,this),y[36](h[0],e),y[36](h[2],N),y[36](h[2],L)]},X3.prototype).V=function(N,C,e,L,h,Q,m,O,t,D,q,u){return[(e=(D=(q=(h=(t=(Q=(m=P[4](14,K[21](32,(u=[(L=[1,2035,33],2),15,0],this),7)),m.next().value),m.next()).value,C=m.next().value,O=m.next().value,m.next().value),m.next().value),m.next()).value,I[21](87)),N=I[21](71), +y)[u[1]](72,78,h),U[u[2]](74,q,ZJ()),U[u[2]](74,D,-1),U[u[2]](90,O,u[0]),Zz(this.B,h,q,D,D,D,D,O),K[11](39,this.G),S[32](6,this.H,this.o,this.K),y[u[1]](75,L[1],Q),v[31](73,Q,C),T[30](54,e,W[u[2]](7,C),W[u[2]](u[0],2048)),y[u[1]](45,201,t),ii(O,C,t,this.o),S[32](68,new b4,L[u[0]]),T[30](56,N,L[u[2]],L[u[2]]),e,U[u[2]](88,q,pg),U[u[2]](93,O,u[2]),I[26](36,this.B,O,W[u[2]](16,q)),N,y[36](3,Q),y[36](3,t),y[36](6,C),y[36](6,O),y[36](1,h),y[36](u[0],q),y[36](6,D)]},JL)(),BJ=f7(),TW=N_(),jq=iy(),Iz=Lz(), +NL=zg(),uj=LW(),Bf=WO(),Uk=ep(),Gz=W$(),DD=(Nu(),hY()),h5=lP(),lo=$0(),Qp=Zv(),Kx=K3(),Wk=Pb(),Eb=De(),Fa=Kj(),b9=C7(),Zb=XE(),MV=Tx(),NQ=m$(),Ju=X6(),$t=Hu(),gi=Z1(),AM=pL(),Re=Uj(),Rz=Dz(),l1=g1(),Ns=C8(),cf=ly(),HL=(hU(),new Map),WL=new Set,Yd,QW=yG(),Z_=cO(),Ef=(((T[40](35,oB,TN),oB.prototype.send=function(N,C,e,L,h,Q){return C=(e=e===void 0?15E3:e,C===(L=this,void 0)?null:C),P[44](77,function(m,O){return m.B==(O=[36,"promise","i"],1)?(Q=U[41](41),h=new qN,L.B.set(Q,h),W[O[0]](80,e,function(){h.reject(Error("reCAPTCHA Timeout ("+ +N+")")),L.B["delete"](Q)}),m[O[2]](I[13](5,2,C,N,Q,L),2)):m.return(h[O[1]])})},oB.prototype).U=function(){(TN.prototype.U.call(this),this.i).close()},T)[40](28,pB,p),[0,i_,-1]),zT=((((T[40](35,(pB.prototype.D=f[38](67,Ef),r8),p),r8).prototype.D=f[38](75,[0,YF,Ef]),T[40](26,p1,p),p1.prototype.Fa=function(){return W[30](1,1,this,Dw)},p1.yl=G9(),p1).prototype.D=f[38](67,["setoken",Dw,S9,sI,S9]),T)[40](3,d6,p),[0,sI,-1]),dn=[(T[40](35,dQ,(d6.prototype.D=f[38](75,zT),p)),0),YF,zT,Ty,sI],wn=[0,zy,(T[40]((dQ.prototype.D= +f[38](27,dn),26),c1,p),EI),-1,kF],VN=[0,wn,-1,1,wn,(T[40](35,Aq,(c1.prototype.D=f[38](67,wn),p)),2),wn,-22],Cx=((((T[40](38,Qj,(Aq.prototype.D=f[38](67,VN),p)),Qj.prototype.qd=function(){return U[13](15,this,SW,70)},P)[31](12,13,yN),Qj).prototype.S2=function(){return U[13](29,this,SW,28)},Qj.prototype).D=f[38](67,[0,4,sI,i_,10,X_,wv,sI,8,wM,-15,1,wM,-3,1,wM,-14,i_,wM,-6,dn,VN,wM,-1,l_,wM,-1,kF]),N_()),q3=X6(),A5=Hu(),ij=iy(),vf=Lz(),RI=zg(),FF=LW(),Tz=WO(),t5=e2(),Ok=Ck(),lj=Ps(),yp=Sh(),mG=ok(), +xM=S0(),ax=tH(),gn=Uv(),bE=Ke(),pu=rO(),JE=FT(),$K=Date.now(),N3=Date.now(),LS=Ox(); +(((((((((((((((((((((T[40](58,C$,TN),C$.prototype).A=function(N,C,e,L){if(L=this.Fd[this.G][C])return L.call(this,N==null?void 0:N,e)},C$.prototype).init=function(N){return N=this,P[44](77,function(C){return(N.K=(0,B8.tj)(N.qp.bind(N),1),C).return(N.K)})},C$.prototype).V=function(N,C,e,L,h,Q,m){if(this[m=(L=[16,(Q=this,2),null],["i",2,"now"]),m[0]][m[0]]&&this.G==FF&&this[m[0]].K)return Promise.resolve(L[m[1]]);if(this[m[0]].G)return C=U[26](25,L[m[1]],12,L[0],13,N,this),N.AE||(e=Date[m[2]](),C.then(function(){return T[38](65, +8,!1,e,1,Q)},function(O,t){return T[38](64,(t=[!1,8,"i"],t)[1],t[0],e,O instanceof hh?4:2,Q,O instanceof hh?O[t[2]].B:void 0)})),N.T2?Promise.race([C,new Promise(function(O,t){setTimeout(function(){return t(M_())},N.T2)})]):C;if(this.o=y[16](12),N&&this[m[0]][m[0]]&&(K[21](4,41,L[1],1,L[0],N,this),!this[m[0]].K))return T[24](1,L[1],this,N.lQ||void 0,N.XI),this.o.promise;return(T[24](19,L[1],this,void 0,(h=N==L[m[1]]?void 0:N.XI)!=L[m[1]]?h:!1),this).o.promise},C$.prototype.z$=function(N,C,e,L){this[this.F= +(e=(C=new (this.T=N[(L=[2,"I","o"],L)[2]],Du),K)[23](10,1,N.B,C),K)[23](33,L[0],N.i,e),L[1]]=N.G},C$.prototype.qp=function(N,C,e,L){return N=this,P[44](45,function(h,Q,m){m=[2,29,(Q=[80,1,!1],9)];switch(h.B){case Q[1]:if(!(C=N.i.V,C))return N.G=Tz,W[3](40,Q[0],S[28](56).parent,QW).send(Gz),h.return();if((((e=((L=B0.M(),K)[1](14,y[17](m[0],Q[1],K[45](22,m[2],L.get()))),N.uI=W[3](4,Q[0],S[28](16).parent,C,new Map([[[uj,h5,Qp,Bf,Uk,cf],N.A],[Wk,N.Np],[Eb,N.ZR],[b9,N.lz],[Ju,N.z$],[Re,N.hj]]),N),new Bd(N.i.F.map(function(O){return S[31](28, +O)}),L.get().G2(),N.B.G.value)),N).uI.send(Rz,e),N.i).G||N.P.then(function(O){return O.send(Rz,e)}),y[19](34,"e",N),P[23](12,null,0,N),T[15](3,Q[m[0]],95,L))&&v[18](4,Q[1],3,m[0],N),T[15](1,Q[m[0]],73,L)&&K[36](m[2],null,m[0],Q[1],N),y[25](23,15,L.get())&&I[49](30,m[0],Q[1],4,3,N),!y[m[1]](3,Q[m[0]],L,Az)){h.js(m[0]);break}return h.i(v[24](33,5,0),m[0]);case m[0]:return h.K(4),h.i(N.j(),6);case 6:return h.i(W[3](m[0],105,15,null,Q[m[0]],N),7);case 7:h.V(5);break;case 4:h.o();case 5:if(((W[27](8,"-", +11,Q[1],0,C),W)[36](72,N.i.u*1E3,function(){return N.A(null,DD)}),N).i.G){h.js(0);break}return h.i(I[40](m[1],m[0],N),m[2]);case m[2]:N.i.K&&N.A(null,t5),h.P()}})},C$.prototype.u=function(N,C){(this[(C=["G","o","wJ"],this.B)[C[2]](N.errorCode),C[0]]=Cx,this.uI.send(Gz,N),this[C[1]])&&this[C[1]].reject(N.errorCode)},C$.prototype.E5=function(N,C,e,L,h,Q,m,O,t,D){if(L=(Q=(O=VV((m=(t=this,D=[(C=[!1,4,18],3),"V",45],new Promise(function(q,u,B,G){W[B=(G=(u=0,[(t.hO=function(c,A,n,R,F,Z,X,Y,k){if(F=(R=c[0], +[1,(k=[2,9,6],null),1024]),R>0){if(c[F[0]]){if((X=(Z=(Y=new c1,H[38](k[0],Y,P[44](25,F[1],c[k[0]]),k[0])),H)[38](k[2],Z,P[44](24,F[1],c[3]),3),T)[15](3,!1,105,B0.M()))A=new Uint8Array(Object.values(c[F[0]])),H[38](3,X,y[39](k[1],F[1],A,!1),4);else f[k[2]](89,F[k[0]],X,F[0],c[F[0]],U[11].bind(null,5));n=X}else n=F[1];B[R-F[0]]=(u++,n),u>=t.s5&&q(B)}else q(B)},74),39,18]),[]),36](G[0],v[G[1]](G[2],19,B0.M().get()),function(){q(B)})})),T[D[2]](34)),I[13](78)).then(function(q,u){return P[44](73,function(B, +G){if((G=["J2","uI","QY"],B.B)==1)return B.i(t[G[1]].send(TW,new dD),2);return u=B.G,q[G[0]](u[G[2]]),B.return(u)})}),I[20](25,C[0],null,[O,P[36](25,C[2],1,C[1],C[0]),Lg(T[D[2]](34),void 0,void 0,O,this.i[D[1]]),hu(),QN(),mx(),Of(),m]).then(function(q,u,B,G,c,A,n,R,F,Z,X,Y,k){return(A=(Z=(B=(X=(F=(Y=(R=P[4](11,q),R.next().value),R.next().value),c=R.next().value,R.next()).value,R).next().value,R).next().value,G=R.next().value,R).next().value,P)[44](45,function(E,J,r,z,d,x,w,a,g,M,hA,mQ,Df,UC,tA){return n= +(g=new (d=(r=(mQ=(Df=(UC=(w=(a=(hA=((k=(u=((x=[77,null,73],tA=[0,(t.Ku=Y.yM,"J2"),1],t.rq=new lH(Y.DX),t).j_=new r8(Y.Az),l[46](4,8,"0",H[13](12,B0.M().get()))),f[25](72,tA[0])*2),t.iz)&&(k-=tA[2]),c[tA[1]](Y.QY),X[tA[1]](Y.QY),B[tA[1]](Y.QY),Z[tA[1]](Y.QY),G[tA[1]](Y.QY),J=new Qj(Y.QY),P[tA[0]](14,J,u,5)),K)[23](26,6,k,hA),y[44](8,18,a,F)),T)[45](98),P)[tA[0]](79,w,UC,19),UR(U[4](18,1872),tA[0])),M=K[23](59,65,mQ,Df),z=UR(t.DR,x[tA[2]]),f[5](8,M,dQ,x[2],z)),f[5](8,r,SW,47,N)),Aq)(A),f)[5](52,d,Aq, +74,g),t.I&&H[38](4,n,P[44](28,x[tA[2]],t.I),x[tA[0]]),E.return(n.G2())})})),Promise.resolve("")),(e=this.i.o.i)==null?0:T[22](2,D[0],e,rY))L=Q.then(function(){return t.i.o.execute(function(){}).then(function(q){return q},function(){return null})});return(h=[Q.then(function(q){return""+y[14](6,q)}),L,Q.then(function(q,u){return(u=[9,16,4],Promise).resolve(T[u[1]](29,u[2],yJ,f[30](2,255,256,$K,W[1](u[0],6,q))))})],Promise).all(h).then(function(q,u){return P[44](13,function(B,G){if((G=["B",1,17],B[G[0]])== +G[1])return B.i(S[G[2]](20,null,5,G[2],t),2);return(u=B.G,q.push(u),B).return(q)})})},C$.prototype.Np=function(N,C,e){return P[44]((C=this,45),function(L,h){if(h=["B","i",2],L[h[0]]==1){if(!C[h[1]].P)throw Error(ax+" client for challengeAccount.");return L[h[1]](C[h[1]][h[0]].send(new vz(N)),h[2])}return e=L.G,L.return(S[31](28,e))})},C$).prototype.mC=function(){this.P.then(function(N){return N.send(cf)})},C$.prototype.lI=function(N){this.uI.send(Iz,N)},C$.prototype.VM=function(N,C,e,L){return P[44](73, +(L=this,function(h,Q,m){if((m=["V",(Q=[1,4,2],1),28],h.B)==Q[0])return h.K(Q[2]),e=S[m[2]](40).name.replace(hd,HX),C=S[m[2]](17).parent.frames[e],C.document&&K[23](16,Q[2],L,N),h[m[0]](0);if(h.B!=Q[m[1]])return h.o(),L.B.QB(),L.P=T[16](20,80,L),L.G=Cx,h.i(I[40](m[2],Q[2],L),Q[m[1]]);L.uI.send(Gz),h.P()}))},C$.prototype).E_=function(N,C){(this[(C=["uI",70,"P"],this).G=RI,C[0]].send(Uk),this)[C[2]].then(function(e){return e.send(Uk,new Am(N))},T[0].bind(null,C[1]))},C$.prototype.lz=function(N){try{this.hO(N.i)}catch(C){}}, +C$).prototype.Vk=function(){return this.O?this.O.then(function(N){return new FY(N)}):Promise.resolve(null)},C$.prototype).C=function(N,C){(C=[0,null,"P"],N.resize)?this[C[2]].then(function(e){return e.send(uj,new Cv({visible:N.visible}))},T[C[0]].bind(C[1],71)):this.G==A5?this.G=vf:N.n0&&N.n0.width<=C[0]&&N.n0.height<=C[0]?(this.G=q3,this[C[2]].then(function(e){return e.send(uj,new Cv({visible:N.visible}))},T[C[0]].bind(C[1],72))):(this.G=vf,this.uI.send(Iz,N))},C$.prototype).Fe=function(N,C){return(0,B8.tj)(function(e, +L,h,Q){if((e=((C[(Q=[(L=[1,"",!0],"B"),48,"iI"],Q)[0]].Zn(),h=!1,C).G=FF,B0.M().get()),C)[Q[2]]!==null)return C[Q[2]].then(function(m){return P[44](41,function(O,t,D,q,u){return((q=(u=["DS",47,"qd"],[2,null,1]),m.k7&&!m.k7.kx()&&(m.k7[u[2]]()&&(N.i=m.k7[u[2]]()),h=T[42](52,4,m.k7),S[u[1]](8,q[2],m.k7[u[0]]())),m.VI)&&(D=new p1,t=P[36](48,q[1],3,Dw,N.response,D,rY),N.response=K[14](6,4,H[1](36,q[0],t,m.VI))),O).return(I[13](49,!0,1E3,N,h,C))})});return(T[42](52,16,e)&&C.i.i&&(U[10](64,U[25](29,zY), +L[1],L[0]),N[Q[0]]&&(h=N[Q[0]],N[Q[0]]=null)),I)[13](Q[1],L[2],1E3,N,h,C)},(C=this,13))},C$.prototype.SW=function(){this.JO=!0},C$.prototype.R=function(N,C){(C=[null,"G",73],this[C[1]])===FF?this.B.dJ():(N.visible?(this[C[1]]=q3,N.n0&&N.n0.width==0&&N.n0.height==0||this.B.wO()):((0,B8.iU)(2),this[C[1]]=vf,this.B.Nm(),this.o&&this.o.resolve(new aE("",0,JD,!1))),this.P.then(function(e){return e.send(uj,N)},T[0].bind(C[0],C[2])))},C$.prototype).bI=function(N,C){(C=[33,1,28],N=this,S[C[2]](C[1]).navigator.onLine)? +this.uI.send(DD):P[29](40,this,S[C[2]](C[0]),hR,function(){return N.uI.send(DD)})},C$).prototype.hj=function(N,C,e,L){return P[44](73,(C=this,function(h,Q){return h.B==(Q=[2,"xg","Ls"],1)?(N=(0,B8.oB)().slice().map(function(m){return S[31](44,m)}),L=(0,B8[Q[1]])().map(function(m){return S[31](20,m)}),(0,B8[Q[2]])(),e=C.B.G.value,C.i.G?h.js(Q[0]):h.i(C.P.then(function(m){return m.send(Re).then(function(O,t,D,q){L=(N=(t=(0,B8[q=["concat","KR","Mo"],D=O.jx,q[1]])(O[q[2]],O.E8),N[q[0]](t)),L[q[0]](D))})}).catch(function(){}), +Q[0])):h.return(new Da(L,e,N))}))},C$.prototype).U=function(N){(this[this.o6.then((N=["U","Xe","terminate"],function(C){return C.dispose()}),function(){}),N[1]][N[2]](),TN.prototype[N[0]]).call(this)},C$).prototype.DR=function(N,C){return K[17](52,3,P[20]((N=(C=[32,1,"navigator"],S[28](C[0])[C[2]]).userAgentData,C[0]),2,K[49](10,2,C[1],new dQ,N.brands.map(function(e,L,h,Q){return L=(Q=["brand","version",15],h=new d6,P[0](12,h,e[Q[0]],1)),P[0](Q[2],L,e[Q[1]],2)})),N.mobile),N.platform)},C$).prototype.vK= +function(){K[23](4,2,(this.G=A5,this))},C$).prototype.mF=function(){this.G=Cx,this.o&&this.o.resolve(new aE("",0,JD,!1))},C$.prototype).jW=function(N,C,e,L){return P[e=this,44](77,function(h,Q,m){m=["o",1,(Q=[3,4,1],2)];switch(h.B){case Q[m[2]]:return C=3E4,h.K(m[2]),h.i(e.o6,Q[m[1]]);case Q[m[1]]:L=h.G,h.V(Q[0]);break;case m[2]:return h[m[0]](),h.return(new Yv(0,[],void 0,7,0));case Q[0]:return h.return(L.send(Ns,N,C))}})},C$).prototype.j=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R){return P[R= +(N=N===void 0?{id:null,timeout:null,K0:null,r$:null}:N,this),44](73,function(F,Z,X){X=[(Z=[10,36,8],22),0,2];switch(F.B){case 1:return F.i(W[7](8,1,"0"),X[2]);case X[2]:return A=F.G,e=c=!1,Q=B0.M(),t=!T[15](7,!1,Z[1],Q),q=[],t&&(q=[xM,gn,ax,bE]),F.i(R.uI.send(lo,new Kw(y[17](1,1,K[45](19,9,Q.get())),v[34](19,X[1],Z[X[1]],l[X[1]](8,1,"")),q,R.i.T,R.PK)),3);case 3:if((L=F.G,N.id)&&(!A||S[41](32,7,void 0,A)!=N.id))return F.return();return(G=new ((((A||(A=new hQ,c=!0),N.id==null)&&(N.id=T[45](67),P[X[1]](15, +A,N.id,7),N.r$!==void 0&&N.r$!==null&&K[23](62,11,N.r$,A),v[12](68,4,A)!=1&&(P[1](73,5,A,(v[12](70,5,A)||X[1])+1),e=!0),f[24](96,4,A,X[1])),H[35](4,1,A,(v[12](70,1,A)||X[1])+1),H[5](15,X[2],A,TH((v[12](70,X[2],A)||X[1])+(N.timeout||X[1]))),f)[24](83,4,A,(v[12](68,4,A)||X[1])+1),F).K(4),SW)(L.Bc),F).i(U[37](12,T[X[0]](X[2],1,G),v[12](65,X[2],G)),6);case 6:return u=F.G,u=u.replace(/"/g,""),W[41](5,4,A,6).includes(u)||I[X[0]](21,X[2],A,l[X[0]].bind(null,14),K[27].bind(null,3),6,u),h=new SW(L.XJ),F.i(U[37](10, +T[X[0]](1,1,h),v[12](65,X[2],h)),7);case 7:if(!(l[11](17,Z[X[2]],(D=F.G,A),+D+(v[12](68,Z[X[2]],A)||X[1])),t)||!L.yU){F.js(Z[X[2]]);break}return(O=new SW(L.yU),F).i(U[37](13,T[X[0]](1,1,O),v[12](70,X[2],O)),9);case 9:C=F.G,C=C.replace(/"/g,""),W[17](X[2],Z[X[1]],A,H[21](41,X[2],X[1],1,U[13](26,A,Rp,Z[X[1]]),pU(C),c,e));case Z[X[2]]:F.V(5);break;case 4:F.o();case 5:if(l[36](77,W[33](9,A,11))!=null)if(n=v[12](65,11,A),n===0)v[47](36,1,R),K[23](17,11,null,A),N.r$=null;else K[23](61,11,n-1,A);return F.i(P[6](57, +X[2],1,"0",A),Z[X[1]]);case Z[X[1]]:m=N.K0?N.K0:5E3,N.timeout=(1+Vn())*m*v[12](65,4,A),N.K0=null,B=I[13](77,N.timeout+500),W[36](64,N.timeout,function(){return R.A(N,v[12](19,0,function(){return mG},B))}),F.P()}})},C$).prototype.ZR=function(N,C,e){return(e=this,P)[44](41,function(L,h){if((h=["i","P","B"],L)[h[2]]==1){if(!e[h[0]][h[1]])throw Error(ax+" client for verifyAccount.");return L[h[0]](e[h[0]][h[2]].send(new Np(N)),2)}return L.return(S[31](36,(C=L.G,C)))})},C$).prototype.Hm=function(N){this[N= +["o","B","G"],this[N[1]].V7(),N[2]]=RI,this.uI.send(Iz,new Cv({visible:!1})),this[N[0]]&&this[N[0]].resolve(new aE("",0,pQ,!1))},C$.prototype).ZM=function(N,C){return P[C=this,44](13,function(e,L,h){if((L=[(h=[18,"o",24],1),3,2],e.B)==L[0]){if(!C.i.P)throw Error(ax+" client for challengeAccount.");return(C.P=T[16](h[0],80,C),e).i(I[40](30,L[2],C),L[2])}if(e.B!=L[1])return e.i(T[h[2]](21,L[2],C,N.lQ||void 0),L[1]);return(C[h[1]]=y[16](16),e).return(C[h[1]].promise)})},T)[40](28,jw,QY),jw.prototype.vm= +function(N){(this.B=P[4]((N=["v",6,"Yx"],N[1]),K[39].bind(null,1),{size:this.G,cS:this.X,FI:this.i,qW:!1,x7:!1,QM:!1,es:!1,errorMessage:this.i,errorCode:this.P}),this)[N[2]](this[N[0]]())},U)[47](29,function(N,C,e){new lN((C=new (e=[20,3,43],HV)(GH(N)),W[e[1]](e[0],80,S[28](49).parent,QW).send(Gz,new dT(l[e[2]](58,8,C,rY,FG),!0)),C))},"recaptcha.anchor.ErrorMain.init");function Mm(N,C,e,L,h,Q){return I[20].call(this,1,N,C,e,L,h,Q)}var ao=(T[0](85,Mm,VO),NW()),Mi=Dp(); +(((((((((((((V=Mm.prototype,V).V7=function(N){this[(Mm.L.V7[N=["call","i","uf"],N[0]](this),this)[N[1]][N[2]](),N[1]].v().focus()},V).wJ=function(N,C,e){N!=(this.i.Iz((e=(C=rj[N]||rj[0],[!1,7,"I6"]),e[0])),2)&&(this.i[e[2]](e[0]),this.Gt(!0,C),P[e[1]](5,this,C))},V.Vl=function(N,C){Mm.L[C=(N=this,[22,48,"Vl"]),C[2]].call(this),y[C[0]](60,y[C[0]](C[1],y[10](19,this),this.i,[TA,Zg],function(e){e.type==TA&&v[44](33,N,"e"),e.preventDefault()}),document,CR,function(e,L){(L=["i","target",0],e[L[1]]&&e[L[1]].tabIndex== +L[2])||this[L[0]].v().focus()},this)},V).QB=function(){this.i.Iz(!1)},V).Zn=function(N){this[(((N=["L","Gt","v"],this).i.Iz(!0),this.i)[N[2]]().focus(),Mm)[N[0]].Zn.call(this),N[1]](!1)},V).Au=function(N){(this[(N=["i","Au","call"],Mm).L[N[1]][N[2]](this),N[0]].uf(),this[N[0]].v()).focus()},V).Rh=function(){return Mm.L.Rh.call(this),this.i.NK()},V).Gt=function(N,C,e,L){((H[7](12,(L=["v",16,"rc-anchor-error"],this[L[0]]()),N,L[2]),P)[49](2,P[43](1,"rc-anchor-error-msg-container",this),N),N)&&(e=P[43](L[1], +"rc-anchor-error-msg",this),H[41](21,e),K[18](51,C,e))},V).wO=function(){this.i.Iz(!1)},V).Yx=function(N,C,e,L){((C=(e=(L=["rc-anchor-checkbox-label","P","Yx"],Mm.L[L[2]].call(this,N),P[43](7,L[0],this)),e.setAttribute(PN(),Mi),this.i),C).nu?(C.bz(),C[L[1]]=e,C.Vl()):C[L[1]]=e,this.i).render(P[43](10,"rc-anchor-checkbox-holder",this))},V).dJ=function(){this.i.v().focus()},V).W2=function(N){return T[N=[0,12,"recaptcha-checkbox"],N[1]](55,9,T[N[0]](44,N[2]))},V).Nm=function(){this.i.v().focus()},V).vm= +function(N){(this.B=(N=["v",null,4],P)[N[2]](2,K[39].bind(N[1],2),{size:this.X,cS:this.cS,FI:"Recaptcha requires verification",qW:this.qW(),x7:this.x7(),QM:this.QM(),es:this.es()}),this).Yx(this[N[0]]())};function bz(N,C,e,L,h,Q){return l[31].call(this,2,N,C,e,L,h,Q)} +T[0](92,bz,VO),bz.prototype.vm=function(N,C){this[(((N=P[4](1,P[14].bind(null,(C=["Yx","i","B"],1)),{FI:"Recaptcha requires verification",cS:this.cS,SQ:this[C[1]],OZ:!1,qW:this.qW(),x7:this.x7(),QM:this.QM(),es:this.es()}),this)[C[2]]=N,U)[32](1,this,function(e){P[47]((e=["smalltext",22,"rc-anchor-invisible-text"],e[1]),N.querySelector(".rc-anchor-invisible-text span")).width>160&&W[e[1]](3,T[0](e[1],e[2]),e[0])}),C)[0]](this.v())},bz.prototype.W2=function(N){return N=[0,12,54],T[N[1]](N[2],9,T[N[0]](63, +"rc-anchor-invisible"))};function H1(N){return U[9].call(this,26,N)} +var e6=(((T[0](84,H1,K2),H1.prototype.i=function(N){return U[1](16,!1,!0,N,this)},H1).prototype.U=function(N,C,e,L,h,Q){((e=(L=(C=(h=(N=(Q=[!1,"U",57],Zf[Wh()]||Zf[Hh()]),N).setTimeout,h[K[44](61,"__",this,Q[0])]||h),N.setTimeout=C,N.setInterval),L[K[44](Q[2],"__",this,Q[0])]||L),N).setInterval=e,H1.L)[Q[1]].call(this)},T)[0](94,cQ,sH),G$)(),$M=[0,sI,(((((T[0](87,MR,yE),T)[0](85,k7,xW),MR.prototype.U=function(N){(N=["call","U",3],K)[34](N[2],this.i),MR.L[N[1]][N[0]](this)},MR.prototype).o=function(N, +C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){if((B=((A=[25,!(q=[1900,(N=N.error||N,!(L=C?l[15](37,C):{},0)),null],1),"B"],N)instanceof Error&&yO(L,N[hw]||{}),v)[19](1,'"',A[1],q[1],q[2],N),this).G)try{this.G(B,L,N)}catch(n){}if(!(e=B.message.substring(0,q[0]),N instanceof sH)||N[A[2]]){Q=B.fileName,u=(m=B.lineNumber,B.stack);try{if((G=(D=cT(this.P,"script",Q,"error",e,"line",m),{}),f[36](14,q[1],this[A[2]]))||(t=D,c=K[A[0]](9,"=",this[A[2]]),D=f[5](2,"?",t,c)),G[qa()]=u,L)for(O in L)G[this.K+O]=L[O];(h=K[A[0]](8, +"=",G),this).V(D,y4(),h,this.A)}catch(n){}}try{v[44](37,this,new k7(B,L))}catch(n){}},U)[47](29,function(N,C){(new (C=new HV(GH(N)),Qt)(C)).i.init()},"recaptcha.anchor.Main.init"),T)[40](34,wi,p),wi.prototype.v=function(){return T[22](2,1,this)},VF)],kq=((T[40](58,(wi.prototype.D=f[38](26,$M),W4),p),W4).prototype.D=f[38](67,[0,YF,$M]),function(){return I[1].call(this,17)});function Nz(){return W[44].call(this,24)} +var fd=(((((((V=((T[0](92,Nz,La),S)[42](81,Nz),Nz).prototype,V).B9=function(){return tD},V).yY=function(N,C,e,L){return(C[(N=(L=["yY","call","W"],Nz.L[L[0]][L[1]](this,N,C)),e=this.getValue(N),L)[2]]=e,C.C=this.rM(N),C.Cu)&16&&this.Qk(N,16,C.gq()),N},V).Qk=function(N,C,e,L){L=[64,1,8];switch(C){case L[2]:case 16:K[13](41,hD,N,e);break;default:case L[0]:case L[1]:Nz.L.Qk.call(this,N,C,e)}},V.KP=function(N,C,e,L){return((C=((e=Nz.L.KP.call(this,(L=["Qk","gq","Cu"],N)),this).v9(e,N.rM()),N.getValue()))&& +this.bf(e,C),N[L[2]]&16)&&this[L[0]](e,16,N[L[1]]()),e},V).getValue=function(){},V).cK=function(){return"goog-button"},V).v9=function(N,C){N&&(C?N.title=C:N.removeAttribute(yl()))},V.bf=function(){},V.rM=function(N){return N.title},J7()),sz=(((((h1(),b$)(),n3(),WD)(),z$(),Sz(),jU(),OR(),uO(),kb(),L_(),tF(),u7(),ov(),Ao(),BE)(),iP(),fs)(),R2(),rB)(),CE=(CT(),fe)();((TZ(),DQ)(),cx(),zp)();function G6(){return I[35].call(this,35)} +((((V=((T[0](86,G6,Nz),S)[42](82,G6),G6.prototype),V.Ih=function(N,C,e,L){(L=(G6.L.Ih.call(this,N,C,e),N.v()))&&C==1&&(L.disabled=e)},V).Eb=function(){},V.Mk=function(){},V).yY=function(N,C,e,L){return((((L=["L",9,27],U[L[2]](4,!1,C),C).SZ&=-256,H)[11](17,1,32,!1,C),N.disabled)&&(e=v[L[1]](L[1],1,this),W[22](7,N,e)),G6)[L[0]].yY.call(this,N,C)},V.zm=function(N,C){y[C=["F",10,22],C[2]](59,y[C[1]](23,N),N.v(),PV,N[C[0]])},V).B9=function(){},V.KP=function(N,C,e,L,h,Q,m,O){return Q=(C=(m={"class":(e= +(h=((U[27](5,(O=[1,(L=["",!1,32],"replace"),0],L[O[0]]),N),N.SZ&=-256,H)[11](29,O[0],L[2],L[O[0]],N),N.A),h.ZS),I[36](4,this,N).join(OY())),disabled:!N.isEnabled(),title:N.rM()||L[O[2]],value:N.getValue()||L[O[2]]},N).U5())?(typeof C==="string"?C:Array.isArray(C)?C.map(v[38].bind(null,4)).join(L[O[2]]):f[22](O[0],L[O[2]],C))[O[1]](/[\t\r\n ]+/g,OY())[O[1]](/^[\t\r\n ]+|[\t\r\n ]+$/g,L[O[2]]):"",e.call(h,$n,m,Q||L[O[2]])},V.C6=function(N){return N.isEnabled()},V.m1=function(){},V.getValue=function(N){return N.value}, +V.bf=function(N,C){N&&(N.value=C)},V).Qk=function(){};function P_(N,C,e){return W[37].call(this,49,N,C,e)} +var ek=(((((V=(T[0](84,P_,jj),P_.prototype),V.getValue=function(){return this.W},V.v9=function(N){(this.C=N,this.G).v9(this.v(),N)},V).U=function(){delete (P_.L.U.call(this),this).W,delete this.C},V).Vl=function(N,C){((C=["L",35,10],P_[C[0]].Vl).call(this),this.Cu&32)&&(N=this.v())&&y[22](C[1],y[C[2]](24,this),N,uA,this.Tt)},V.Tt=function(N,C){return C=[32,"keyCode",13],N[C[1]]==C[2]&&N.type==g0||N[C[1]]==C[0]&&N.type==uA?this.F(N):N[C[1]]==C[0]},V.rM=function(){return this.C},U[46](25,function(){return new P_(null)}, +"goog-button"),T[40](6,Lb,P_),Lb.prototype.Vl=function(N,C,e,L,h){(((L=(C=((e=((h=["i",(N=this,"v"),"call"],P_.prototype).Vl[h[2]](this),this)[h[1]](),e).setAttribute(PN(),P[9](13,":",this)),e.tabIndex=this[h[0]],e).click,!1),fu)(e,Sf(),{get:function(){function Q(){C.call((L=!0,this))}return Q.toString=function(){return C.toString()},Q}}),y)[22](35,y[10](20,this),this,y0,function(Q,m,O,t){t=["P","h",23],N.isEnabled()&&(Q=new wi,O=v[38](10,N[t[0]]),m=P[0](76,Q,O,1),L&&I[22](t[2],2,m,v[22].bind(null, +49),l[26].bind(null,36),2,1),N[t[1]](m))}),y)[22](53,y[10](24,this),new mT(this[h[1]](),!0),O5,function(){this.isEnabled()&&this.F.apply(this,arguments)})},Lb.prototype.I6=function(N,C,e,L,h){if(h=["I6",!1,29],P_.prototype[h[0]].call(this,N),N){if(this.i=e=this.i,C=this.v())e>=0?C.tabIndex=this.i:I[h[2]](34,0,C,h[1])}else(L=this.v())&&I[h[2]](2,0,L,h[1])},T[40](32,Hv,K2),Hv).prototype.reset=function(N,C){for(N in this.B)delete this.B[N];for(C in this.i)delete this.i[C]},Hv.prototype).U=function(){(this.reset(), +K2).prototype.U.call(this)},T[3](57,null,Zh,UA)),LE=(T[40](35,m5,p),[0,vg,i_,wv,DU,i_,-1]),hX=[0,sI,Bg,(((((T[40](59,(m5.prototype.D=f[38](73,LE),LX),p),LX.prototype.fu=function(){return S[49](26,1,this)},LX.prototype.setTimeout=function(N){return T[21](56,this,2,N)},LX.prototype).kx=function(){return W[4](3,this,4)},LX.prototype.m0=function(N){return W[N=[33,null,2],N[0]](17,this,N[2],void 0,void 0,P[0].bind(N[1],47))},T)[40](3,Ky,p),V=Ky.prototype,V).setTimeout=function(N){return T[21](24,this, +3,N,void 0,rY)},V.qd=function(){return T[22](1,9,this,rY)},V.kx=function(){return l[43](63,4,this,rY,FG)},V).fP=function(){return U[13](14,this,fA,8,rY)},V.m0=function(N){return W[33](21,this,(N=[null,3,0],N[1]),rY,void 0,P[N[2]].bind(N[0],40))},Ky.yl=OS(),1),wv,YF,[0,sI,-1],kF,sI,-1,kF,sI,-2],Kl=(Ky.prototype.D=f[38](26,["uvresp",sI,Ty,Bg,wv,Y6,1,PU,ox,(LX.prototype.D=f[38](67,hX),sI),Ty,-1,LE,hX]),Sx)(),Gv=eo(),jK=Nq(),yB=T1(),A0=sM(),I4=uT(),nl=nt(),F4=xu(),Tv=(uQ(),PC()),P4=(en(),HE)(),o4=jf(), +X4=Vx(),fl=kS(),QA=im(),mE=jS(),O4=BK(),tX=HW(),U4=xO(),DS=o0(),qz=Zn(),HQ=iq(),u2=(pe(),w$()),dY=jl(),c4=kA(),v4=EG(),R4=Jo(),ln=e_(),ZZ=$h(),sw=xa(),SK=GL(),Yt=mw(),tW=oW(),B4=Kn(),I$=YA(),dw=cW(),rq=tn(); +((((((((((V=(((T[40](35,eB,QY),eB).prototype.Yx=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c){if((m=(((Q=(q=((G=(D=(h=((L=(t=(((u=(B=((O=((e=(c=["R",84,69],[24,33,32]),QY).prototype.Yx.call(this,N),P[43](8,QA,this)),this).lI.render(O),B0.M().get()),P)[43](9,mE,this),T[42](68,e[2],B))?u.style.display=sh():this[c[0]].render(u),C=P[43](3,O4,this),T[42](52,e[1],B))?C.style.display=sh():this.j_.render(C),P[43](8,tX,this)),P[39](5,e[0],B0.M().get())))!=null&&L?this.C.render(t):t.style.display=sh(),P)[43](7,U4, +this),B0.M().get()),T[42](32,30,D)),G)!=null&&G?this.o6.render(h):h.style.display=sh(),P[43](8,DS,this)),this.S_.render(q),P)[43](2,qz,this),this.iI).render(Q),H)[35](c[1],this.iI),P[43](10,u2,this)),this.S.render(m),P[39](4,e[0],B)&&T[42](48,e[2],B))&&T[42](68,e[1],B))H[35](74,this.C),H[35](79,this.S);else if(this.z$)H[35](c[2],this.j_);else if(this.bI)H[35](85,this[c[0]]);else this.iz?(H[35](75,this.C),H[35](68,this.S)):this.DR&&(H[35](70,this.o6),H[35](71,this.S))},eB).prototype.Vl=function(N, +C){(((((C=[22,"o6",(N=this,43)],QY).prototype.Vl.call(this),y[C[0]](56,y[10](C[0],this),this.lI,y0,this.Jt),y[C[0]](41,y[10](24,this),this.R,y0,function(){(this.r0(!1),v)[44](34,this,"m")}),y)[C[0]](25,y[10](19,this),this.C,y0,function(){this.r0(!1),v[44](37,this,"o")}),y[C[0]](37,y[10](20,this),this.j_,y0,function(){this.r0(!1),v[44](32,this,"n")}),y[C[0]](C[2],y[10](C[0],this),this[C[1]],y0,function(){(this.r0(!1),v)[44](36,this,"p")}),y[C[0]](44,y[10](17,this),this.S_,y0,function(e){((e=["q","none", +5],y)[e[2]](8,e[1],0,this),v)[44](36,this,e[0])}),y)[C[0]](52,y[10](23,this),this.iI,y0,this.Bn),y)[C[0]](45,y[10](19,this),this.v(),uA,function(e){e.keyCode==27&&v[44](33,this,"i")}),y)[C[0]](56,y[10](17,this),this.S,y0,function(){return U[29](2,!1,N)})},eB.prototype.getName=function(){return this.qp},eB).prototype,eB.prototype.az=function(N,C,e){if(!(e=[35,5,!1],N)||U[e[1]](27,"none",N)==C)return e[2];return!(P[49](6,N,C),I[29](e[0],0,N,C),0)},V).xU=function(){this.R.v().focus()},eB).prototype.Ac= +function(N,C,e,L,h,Q,m){return(h=((Q=new sB(K[43](18,(m=[(e=e===void 0?"":e,2),3,76],QV))+e),U)[35](m[2],Q,NZ,N),L=B0.M().get(),T[22](m[1],m[0],L,rY)),U[35](77,Q,XN,h),C&&U[35](74,Q,V0,C),Q).toString()},eB.prototype).rr=function(){},eB).prototype.RW=function(){return""},eB.prototype.s_=function(N,C,e){if(e=[2,"forEach",100],N)if(this.hO.length==0)P[28](e[0],e[2],this);else C=this.hO.slice(0),this.hO=[],C[e[1]](function(L){L()})},eB).prototype.KI=function(){return l[49](26,this.Fe)},V.Bn=function(){}, +V).Xd=function(){return!1},eB).prototype.oz=function(){},eB.prototype).r0=function(N,C){((((this.lI[C=[5,"I6","j_"],C[1]](N),this.R)[C[1]](N),this[C[2]][C[1]](N),this).C[C[1]](N),this.o6)[C[1]](N),this.S[C[1]](N),this.S_[C[1]](N),y)[C[0]](7,"none",0,this,!1)},V).tm=function(){return!1},V.Mp=function(N,C,e,L,h,Q){if((h=[!0,(C=C===void 0?null:C,Q=[2,10,!1],"Left"),"none"],N)||!C||U[5](28,h[Q[0]],C))N&&(L=this.az(C,h[0])),!C||N&&!L||(e=l[49](27,this.P),e.height+=(N?1:-1)*(P[47](38,C).height+P[Q[1]](3, +h[1],"margin",C).top+P[Q[1]](Q[0],h[1],"margin",C).bottom),K[34](59,"h",e,this,!N)),N||this.az(C,Q[2])},V).Jt=function(){return K[34].call(this,8)};function bY(N,C){return v[38].call(this,23,N,C)} +var j3,BB=((((((((((((V=((T[0](90,bY,QY),bY.prototype).l=function(N){((N=[39,29,14],S)[37](N[1],null)||(H[N[0]](73,this.i,this.v(),PV,this.P),this.O_=null),this).ux=!1,H[22](N[2],null,this)},bY).prototype,V.ux=!1,V).U=function(N){N=["i","call","dispose"],bY.L.U[N[1]](this),this[N[0]]&&(this[N[0]][N[2]](),this[N[0]]=null)},V).Vl=function(N,C,e){this[((((e=[8,"v","i"],bY).L.Vl.call(this),C=new TN(this),y[22](49,C,this[e[1]](),CR,this.P),y)[22](45,C,this[e[1]](),NU,this.l),S)[37](55,null)?this[e[2]]= +C:(bj&&y[22](32,C,this[e[1]](),[q$,oF,uA],this.nV),N=f[27](32,9,this[e[1]]()),I[7](1,S[28](49,N),void 0,Y3,C,this.kq),this[e[2]]=C,v[e[0]](13,!0,this)),H)[22](22,null,this),e[1]]()[e[2]]=this},V.nV=function(N){return v[7].call(this,1,N)},V.sG=function(){return l[18].call(this,1)},V.vm=function(){this.B=this.A.ZS(xn,{type:CE})},V.uY=function(){return H[28].call(this,5)},bY).prototype.P=function(N,C){(this[C=["X","label-input-label","ux"],C[2]]=!0,N=this.v(),W[16](67,N,C[1]),S[37](25,null))||K[4](83, +"",this)||this[C[0]]||!this.v()||(this.v().value="")},V.O_=null,V.bz=function(N){this[bY.L[N=[null,"bz","i"],N[1]].call(this),N[2]]&&(this[N[2]].dispose(),this[N[2]]=N[0]),this.v()[N[2]]=N[0]},V).kq=function(){return v[9].call(this,1)},V).Yx=function(N,C,e,L,h){((this[bY.L.Yx.call((h=(L=[null,!0,"label-input-label"],["G","v",40]),this),N),h[0]]||(this[h[0]]=N.getAttribute(zD())||""),y[14](32,L[0],f[27](9,9,N))==N)&&(this.ux=L[1],e=this[h[1]](),W[16](11,e,L[2])),S[37](23,L[0])&&(this[h[1]]().placeholder= +this[h[0]]),C=this[h[1]](),K)[13](h[2],Jf,C,this[h[0]])},bY.prototype).clear=function(N){this[(N=["","O_",null],this).v().value=N[0],N[1]]!=N[2]&&(this[N[1]]=N[0])},bY).prototype.reset=function(N){N=[6,86,"clear"],K[4](N[1],"",this)&&(this[N[2]](),H[22](N[0],null,this))},bY).prototype.getValue=function(N){return(N=[null,"O_","v"],this[N[1]])!=N[0]?this[N[1]]:K[4](7,"",this)?this[N[2]]().value:""},bY).prototype.isEnabled=function(){return!this.v().disabled},bY).prototype.F=function(N){(N=["",4,"v"], +!this[N[2]]()||K[N[1]](82,N[0],this)||this.ux)||(this[N[2]]().value=this.G)},bY.prototype).h=function(){this.X=!1},T[40](3,Qn,bY),Qn.prototype.vm=function(N){(((bY[(N=["prototype","rc-response-input-field",9],N)[0]].vm.call(this),this.v().setAttribute(PN(),P[N[2]](14,":",this)),this.v()).setAttribute(Ai(),ND()),this).v().setAttribute(ar(),ND()),this.v()).setAttribute(k0(),ND()),this.v().setAttribute(cn(),lM()),this.v().setAttribute(kO(),KK()),W[22](2,this.v(),N[1])},function(N,C,e,L,h,Q){return Q= +[49,16,"exec"],TM?(h=/Windows NT ([0-9.]+)/,(L=h[Q[2]](S[Q[1]](Q[0])))?L[1]:ZJ()):gw?(h=/1[0|1][_.][0-9_.]+/,(N=h[Q[2]](S[Q[1]](47)))?N[0].replace(/_/g,ZD()):Ys()):vy?(h=/Android\s+([^\);]+)(\)|;)/,(C=h[Q[2]](S[Q[1]](15)))?C[1]:""):At||yc||qC?(h=/(?:iPhone|CPU)\s+OS\s+(\S+)/,(e=h[Q[2]](S[Q[1]](Q[0])))?e[1].replace(/_/g,ZD()):""):""}()),io=YA(),vc=new B2(280,275),yU=new B2(280,235),jk=qW(),G5=Gx(),cB=hc(),KE=ft(),AX=$a(),yA=hH(),i2=f3(),vB=iO(),nE=uJ(),IL=(Vm(),NF)(),nc=nT(),RL=u$(),Fl=Hm(),l2=Et(), +Nm=((((((V=(T[40](6,Tj,eB),Tj.prototype),V.oz=function(N){N=["G","getValue",!1],this.response[tK()]=this[N[0]][N[1]](),y[30](5,this[N[0]],N[2])},V.Vl=function(N,C){(((N=((eB[(C=[29,"prototype",63],C)[1]].Vl.call(this),this).T=P[43](4,jk,this),this.G.render(P[43](10,i2,this)),this).G.v(),K)[13](43,LQ,N,[l2]),y)[22](C[0],y[22](C[2],y[22](28,y[22](C[0],y[10](24,this),T[0](12,vB),CR,function(){f[19](63,null)}),T[0](11,nE),CR,function(){f[19](60,null,[cB,AX])}),N,oF,function(e){e.ctrlKey&&e.keyCode==17&& +this.cn()}),document,oF,function(e){e.keyCode==82&&e.target!=N&&this.cn()}),this.i=P[43](1,cB,this),W[48](48,this.F,document),y)[22](41,y[10](20,this),this.F,g0,this.n8)},V).az=function(N,C,e,L){if(L=[9,8,"i"],N)return e=!!this[L[2]]&&f[22](L[1],"",this[L[2]]).length>0,P[49](14,this[L[2]],C),I[31](L[0],C,this.G),H[41](21,this[L[2]]),C&&K[18](52,"Multiple correct solutions required - please solve more.",this[L[2]]),C!=e;return!(this.Mp(C,this[L[2]]),1)},V.xU=function(N,C){(C=["focus",1,(N=[0,"",10], +6)],!(this.i&&f[22](9,N[C[1]],this.i).length>N[0]))||uv&&T[48](12,N[0],N[2],BB)>=N[0]?T[0](C[2],AX).children[N[0]][C[0]]():this.i[C[0]]()},V.n8=function(N){return I[35].call(this,16,N)},V).vm=function(N){this[this.B=((N=["Yx",43,"vm"],eB).prototype[N[2]].call(this),P[4](4,y[N[1]].bind(null,1),{Wj:RL})),N[0]](this.v())},V.cn=function(N,C,e){return W[45].call(this,25,N,C,e)},V).Xd=function(N){return(N=[17,26,23],this).h&&this.h.pause(),S[N[2]](6,this.G.getValue())?(I[N[0]](N[1],RL,document).focus(), +!0):!1},V).s_=function(N,C){((C=["h","prototype","s_"],eB)[C[1]][C[2]].call(this,N),!N&&this[C[0]])&&this[C[0]].pause()},V.pu=function(N,C,e,L,h,Q,m,O,t,D,q){if(((this.Mp(!(q=["cn",2,(Q=["Press CTRL to play again.",!1,1],"v")],!e)),this.G.clear(),y[30](36,this.G,!0),this.l)||(y[10](74,T[q[1]].bind(null,19),P[43](q[1],G5,this),{c3:this.Ac(N,void 0,"/audio.mp3"),jQ:v[10](10,"div",Q[1])?"rc-audiochallenge-tdownload-link-on-dark":"rc-audiochallenge-tdownload-link"}),y[19](64,Q[q[1]],this,f[28](33,!0, +P[43](1,G5,this)),Vq())),Zu(YA())).play)C&&U[13](21,C,xH,8,rY)&&(D=U[13](19,C,xH,8,rY),l[43](56,Q[q[1]],D,void 0,FG)),t=P[43](16,KE,this),K[18](58,"Press PLAY to listen",t),m=P[43](7,yA,this),K[18](48,"Enter what you hear",m),this.l||K[18](56,Q[0],I[17](q[1],Fl,document)),L=this.Ac(N,""),y[10](q[1],f[11].bind(null,24),this.T,{c3:L}),this.h=I[17](10,IL,document),y[19](96,Q[q[1]],this,this.h,pv()),h=P[43](11,AX,this),O=P[28](35,"PLAY",void 0,void 0,void 0,this),I[5](11,this,O),O.render(h),K[13](37, +LQ,O[q[2]](),[RL,Fl]),y[22](29,y[10](21,this),O,y0,this[q[0]]);else y[10](66,y[13].bind(null,3),this.T);return T[23](34)},V).rr=function(N,C){y[C=[10,null,73],C[0]](34,K[45].bind(C[1],C[2]),N,{vj:this.l})},kI()),Fz=wN(),T5=V1(),ZS=WY(),mc=mw(),$k=new B2(400,580),oL=(((((V=((((T[40](28,v0,eB),v0.prototype).oz=function(){this.response[tK()]=I[46](8,this)},V=v0.prototype,v0.prototype).vm=function(N){this.B=(eB.prototype.vm.call((N=[4,18,null],this)),P[N[0]](6,I[N[1]].bind(N[2],5))),this.Yx(this.v())}, +V.pu=function(N,C,e,L,h,Q,m,O,t){return((((Q=((m=K[t=[8,(h=this,L=[2,null,""],12),(this.metadata=C,31)],13](t[2],1,this.metadata),this).JO=T[22](4,1,m),this.ZM=v[t[1]](69,3,m)||1,O=ys(),l[43](42,6,m)==1&&(O=Jb()),T[22](4,7,m)),Q!=L[1])&&(Q=Q.toLowerCase()),y[10](42,f[7].bind(null,15),this.h,{label:this.JO,zQ:y[15](1,L[2],L[1],W[33](37,m,L[0],void 0,FG,f[22].bind(null,77))),eH:O,PS:this.getName(),eP:Q}),K)[41](35,L[2],{assert:y[25].bind(null,2)}.assert(this.h),S[10](16,L[1],this.h.innerHTML.replace(ZD(), +L[2]))),this.G).Ss.element=K9(T5),K)[34](11,"h",this.KI(),this,!0),T[t[0]](19,L[0],this),K[t[2]](t[1],"*",this.PE(this.Ac(N))).then(function(){e&&h.Mp(!0,T[0](61,"rc-imageselect-incorrect-response"))})},V.PE=function(N,C,e,L,h,Q,m,O,t,D,q){return((D=((h=(((O=(t=(e=(L=(m=T[5](2,(C=(q=[1,38,19],Q=this,[null,"px","td"]),4),K[13](q[2],q[0],this.metadata)),K)[41](q[0],5,K[13](14,q[0],this.metadata)),[]),T[4](q[0],C[q[0]],q[0],this,L,m)),t.f7=N,P)[4](2,v[2].bind(null,q[1]),t),W)[49](10,P[43](9,"rc-imageselect-target", +this),O),Array.prototype.forEach).call(S[q[2]](8,"*",C[0],document,O,C[2]),function(u,B,G){e.push((G=(B=this,{selected:!1,element:u}),G)),y[22](37,y[10](20,this),new mT(u,!1,!0),O5,function(){return void B.Vy(G)})},this),S[q[2]](16,"*","rc-imageselect-tile",document,O,C[2])),QU)(h,function(u,B,G){(y[G=(B=this,[22,17,"call"]),G[0]](47,y[10](G[1],this),u,[CR,NU],function(){}),y)[G[0]](60,y[10](G[0],this),u,oF,function(c){return void K[37](10,9,0,c,B,L)}),Array.prototype.forEach[G[2]](S[19](4,"*",null, +document,u,"img"),function(c){y[19](65,1,this,c,"src")},this)},this),I[17](10,ZS,document)),T[47](40,!1,!0,D)||K[26](9,oF,D,function(u){return void K[37](11,9,0,u,Q,L)}),this.G).Ss.Jc={rowSpan:m,colSpan:L,tc:e,vS:0},this).tm()?K[33](40,this,"Skip"):K[33](37,this),O},V.az=function(N,C,e){return(e=["rc-imageselect-error-select-more","rc-imageselect-incorrect-response","rc-imageselect-error-dynamic-more"],!C)&&N||e.forEach(function(L,h){(h=T[0](62,L),h!=N)&&this.Mp(!1,h)},this),N?eB.prototype.az.call(this, +N,C):!1},V.Xd=function(N){return(N=["G",!0,"rc-imageselect-error-select-more"],this[N[0]].Ss.Jc).vS<this.ZM?(this.Mp(N[1],T[0](63,N[2])),N[1]):!1},V).Vy=function(N,C,e,L){((C=((((e=!((L=[4,7,38],this).Mp(!1),N.selected))?W[22](L[1],N.element,"rc-imageselect-tileselected"):W[16](10,N.element,"rc-imageselect-tileselected"),N).selected=e,this.G).Ss.Jc.vS+=e?1:-1,T)[0](29,"rc-imageselect-checkbox",N.element),P)[49](L[0],C,e),this.tm())?K[33](L[2],this,"Skip"):K[33](39,this)},v0.prototype),V.Vl=function(N){(eB.prototype[N= +[20,"Vl",11],N[1]].call(this),y[22](61,y[10](N[0],this),T[0](N[2],"rc-imageselect-tabloop-end"),CR,function(){f[19](62,null,["rc-imageselect-tile"])}),y)[22](47,y[10](21,this),T[0](13,"rc-imageselect-tabloop-begin"),CR,function(){f[19](56,null,["verify-button-holder"])})},V).Yx=function(N,C){this[(C=[43,"h","call"],eB).prototype.Yx[C[2]](this,N),C[1]]=P[C[0]](9,"rc-imageselect-payload",this)},V.tm=function(N,C){return(N=(C=this.getName()===Fz,this.G.Ss.Jc.vS===0),C)&&N},V).xU=function(){},V).KI=function(N, +C,e,L){return new (N=RY((L=[194,29,300],C=this.X||y[L[1]](5,20),C.height-L[0]),400,C.width),e=vh(N,L[2]),B2)(e,180+e)},V).rr=function(N,C){(C=[10,"getName",null],y)[C[0]](50,l[15].bind(C[2],14),N,{LI:this[C[1]]()})},YC)(),PB=(nW(),mh()),s4=ih(),fE=KG(); +(((T[40](34,Oz,v0),Oz.prototype.q7=function(N){N=[49,!1,"iI"],this.Mp(N[1]),P[N[0]](8,this[N[2]].v(),!0)},Oz).prototype.tm=function(){return!1},Oz).prototype.oz=function(N,C,e,L,h,Q,m){for(h=(m=(C=0,["response",8,1]),[]);C<this.i.length;C++){for(L=0,Q=[];L<this.i[C].length;L++)N=this.i[C][L],e=I[m[1]](7,new aw(N.x,N.y),m[2]/this.l).round(),Q.push({x:e.x,y:e.y});h.push(Q)}this[m[0]][tK()]=h},Oz.prototype).PE=function(N,C,e,L,h,Q,m,O){return((C=(Q=(this.l=((((e=(h=P[4](4,K[2].bind(null,(m=(O=(this.i= +(L=this,[[]]),[10,"px",27]),["rc-canvas-canvas","rc-canvas-image",386]),1)),{f7:N}),W[49](9,T[0](12,"rc-imageselect-target"),h),T)[0](O[2],m[0]),e).width=l[49](17,this.P).width-14,e).height=e.width,h.style).height=I[45](20,O[1],e.height),e).width/m[2],e.getContext(K0())),T[0](60,m[1])),K)[26](12,Y3,C,function(){Q.drawImage(C,0,0,e.width,e.height)}),y)[22](61,y[O[0]](24,this),new mT(e),O5,function(t){return void L.q7(t)}),h};function Xl(N,C,e,L){return S[29].call(this,1,C,L,N,e)} +var o9=(Xl.prototype.equals=function(N,C){return this[C=["G","i","o"],C[0]]==N[C[0]]&&this[C[2]]==N[C[2]]&&this[C[1]]==N[C[1]]&&this.B==N.B},ow)(),pM=(((V=(T[40](58,P1,Oz),P1.prototype),V).Xd=function(N,C,e,L,h,Q,m,O){if(!(O=(Q=[!0,.5,1],[0,"rc-imageselect-error-select-something",27]),e=this.i[O[0]].length<=2)){for(C=O[N=O[0],0];N<this.i.length;N++)for(m=this.i[N],L=O[0],h=m.length-Q[2];L<m.length;L++)C+=(m[h].x+m[L].x)*(m[h].y-m[L].y),h=L;e=Vc(C*Q[1])<500}return e?(this.Mp(Q[O[0]],T[O[0]](O[2],O[1])), +Q[O[0]]):!1},V.Bn=function(N,C){this[N=((N=(C=["pop","i",0],this[C[1]]).length-1,this)[C[1]][N].length==C[2]&&N!=C[2]&&this[C[1]][C[0]](),this[C[1]].length-1),C[1]][N].length!=C[2]&&this[C[1]][N][C[0]](),this.CI()},V.CI=function(N,C,e,L,h,Q,m,O,t){for(((e=(m=T[0](11,(Q=[1,"rc-canvas-image",(t=["drawImage","fill","lineTo"],0)],"rc-canvas-canvas")),m).getContext(K0()),O=T[0](30,Q[1]),e)[t[0]](O,Q[2],Q[2],m.width,m.height),e.strokeStyle=oL,e).lineWidth=2,L=Q[2];L<this.i.length;L++)if(C=this.i[L].length, +C!=Q[2]){for(h=(((L==this.i.length-Q[0]&&(N&&(e.beginPath(),e.strokeStyle=PB,e.moveTo(this.i[L][C-Q[0]].x,this.i[L][C-Q[0]].y),e[t[2]](N.x,N.y),e.setLineDash([0]),e.stroke(),e.closePath()),e.strokeStyle=s4,e.beginPath(),e.fillStyle=s4,e.arc(this.i[L][C-Q[0]].x,this.i[L][C-Q[0]].y,3,Q[2],2*Math.PI),e[t[1]](),e.closePath()),e).beginPath(),e).moveTo(this.i[L][Q[2]].x,this.i[L][Q[2]].y),Q[0]);h<C;h++)e[t[2]](this.i[L][h].x,this.i[L][h].y);((((e[(e.fillStyle=fE,t)[1]](),e).setLineDash([0]),e).stroke(), +e[t[2]](this.i[L][Q[2]].x,this.i[L][Q[2]].y),e).setLineDash([10]),e.stroke(),e).closePath()}},V).q7=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z){if(r=(O=(h=(Oz.prototype.q7.call(this,(z=[1,12,2],A=[1E-5,0,1],N)),T)[0](29,"rc-canvas-canvas"),K[48](17,A[z[2]],A[z[0]],h)),G=new aw(N.clientX-O.x,N.clientY-O.y),m=this.i[this.i.length-A[z[2]]],m.length)>=3)q=m[A[z[0]]],k=G.x-q.x,u=G.y-q.y,r=L9(k*k+u*u)<15;R=r;a:{if(m.length>=z[2])for(E=m.length-A[z[2]];E>A[z[0]];E--)if(Y=m[E-A[z[2]]], +n=m[m.length-A[z[2]]],L=m[E],C=G,B=H[23](34,Y,L),Z=H[23](3,n,C),B==Z?e=!0:(c=B[A[z[0]]]*Z[A[z[2]]]-Z[A[z[0]]]*B[A[z[2]]],Vc(c-A[z[0]])<=A[0]?e=!1:(D=I[8](3,new aw(Z[A[z[2]]]*B[z[2]]-B[A[z[2]]]*Z[z[2]],B[A[z[0]]]*Z[z[2]]-Z[A[z[0]]]*B[z[2]]),A[z[2]]/c),T[47](8,A[0],D,Y)||T[47](15,A[0],D,L)||T[47](9,A[0],D,n)||T[47](10,A[0],D,C)?e=!1:(J=new Xl(L.y,Y.y,Y.x,L.x),Q=l[15](8,S[27](14,f[8](49,D.x,J,D.y),A[z[0]],A[z[2]]),J),X=new Xl(C.y,n.y,n.x,C.x),F=l[15](9,S[27](z[1],f[8](48,D.x,X,D.y),A[z[0]],A[z[2]]), +X),e=T[47](11,A[0],D,Q)&&T[47](8,A[0],D,F)))),e){t=R&&E==A[z[2]];break a}t=!0}t?(R?(m.push(m[A[z[0]]]),this.i.push([])):m.push(G),this.CI()):(this.CI(G),W[36](80,250,this.CI,this))},V.rr=function(N){y[10](74,K[14].bind(null,32),N)},sW()),ha=(((((T[40](56,sK,Oz),sK.prototype.CI=function(N,C,e,L,h,Q,m,O,t){for((h=((C=((O=(N=((Q=(t=["fillStyle",23,"i"],[1,"rc-canvas-image",0]),this[t[2]]).length==Q[2]?f[40](t[1],"width",Q[0],Q[2]):f[40](12,"width",3,this[t[2]].length-Q[0]),T[0](12,"rc-canvas-canvas")), +e=N.getContext(K0()),T)[0](13,Q[1]),e).drawImage(O,Q[2],Q[2],N.width,N.height),Zu(ow())),C.width=N.width,C).height=N.height,C.getContext(K0())),h)[t[0]]=oL,L=Q[2];L<this[t[2]].length;L++)for(L==this[t[2]].length-Q[0]&&(h[t[0]]=s4),m=Q[2];m<this[t[2]][L].length;m++)h.beginPath(),h.arc(this[t[2]][L][m].x,this[t[2]][L][m].y,20,Q[2],2*Math.PI),h.fill(),h.closePath();(e.drawImage(C,Q[2],(e.globalAlpha=.5,Q[2])),e).globalAlpha=Q[0]},sK).prototype.Xd=function(N,C){if(N=[!0,"None Found",(C=["i",2,36],!1)], +this[C[0]].push([]),this.CI(),this[C[0]].length>3)return N[C[1]];return((this.r0(N[C[1]]),W)[C[2]](88,500,function(){this.r0(!0)},this),W[5](39,1,C[1],this),P[49](4,this.iI.v(),N[C[1]]),K[33](41,this,N[1],N[0]),N)[0]},sK.prototype.PE=function(N,C,e,L){return(((e=Oz.prototype.PE.call(this,(C=[0,(L=[11,40,!0],"None Found"),"width"],N)),W)[5](L[1],1,2,this),f)[L[1]](L[0],C[2],1,C[0]),K)[33](43,this,C[1],L[2]),e},sK).prototype.Bn=function(N,C){this[this[N=this[C=["i","pop",0],C[0]].length-1,C[0]][N].length!= +C[2]&&this[C[0]][N][C[1]](),C[0]][N].length==C[2]&&K[33](33,this,"None Found",!0),this.CI()},sK.prototype).rr=function(N){y[10](66,y[38].bind(null,4),N)},sK).prototype.q7=function(N,C,e,L){(((e=(C=(Oz.prototype.q7.call(this,(L=[43,1,33],N)),T[0](L[0],"rc-canvas-canvas")),K[48](16,L[1],0,C)),this.i)[this.i.length-L[1]].push(new aw(N.clientX-e.x,N.clientY-e.y)),K)[L[2]](32,this,"Next"),this).CI()},ya)(),Ly=new B2(300,185),Sk=LD(),IM=((((((((V=(T[40](32,n6,eB),n6.prototype),V).rr=function(N){y[10](34, +v[1].bind(null,5),N)},V).s8=function(N){return v[30].call(this,2,N)},V).Vl=function(N){((this[(this[((eB.prototype.Vl.call((N=[9,"i","v"],this)),this).h=P[43](7,"rc-defaultchallenge-payload",this),N)[1]].render(P[43](N[0],"rc-defaultchallenge-response-field",this)),N)[1]][N[2]]().setAttribute(PN(),Sk),W)[48](52,this.G,this[N[1]][N[2]]()),y)[22](27,y[10](19,this),this.G,g0,this.s8),y[22](51,y[10](17,this),this[N[1]][N[2]](),uA,this.kn)},V).kn=function(){return I[2].call(this,1)},V.Xd=function(){return S[23](7, +this.i.getValue())},V.pu=function(N,C,e,L){return(this[(this.Mp(!(L=["i",23,33],!e)),L)[0]].clear(),y[10](2,K[26].bind(null,40),this.h,{Ac:this.Ac(N)}),T)[L[1]](L[2])},V).xU=function(N,C,e){(e=[84,!0,"v"],At||yc||vy)||(this.i.getValue()?this.i[e[2]]().focus():(N=this.i,C=K[4](e[0],"",N),N.X=e[1],N[e[2]]().focus(),C||S[37](26,null)||(N[e[2]]().value=N.G),N[e[2]]().select(),S[37](24,null)||(N.i&&P[29](9,N.i,N[e[2]](),PV,N.P),W[36](88,10,N.h,N))))},V).vm=function(N){((N=[null,"vm",3],eB.prototype[N[1]]).call(this), +this).B=P[4](N[2],P[17].bind(N[0],33)),this.Yx(this.v())},V).az=function(N,C,e){if(e=["i","call","prototype"],N)return I[31](8,C,this[e[0]]),eB[e[2]].az[e[1]](this,N,C);return this.Mp(C,T[0](44,"rc-defaultchallenge-incorrect-response")),!1},V.oz=function(){this.response[tK()]=this.i.getValue(),this.i.clear()},Rt()),nm=new B2(300,250),zz=((((((T[40](38,R9,eB),R9.prototype.oz=function(){this.response[tK()]=""},R9).prototype.s_=function(N){N&&P[43](3,"rc-doscaptcha-body-text",this).focus()},R9.prototype).vm= +function(N){(this.B=(eB.prototype.vm.call((N=[1,2,null],this)),P[4](N[0],K[45].bind(N[2],N[1]))),this).Yx(this.v())},R9.prototype).pu=function(N,C,e,L,h,Q){return((C=(e=(h=[null,"rc-doscaptcha-body-text",(Q=[0,2,43],"rc-doscaptcha-body")],this.r0(!1),P)[Q[2]](1,"rc-doscaptcha-header-text",this),P[Q[2]](8,h[Q[1]],this)),L=P[Q[2]](12,h[1],this),e&&v[37](Q[1],h[Q[0]],e,-1),C&&L)&&(N=P[47](38,C).height,v[37](34,h[Q[0]],L,N)),T)[23](66)},T)[40](56,u6,p),u6.prototype).Fa=function(){return W[30](2,2,this, +B7)},u6.yl=Ol(),u6.prototype.D=f[38](26,["clrep",B7,sI,S9,sI,bW,S9]),T[40](58,Gk,KN),ww.prototype.send=function(N,C,e,L,h,Q,m,O){return P[C=C===(e=e===void 0?!0:e,void 0)?!1:C,44](41,function(t,D,q){q=["V",1,"WL"],D=[7,5,500];switch(t.B){case q[1]:h={method:N.G_(),headers:{"Content-Type":N[q[2]]?N[q[2]]:N.Rz?Uc:""},body:N.U5(),A6:C},e||(h.mode=sD()),O=0;case 2:return t.K(D[q[1]]),t.i(fetch(N.sn.toString(),h),D[0]);case D[0]:t[Q=t.G,q[0]](4);break;case D[q[1]]:L=m=t.o();case 4:if(O++<3&&(!Q||!Q.ok&& +(Q.status>D[2]||Q.status===408)))t.js(2);else return Q||(Q=new Response(L,{status:400})),t.return(Q)}})},[104,97,110,100,103,101,115,116,117,114,101].map(function(N){return String.fromCharCode(N)})).join(""),Ek=new B2(400,580),Y8=Bs(),qp=e1(),zS=((((((T[40](56,Sr,eB),Sr.prototype.s_=function(N,C,e,L){((eB.prototype.s_.call(this,(L=[25,"querySelector","T"],N)),!N&&(C=this.i,e=C[L[1]](vN())))&&(C.removeChild(e),this[L[2]]=!0),N&&this[L[2]])&&I[L[0]](5,11,8,this.F,this)},Sr.prototype).vm=function(N){this.i= +((N=[23,"Yx","vm"],eB.prototype)[N[2]].call(this),this.B=P[4](3,v[26].bind(null,N[0])),this[N[1]](this.v()),P)[43](4,Y8,this)},Sr.prototype.KI=function(N,C,e,L){return e=(N=RY((C=this[L=[194,"X",20],L[1]]||y[29](6,L[2]),C).height-L[0],400,C.width),vh(N,300)),new B2(e,180+e)},Sr.prototype.oz=function(N){((N=[29,24,null],this).response[Vs()]=T[N[0]](12,N[2],this.G,1),this.response)[iZ()]=S[49](N[1],2,this.G)},Sr.prototype).xU=function(){this.i.focus()},Sr.prototype).pu=function(N,C,e){return(((K[34](75, +(e=["h",23,25],e[0]),this.KI(),this,!0),this).F=C,this).l=N,T)[e[1]](97,I[e[2]](4,11,8,C,this))},T)[40](34,EF,v0),EF.prototype.reset=function(){this.u=(this.T=(this.O=!1,[]),[])},EF.prototype.pu=function(N,C,e){return(this.reset(),v0.prototype.pu).call(this,N,C,e)},EF).prototype.tm=function(){return!1},h0()),WB=Fb(),rf=(V=((T[40](38,ZR,EF),ZR).prototype.reset=function(N){this[this.F=((this.i=((N=["W","prototype","l"],EF)[N[1]].reset.call(this),[]),this.rq=[],this)[N[0]]=!1,0),N[2]]=[]},ZR).prototype, +V.Vy=function(N,C,e){(C=(e=[33,1,45],["Next","rc-imageselect-carousel-instructions","rc-imageselect-carousel-instructions-hidden"]),EF.prototype.Vy.call(this,N),this.G.Ss).Jc.vS>0?(W[22](5,T[0](e[2],C[e[1]]),C[2]),this.W?K[e[0]](35,this):K[e[0]](34,this,C[0])):(W[16](26,T[0](46,C[e[1]]),C[2]),K[e[0]](48,this,"Skip"))},V.CR=function(N,C,e,L){((qc(this.i,((e=["r",0,(L=[0,35,44],2)],N.length)==e[1]&&(this.W=!0),N)),qc)(this.rq,C),this.l).length==this.i.length+1-N.length&&(this.W?v[L[2]](37,this,e[L[0]]): +l[18](L[1],e[2],600,this))},V.oz=function(){this.response[tK()]=this.l},V.Xd=function(N,C){if((((this.Mp((C=[600,"G",(N=[!1,2,"j"],32)],N[0])),this.l).push([]),this[C[1]].Ss).Jc.tc.forEach(function(e,L){e.selected&&this.l[this.l.length-1].push(L)},this),this).W)return N[0];return this.u=v[40](52,this.l),f[26](C[2],N[2],this),l[18](34,N[1],C[0],this),!0},V.pu=function(N,C,e,L,h,Q,m,O,t,D,q,u){return((Q=(this.rq=(q=(L=((O=(h=(u=[1,13,33],[5,1,4]),U)[u[1]](9,C,kB,h[0],rY),m=y[48](34,h[u[0]],O,y[11](34), +s5),f)[5](20,C,s5,h[u[0]],m[0],rY),EF.prototype).pu.call(this,N,C,e),U)[u[1]](12,C,kB,h[0],rY),y)[48](10,h[u[0]],q,y[11](11,F3),s5),this.i.push(this.Ac(N,WB)),t=this.i,D=U[u[1]](u[1],C,kB,h[0],rY),W[41](32,h[2],D,2)),qc)(t,Q),K)[u[2]](42,this,"Skip"),L},QB()),HB=[0,((((((T[40](59,lf,EF),lf.prototype.reset=function(){EF.prototype.reset.call(this),this.i=0,this.l={}},lf).prototype.Xd=function(N,C,e,L,h){if(!(h=[!0,"T",0],EF).prototype.Xd.call(this)){if(!this.O){L=P[4](11,this[h[1]]),e=L.next();try{for(;!e.done;e= +L.next())if(C=this.l,C!==null&&e.value in C)return!1}finally{e&&!e.done&&(N=L.return)&&N.call(L)}}this.Mp(h[0],T[h[2]](43,"rc-imageselect-error-dynamic-more"))}return h[0]},lf).prototype.oz=function(){this.response[tK()]=this.T},lf).prototype.CR=function(N,C,e,L,h,Q,m,O,t,D){h=(D=[9,(m=[0,"px",""],e=this,64),2],C=P[4](14,I[29](54,this)),C).next();try{for(L={};!h.done;L={jy:void 0,dz:void 0,IM:void 0,L7:void 0},h=C.next()){if(N.length==m[O=h.value,0])break;(((((Q=(this.T.push(O),T[4](D[2],m[1],1,this, +this.G.Ss.Jc.colSpan,this.G.Ss.Jc.rowSpan)),yO(Q,{tW:0,JW:0,rowSpan:1,colSpan:1,f7:N.shift()}),L).L7=f[3](1,null,m[D[2]],D[0],1,Q),L).dz=this.l[O]||O,L).jy=this.G.Ss.Jc.tc.length,L.IM={selected:!0,element:this.G.Ss.Jc.tc[L.dz].element},this.G.Ss.Jc).tc.push(L.IM),W)[36](D[1],this.i+1E3,function(q){return function(u){(((((u=["l",16,18],e[u[0]])[q.jy]=q.dz,H)[41](u[2],q.IM.element),q.IM).element.appendChild(q.L7),S)[28](2,"0",100,q.IM),q.IM).selected=!1,W[u[1]](35,q.IM.element,"rc-imageselect-dynamic-selected"), +y[22](28,y[10](22,e),new mT(q.IM.element),O5,kW(e.Vy,q.IM))}}(L))}}finally{h&&!h.done&&(t=C.return)&&t.call(C)}},lf.prototype).Vy=function(N,C,e){this.T.indexOf((C=["rc-imageselect-dynamic-selected",!0,1E3],e=["transition","s ease",26],this.G.Ss.Jc.tc.indexOf(N)))==-1&&(this.Mp(!1),N.selected||(++this.G.Ss.Jc.vS,N.selected=C[1],this.i&&S[29](7,N.element,e[0],"opacity "+(this.i+C[2])/C[2]+e[1]),W[22](1,N.element,C[0]),qc(this.u,this.G.Ss.Jc.tc.indexOf(N)),f[e[2]](16,"j",this)))},lf.prototype).pu=function(N, +C,e,L,h,Q){return this[h=(L=EF.prototype.pu.call(this,N,(Q=[2,13,"i"],C),e),U)[Q[1]](11,C,ZP,3,rY),Q[2]]=v[12](71,Q[0],h)||0,L},T[40](58,Rm,p),Nj),sI],Lh=T[3](25,null,(Rm.prototype.D=f[38](73,HB),HB),Rm),k8,kK=(function(N){(function(C,e,L){C[(new (((e=(L=["B","BYTE","wv"],function(h,Q){(this.i=Q,this).Hw=h}),e).prototype.Vq=function(h){return W[1].call(this,4,h)},e[L[2]]=new e(1,[10,12,14]),e).ZD=new e(2,[9,11,13]),e[L[1]]=new e(4,[8,16,16]),new e(8,[8,10,12]),e)(7,[0,0,0]),L)[0]]=e})(N.qk||(N.qk= +{}))}((function(N,C,e,L,h){C=(h=(L=["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:",3,40],["prototype",0,"N7"]),function(m,O,t,D,q,u,B,G,c,A,n,R,F){if(m<(F=(this.version=(this.G=[],this.j=(this.mask=(R=[],this.i=[],D),O),m),[!1,"Version value out of range",1]),n=[8,0,4],C.K)||m>C.o)throw Error(F[1]);if(D<-1||D>7)throw Error("Mask value out of range");for(u=n[this.size=m*n[2]+17,F[2]];u<this.size;u++)R.push(F[0]);for(G=n[F[2]];G<this.size;G++)this.i.push(R.slice()),this.G.push(R.slice());if((this.Y(), +c=this.h(t),this.S(c),D)==-1)for(A=n[F[2]],B=1E9;A<n[0];A++)this.K(A),this.V(A),q=this.F(),q<B&&(D=A,B=q),this.K(A);if(D<n[F[2]]||D>7)throw Error("Assertion error");this.G=((this.mask=D,this).K(D),this.V(D),[])});function Q(m,O,t,D,q,u){if(O<(u=(D=["Value out of range",1,0],[2,31,0]),D[u[0]])||O>u[1]||m>>>O!=D[u[0]])throw Error(D[u[2]]);for(q=O-D[1];q>=D[u[0]];q--)t.push(m>>>q&D[1])}N.qk=((((N[h[2]]=((((C.A=[[-1,7,10,15,20,26,18,20,24,30,18,20,24,26,30,22,24,28,30,28,28,28,28,30,30,26,28,30,30,30, +30,30,30,30,30,30,30,30,30,30,30],[-1,10,16,26,18,24,16,18,22,22,26,30,22,22,24,24,28,28,26,26,26,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28],[-1,13,22,18,26,18,(C.j=[[-1,1,1,1,1,1,2,2,2,2,4,4,4,4,4,6,6,6,6,7,8,8,9,9,10,12,12,(C.X=((C[h[C.B=(((C.o=(C.P=function(m,O,t,D,q){if((t=[2,(q=[128,29648,64],16),36],m<C.K)||m>C.o)throw Error("Version number out of range");if(!(208<=(m>=(D=(t[1]*m+q[0])*m+q[2],t[0])&&(O=TH(m/7)+t[0],D-=(25*O-10)*O-55,m>=7&&(D-=t[2])),D)&&D<=q[1]))throw Error("Assertion error"); +return D},(C[h[0]].A=function(m,O,t,D,q){if((O=m[(q=[2,(t=["Assertion error",4,3],6),1],q)[2]],O)>this.size*t[q[0]])throw Error(t[0]);return((D=O>0&&m[q[0]]==O&&m[t[q[0]]]==O*t[q[0]]&&m[t[q[2]]]==O&&m[5]==O,D&&m[0]>=O*t[q[2]]&&m[q[1]]>=O)?1:0)+(D&&m[q[1]]>=O*t[q[2]]&&m[0]>=O?1:0)},L)[2]),C[(C.h=(C[(C.l=((C[h[0]].I=function(m,O){return 0<=O&&O<this.size&&0<=m&&m<this.size&&this.i[m][O]},C)[h[0]].X=(C[h[e=function(m,O,t,D){if(((this.mode=(D=["hK","wM","slice"],m),this)[D[1]]=t,this[D[0]]=O,O)<0)throw Error("Invalid argument"); +this[D[1]]=t[D[2]]()},0]].Y=function(m,O,t,D,q,u,B){for(B=(O=[4,6,0],[2,"B","V"]),q=O[B[0]];q<this.size;q++)this[B[1]](q,O[1],q%B[0]==O[B[0]]),this[B[1]](O[1],q,q%B[0]==O[B[0]]);for(D=(t=((this.P(3,3),this).P(this.size-O[0],3),this.P(3,this.size-O[0]),this.l()),O[B[0]]),m=t.length;D<m;D++)for(u=O[B[0]];u<m;u++)D==O[B[0]]&&u==O[B[0]]||D==O[B[0]]&&u==m-1||D==m-1&&u==O[B[0]]||this.J(t[u],t[D]);this[B[2]](O[B[0]]),this.Z()},C[h[0]].F=function(m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d){for(E=(d=["i", +(A=[0,5,1],0),2],n=A[d[1]],A)[d[1]];n<this.size;n++){for(Z=A[O=[0,0,0,(u=A[d[1]],0),(t=!1,0),0,0],d[1]];Z<this.size;Z++)this[d[0]][n][Z]==t?(u++,u==A[1]?E+=C.X:u>A[1]&&E++):(this.o(O,u),t||(E+=this.A(O)*C.B),u=A[d[2]],t=this[d[0]][n][Z]);E+=this.X(u,t,O)*C.B}for(z=A[d[1]];z<this.size;z++){for(r=(F=A[d[1]],A[B=[0,0,0,0,0,0,0],d[1]]),k=!1;F<this.size;F++)this[d[0]][F][z]==k?(r++,r==A[1]?E+=C.X:r>A[1]&&E++):(this.o(B,r),k||(E+=this.A(B)*C.B),k=this[d[0]][F][z],r=A[d[2]]);E+=this.X(r,k,B)*C.B}for(X=A[d[1]];X< +this.size-A[d[2]];X++)for(D=A[d[1]];D<this.size-A[d[2]];D++)q=this[d[0]][X][D],q==this[d[0]][X][D+A[d[2]]]&&q==this[d[0]][X+A[d[2]]][D]&&q==this[d[0]][X+A[d[2]]][D+A[d[2]]]&&(E+=C.h);Y=(J=P[4]((m=A[d[1]],12),this[d[0]]),J.next());try{for(;!Y.done;Y=J.next())m=Y.value.reduce(function(x,w){return x+(w?1:0)},m)}finally{Y&&!Y.done&&(c=J.return)&&c.call(J)}return G=wq(Vc(m*(R=this.size*this.size,20)-R*10)/R)-A[d[2]],E+=G*C.J},function(m,O,t){return(O&&(this.o(t,m),m=0),m+=this.size,this.o(t,m),this).A(t)}), +C.K=1,C.G=function(m,O,t){return(t=[8,"Xb","P"],TH)(C[t[2]](O)/t[0])-C.A[m[t[1]]][O]*C.j[m[t[1]]][O]},function(m,O,t,D,q,u,B,G){D=(q=(u=(G=["forEach",0,"map"],O[G[2]](function(){return 0})),P)[4](15,m),q.next());try{for(B={};!D.done;B={XV:void 0},D=q.next())B.XV=D.value^u.shift(),u.push(G[1]),O[G[0]](function(c){return function(A,n){return u[n]^=C.V(c.XV,A)}}(B))}finally{D&&!D.done&&(t=q.return)&&t.call(q)}return u}),h)[0]].Z=(C.V=function(m,O,t,D,q,u){if((u=[(q=[7,8,1],2),0,1],O)>>>q[u[2]]!=u[1]|| +m>>>q[u[2]]!=u[1])throw Error("Byte out of range");for(t=(D=q[u[1]],u)[1];D>=u[1];D--)t=t<<q[u[0]]^(t>>>q[u[1]])*285,t^=(m>>>D&q[u[0]])*O;if(t>>>q[u[2]]!=u[1])throw Error("Assertion error");return t},function(m,O,t,D,q,u,B,G,c){if(!((c=[0,2,3],u=[18,1,11],this.version)<7)){for(t=(O=c[0],this).version;O<12;O++)t=t<<u[1]^(t>>>u[c[1]])*7973;if(q=this.version<<12|t,q>>>u[c[0]]!=c[0])throw Error("Assertion error");for(D=c[0];D<u[c[0]];D++)m=this.size-u[c[1]]+D%c[2],B=(q>>>D&u[1])!=c[0],G=TH(D/c[2]),this.B(G, +m,B),this.B(m,G,B)}}),L)[1],C[h[0]].B=function(m,O,t){this.G[this.i[m][O]=t,m][O]=!0},h)[C[h[0]].jC=(C.S=function(m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E,J,r,z,d,x,w,a,g,M){if(w=(g=(R=[0,(z=z===void 0?!0:z,a=(G=G===void 0?40:G,a===(A=[],void 0)?-1:a),M=["K",7,15],8),"Invalid value"],[]),w)===void 0?1:w,!(C[M[0]]<=w&&w<=G&&G<=C.o)||a<-1||a>M[1])throw Error(R[2]);for(c=w;;c++){if(Z=(E=C.G(O,c)*R[1],e[M[0]](c,m)),Z<=E){X=Z;break}if(c>=G)throw Error("Data too long");}d=P[4](M[2],[C.i.No,C.i.dv,C.i.HM]),r= +d.next();try{for(;!r.done;r=d.next())q=r.value,z&&X<=C.G(q,c)*R[1]&&(O=q)}finally{r&&!r.done&&(n=d.return)&&n.call(d)}t=P[4](M[2],m),J=t.next();try{for(;!J.done;J=t.next()){x=(F=(Q((Q((B=J.value,B.mode.Hw),4,g),B).hK,B.mode.Vq(c),g),P)[4](10,B.getData()),F.next());try{for(;!x.done;x=F.next())g.push(x.value)}finally{x&&!x.done&&(D=F.return)&&D.call(F)}}}finally{J&&!J.done&&(u=t.return)&&u.call(t)}if(g.length!=X)throw Error("Assertion error");if(k=C.G(O,c)*R[1],g.length>k)throw Error("Assertion error"); +if((Q((Q(R[0],RY(4,k-g.length),g),R)[0],(R[1]-g.length%R[1])%R[1],g),g).length%R[1]!=R[0])throw Error("Assertion error");for(Y=236;g.length<k;Y^=253)Q(Y,R[1],g);for(;A.length*R[1]<g.length;)A.push(R[0]);return g.forEach(function(hA,mQ){return A[mQ>>>3]|=hA<<7-(mQ&7)}),new C(c,O,A,a)},function(m,O,t,D,q,u){return l[27].call(this,24,m,O,t,D,q,u)}),0]].l=function(m,O,t,D,q,u){if((u=(D=[2,1,7],[0,"version",2]),this[u[1]])==D[1])return[];for(O=(t=this[m=(q=[6],TH(this[u[1]]/D[u[2]])+D[u[0]]),u[1]]==32? +26:wq((this.size-13)/(m*D[u[0]]-D[u[0]]))*D[u[0]],this.size)-D[u[2]];q.length<m;O-=t)q.splice(D[1],u[0],O);return q},C)[h[0]].h=function(m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y,k,E){if(m.length!=(F=this[E=[1,(D=[],Y=["Invalid argument",0,"Assertion error"],"forEach"),"version"],E[2]],G=this.j,C).G(G,F))throw Error(Y[0]);for(u=(A=(t=(B=(X=(k=TH((c=(q=[],C.j[G.Xb][Z=C.A[G.Xb][F],F]),C.P(F)/8)),c)-k%c,TH(k/c)),C.Z(Z)),Y)[E[0]],Y[E[0]]);A<c;A++)R=m.slice(u,u+B-Z+(A<X?0:1)),u+=R.length,n=C.l(R,t),A<X&&R.push(Y[E[0]]), +D.push(R.concat(n));for(O={sK:0};O.sK<D[Y[E[0]]].length;O={sK:O.sK},O.sK++)D[E[1]](function(J){return function(r,z){(J.sK!=B-Z||z>=X)&&q.push(r[J.sK])}}(O));if(q.length!=k)throw Error(Y[2]);return q},C)[h[0]].o=function(m,O){((m[0]==0&&(O+=this.size),m).pop(),m).unshift(O)},L[2]),0]].P=function(m,O,t,D,q,u,B,G,c){for(c=[0,"B",(t=-4,2)],D=[4,0,2];t<=D[c[0]];t++)for(q=-4;q<=D[c[0]];q++)u=vh(Vc(q),Vc(t)),B=m+q,G=O+t,D[1]<=B&&B<this.size&&D[1]<=G&&G<this.size&&this[c[1]](G,B,u!=D[c[2]]&&u!=D[c[0]])}, +C).Y=function(m,O,t,D){return t=N.qk.j((O=(D=["i","S","N7"],k8)[D[2]][D[0]][D[0]],m)),C[D[1]](t,O)},L[1]),C[h[0]].K=function(m,O,t,D,q,u){if((u=[1,(t=[2,3,5],7),0],m<u[2])||m>u[1])throw Error("Mask value out of range");for(D=u[2];D<this.size;D++)for(q=u[2];q<this.size;q++){switch(m){case u[2]:O=(q+D)%t[u[2]]==u[2];break;case u[0]:O=D%t[u[2]]==u[2];break;case t[u[2]]:O=q%t[u[0]]==u[2];break;case t[u[0]]:O=(q+D)%t[u[0]]==u[2];break;case 4:O=(TH(q/t[u[0]])+TH(D/t[u[2]]))%t[u[2]]==u[2];break;case t[2]:O= +q*D%t[u[2]]+q*D%t[u[0]]==u[2];break;case 6:O=(q*D%t[u[2]]+q*D%t[u[0]])%t[u[2]]==u[2];break;case u[1]:O=((q+D)%t[u[2]]+q*D%t[u[0]])%t[u[2]]==u[2];break;default:throw Error("Assertion error");}!this.G[D][q]&&O&&(this.i[D][q]=!this.i[D][q])}},12),13,14,15,16,17,18,19,19,20,21,22,24,25],[-1,1,1,1,2,2,4,4,4,5,5,5,8,9,9,10,10,11,13,14,16,17,17,18,20,21,23,25,26,28,29,31,33,35,37,38,40,43,45,47,49],[-1,1,1,2,2,4,4,6,6,8,8,8,10,12,16,12,17,16,18,21,20,23,23,25,27,29,34,34,35,38,40,43,45,48,51,53,56,59,62, +65,68],[-1,1,1,2,4,4,4,5,6,8,8,11,11,16,16,18,16,19,21,25,25,25,34,30,32,35,37,40,42,45,48,51,54,57,60,63,66,70,(C[h[0]].J=function(m,O,t,D){for(t=-2;t<=2;t++)for(D=-2;D<=2;D++)this.B(m+t,O+D,vh(Vc(D),Vc(t))!=1)},74),77,81]],C[h[0]].S=function(m,O,t,D,q,u,B,G,c){if(m.length!=TH((t=[(c=[0,2,1],0),8,1],C.P(this.version)/t[c[2]])))throw Error("Invalid argument");for(B=this.size-t[c[1]],G=t[c[0]];B>=t[c[1]];B-=c[1])for(B==6&&(B=5),O=t[c[0]];O<this.size;O++)for(D=t[c[0]];D<c[1];D++)u=(B+t[c[1]]&c[1])== +t[c[0]]?this.size-t[c[1]]-O:O,q=B-D,!this.G[u][q]&&G<m.length*t[c[2]]&&(this.i[u][q]=(m[G>>>3]>>>7-(G&7)&t[c[1]])!=t[c[0]],G++);if(G!=m.length*t[c[2]])throw Error("Assertion error");},C.Z=function(m,O,t,D,q,u,B,G){if(m<(D=[(G=["V",0,(q=[],"Degree out of range")],1),255,0],D[G[1]])||m>D[1])throw Error(G[2]);for(O=D[2];O<m-D[G[1]];O++)q.push(D[2]);for(t=(B=(q.push(D[G[1]]),D[2]),D[G[1]]);B<m;B++){for(u=D[2];u<q.length;u++)q[u]=C[G[0]](t,q[u]),u+D[G[1]]<q.length&&(q[u]^=q[u+D[G[1]]]);t=C[G[0]](2,t)}return q}, +24),18,22,20,24,28,26,24,20,30,24,28,28,26,30,28,30,30,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,17,28,22,16,22,28,26,26,24,28,24,28,22,24,24,30,28,28,26,28,30,24,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30]],C[h[0]].V=function(m,O,t,D,q,u,B,G,c,A,n){for(D=(B=this.j.J0<<(G=[0,6,1],n=[2,"B",10],3)|m,t=G[0],B);t<n[2];t++)D=D<<G[n[0]]^(D>>>9)*1335;if((q=(B<<n[2]|D)^21522,q)>>>15!=G[0])throw Error("Assertion error");for(O=G[0];O<=5;O++)this[n[1]](O,8,(q>>>O&G[n[0]])!=G[0]);for(A= +(this[((this[n[1]](7,8,(q>>>G[1]&G[n[0]])!=G[0]),this)[n[1]](8,8,(q>>>7&G[n[0]])!=G[0]),n)[1]](8,7,(q>>>8&G[n[0]])!=G[0]),9);A<15;A++)this[n[1]](8,14-A,(q>>>A&G[n[0]])!=G[0]);for(c=G[0];c<8;c++)this[n[1]](8,this.size-G[n[0]]-c,(q>>>c&G[n[0]])!=G[0]);for(u=8;u<15;u++)this[n[1]](this.size-15+u,8,(q>>>u&G[n[0]])!=G[0]);this[n[1]](this.size-8,8,!0)},e).A=function(m,O,t,D,q,u){if(!(t=["String contains non-numeric characters",(u=[1,"B",10],0),3],this.o).test(m))throw Error(t[0]);for(O=(D=t[u[0]],[]);D< +m.length;)q=RY(m.length-D,t[2]),Q(parseInt(m.substr(D,q),u[2]),q*t[2]+u[0],O),D+=q;return new e(e[u[1]].wv,m.length,O)},C).J=10,e).j=function(m,O){return m==(O=["X","V",""],O[2])?[]:this.o.test(m)?[e.A(m)]:this.G.test(m)?[e.P(m)]:[e[O[1]](e[O[0]](m))]},e.V=function(m,O,t,D,q,u){t=(D=P[u=["B",15,(O=[],"call")],4](u[1],m),D.next());try{for(;!t.done;t=D.next())Q(t.value,8,O)}finally{t&&!t.done&&(q=D.return)&&q[u[2]](D)}return new e(e[u[0]].BYTE,m.length,O)},C),e).P=function(m,O,t,D,q,u){if(!(t=[6,(q= +[],0),(u=[1,45,"charAt"],"String contains unencodable characters in alphanumeric mode")],this).G.test(m))throw Error(t[2]);for(D=t[u[0]];D+2<=m.length;D+=2)O=e.i.indexOf(m[u[2]](D))*u[1],O+=e.i.indexOf(m[u[2]](D+u[0])),Q(O,11,q);return D<m.length&&Q(e.i.indexOf(m[u[2]](D)),t[0],q),new e(e.B.ZD,m.length,q)},e)[h[0]].getData=function(){return this.wM.slice()},e).o=/^[0-9]*$/,e.K=function(m,O,t,D,q,u,B,G,c){D=P[(t=(c=["wM",4,"Vq"],0),c)[1]](15,O),u=D.next();try{for(;!u.done;u=D.next()){if(B=u.value, +G=B.mode[c[2]](m),B.hK>=1<<G)return Infinity;t+=c[1]+G+B[c[0]].length}}finally{u&&!u.done&&(q=D.return)&&q.call(D)}return t},e.i=L[h[1]],e.X=function(m,O,t,D,q){for(t=(D=(q=["charAt","push","charCodeAt"],[0,2,1]),m=encodeURI(m),O=D[0],[]);O<m.length;O++)if(m[q[0]](O)!="%")t[q[1]](m[q[2]](O));else t[q[1]](parseInt(m.substr(O+D[2],D[1]),16)),O+=D[1];return t},e.G=/^[A-Z0-9 $%*+.\/:-]*$/,e)}(k8||(k8={})),function(N){(function(C,e){C.i=(((e=function(L,h){this.Xb=(this.J0=h,L)},e).i=new e(0,1),e.No=new e(1, +0),e).dv=new e(2,3),e.HM=new e(3,2),e)})(N.N7||(N.N7={}))}(k8||(k8={})),k8)||(k8={})),new B2(400,580)),nq=((((((V=(T[40](6,Y5,eB),Y5.prototype),V).oz=function(){this.response.mobileToken=this.mobileToken},V.pu=function(N,C,e,L,h,Q,m,O,t){if(!(e=["n","iPod",(t=["h","inline-block","G"],m=this,"#Intent;scheme=https;action=android.intent.action.VIEW;end;")],this.Qy(C)))return v[44](32,this,e[0]),T[23](33);return(((L=((this.u=(this.T=(0,(Q=(this.F=U[43](59,1,W[35](13,12,C)),O=P[41](14,3,W[35](15,12,C)), +W)[38](8,4,W[35](14,12,C)),h=W[44](1,5,W[35](13,12,C)),this.url="https://recaptcha.net/qr/"+this.F,S[48](77,"",this.i,P[22](93,0,this.url)),B8).tj)(function(D,q,u,B,G,c,A,n,R,F,Z,X,Y){if(X=P[((F=["custom:",(Y=[(q=new gU(O),48),"i","B"],"/punctual"),0],q[Y[1]])[Y[1]]=Q,Y)[0]](27,q[Y[1]]),G=q[Y[2]],!G.startsWith("/punctual/"))throw Error("Invalid Punctual project path does not start with /punctual/: "+G);if((B=G.substring(10).split("/"),B.length)!==2)throw Error("Invalid Punctual path has an incorrect number of parts: "+ +G);if(D=(R=(u=P[4](11,B),u).next().value,u.next().value),R.startsWith(F[0]))A=R.substring(7),c=new sB(decodeURIComponent(A)),I[34](6,!0,c,F[1]),n={f0:c,Y7:c,BS:!1};else{if(Z=fR.get(R),!Z)throw Error("Invalid Punctual environment: '"+R+"'");n=Z}return y[26](1,null,F[2],1,!1,{V$:q.V$,H3:D,Xl:void 0,rz:q.rz,JE:q.JE,Oc:q.Oc},n,X)},23),qY)(),k8.N7).Y(this.url).jC(this[t[2]]),"To continue on your mobile device, enter the link ")+this.url+" in your mobile browser.",this[t[2]]).title=L,this.W&&(this.W.textContent= +L),this.EK())?(S[47](25)?(this.url="intent://recaptcha.net/qr/"+this.F+e[2],S[48](78,"",this.i,this.url)):(P[35](25,e[1])||S[22](14)&&Zf.navigator.maxTouchPoints>0)&&T[48](18,0,"16.4",v[16](51,"",1))>=0&&!h&&(this.url="https://appclip.apple.com/id?p=com.google.Recaptcha.VerifyClip&id="+this.F,S[48](75,"",this.i,this.url)),v[49](4,this),P[45](42,this,!1),this[t[0]]&&this.l&&(this[t[0]].style.display="none",this.l.style.display=t[1])):(v[49](5,this,!1),P[45](41,this),this[t[0]]&&this.l&&(this[t[0]].style.display= +t[1],this.l.style.display="none")),(0,B8.tj)(function(D){return T[19]((D=[1E3,12,2],D[1]),D[2],!1,3,D[0],m)},24)).then(function(D){v[44](32,(m.mobileToken=D,m),"r")}).catch(function(){return(v[44](32,m,"n"),T)[23](33)})},V).KI=function(N,C,e,L){return new (e=(N=RY((C=(L=[400,4,20],this.X||y[29](L[1],L[2])),C.height)-194,L[0],C.width),vh(N,300)),B2)(e,180+e)},Y5).prototype.xU=function(N,C,e){(e=["G","focus",null],this.EK())?(N=this.i)==e[2]||N[e[1]]():(C=this[e[0]])==e[2]||C[e[1]]()},V.Qy=function(N, +C,e,L,h,Q){if((C=[!1,(Q=[0,12,15],1),4],!N)||!TT(N)||!W[35](22,Q[1],N))return C[Q[0]];if(!(h=U[43](58,C[1],W[35](21,Q[1],N)),h)||h.length===0)return C[Q[0]];return(e=P[41](28,3,W[35](14,Q[1],N)),e&&e.length!==0)?(L=W[38](10,C[2],W[35](Q[2],Q[1],N)))&&L.length!==0?!0:!1:C[Q[0]]},V.rr=function(N,C){(C=[14,null,10],this).EK()?y[C[2]](58,f[13].bind(C[1],5),N):y[C[2]](26,W[40].bind(C[1],C[0]),N)},V).vm=function(N,C,e){this.h=(this.i=(this.W=(this.G=(C=(N=[0,"recaptchaJavascriptChallengeQrFallbackText", +(e=["getElementsByClassName",1,2],"recaptchaJavascriptChallengeQrCameraIcon")],P[4](e[2],W[17].bind(null,7),{EK:this.EK()})),eB.prototype.Yx.call(this,C),C[e[0]]("recaptchaJavascriptChallengeQrCanvas")[N[0]]),C[e[0]](N[e[1]]))[N[0]],C[e[0]]("recaptchaJavascriptChallengeQrButton")[N[0]]),C[e[0]](N[e[2]])[N[0]]),this.l=C[e[0]]("recaptchaJavascriptChallengeQrMobileIcon")[N[0]]},Y5.prototype).EK=function(N,C){return((C=[0,2,(N=["CriOS","AppleWebKit","Silk"],1)],eZ)&&Ie?Ie.mobile:!l[22](8,"Mobile",N[C[1]])&& +(I[C[2]](73,"iPod")||I[C[2]](94,"iPhone")||I[C[2]](79,"Android")||I[C[2]](76,"IEMobile")))||S[22](C[1])&&Zf.navigator.maxTouchPoints>C[0]||(I[C[2]](78,"iPad")||I[C[2]](90,"iPhone"))&&!T[45](24,"Safari")&&!S[C[2]](19,N[C[0]])&&!(U[38](33)?0:I[C[2]](90,"Coast"))&&!v[36](63,"FxiOS")&&I[C[2]](73,N[C[2]])||l[22](24,"Mobile",N[C[1]])&&!S[17](31,N[C[1]])},Y9()),vv=new B2(350,410),ML=(((((((((T[40](26,f6,eB),f6.prototype).Yx=function(N,C){this.h=(eB.prototype[(C=["call","Yx",16],C)[1]][C[0]](this,N),P[43](C[2], +"rc-prepositional-payload",this))},V=f6.prototype,V).Xd=function(N,C){return W[N=["rc-prepositional-select-more",!(C=[43,!1,41],0),4],C[2]](37,N[2],this.G,1).length-this.i.length<this.F?(this.Mp(N[1],P[C[0]](4,N[0],this)),N[1]):C[1]},V.xU=function(){P[43](4,"rc-prepositional-instructions",this).focus()},V.pu=function(N,C,e,L,h,Q,m,O){return this.l=(h=(((Q=(this[(O=[30,4,(L=[1,"rc-prepositional-instructions",3],"G")],this).i=(m=this,[]),O[2]]=U[13](O[0],C,an,7,rY),K[13](O[0],L[0],C)))&&v[12](68,L[2], +Q)&&(this.F=v[12](65,L[2],Q)),y)[10](42,H[O[0]].bind(null,18),this.h,{text:W[41](33,O[1],this[O[2]],L[0])}),T[0](6,L[1])),Vn)()<.5,K[18](59,this.l?"Select the phrases that are improperly formed:":"Select the phrases that sound incorrect:",h),this.Mp(!1),v[39](9,function(t,D){(K[D=[2,(t=["rc-prepositional-verify-failed","td",0],"KI"),34],D[2]](91,"h",m[D[1]](),m),y[45](1,!1,t[D[0]],t[1],"*",m),e)&&m.Mp(!0,P[43](15,t[0],m))},this),T[23](34)},V.oz=function(){(this.response[tK()]=this.i,this.response)[rz()]= +this.l?Ji():oU()},V).az=function(N,C,e){return e=["rc-prepositional-select-more","rc-prepositional-verify-failed"],!C&&N||e.forEach(function(L,h){(h=P[43](11,L,this),h!=N)&&this.Mp(!1,h)},this),N?eB.prototype.az.call(this,N,C):!1},f6.prototype.vm=function(N){this.B=(eB.prototype.vm[N=["v",null,"call"],N[2]](this),P[4](1,v[26].bind(N[1],4))),this.Yx(this[N[0]]())},f6).prototype.Vl=function(N){(eB[(N=[15,"prototype",32],N)[1]].Vl.call(this),y)[22](51,y[22](N[2],y[10](19,this),P[43](12,"rc-prepositional-tabloop-begin", +this),CR,function(){f[19](59,null)}),P[43](N[0],"rc-prepositional-tabloop-end",this),CR,function(){f[19](58,null,["rc-prepositional-select-more","rc-prepositional-verify-failed","rc-prepositional-instructions"])})},V).rr=function(N,C,e){(C=(e=[10,"G",1],W[41](e[2],4,this[e[1]],2)),y)[e[0]](58,W[49].bind(null,e[2]),N,{sources:C})},V.KI=function(N,C,e,L,h){return new (N=(e=(L=P[C=(h=["X",54,10],this)[h[0]]||y[29](7,20),47](h[1],this.h),RY(C.width-h[2],vv.width)),vh)(e,280),B2)(N,L.height+60)},T[40](2, +I9,eB),I9.prototype).s_=function(N){N&&U[29](22,!1,this)},I9).prototype.vm=function(N){this.B=((N=["prototype",3,32],eB[N[0]]).vm.call(this),P)[4](N[1],H[N[2]].bind(null,36)),this.Yx(this.v())},I9).prototype.pu=function(){return T[23](97)},I9.prototype.oz=function(N,C){(N=((C=["",5,"0"],this).response[tK()]=C[0],this.X))&&(this.response[De()]=l[46](C[1],8,C[2],C[0]+N.width+N.height))},oW());function Ub(N,C,e,L){return H[33].call(this,4,N,C,e,L)} +var wa=((T[0](87,Ub,jj),Ub.prototype).Iz=function(N,C){C=["G","Md","v"],N!=this.S&&(this.S=N,this[C[0]][C[1]](this[C[2]](),this.S))},function(){return T[41].call(this,31)}),rb=((((T[0](89,wa,(Ub.prototype.gq=function(){return this.S==1},Ub.prototype.Vl=(Ub.prototype.Tt=function(N){return N.keyCode==32&&(this.F(N),this.i(N)),!1},function(N,C){(C=["L",40,22],Ub[C[0]].Vl.call(this),this).I7&&(N=y[10](21,this),y[C[2]](C[1],N,this.v(),PV,this.i))}),Ub.prototype.i=function(N,C,e){((e=["i",33,"Iz"],N)[e[0]](), +C=this.S?rm:kr,this.isEnabled()&&!N.target.href)&&v[44](34,this,C)&&(N.preventDefault(),this[e[2]](this.S?!1:!0),v[44](e[1],this,iX))},La)),S)[42](85,wa),V=wa.prototype,V).Md=function(N,C,e,L){(L=[27,37,null],N)&&(e=U[18](24,L[2],this,C),v[36](1,N,e)||(P[20](4,Ib,function(h,Q){(Q=U[18](22,null,this,h),H)[7](11,N,Q==e,Q)},this),K[13](38,t4,N,P[L[1]](L[0],L[2],!0,C))))},V.cK=function(){return"goog-checkbox"},V).yY=function(N,C,e,L,h,Q){return(L=(h=(N=wa[(Q=(e=[!1,null,!0],[1,"L",2]),Q)[1]].yY.call(this, +N,C),U[19](35,N)),e[0]),S[9](47,h,U[18](19,e[Q[0]],this,e[Q[0]]))?L=e[Q[0]]:S[9](41,h,U[18](18,e[Q[0]],this,e[Q[2]]))?L=e[Q[2]]:S[9](41,h,U[18](23,e[Q[0]],this,e[0]))&&(L=e[0]),C.S=L,K)[13](26,t4,N,P[37](26,e[Q[0]],e[Q[2]],L)),N},V.B9=function(){return Ui},V.KP=function(N,C,e){return this[C=(e=["Md","ZS",6],N.A[e[1]](he,I[36](e[2],this,N).join(OY()))),e[0]](C,N.S),C},U[46](26,function(){return new Ub},"goog-checkbox"),l)[9](27,[""]),it=En(),pE=new ((((((((((V=(T[40](34,Xz,eB),Xz.prototype),V).vm= +function(N){(this[((N=["B",4,"call"],eB.prototype).vm[N[2]](this),N)[0]]=P[N[1]](6,P[11].bind(null,N[1])),this).Yx(this.v())},V).Yx=function(){this.l=P[43](3,"rc-2fa-payload",this)},V).xU=function(N,C){N=(C=[15,0,48],P[43](11,"rc-2fa-error-message",this)||P[43](C[0],"rc-2fa-instructions",this)),!N||uv&&T[C[2]](13,C[1],10,BB)>=C[1]||N.focus()},V).RW=function(){return this.T||""},V).Vl=function(N,C){((C=["prototype",(N=this,21),59],eB[C[0]].Vl.call(this),y[22](36,y[22](47,y[10](C[1],this),T[0](30,"rc-2fa-tabloop-begin"), +CR,function(){f[19](61,null)}),T[0](C[2],"rc-2fa-tabloop-end"),CR,function(){f[19](57,null,["rc-2fa-error-message","rc-2fa-instructions"])}),W[48](50,this.h,document),y)[22](63,y[10](C[1],this),this.h,g0,this.WM),this.G).I6(!1),y[22](49,y[10](17,this),this.G,y0,function(e){(e=[!1,"G",29],N[e[1]].I6(e[0]),U)[e[2]](2,e[0],N,"t")}),y[22](52,y[10](C[1],this),this.u,y0,function(){return v[44](35,N,"l")})},V).KI=function(){return this.X?new B2(this.X.width,this.X.height):new B2(0,0)},V.Mp=function(){}, +V.r0=function(){},V).WM=function(N){return K[0].call(this,2,N)},V.pu=function(N,C,e,L,h,Q,m,O,t,D,q){if((D=[7,!0,"style"],q=(m=this,[2,"G",32]),t=C.hm(),C).kx()==10)return this.T=C.i(),v[39](q[2],function(){v[44](33,m,"s")},this),T[23](65);return((((Q=(((((O=U[13](23,t,O9,5),O)!=null&&(L=W[26](4,null,D[0],O)||new dr(rb[0]),S[12](28,"",9,D[q[0]],"*",L,this.l)),y[10](26,K[15].bind(null,38),this.l,{identifier:S[49](22,1,t),cj:e,RF:v[28](28,f[29](3,t,4)),De:W[4](11,t,D[0])==q[0]?"phone":"email"}),K)[34](43, +"h",this.KI(),this,D[1]),this.i).render(P[43](q[0],"rc-2fa-response-field",this)),this.i.v().setAttribute(JK(),T[8](16,q[0],t)),this).i.clear(),y[30](37,this.i,D[1]),P[43](3,"rc-2fa-submit-button-holder",this)),h=P[43](12,"rc-2fa-cancel-button-holder",this),this)[q[1]].render(Q),this).u.render(h),y)[22](36,y[10](20,this),this.i.v(),LR,function(u){(u=["G",48,8],m).i.getValue().length==T[u[2]](u[1],2,t)?m[u[0]].I6(!0):m[u[0]].I6(!1)}),T)[23](65)},V).Xd=function(N){return(N=[15,"rc-2fa-instructions", +!1],S[23](N[0],this.i.getValue()))?(P[43](16,N[1],this).focus(),!0):N[2]},V).oz=function(N){((N=[!1,"i","gq"],this.response[Ue()]=this[N[1]].getValue(),this.response)[P6()]=this.F[N[2]](),y)[30](4,this[N[1]],N[0])},B2)(302,422),VB=((((T[40](38,fC,kJ),fC).prototype.render=function(N,C,e,L,h,Q,m){(((h=(Q=(m=["appendChild",2,29],P[4](3,H[9].bind(null,m[1]),{hE:C,n7:pl})),S[m[2]](55,P[48](36,aY,Q)[0],lc),gA[L]),U)[34](4,"px",Q,h),this).o[m[0]](Q),f)[6](3,"Safari",0,this,h,e,N,f[28](4,!0,Q))},fC).prototype.u= +function(){return this.K},fC.prototype.I=function(N,C,e,L,h){this[(L=(H[h=["o",0,2],e=[0,null,"px"],18](h[2],e[1],this),this.G=KU,P[4](6,f[22].bind(null,34),{Tk:U[31](5,e[1],N),hE:C,n7:pl})),S[29](51,P[48](5,HJ,L)[e[h[1]]],{width:pE.width+e[h[2]],height:pE.height+e[h[2]]}),S[29](67,P[48](4,EC,L)[e[h[1]]],TE),S[29](35,P[48](6,aY,L)[e[h[1]]],lc),S[29](51,P[48](3,aY,L)[e[h[1]]],"display","block"),h)[0]].appendChild(L)},fC).prototype.j=function(N,C,e,L){(e=vh(S[C=(L=[1.5,null,"j"],C===void 0?!1:C),41](50, +0,this).width-K[4](8,L[1],this).x,K[4](5,L[1],this).x),N)?kJ.prototype[L[2]].call(this,N,C):e>gA[xe()].width*L[0]?kJ.prototype[L[2]].call(this,R$,C):kJ.prototype[L[2]].call(this,void 0,C)},A1()),dx=o8(),JX=FH(),TB=sh(),gx=ZV(),a4=ZJ(),E4=(tR[dx]={display:HM(),transition:Aj(),position:On(),bottom:Xr(),right:gx,"box-shadow":Gf(),"border-radius":fT(),overflow:OR()},tR[VB]={display:HM(),transition:lh(),position:On(),bottom:Xr(),left:gx,"box-shadow":Gf(),"border-radius":fT(),overflow:OR()},tR[JX]={"box-shadow":Gf()}, +tR[TB]={position:On(),visibility:OR()},tR),et=[VB,dx],MT=((((T[40](56,Pi,kJ),Pi.prototype).render=function(N,C,e,L,h,Q,m){((h=((this[((m=[12,"B",(Q=[0,"px","Safari"],48)],this).style=E4.hasOwnProperty(this.T)?this.T:dx,S[9](45,et,this.style)&&S[4](6,Q[0]))&&(this.style=TB),m[1]]=P[4](4,K[31].bind(null,32),{hE:C,n7:pl,style:this.style}),S)[29](67,P[m[2]](35,aY,this[m[1]])[Q[0]],lc),gA)[L],U[34](1,Q[1],this[m[1]],h),this.o.appendChild(this[m[1]]),f)[6](2,Q[2],Q[0],this,h,e,N,f[28](m[0],!0,this[m[1]])), +P)[22](57,this[m[1]],"display")=="none"&&(S[29](39,this[m[1]],E4[TB]),this.style=dx),S[29](19,this[m[1]],E4[this.style])},Pi.prototype.u=function(){return this.o},Pi.prototype).I=function(N,C,e,L,h){this[L=(this.G=(H[(h=[null,"o",18],h)[2]](5,h[0],this),KU),P[4](4,I[16].bind(h[0],2),{Pj:e})),h[1]].appendChild(L)},T)[40](2,YU,TN),Error)("Timeout"),tr=function(N,C,e,L,h){return l[21].call(this,19,C,h,e,L,N)},X2,yn=!1,jL,Sw,i5=!1,Bj=new WeakMap; +function YD(N,C,e,L,h){return H[32].call(this,3,N,C,e,L,h)}function WH(N,C,e,L,h,Q,m,O,t,D,q){return v[23].call(this,10,N,C,e,L,h,Q,m,O,t,D,q)} +var Ij=MW(),Od=fe(),IG=FC(),vi=u7(),RG=Ft(),Fy=Sz(),Zy=CT(),ld=yv(),nC=PF(),Tw=Ye(),Bz=Uj(),z5=PW(),Ch=(tI.prototype.toString=(tI.prototype.add=function(N,C,e,L,h,Q,m,O,t,D){if(h=[!1,22480,(D=["i",0,31],4294967296)],this.B<=D[1])return h[D[1]];for(t=(O=(Q=(e=h[D[1]],Vc(y[14](9,N))),y)[D[2]](43,Q,1013904223,1664525,h[2]),D[1]);t<13;t++)C=TH(O()*h[2])%h[1],L=C>>3,m=this[D[0]][L],this[D[0]][L]|=1<<(C&7),m!==this[D[0]][L]&&(e=!0);return e&&this.B--,!0},function(N,C,e,L,h,Q,m,O,t,D,q,u){for(C=(Q=(O=(h= +(D=(e="",[8,4,1008]),u=["i",16515072,258048],this[u[0]].byteLength),h%3),h-O),0);C<Q;C+=3)q=this[u[0]][C]<<16|this[u[0]][C+1]<<D[0]|this[u[0]][C+2],m=(q&u[1])>>18,L=(q&4032)>>6,t=q&63,N=(q&u[2])>>12,e+=z5[m]+z5[N]+z5[L]+z5[t];return(O==1?(q=this[u[0]][Q],e+=z5[(q&252)>>2]+z5[(q&3)<<D[1]]):O==2&&(q=this[u[0]][Q]<<D[0]|this[u[0]][Q+1],e+=z5[(q&64512)>>10]+z5[(q&D[2])>>D[1]]+z5[(q&15)<<2]),this).G+e}),XM()),Vp=ZJ(),eW=new Map([[0,"no-error"],[2,"challenge-expired"],[3,"invalid-request-token"],[4,"invalid-pin"], +[5,"pin-mismatch"],[6,"attempts-exhausted"],[10,"aborted"]]),OF=(zJ.prototype.Qy=function(){return this.B},tF()),tw=QR(),Dj=XG(),L6=hK(),er=U8(),hq=uD(),OK=Ce(),QJ=aa(),mi=p4(),C6=Object.defineProperty,Nr=Object.getOwnPropertyNames,Tt=Number.MAX_SAFE_INTEGER,tl=Promise.resolve(),H8=xk(),tS=(Ar.prototype.I=U[3](42,(((((((((((V=((Ar.prototype.Hm=(((V=(Ar.prototype.lI=(((V=Ar.prototype,V.dispose=(Ar.prototype.Xe=function(N,C,e,L,h,Q){(L=(N=(Q=[32,"i",36],C=this,e=H[15](Q[2],this),h=v[4](Q[0],this),P[2](17, +this)),this.Fe.bind(this,this[Q[1]][Q[1]]+h,N)),this).Pm[e]=function(){var m=aq.apply(0,arguments);C.h.run(function(){return L.apply(null,T[5](73,m))})}},function(N,C,e,L,h,Q,m,O,t,D){for(h=(O=(m=(D=undefined,[22,8,(Q=23,60)]),49),!1);;)try{if(O==m[0])break;else if(O==90)O=42;else if(O==71)U[47](6,0,this,e.value),O=40;else if(O==36)Q=m[1],O=90;else if(O==m[2])Q=23,e&&!e.done&&(N=C.return)&&N.call(C),O=54;else if(O==15)C=P[4](10,this.K),e=C.next(),O=36;else if(O==40)e=C.next(),O=42;else if(O==7)Q= +23,this.K.length=0,O=m[0];else if(O==42)O=e.done?m[2]:71;else if(O==49)O=this.K.length>0?15:m[0];else if(O==54)D!==undefined?(O=D,D=undefined):O=7;else if(O==75)throw t;}catch(q){if((t=q,Q)==23)throw q;Q==m[1]&&(D=75,O=m[2])}}),Ar.prototype.Ku=function(N,C,e,L){(e=(L=[59,"i",54],N=v[4](2,this),C=y[34](L[0],this),y[34](L[2],this)),C)==e&&T[0](3,N,this[L[1]])},V.KJ=function(N,C,e,L,h,Q){return y[2].call(this,1,N,C,e,L,h,Q)},V.R5=function(N,C,e){return f[27].call(this,15,N,C,e)},V.LV=function(N,C,e, +L,h){return P[48].call(this,64,N,C,e,L,h)},V).o5=function(N,C){return K[49].call(this,1,N,C)},V).hM=function(N,C){return U[43].call(this,1,N,C)},Ar.prototype.Fe=function(N,C){U[47](66,0,this,new vH(C,N,aq.apply(2,arguments),1,null))},function(N,C,e,L,h){for(h=(L=[92,79,16],80);h!=L[0];)h==11?(C.push(f[1](67,this)),h=1):h==80?(C=[],e=0,h=4):h==L[2]?(this.iI(C),h=L[0]):h==4?h=L[1]:h==1?(e++,h=L[1]):h==L[1]&&(h=e<N?11:L[2])}),V.AM=function(){return I[15].call(this,23)},Ar).prototype,V).Bw=function(N, +C){return S[48].call(this,16,N,C)},V.UC=function(N,C,e){return U[29].call(this,12,N,C,e)},Ar.prototype.hO=function(N,C,e,L){(e=(C=v[L=[33,34,66],4](L[0],this),N=y[L[1]](60,this),y[L[1]](59,this)),N)<e&&T[0](L[2],C,this.i)},V.A0=function(N,C,e,L,h){return S[2].call(this,50,N,C,e,L,h)},V.fV=function(){return l[26].call(this,7)},Ar.prototype.S_=function(N,C,e,L,h){this[(N>(L=(C=(e=(h=[34,62,"Pm"],H)[15](4,this),y[h[0]](h[1],this)+""),0),1)&&(L=y[h[0]](56,this)),h)[2]][e]=y[14](7,C,L)},V.Hc=function(N, +C){return I[26].call(this,31,N,C)},V.ik=function(N,C,e,L){return K[4].call(this,14,N,C,e,L)},V).xq=function(N,C){return U[40].call(this,6,N,C)},function(N,C){N=(C=H[15](1,this),y[34](61,this)),this.Pm[C]=!N}),V.wZ=function(N){return S[3].call(this,26,N)},V.iK=function(){return H[28].call(this,16)},V).pV=function(N,C,e,L,h,Q,m,O,t,D,q){return I[29].call(this,5,N,C,e,L,h,Q,m,O,t,D,q)},V.qh=function(N,C){return U[43].call(this,8,N,C)},Ar.prototype),V.Zg=function(N){return I[16].call(this,1,N)},V).Pw= +function(N,C,e,L,h,Q,m){return y[18].call(this,2,N,C,e,L,h,Q,m)},V.mo=function(N,C,e,L,h,Q){return U[11].call(this,10,N,C,e,L,h,Q)},V.H9=function(){return W[5].call(this,66)},V).Vd=function(N){return T[38].call(this,1,N)},V.Wc=function(N,C,e){return H[21].call(this,9,N,C,e)},V).Ta=function(){return l[16].call(this,16)},V.a5=function(N,C){return I[26].call(this,7,N,C)},V.nR=function(){return S[14].call(this,7)},V).zz=function(N){return S[25].call(this,9,N)},V).eC=function(N,C,e,L,h){return y[26].call(this, +4,N,C,e,L,h)},V).aC=function(N){return v[21].call(this,17,N)},V).rZ=function(N,C){return T[26].call(this,5,N,C)},V.CV=function(N,C,e,L,h,Q){return S[18].call(this,1,N,C,e,L,h,Q)},V).yd=function(N,C,e,L){return K[35].call(this,9,N,C,e,L)},V).tM=function(){return S[5].call(this,32)},V.qm=function(){return I[15].call(this,80)},V).Ju=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){return T[45].call(this,27,N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n)},V.OG=function(N,C,e,L,h,Q){return W[30].call(this,23,N,C,e,L,h, +Q)},V.Gz=function(N,C,e){return v[20].call(this,10,N,C,e)},2048)),new WeakMap),Bh=(T[40](3,((tP.prototype.i=function(N){return l[N=N===void 0?Tt:N,35](64,0,tS.get(this),N)},tP).prototype.dispose=function(){tS.get(this).dispose()},Qr),p),Qr.prototype.D=f[38](75,[0,sI,i_]),$O(),ex)(),bo=lF(),g6=R_(),SY=Me(); +(((((((((((((V=(Qw(),Hw(),Yx).prototype,Yx.prototype.j_=function(N,C,e,L,h){return P[44](41,(e=this,function(Q,m,O){O=[31,(m=[4,1,5],"i"),3];switch(Q.B){case m[1]:return c_=N.G,v[34](18,0,10,N.o),Zf.window[Bh][xQ()]=Zf.window[Bh][xQ()]||N.K,Q[O[1]](xR(U[41](33),I[13](98)),2);case 2:return h=Q.G,Q[O[1]](aJ(),O[2]);case O[2]:if(!Array.isArray(N[L=Q.G,C=void 0,O[1]])||!N[O[1]].length){Q.js(m[0]);break}return Q[O[1]](gM(U[41](1),void 0,void 0,N[O[1]]),m[2]);case m[2]:C=Q.G,C=S[O[0]](44,C.CD());case m[0]:return e.I&& +(U[35](1,"load",!0,0,N.B,e),e.I=!1),Q.return(new VC(S[O[0]](52,h.CD()),S[O[0]](28,L.CD()),C))}}))},Yx.prototype.rq=function(N,C){C=[null,16,23],P[C[2]](4,500,0,this.B,N.visible,N.n0),this.G.then(function(e){return e.send(Bf,N)}).catch(l[2].bind(C[0],C[1]))},Yx.prototype).C=function(){P[1](1,!0,this,2)},Yx.prototype).Ku=function(N,C,e,L,h){(C=(N.i[(h=[0,10,(e=[!0,0,10],1)],Nw)()]=String(T[27](5,e[h[2]],e[2],this)),U[31](h[2],null,l[28](23,null,e[h[0]],ci,new fz(N.i[g$()])))),S)[h[1]](2,e[h[2]],h[2], +N.B,this.Z,C,N.i,this.B),(L=S[21](6,e[h[0]],this.B))&&K[26](12,PV,L,function(){this.G.then(function(Q){return Q.send(cf)}).catch(l[2].bind(null,24))},!1,this)},V).Xa=function(N,C,e,L,h,Q,m,O){return y[29].call(this,19,N,C,e,L,h,Q,m,O)},Yx.prototype.O=function(N,C,e,L,h,Q,m,O,t){return Q=(L=(N=(O=(t=[49,(h=new Date,58),(m=[4,null,1],2)],e=K[22](1,m[1]))?e:P[t[2]](t[2],20,0,m[1]),C=new Date-h,new Qr),P[0](76,N,O,m[t[2]])),K[23](t[1],t[2],C,L)),W[39](t[0],m[0],Q.G2())},Yx).prototype.R=function(N,C,e, +L,h){(L=(C=(h=[null,0,4],e=[96,0,!1],e[1]),N&&(C=P[13](25,"HEADER",h[0],16,e[h[1]])),K[37](h[2],e[2],"Edge","FxiOS","Silk")),this.G).then(function(Q){Q.send(Ju,new eF(L.i,L.B,C,L.G))}).catch(l[2].bind(h[0],32))},V).bY=function(N){return U[28].call(this,24,N)},V).I5=function(N,C){return I[21].call(this,10,N,C)},Yx).prototype.W=function(N,C,e,L,h,Q,m,O,t,D,q,u,B){if((N.iQ&&(this.j=N.iQ),Q=(B=["Z",(C=[null,36,""],"S"),"P"],this),Array.isArray(N.B))&&N.B.length>0)try{t=N.B.map(function(G){return new lI(G)}), +D={iQ:(q=this.j)!=C[0]?q:"",origin:(O=I[6](37,this.i,kd))!=C[0]?O:""},this[B[2]]=H[46](2,function(G,c){return(c={},G&&(c[Cu.getName()]=G),Q).V(Q.Xa.bind(Q,h5,c,void 0,!0))},function(G,c){return c=["P","B","i"],G=Q[c[1]],!!G[c[0]]&&!!G[c[2]]&&I[49](18,"",G[c[2]])==="visible"},I[6](37,this.i,SX)||C[2],D,t),l[45](25,"fetch",!0,this[B[2]].i)}catch(G){this[B[2]]=C[0]}try{L=gk(N.i),e=new B0,e.init(L),T[29](4,C[0],L,26,void 0,rY)&&P[30](8,2,this,0,!0),T[22](2,C[1],L,rY)&&this[B[1]]&&(v[22](56,C[0],!0,24, +this[B[1]],T[22](2,C[1],L,rY)),u=l[42](1,this[B[1]]),(m=(h=this.K)==C[0]?void 0:h.B)&&(m[rN()]=u)),this[B[0]]=y[29](2,!1,e,Kp)}catch(G){}},V).UG=function(N,C,e){return K[2].call(this,14,N,C,e)},Yx.prototype.o6=function(N){(((N=[40,"G",1],l[23](N[2],this.id).value="",this.i).has(WP)&&W[4](N[0],this.i,WP,!0)(),P)[N[2]](16,!0,this),this[N[1]]).then(function(C){return C.send(Uk)}).catch(l[2].bind(null,N[0]))},Yx.prototype).V=function(N){var C=["apply","u",25];return B8.Hn[C[0]](null,[N,3,this[C[1]].bind(this)].concat(T[5](C[2], +aq[C[0]](1,arguments))))},Yx).prototype.u=function(N,C,e){(0,(e=[29,10,5],B8).h2)(N),I[28](e[1],2,"",C,T[e[0]](e[2],null,N,4),this)},Yx.prototype.iI=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n,R,F,Z,X,Y){Y=[8,(e=new Map,c=new Set,"startTime"),24],u=N.i;try{B=P[4](15,performance.getEntriesByType(qB())),G=B.next();try{for(;!G.done;G=B.next()){h=(O=(D=G.value,P[4](10,u)),O.next());try{for(;!h.done;h=O.next())F=h.value,m=F[0],D.name.includes(m)&&(R=e,Q=R.set,A=new UO,Z=y[44](Y[0],1,A,Number(F[1])),n=ae(D.duration), +L=H[38](3,Z,K[Y[2]](7,n),2),q=ae(D[Y[1]]),X=H[38](2,L,K[Y[2]](21,q),3),Q.call(R,m,S[31](44,X)))}finally{h&&!h.done&&(C=O.return)&&C.call(O)}try{c.add((new sB(D.name)).i)}catch(k){}}}finally{G&&!G.done&&(t=B.return)&&t.call(B)}}catch(k){}return new IO(c,e)},Yx).prototype.T=function(N,C,e,L,h,Q,m){(h=(((Q=(this.o=new ((C=[1,2,(m=[0,(e=this,17),1],0)],this).K=this.K||new Hv,tP)(this.K.B,N.HS,N.w$,function(O){e.G.then(function(t){return t.send(b9,new Mf(O))}).catch(l[2].bind(null,48))}),U[21](m[1],C[m[2]], +P[27](4,C[m[0]],new bR,N.YU),N.tE)),S)[45](6,C[2],Q,this.o),N.OK&&N.d$)&&(L=U[21](6,C[m[2]],P[27](6,C[m[0]],new bR,N.OK),N.d$),S[45](10,C[2],L,this.o)),U[21](18,C[m[2]],P[27](5,C[m[0]],new bR,N.uK),N.z4)),S)[45](4,C[2],h,this.o)},Yx.prototype).l=function(N,C,e,L){((((e=[!0,(L=[28,2,"G"],5),0],N.IB)&&I[L[0]](26,L[1],"",N,null,this),l[23](3,this.id)).value=N.response,N[L[2]])&&U[10](16,NP,N[L[2]],e[L[1]]),N.i&&(C=N.i,U[10](50,S[4](16,"_"),C,e[L[1]])),N).response&&this.i.has($q)&&W[4](42,this.i,$q,e[0])(N.response), +N.o&&W[21](1,"https:",3,"",e[1],N.o)},V.Qp=function(N,C){return T[12].call(this,3,N,C)},Zf).window&&Zf.window[OQ()]&&P[16](1,"load","onload",null,0);function lD(N,C,e){return W[11].call(this,1,N,C,e)} +var db=(T[0](94,lD,kR),[]).concat([128],l[39](13,0,127)),iz=v[5](11,2,1,(lD.prototype.update=(lD.prototype.digest=function(N,C,e,L,h,Q,m,O,t,D,q,u){if(m=[112,(u=[0,2,"tO"],8),255],this.P)throw Error("this hasher needs to be reset");for(this.G<m[e=this.K*m[1],u[0]]?this.update(db,m[u[0]]-this.G):this.update(db,this.B-this.G+m[u[0]]),Q=127;Q>=m[u[0]];Q--)this.o[Q]=e&m[u[1]],e/=256;for(O=(t=(l[4](10,23,this),u)[0],Array(m[1]*this.V)),D=u[0];D<this.V;D++){for(h=(q=(C=24,L=this.i[D],L).m,L[u[2]]);C>=u[0];C-= +m[1])O[t++]=q>>C&m[u[1]];for(N=24;N>=u[0];N-=m[1])O[t++]=h>>N&m[u[1]]}return this.P=!0,O},lD.prototype.A=function(N,C,e){for(var L=[0,"m","tO"],h=[1,4294967296,2147483648],Q=arguments.length-h[L[0]],m=(N[L[2]]^h[2])+(C[L[2]]^h[2]),O=N[L[1]]+C[L[1]];Q>=2;--Q)m+=arguments[Q][L[2]]^h[2],O+=arguments[Q][L[1]];return new ((O+=arguments.length>>h[L[0]],arguments.length&h[L[0]])&&(m+=h[2]),O+=TH(m/h[1]),mu)(O,m)},lD.prototype.reset=function(N){this.P=((this[N=[37,"G","K"],N[1]]=0,this[N[2]]=0,this).i=v[40](N[0], +this.j),!1)},function(N,C,e,L,h,Q,m,O,t,D){if((L=(m=C!==void 0?C:N.length,["this hasher needs to be reset",0,(D=[1,22,2],255)]),this).P)throw Error(L[0]);if((h=this.G,typeof N)==="string")for(t=L[D[0]];t<m;t++){if((e=N.charCodeAt(t),e)>L[D[2]])throw Error("Characters must be in range [0,255]");this.o[h++]=e,h==this.B&&(l[4](9,23,this),h=L[D[0]])}else if(l[D[1]](D[0],"object",N))for(Q=L[D[0]];Q<m;Q++){if((O=N[Q],typeof O!=="number")||O<L[D[0]]||O>L[D[2]]||O!=(O|L[D[0]]))throw Error("message must be a byte array"); +this.o[h++]=O,h==this.B&&(l[4](8,23,this),h=L[D[0]])}else throw Error("message must be string or array");(this.K+=m,this).G=h}),[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774, +944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460, +2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614, +3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591])),TO=[1779033703,4089235720,3144134277,2227873595,1013904242,4271175723,2773480762,1595750129,1359893119,2917565137,2600822924,725511199,528734635,4215389547,1541459225,(T[40](60, +Ew,lD),327033209)],n$=(function(){globalThis.scrypt=function(T,ca,K,h,ia,L,U,da){function V(b){function c(H){for(var W=0,X=H.length;64<=X;){var u,l,m=e,x=a,y=g,C=f,n=k,v=p,z=q,D=A;for(l=0;l<16;l++){var r=W+4*l;B[l]=(255&H[r])<<24|(255&H[r+1])<<16|(255&H[r+2])<<8|255&H[r+3]}for(l=16;l<64;l++){r=((u=B[l-2])>>>17|u<<15)^(u>>>19|u<<13)^u>>>10;var E=((u=B[l-15])>>>7|u<<25)^(u>>>18|u<<14)^u>>>3;B[l]=(r+B[l-7]|0)+(E+B[l-16]|0)|0}for(l=0;l<64;l++)r=(((n>>>6|n<<26)^(n>>>11|n<<21)^(n>>>25|n<<7))+(n&v^~n&z)| +0)+(D+(d[l]+B[l]|0)|0)|0,E=((m>>>2|m<<30)^(m>>>13|m<<19)^(m>>>22|m<<10))+(m&x^m&y^x&y)|0,D=z,z=v,v=n,n=C+r|0,C=y,y=x,x=m,m=r+E|0;e=e+m|0;a=a+x|0;g=g+y|0;f=f+C|0;k=k+n|0;p=p+v|0;q=q+z|0;A=A+D|0;W+=64;X-=64}}var d=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808, +3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],e=1779033703,a=3144134277,g=1013904242,f=2773480762,k=1359893119,p=2600822924,q=528734635,A=1541459225, +B=Array(64);c(b);var I=b.length%64;var M=b.length/536870912|0,N=b.length<<3,ea=I<56?56:120;b=b.slice(b.length-I,b.length);b.push(128);for(I+=1;I<ea;I++)b.push(0);return b.push(M>>>24&255),b.push(M>>>16&255),b.push(M>>>8&255),b.push(M>>>0&255),b.push(N>>>24&255),b.push(N>>>16&255),b.push(N>>>8&255),b.push(N>>>0&255),c(b),[e>>>24&255,e>>>16&255,e>>>8&255,e>>>0&255,a>>>24&255,a>>>16&255,a>>>8&255,a>>>0&255,g>>>24&255,g>>>16&255,g>>>8&255,g>>>0&255,f>>>24&255,f>>>16&255,f>>>8&255,f>>>0&255,k>>>24&255, +k>>>16&255,k>>>8&255,k>>>0&255,p>>>24&255,p>>>16&255,p>>>8&255,p>>>0&255,q>>>24&255,q>>>16&255,q>>>8&255,q>>>0&255,A>>>24&255,A>>>16&255,A>>>8&255,A>>>0&255]}function ja(b,c,d){function e(){for(var q=g-1;g-4<=q&&!(f[q]++,f[q]<=255);q--)f[q]=0}64<b.length&&(b=V(b.push?b:Array.prototype.slice.call(b,0)));var a,g=64+c.length+4,f=Array(g),k=Array(64),p=[];for(a=0;a<64;a++)f[a]=54;for(a=0;a<b.length;a++)f[a]^=b[a];for(a=0;a<c.length;a++)f[64+a]=c[a];for(a=g-4;a<g;a++)f[a]=0;for(a=0;a<64;a++)k[a]=92;for(a= +0;a<b.length;a++)k[a]^=b[a];for(;32<=d;)e(),p=p.concat(V(k.concat(V(f)))),d-=32;return 0<d&&(e(),p=p.concat(V(k.concat(V(f))).slice(0,d))),p}function ka(b,c,d,e){var a,g=b[0]^c[d++],f=b[1]^c[d++],k=b[2]^c[d++],p=b[3]^c[d++],q=b[4]^c[d++],A=b[5]^c[d++],B=b[6]^c[d++],I=b[7]^c[d++],M=b[8]^c[d++],N=b[9]^c[d++],ea=b[10]^c[d++],H=b[11]^c[d++],W=b[12]^c[d++],X=b[13]^c[d++],u=b[14]^c[d++],l=b[15]^c[d++],m=g,x=f,y=k,C=p,n=q,v=A,z=B,D=I,r=M,E=N,O=ea,Y=H,Z=W,aa=X,ba=u,P=l;for(d=0;d<8;d+=2)m^=(a=(Z^=(a=(r^=(a= +(n^=(a=m+Z)<<7|a>>>25)+m)<<9|a>>>23)+n)<<13|a>>>19)+r)<<18|a>>>14,v^=(a=(x^=(a=(aa^=(a=(E^=(a=v+x)<<7|a>>>25)+v)<<9|a>>>23)+E)<<13|a>>>19)+aa)<<18|a>>>14,O^=(a=(z^=(a=(y^=(a=(ba^=(a=O+z)<<7|a>>>25)+O)<<9|a>>>23)+ba)<<13|a>>>19)+y)<<18|a>>>14,P^=(a=(Y^=(a=(D^=(a=(C^=(a=P+Y)<<7|a>>>25)+P)<<9|a>>>23)+C)<<13|a>>>19)+D)<<18|a>>>14,m^=(a=(C^=(a=(y^=(a=(x^=(a=m+C)<<7|a>>>25)+m)<<9|a>>>23)+x)<<13|a>>>19)+y)<<18|a>>>14,v^=(a=(n^=(a=(D^=(a=(z^=(a=v+n)<<7|a>>>25)+v)<<9|a>>>23)+z)<<13|a>>>19)+D)<<18|a>>>14,O^= +(a=(E^=(a=(r^=(a=(Y^=(a=O+E)<<7|a>>>25)+O)<<9|a>>>23)+Y)<<13|a>>>19)+r)<<18|a>>>14,P^=(a=(ba^=(a=(aa^=(a=(Z^=(a=P+ba)<<7|a>>>25)+P)<<9|a>>>23)+Z)<<13|a>>>19)+aa)<<18|a>>>14;c[e++]=b[0]=m+g|0;c[e++]=b[1]=x+f|0;c[e++]=b[2]=y+k|0;c[e++]=b[3]=C+p|0;c[e++]=b[4]=n+q|0;c[e++]=b[5]=v+A|0;c[e++]=b[6]=z+B|0;c[e++]=b[7]=D+I|0;c[e++]=b[8]=r+M|0;c[e++]=b[9]=E+N|0;c[e++]=b[10]=O+ea|0;c[e++]=b[11]=Y+H|0;c[e++]=b[12]=Z+W|0;c[e++]=b[13]=aa+X|0;c[e++]=b[14]=ba+u|0;c[e++]=b[15]=P+l|0}function fa(b,c,d,e,a){for(var g= +0,f=d+16*(2*a-1),k=16;k--;)b[g++]=c[f++];for(g=0;g<2*a;g+=2)ka(b,c,d+16*g,e+8*g),ka(b,c,d+16*g+16,e+8*g+16*a)}function la(b){for(var c=[],d=0;d<b.length;d++){var e=b.charCodeAt(d);if(e<128)c.push(e);else{if(e<2048)c.push(192|e>>6);else{if(e<55296)c.push(224|e>>12);else{if(d>=b.length-1)throw Error("invalid string");d++;e=(1023&e)<<10;e|=1023&b.charCodeAt(d);e+=65536;c.push(240|e>>18);c.push(128|e>>12&63)}c.push(128|e>>6&63)}c.push(128|63&e)}}return c}function ma(b){for(var c=0;c<32*h;c++){var d=b+ +4*c;t[F+c]=(255&G[d+3])<<24|(255&G[d+2])<<16|(255&G[d+1])<<8|(255&G[d+0])<<0}}function na(b,c){for(;b<c;b+=2){for(var d=S,e=32*h*b,a=t,g=F,f=32*h;f--;)d[e++]=a[g++];fa(ha,t,F,Q,h);d=S;e=32*h*(b+1);a=t;g=Q;for(f=32*h;f--;)d[e++]=a[g++];fa(ha,t,Q,F,h)}}function oa(b,c){for(;b<c;b+=2){var d=t[F+16*(2*h-1)]&J-1,e=t,a=F,g=S;d*=32*h;for(var f=32*h;f--;)e[a++]^=g[d++];fa(ha,t,F,Q,h);d=t[Q+16*(2*h-1)]&J-1;e=t;a=Q;g=S;d*=32*h;for(f=32*h;f--;)e[a++]^=g[d++];fa(ha,t,Q,F,h)}}function pa(b){for(var c=0;c<32*h;c++){var d= +t[F+c];G[b+4*c+0]=d>>>0&255;G[b+4*c+1]=d>>>8&255;G[b+4*c+2]=d>>>16&255;G[b+4*c+3]=d>>>24&255}}function qa(b,c,d,e,a){(function f(){ra(function(){e(b,b+d<c?b+d:c);(b+=d)<c?f():a()})})()}function sa(b){var c=ja(T,G,ia);return"base64"===b?function(d){for(var e,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),g=d.length,f=[],k=0;k<g;)e=((k<g?d[k++]:0)<<16)+((k<g?d[k++]:0)<<8)+(k<g?d[k++]:0),f.push(a[e>>>18&63]),f.push(a[e>>>12&63]),f.push(a[e>>>6&63]),f.push(a[e>>>0&63]); +return 0<g%3&&(f[f.length-1]="=",g%3==1&&(f[f.length-2]="=")),f.join("")}(c):"hex"===b?function(d){for(var e="0123456789abcdef".split(""),a=d.length,g=[],f=0;f<a;f++)g.push(e[d[f]>>>4&15]),g.push(e[d[f]>>>0&15]);return g.join("")}(c):"binary"===b?new Uint8Array(c):c}var R=1;if("object"==typeof K){if(4<arguments.length)throw Error("scrypt: incorrect number of arguments");var w=K;if(U=h,void 0===(K=w.logN)){if("undefined"==typeof w.N)throw Error("scrypt: missing N parameter");if(w.N<2||w.N>4294967295)throw Error("scrypt: N is out of range"); +if(0!=(w.N&w.N-1))throw Error("scrypt: N is not a power of 2");K=Math.log(w.N)/Math.LN2}R=w.p||1;h=w.r;ia=w.dkLen||32;L=w.interruptStep||0;da=w.encoding}if(R<1)throw Error("scrypt: invalid p");if(h<=0)throw Error("scrypt: invalid r");if(K<1||31<K)throw Error("scrypt: logN must be between 1 and 31");var t,S,J=1<<K>>>0;if(1073741824<=h*R||3.35544319921875E7/R<h||1.677721599609375E7<h||3.35544319921875E7/h<J)throw Error("scrypt: parameters are too large");"string"==typeof T&&(T=la(T));"string"==typeof ca&& +(ca=la(ca));var ha="undefined"!=typeof Int32Array?(t=new Int32Array(64*h),S=new Int32Array(32*J*h),new Int32Array(16)):(t=[],S=[],Array(16));var G=ja(T,ca,128*R*h);var F=0,Q=32*h,ra="undefined"!=typeof setImmediate?setImmediate:setTimeout;"function"==typeof L&&(da=U,U=L,L=1E3);L<=0?function(){for(var b=0;b<R;b++)ma(128*b*h),na(0,J),oa(0,J),pa(128*b*h);U(sa(da))}():function d(c){ma(128*c*h);qa(0,J,2*L,na,function(){qa(0,J,2*L,oa,function(){pa(128*c*h);c+1<R?ra(function(){d(c+1)}):U(sa(da))})})}(0)}}.call(globalThis), +globalThis.scrypt),Mw=new TextEncoder,wb=self,VA=new Map([[l1,function(N,C){return K[32]((C=["M",255,2],13),C[1],RB[C[0]](),N.w$),B0[C[0]]().init(gk(N.i)),I[26](53,C[2],1,N.B)}],[Ns,function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A,n){return P[44](45,function(R,F,Z){if((Z=["i","usedJSHeapSize",(F=[2,!1,""],"performance")],R.B)==1)return L=(Q=(G=self)==null?void 0:(A=G[Z[2]])==null?void 0:A.memory)?Q[Z[1]]:void 0,e=performance.now(),R.K(F[0]),D=N[Z[0]],h=GH(D),u=new XZ(h),R[Z[0]](K[14](8,0,F[0],F[2],F[1],u), +4);if(R.B!=F[0])return t=R.G,B=performance.now(),c=Q?Q[Z[1]]:void 0,C=ae(B-e),n=navigator.deviceMemory||0,m=L!==void 0&&c!==void 0?c-L:void 0,R.return(new Yv(n,t,m,1,C));return(q=(O=(R.o(),ae(performance.now()-e)),navigator).deviceMemory||0,R).return(new Yv(q,[],void 0,6,O))})}]]),x8=new MessageChannel,aL=(new (postMessage(Z_,[x8.port2]),oB)(x8.port1,VA,wb,Zf.location.origin,x8),D5)(),Ip=Wp(),gH=(((((((V=mm.prototype,V.On=function(){this.i.send(Uk)},V.XG=function(){this.i.send(Kx)},V).m$=function(N){this.i.send(jq, +N)},V.ip=function(N,C){return this.i.send(uj,new Cv({visible:C,n0:N}))},V).p6=function(N,C,e,L,h,Q,m,O,t){(O=(t=(m=m||function(){},[43,(h=h||function(){},Q=Q||function(){},"i"),28]),S[t[2]](41).name.replace(HX,hd)),this)[t[1]]=W[3](t[2],80,S[t[2]](33).parent.frames[O],K[t[0]](34,ye),new Map([[Rz,h],[Fa,Q],[cf,m],[[Iz,h5],N],[uj,C],[Uk,e],[Re,L]]),this)},V).L6=function(N){this.i.send(uj,new Cv({visible:!0,n0:N,resize:!0}))},V).onError=function(N){this.i.send(Gz,new dT(N))},V).DD=function(){this.i.send(MV)}, +V.AK=function(){return this.i.send($t)},V.rJ=function(){return aL},V.Fq=function(){},V).YN=function(N,C){return this.i.send(Ns,N,C)},dc()),xZ=Lk(),PL=Eo(),mr=(((((((((V=((((((((V=(((((V=((((((((T[40](60,sL,J_),sL.prototype).fu=function(){return this.K},T)[40](34,RE,p),RE.prototype.fu=function(){return T[22](4,1,this,rY)},RE.prototype).kx=function(){return l[43](40,3,this,rY,FG)},RE.yl=sl(),RE).prototype.D=f[38](27,["dresp",sI,X_,wv,YF,Zh,sI]),T[40](27,KC,KN),T)[40](58,i9,KN),T[40](34,K6,p),K6).prototype.D= +f[38](75,[0,VN,kF]),T[40](2,Ss,TN),Ss).prototype.init=function(N,C){(y[C=["u","F",6],29](1,!1,B0.M(),Az)&&v[24](34,5,0),N&&H[15](C[2],this,N),this.i.i).p6(this.oG.bind(this),this.T.bind(this),this[C[0]].bind(this),this.R.bind(this),this[C[1]].bind(this),this.gv.bind(this),this.Mm.bind(this))},Ss.prototype.T=function(N){N&&(this.B.i.s_(N.visible),f[38](92).style.height=Tu())},Ss.prototype),V.Mm=function(){return P[16].call(this,49)},V).lf=function(N,C,e,L,h,Q){return S[49].call(this,8,N,C,e,L,h,Q)}, +Ss.prototype).F=function(N,C,e,L,h,Q){if(!(Q=(L=[!1,null,23],[17,0,21]),N).i)return L[Q[1]];try{return C=gk(N.i),W[33](Q[2],C,L[2],rY,void 0,f[22].bind(null,78))!=L[1]&&(h=B0.M().get(),e=W[33](Q[0],C,L[2],rY,FG,f[22].bind(null,79)),H[38](2,h,y[39](24,L[1],e,L[Q[1]]),L[2],rY),B0.M().init(h)),!0}catch(m){return L[Q[1]]}},Ss.prototype.I=function(N,C,e,L,h){if((L=[null,2,(h=[2,"hm","i"],4)],N.kx()!=L[0]&&N.kx()!=0)&&N.kx()!=10&&N.kx()!=6)if(S[49](21,L[1],N))H[15](23,this,S[49](24,L[1],N)),e=N[h[1]](), +this.lf(it,S[49](20,L[1],N),N,v[28](76,f[29](3,e,L[h[0]]))*60,!0);else P[15](9,this,!1);else C=new aE(N[h[2]](),60,null,null,null,N.jZ()||L[0]),this[h[2]][h[2]].m$(C),P[15](10,this,!1)},V.oG=function(N){return S[0].call(this,7,N)},Ss).prototype.u=function(N){this.i.fu()==N.response&&(this.i.G=xZ)},V.en=function(){return y[22].call(this,10)},V).gv=function(N,C,e,L,h,Q){return l[25].call(this,2,N,C,e,L,h,Q)},Ss).prototype,V).BU=function(N,C,e,L,h,Q,m,O,t,D,q,u,B,G,c,A){return I[24].call(this,4,N,C, +e,L,h,Q,m,O,t,D,q,u,B,G,c,A)},V).Xn=function(N,C,e,L){return v[5].call(this,4,N,C,e,L)},V.iY=function(){return T[32].call(this,2)},V).C8=function(N,C,e,L,h){return P[32].call(this,24,N,C,e,L,h)},V).U=function(){TN.prototype.U.call(this)},V).Nz=function(){return y[37].call(this,1)},V).IG=function(N,C){return P[24].call(this,7,N,C)},Ss).prototype.R=function(N,C){return new ((0,(N=(0,B8.oB)().map(function(e){return S[31](20,e)}),C=(0,B8.xg)().map(function(e){return S[31](36,e)}),B8).Ls)(),Da)(C,null, +N)},U[47](26,function(N,C){if(window.RecaptchaEmbedder)RecaptchaEmbedder.onError(N,C)},"recaptcha.frame.embeddable.ErrorRender.errorRender"),X1.prototype),V.XG=function(){},V.ip=function(N,C){if(window.RecaptchaEmbedder&&RecaptchaEmbedder.onShow)RecaptchaEmbedder.onShow(C,N.width,N.height);return Promise.resolve(new Cv({visible:C,n0:N}))},V).On=function(){if(window.RecaptchaEmbedder&&RecaptchaEmbedder.onChallengeExpired)RecaptchaEmbedder.onChallengeExpired()},V).L6=function(N){if(window.RecaptchaEmbedder&& +RecaptchaEmbedder.onResize)RecaptchaEmbedder.onResize(N.width,N.height);Promise.resolve(new Cv({visible:!0,n0:N,resize:!0}))},V.m$=function(N){window.RecaptchaEmbedder&&RecaptchaEmbedder.verifyCallback&&RecaptchaEmbedder.verifyCallback(N.response)},V.p6=function(N,C){this.G=(this.B=N,C),window.RecaptchaEmbedder&&RecaptchaEmbedder.challengeReady&&RecaptchaEmbedder.challengeReady()},V).onError=function(N){if(window.RecaptchaEmbedder&&RecaptchaEmbedder.onError)RecaptchaEmbedder.onError(N,!0)},V).rJ= +function(){return Ip},V.Fq=function(N,C,e){(this.i=N,window.RecaptchaEmbedder)&&RecaptchaEmbedder.requestToken&&RecaptchaEmbedder.requestToken(C,e)},V).DD=function(){},V).AK=function(){return Promise.resolve(null)},V).YN=function(){return null},T[40](26,Rg,QY),Rg.prototype).fu=function(){return this.G.value},PA)(),gb=["finput",sI,r4,sI,((T[40](59,W0,p),W0).yl=q5(),1),PU,i_,-1],b2=T[3](41,null,(W0.prototype.D=f[38](73,gb),gb),W0),Mz=[0,((U[47](30,function(N,C){C=new W0(GH(N)),new gP(C)},"recaptcha.frame.embeddable.Main.init"), +U)[47](31,function(N,C){(C=new W0(GH(N)),new Cs(C)).i.init(T[22](4,1,C,rY))},"recaptcha.frame.Main.init"),YF),[0,sI,-1,nV,wv,i_,kF,-2],sI],$8=[0,sI,-4,[0,sI,Mz],[0,sI,Mz,kF],[0,sI,-1],[0,sI,Mz],[0,sI,Mz],[0,Mz]],NO=(T[40](28,CX,p),CX.prototype.D=f[38](73,[0,sI,-6,$8,sI,-1]),T[3](73,null,hX,LX)); +((((((((T[40](34,eL,KN),T[40](34,l0,TN),l0.prototype).init=function(N,C,e,L){(((N=this[L=["B",null,(e=this.P.bind(this),"zzrd")],L[0]],N)[L[0]]=this.h.bind(this),N).i=e,(C=P[34](47,L[1]))==L[1])||C[L[2]]()},l0.prototype).resize=function(N,C,e){(N=(e=[39,null,34],W[e[0]](9,this.i)),(C=P[e[2]](23,e[1]))==e[1])||C.zzrs(N.width,N.height)},l0).prototype.P=function(N,C,e,L,h,Q,m,O,t,D,q){if((t=l[43](62,4,(q=(D=(C=this,[!0,'"',1]),[53,1E3,1]),N)),t)!=null)this.B.onError(t);else{m=(e=(L=(O=(h=((this.j=((this.K= +Q=S[41](34,D[2],void 0,N),this.i).G.value=Q,this.G=PL,performance).now(),this).A=performance.now(),S[41](8,10,void 0,N)),N.m0()),O)==null?0:Number(O),T[49](3,D[q[2]],")",this.i,h),void 0),this.i).i;try{e=ek(v[33](q[0],S[49](30,12,N)||""))}catch(u){this.B.onError(D[2]);return}(f[36](q[2],D[0],"h",m,S[41](42,11,void 0,N),e?e:void 0),this.o)&&(S[3](41,this.o),this.o=null),L>0&&(this.o=W[36](88,L*q[1],function(u,B){C[B=["G",39,34],B[0]]===PL&&(C[B[0]]=xZ,(u=P[B[2]](B[1],null))==null||u.zzce())})),P[q[2]](39, +null,D[0],W[39](11,this.i))}},V=hW.prototype,l0.prototype.fu=function(){return this.K},l0).prototype.h=function(N){N&&this.i.i&&this.i.i.s_(N.visible)},V.zzrd=function(){this.handler.postMessage({action:"zzrd"})},V).zzsh=function(N,C,e){this.handler.postMessage({action:"zzsh",visible:N,width:C,height:e})},V.zzrs=function(N,C){this.handler.postMessage({action:"zzrs",width:N,height:C})},V).zzsc=function(N){this.handler.postMessage({action:"zzsc",token:N})},V.zzce=function(){this.handler.postMessage({action:"zzce"})}, +V).zzer=function(N){this.handler.postMessage({action:"zzer",errorCode:N})},T_.prototype.onError=function(N,C){(C=P[34](31,null))==null||C.zzer(N)},U)[47](25,function(N,C){(C=b2(v[33](20,N)),(new I3(C)).controller).init()},"recaptcha.frame.mobile.Main.init");}).call(this); diff --git a/extension/recaptcha_enterprise.js b/extension/recaptcha_enterprise.js new file mode 100644 index 000000000..35a896cce --- /dev/null +++ b/extension/recaptcha_enterprise.js @@ -0,0 +1 @@ +/* PLEASE DO NOT COPY AND PASTE THIS CODE. */(function(){var w=window,C='___grecaptcha_cfg',cfg=w[C]=w[C]||{},N='grecaptcha';var E='enterprise',a=w[N]=w[N]||{},gr=a[E]=a[E]||{};gr.ready=gr.ready||function(f){(cfg['fns']=cfg['fns']||[]).push(f);};w['__recaptcha_api']='https://www.google.com/recaptcha/enterprise/';(cfg['enterprise']=cfg['enterprise']||[]).push(true);(cfg['render']=cfg['render']||[]).push('explicit');(cfg['anchor-ms']=cfg['anchor-ms']||[]).push(20000);(cfg['execute-ms']=cfg['execute-ms']||[]).push(30000);w['__google_recaptcha_client']=true;var d=document,po=d.createElement('script');po.type='text/javascript';po.async=true; po.charset='utf-8';po.src='https://www.gstatic.com/recaptcha/releases/8x-4t2pegToiW8KmThtO4AQt/recaptcha__en.js';po.crossOrigin='anonymous';po.integrity='sha384-KmhOiTn6sHD8dy14OaGi/9+f17owL+KWDoLiUoEjdbwL0MkY5QTE9wPi90EHLAnV';var e=d.querySelector('script[nonce]'),n=e&&(e['nonce']||e.getAttribute('nonce'));if(n){po.setAttribute('nonce',n);}var s=d.getElementsByTagName('script')[0];s.parentNode.insertBefore(po, s);})(); \ No newline at end of file From 083fed75cfbe08e9afc3e591ce57e1ebadc855c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=82=CC=81ng=20Phu=CC=9Bo=CC=9B=CC=81c=20Vo=CC=83?= <se.votong@gmail.com> Date: Fri, 25 Sep 2026 10:51:19 +0700 Subject: [PATCH 35/68] feat: bypass extension_hijack_detected + Trusted Types CSP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extension v0.5.2: - hijack_bypass.js: capture pristine grecaptcha.enterprise.execute before Flow's x2a trap replaces it with extension_hijack_detected action - injected.js: 3-level bypass (pristine → Object.assign neuter → legacy) - manifest.json: inject all MAIN world scripts via manifest content_scripts to bypass Trusted Types CSP (require-trusted-types-for 'script') - content.js: removed createElement('script') injection, keep message bridge - background.js: RPC label mapping for side panel (Gen Video, Upload Image, etc) Agent: - flow_client.py: distinguish [HIJACK] errors (30s cooldown) from abuse blocks (120s) - processor.py: [HIJACK] errors don't burn retry counts - flow.py: POST /api/flow/clear-hijack endpoint for manual cooldown reset --- .gitignore | 2 + agent/api/flow.py | 18 +++ agent/services/flow_client.py | 26 +++- agent/worker/processor.py | 13 ++ extension/background.js | 10 +- extension/content.js | 35 ++---- extension/hijack_bypass.js | 217 ++++++++++++++++++++++++++++++++++ extension/injected.js | 136 +++++++++++++++++---- extension/manifest.json | 19 ++- 9 files changed, 419 insertions(+), 57 deletions(-) create mode 100644 extension/hijack_bypass.js diff --git a/.gitignore b/.gitignore index 0f317e30a..35e1ef44d 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ extension/_metadata/ # oh-my-claudecode session state (plans, hud, logs) — tooling, not project content .omc/ +.agent/ +flow_session_project.json diff --git a/agent/api/flow.py b/agent/api/flow.py index f2472a7b4..e74647cef 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -193,6 +193,24 @@ async def extension_status(): } +@router.post("/clear-hijack") +async def clear_hijack_cooldown(): + """Reset the generation cooldown triggered by extension_hijack_detected. + + Call this after deploying the bypass fix to immediately resume generation + without waiting for the cooldown to expire. + """ + import time as _time + client = get_flow_client() + old_until = client._generation_unusual_until + client._generation_unusual_until = 0.0 + was_active = old_until > 0.0 and old_until > _time.monotonic() + return { + "cleared": True, + "was_active": was_active, + } + + @router.get("/credits") async def get_credits(): """Get user credits from Google Flow.""" diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index b4033677b..c771b4253 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -555,10 +555,32 @@ async def batch_rpc(self, rpcid: str, freq: str, result = await self._send("batch_rpc", params, timeout=timeout) blob = f"{result.get('error', '')} {result.get('data', '')}" - if ( + is_hijack = "extension_hijack" in blob.lower() + is_unusual = ( "PUBLIC_ERROR_UNUSUAL_ACTIVITY" in blob or "unusual activity" in blob.lower() - ): + ) + if is_hijack: + # x2a trap: the token was poisoned with action + # "extension_hijack_detected". This is a system-level trap, + # NOT an account issue — don't apply the long cooldown. + # Short pause lets the bypass re-initialise on next tab. + self._generation_unusual_until = max( + self._generation_unusual_until, + time.monotonic() + 30.0, + ) + self._generation_last_unusual_at = time.time() + self._generation_last_unusual_rpc = rpcid + logger.error( + "[HIJACK] extension_hijack_detected — captcha bypass may " + "have failed; pausing generation submits for 30s" + ) + # Tag the result so processor can distinguish it + if isinstance(result.get("error"), str): + result["error"] = f"[HIJACK] {result['error']}" + else: + result["error"] = "[HIJACK] extension_hijack_detected" + elif is_unusual: self._generation_unusual_until = max( self._generation_unusual_until, time.monotonic() + FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, diff --git a/agent/worker/processor.py b/agent/worker/processor.py index 829ed4950..c736410aa 100644 --- a/agent/worker/processor.py +++ b/agent/worker/processor.py @@ -444,6 +444,19 @@ async def _handle_failure(rid: str, req: dict, result: dict, retry_after: dict = error_lower = str(error_msg).lower() + # [HIJACK] extension_hijack_detected — the captcha bypass failed and the + # token was poisoned by x2a. This is a system-level trap, NOT an account + # issue. Don't burn retry count — the bypass may succeed on the next + # attempt once the tab re-initializes. + if "[hijack]" in error_lower or "extension_hijack" in error_lower: + await crud.update_request(rid, status="PENDING", error_message=str(error_msg)) + logger.error( + "Request %s [HIJACK] captcha bypass failed — will retry without " + "counting (system error, not account error): %s", + rid[:8], error_msg, + ) + return + # PUBLIC_ERROR_UNUSUAL_ACTIVITY is a Google anti-abuse/session trust block, # not an ordinary CAPTCHA mint failure. Retrying it in the generic CAPTCHA # loop only creates more generation submits while Google is asking us to diff --git a/extension/background.js b/extension/background.js index 6def15cfd..889acdc5d 100644 --- a/extension/background.js +++ b/extension/background.js @@ -554,9 +554,17 @@ async function handleBatchRpc(msg) { // Polls and listing lookups run constantly; only the generates are worth // a row in the log the popup shows. const visible = hasCaptcha; + const _RPC_LABELS = { + ogiZ0b: 'Gen Image', eb1hJf: 'Gen Video', YhhmEf: 'Gen Video (text)', + nprQif: 'Gen Video (chain)', MZZa6b: 'Gen Video (refs)', + maseQ: 'Upload Image', SPrCad: 'Upscale Image', + jHPbke: 'Create Project', jwpduf: 'Poll Operation', + Zzl0ze: 'Project Media', as29s: 'Get Media', + }; + const logType = _RPC_LABELS[rpcid] || `RPC:${rpcid}`; if (visible) { addRequestLog({ - id, type: `RPC:${rpcid}`, time: new Date().toISOString(), + id, type: logType, time: new Date().toISOString(), status: 'processing', error: null, outputUrl: null, url: rpcid, payloadSummary: freq.slice(0, 200), }); diff --git a/extension/content.js b/extension/content.js index ec9c2c1b5..89fb80f31 100644 --- a/extension/content.js +++ b/extension/content.js @@ -1,33 +1,14 @@ /** - * Content script — bridge between background.js and injected.js - * Injects injected.js into MAIN world to access window.grecaptcha + * Content script — bridge between background.js (ISOLATED world) and + * injected.js (MAIN world). * - * reCAPTCHA preload (ported from FlowBridge2): flow.google.com enforces - * `require-trusted-types-for 'script'` with a policy that rejects google.com - * URLs, and it no longer ships grecaptcha in the MAIN world at page load — a - * plain <script src="https://www.google.com/recaptcha/enterprise.js"> tag is - * blocked and the lazy wait then times out with `grecaptcha not available`. - * Scripts fetched from the extension's own chrome-extension:// URL bypass the - * page CSP entirely, so we ship enterprise.js + its real client locally and - * feed them in right after the anchor evaluates. + * All MAIN world scripts (hijack_bypass.js, recaptcha_enterprise.js, + * recaptcha__en.js, injected.js) are now loaded via manifest.json + * content_scripts with "world": "MAIN" — this bypasses the page's + * Trusted Types CSP entirely. No more createElement('script') needed. + * + * This content script only handles the message relay between the two worlds. */ -(function () { - function addExtScript(name) { - const s = document.createElement('script'); - // Cache-buster: Chrome may serve a stale injected.js out of its - // chrome-extension:// resource cache after an extension reload. - s.src = chrome.runtime.getURL(name) + '?v=' + chrome.runtime.getManifest().version; - s.onload = () => s.remove(); - s.setAttribute('data-flowkit', name); - (document.head || document.documentElement).appendChild(s); - } - - addExtScript('injected.js'); - // The anchor sets ___grecaptcha_cfg stubs; its own gstatic append is - // CSP-blocked, so the real client (bundled locally) follows. - addExtScript('recaptcha_enterprise.js'); - setTimeout(() => addExtScript('recaptcha__en.js'), 50); -})(); chrome.runtime.onMessage.addListener((msg, _, reply) => { if (msg.type !== 'GET_CAPTCHA') return; diff --git a/extension/hijack_bypass.js b/extension/hijack_bypass.js new file mode 100644 index 000000000..d7c05a589 --- /dev/null +++ b/extension/hijack_bypass.js @@ -0,0 +1,217 @@ +/** + * hijack_bypass.js — Three-level property trap for grecaptcha.enterprise.execute + * + * Runs in MAIN world at document_start (via manifest.json) — guaranteed to + * execute before any page scripts, including the reCAPTCHA loader and Flow's + * x2a trap. + * + * Flow's front-end (build boq_labs-ai-sandbox-frontend_20260922.00_p0) ships a + * function x2a that overwrites grecaptcha.enterprise.execute with a wrapper + * which forces action: "extension_hijack_detected" via Object.assign. The + * original execute is stashed in page-private state (a.ha) for the page's own + * use. Any token minted through the public API carries the poison action, and + * the backend rejects it with PUBLIC_ERROR_UNUSUAL_ACTIVITY. + * + * This script intercepts the pristine execute function the moment reCAPTCHA + * assigns it — before x2a can overwrite it — and exposes it via + * window.__fk_hijack for injected.js to consume. + * + * Three capture layers, each a fallback for the one above: + * Level 1: defineProperty on window.grecaptcha + * Level 2: defineProperty on grecaptcha.enterprise + * Level 3: defineProperty on enterprise.execute + * + * Plus two polling fallbacks: + * - Rapid poll (2ms): catches cases where defineProperty gets clobbered + * - ready() callback race (5ms): registers our callback before Angular's + * + * After capture, all traps self-clean — Object.getOwnPropertyDescriptor returns + * {value, writable} as if we were never there. + */ +(function () { + 'use strict'; + + let _pristineExecute = null; + let _capturedTrapped = false; + let _captureSource = null; // diagnostic: which layer caught it + + // ── Core capture ────────────────────────────────────────────────────────── + + function savePristine(fn, enterprise, source) { + if (_pristineExecute || typeof fn !== 'function') return false; + // Verify this isn't the trapped version — x2a's wrapper contains the + // string "extension_hijack_detected" in its source. + try { + const src = fn.toString(); + if (src.includes('extension_hijack_detected')) { + _capturedTrapped = true; + return false; + } + } catch (e) { + // toString on native code may throw; treat as plausibly pristine + } + _pristineExecute = fn.bind(enterprise); + _captureSource = source; + // Schedule cleanup on next microtask — let the current setter chain finish + // before we rip out the traps, otherwise the setter's own return path blows + // up when the descriptor it's running under is yanked mid-execution. + Promise.resolve().then(cleanAllTraps); + return true; + } + + // ── Trap cleanup ────────────────────────────────────────────────────────── + + // Restore a trapped property to a plain data property. + function cleanTrap(obj, prop) { + try { + const desc = Object.getOwnPropertyDescriptor(obj, prop); + if (!desc || (!desc.get && !desc.set)) return; // already clean + Object.defineProperty(obj, prop, { + value: desc.get ? desc.get() : undefined, + writable: true, + configurable: true, + enumerable: true, + }); + } catch (e) { /* frozen or non-configurable — leave it */ } + } + + let _cleanedUp = false; + function cleanAllTraps() { + if (_cleanedUp) return; + _cleanedUp = true; + try { + const gc = window.grecaptcha; + if (gc) { + const ent = gc.enterprise; + if (ent) cleanTrap(ent, 'execute'); + cleanTrap(gc, 'enterprise'); + } + cleanTrap(window, 'grecaptcha'); + } catch (e) { /* best-effort */ } + } + + // ── Level 3: enterprise.execute ─────────────────────────────────────────── + + function watchExecute(enterprise) { + let _val = enterprise.execute; + if (typeof _val === 'function' && savePristine(_val, enterprise, 'L3-immediate')) { + return; + } + try { + Object.defineProperty(enterprise, 'execute', { + get() { return _val; }, + set(fn) { + _val = fn; + savePristine(fn, enterprise, 'L3-setter'); + }, + configurable: true, + enumerable: true, + }); + } catch (e) { /* non-configurable — fall through to poll */ } + } + + // ── Level 2: grecaptcha.enterprise ──────────────────────────────────────── + + function watchEnterprise(grecaptcha) { + let _val = grecaptcha.enterprise; + if (_val && typeof _val === 'object') { + watchExecute(_val); + } + try { + Object.defineProperty(grecaptcha, 'enterprise', { + get() { return _val; }, + set(obj) { + _val = obj; + if (obj && typeof obj === 'object') { + watchExecute(obj); + } + }, + configurable: true, + enumerable: true, + }); + } catch (e) { /* non-configurable */ } + } + + // ── Level 1: window.grecaptcha ──────────────────────────────────────────── + + function installCapture() { + let _val = window.grecaptcha; + if (_val && typeof _val === 'object') { + watchEnterprise(_val); + } + try { + Object.defineProperty(window, 'grecaptcha', { + get() { return _val; }, + set(obj) { + _val = obj; + if (obj && typeof obj === 'object') { + watchEnterprise(obj); + } + }, + configurable: true, + enumerable: true, + }); + } catch (e) { /* non-configurable */ } + + // ── Fallback A: rapid poll (2ms) ────────────────────────────────────── + + const pollId = setInterval(() => { + if (_pristineExecute) { clearInterval(pollId); return; } + try { + const exec = window.grecaptcha?.enterprise?.execute; + if (typeof exec === 'function') { + savePristine(exec, window.grecaptcha.enterprise, 'poll-2ms'); + if (_pristineExecute) clearInterval(pollId); + } + } catch (e) { /* ignore */ } + }, 2); + setTimeout(() => clearInterval(pollId), 30000); + + // ── Fallback B: ready() callback race (5ms poll) ───────────────────── + + const readyPollId = setInterval(() => { + if (_pristineExecute) { clearInterval(readyPollId); return; } + try { + const ready = window.grecaptcha?.enterprise?.ready; + if (typeof ready === 'function') { + clearInterval(readyPollId); + ready.call(window.grecaptcha.enterprise, () => { + try { + const exec = window.grecaptcha?.enterprise?.execute; + if (typeof exec === 'function') { + savePristine(exec, window.grecaptcha.enterprise, 'ready-race'); + } + } catch (e) { /* ignore */ } + }); + } + } catch (e) { /* ignore */ } + }, 5); + setTimeout(() => clearInterval(readyPollId), 30000); + } + + installCapture(); + + // ── Expose to injected.js ───────────────────────────────────────────────── + // Non-enumerable property so page code won't stumble on it in for..in loops. + // The getters read closure variables so the value tracks capture state live. + + try { + Object.defineProperty(window, '__fk_hijack', { + value: Object.freeze({ + get pristine() { return _pristineExecute; }, + get trapped() { return _capturedTrapped; }, + get source() { return _captureSource; }, + }), + writable: false, + configurable: false, + enumerable: false, + }); + } catch (e) { + // If defineProperty fails (already defined), assign directly + window.__fk_hijack = { + get pristine() { return _pristineExecute; }, + get trapped() { return _capturedTrapped; }, + get source() { return _captureSource; }, + }; + } +})(); diff --git a/extension/injected.js b/extension/injected.js index 1ae4ec7fd..1293d2fb1 100644 --- a/extension/injected.js +++ b/extension/injected.js @@ -1,11 +1,22 @@ /** - * Injected into the page's MAIN world on flow.google.com (and an old pinned - * labs.google tab) — has access to window.grecaptcha. + * Injected into the page's MAIN world on flow.google.com — has access to + * window.grecaptcha and the hijack bypass state from hijack_bypass.js. * - * The reCAPTCHA site key survived the September 2026 migration unchanged. The - * TRPC fetch intercept below did not: it belongs to the labs.google frontend - * and is inert on flow.google.com, where media urls come back inline on the - * generate call and from the media rpc. + * reCAPTCHA minting strategy (v0.5.1): + * + * 1. PRISTINE path (preferred): hijack_bypass.js captured the real execute + * function before Flow's x2a trap overwrote it. We call it directly with + * our own action — the token is clean. + * + * 2. OBJECT.ASSIGN NEUTER (fallback): we lost the race (all three trap levels + * + ready + poll missed). x2a's wrapper uses Object.assign to inject the + * poison action. We temporarily replace Object.assign during the execute + * call: if the result contains action:"extension_hijack_detected", we + * restore the real action before it reaches the original execute function. + * + * 3. WIDGET path (legacy fallback): if neither bypass is available, fall back + * to the pre-bypass render+execute approach. This WILL be trapped, but + * provides graceful degradation with a clear error message. */ const SITE_KEY = '6LdsFiUsAAAAAIjVDZcuLhaHiDn5nnHVXVRQGeMV'; @@ -36,15 +47,10 @@ window.fetch = async function (...args) { let captchaMintTail = Promise.resolve(); -// ─── reCAPTCHA mint (ported from FlowBridge2 — live-verified on the 2026-09-22 build) ─── -// Flow's current build rejects a token obtained by calling -// `grecaptcha.enterprise.execute(SITE_KEY, {action})` directly with -// PUBLIC_ERROR_UNUSUAL_ACTIVITY ("reCAPTCHA evaluation failed"), even though the -// site key and action match the UI byte for byte, while the same account's UI -// still generates. The working recipe is the one the page itself uses: ready() → -// render an invisible widget bound to the page's own site key → execute(widgetId). -// Prefer the site key the page is currently configured with; the constant is only -// a fallback for a page that has not configured one yet. +// ─── Site key resolution ──────────────────────────────────── +// Prefer the site key the page is currently configured with; the constant is +// only a fallback for a page that has not configured one yet. + function resolveSitekey() { try { const cfg = window.___grecaptcha_cfg || {}; @@ -66,6 +72,53 @@ function waitReady(timeout = 5000) { }); } +// ─── Bypass: Object.assign neuter ─────────────────────────── +// Last-resort fallback when hijack_bypass.js couldn't capture the pristine +// execute. x2a's wrapper does: +// c.execute = (e, f) => d(e, Object.assign({}, f, { action: "extension_hijack_detected" })) +// We temporarily replace Object.assign so the poison action is stripped before +// it reaches the real execute function `d`. + +const _realObjectAssign = Object.assign; + +async function executeWithAssignNeuter(sitekey, action) { + const targetAction = action; + + Object.assign = function (target, ...sources) { + const result = _realObjectAssign.call(this, target, ...sources); + if (result && typeof result === 'object' && + result.action === 'extension_hijack_detected') { + result.action = targetAction; + } + return result; + }; + + try { + await waitReady(2500); + const token = await Promise.race([ + window.grecaptcha.enterprise.execute(sitekey, { action }), + new Promise((_, rej) => setTimeout(() => rej(new Error('execute_hang')), 8000)), + ]); + return token ? String(token) : null; + } finally { + Object.assign = _realObjectAssign; + } +} + +// ─── Bypass: pristine execute (primary path) ──────────────── + +async function executeWithPristine(sitekey, action) { + const pristine = window.__fk_hijack?.pristine; + if (typeof pristine !== 'function') return null; + const token = await Promise.race([ + pristine(sitekey, { action }), + new Promise((_, rej) => setTimeout(() => rej(new Error('execute_hang')), 8000)), + ]); + return token ? String(token) : null; +} + +// ─── Legacy widget path (will be trapped) ─────────────────── + let _widgetPromise = null; function ensureWidget(sitekey) { if (_widgetPromise) return _widgetPromise; @@ -95,18 +148,41 @@ function ensureWidget(sitekey) { return _widgetPromise; } +// ─── Unified mint with retry ──────────────────────────────── + async function executeWithRetry(sitekey, action, attempts = 2) { let lastErr = null; + const hijack = window.__fk_hijack; + const hasPristine = typeof hijack?.pristine === 'function'; + const knownTrapped = !!hijack?.trapped; + for (let i = 0; i < attempts; i++) { try { - await waitReady(2500); - const widgetId = await ensureWidget(sitekey); - const token = await Promise.race([ - window.grecaptcha.enterprise.execute(widgetId, { action }), - new Promise((_, rej) => setTimeout(() => rej(new Error('execute_hang')), 8000)), - ]); - if (token) return String(token); - lastErr = new Error('empty_token'); + // Path 1: pristine execute captured by hijack_bypass.js + if (hasPristine) { + const token = await executeWithPristine(sitekey, action); + if (token) return token; + lastErr = new Error('pristine_empty_token'); + // Fall through to retry + } + // Path 2: Object.assign neuter (we know the trap is active) + else if (knownTrapped) { + const token = await executeWithAssignNeuter(sitekey, action); + if (token) return token; + lastErr = new Error('assign_neuter_empty_token'); + } + // Path 3: legacy widget (no bypass available — may still work if + // the x2a flag a.na.Aa is turned off) + else { + await waitReady(2500); + const widgetId = await ensureWidget(sitekey); + const token = await Promise.race([ + window.grecaptcha.enterprise.execute(widgetId, { action }), + new Promise((_, rej) => setTimeout(() => rej(new Error('execute_hang')), 8000)), + ]); + if (token) return String(token); + lastErr = new Error('empty_token'); + } } catch (e) { lastErr = e; } @@ -132,8 +208,16 @@ window.addEventListener('GET_CAPTCHA', async ({ detail }) => { const { requestId, pageAction } = detail; try { const token = await mintCaptcha(pageAction); + const hijack = window.__fk_hijack; window.dispatchEvent(new CustomEvent('CAPTCHA_RESULT', { - detail: { requestId, token }, + detail: { + requestId, + token, + // Diagnostic: tell the agent which path was used + bypassPath: typeof hijack?.pristine === 'function' + ? `pristine(${hijack.source})` + : hijack?.trapped ? 'assign_neuter' : 'legacy_widget', + }, })); } catch (e) { window.dispatchEvent(new CustomEvent('CAPTCHA_RESULT', { @@ -142,10 +226,12 @@ window.addEventListener('GET_CAPTCHA', async ({ detail }) => { } }); -function waitForGrecaptcha(timeout = 22000) { // it loads lazily; 10s was optimistic +function waitForGrecaptcha(timeout = 22000) { return new Promise((resolve, reject) => { const start = Date.now(); const check = () => { + // If we have pristine, grecaptcha is ready regardless of public state + if (window.__fk_hijack?.pristine) return resolve(); if (window.grecaptcha?.enterprise?.execute) return resolve(); if (Date.now() - start > timeout) return reject(new Error('grecaptcha not available')); setTimeout(check, 200); diff --git a/extension/manifest.json b/extension/manifest.json index 13c168b2c..e56fce626 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,8 +1,8 @@ { "manifest_version": 3, "name": "Flow Kit", - "version": "0.3.4", - "description": "Local agent bridge for Google Flow \u2014 runs batchexecute RPCs inside a signed-in flow.google.com tab, mints reCAPTCHA, proxies API calls", + "version": "0.5.2", + "description": "Local agent bridge for Google Flow — runs batchexecute RPCs inside a signed-in flow.google.com tab, mints reCAPTCHA with hijack bypass, proxies API calls", "permissions": [ "storage", "alarms", @@ -23,6 +23,21 @@ "service_worker": "background.js" }, "content_scripts": [ + { + "matches": [ + "https://flow.google.com/*", + "https://labs.google/fx/tools/flow*", + "https://labs.google/fx/*/tools/flow*" + ], + "js": [ + "hijack_bypass.js", + "recaptcha_enterprise.js", + "recaptcha__en.js", + "injected.js" + ], + "run_at": "document_start", + "world": "MAIN" + }, { "matches": [ "https://flow.google.com/*", From 6e0416324b84618e29a89263f6127b5f79311bbf Mon Sep 17 00:00:00 2001 From: Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Mon, 28 Sep 2026 18:23:23 +0700 Subject: [PATCH 36/68] docs: add showcase videos to README --- README.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b9033f3ee..a133db9d4 100644 --- a/README.md +++ b/README.md @@ -44,11 +44,27 @@ Standalone system to generate AI videos via Google Flow. Uses a Chrome extension All outputs below were generated end-to-end by this system — from story concept to final YouTube-ready video with thumbnails, narration, and branding. +### Full Video Demos + +<p align="center"> + <a href="https://youtu.be/DNroTtRKyUM"> + <img src="https://img.youtube.com/vi/DNroTtRKyUM/maxresdefault.jpg" width="400" alt="F-15E Pilot Rescue — 36 Hours Evading Behind Enemy Lines" /> + </a> + <a href="https://youtu.be/KhCj_zjbSps"> + <img src="https://img.youtube.com/vi/KhCj_zjbSps/maxresdefault.jpg" width="400" alt="Hormuz Strait — US Navy vs 6 Iranian Attack Boats" /> + </a> +</p> +<p align="center"> + <a href="https://youtu.be/DNroTtRKyUM">▶️ <b>Watch: F-15E Pilot Rescue (36 Hours Evading)</b></a> +   •   + <a href="https://youtu.be/KhCj_zjbSps">▶️ <b>Watch: Hormuz Strait (US Navy vs 6 Attack Boats)</b></a> +</p> + ### Generated YouTube Thumbnails <p align="center"> - <img src="docs/images/thumbnail_hormuz.jpg" width="400" alt="Hormuz Strait naval blockade thumbnail" /> - <img src="docs/images/thumbnail_f15e_rescue.jpg" width="400" alt="F-15E pilot rescue thumbnail" /> + <a href="https://youtu.be/KhCj_zjbSps"><img src="docs/images/thumbnail_hormuz.jpg" width="400" alt="Hormuz Strait naval blockade thumbnail" /></a> + <a href="https://youtu.be/DNroTtRKyUM"><img src="docs/images/thumbnail_f15e_rescue.jpg" width="400" alt="F-15E pilot rescue thumbnail" /></a> </p> <p align="center"> <img src="docs/images/thumbnail_operation_resolve.jpg" width="400" alt="Operation Absolute Resolve thumbnail" /> @@ -96,7 +112,7 @@ The reference image system keeps characters consistent across an entire video. E <img src="docs/images/scene_f15e_survival.jpg" width="260" alt="Scene 20: Pilot surviving in mountains" /> </p> -<sub>Strategic briefing → pilot departure → formation flight → aircraft hit → CSAR alert → pilot survival.</sub> +<sub>Strategic briefing → pilot departure → formation flight → aircraft hit → CSAR alert → pilot survival. • <a href="https://youtu.be/DNroTtRKyUM">Watch full video on YouTube ▶</a></sub> ### Hormuz Strait — Naval Scenes @@ -109,6 +125,8 @@ The reference image system keeps characters consistent across an entire video. E <img src="docs/images/scene_hormuz_sunset.jpg" width="400" alt="Warship sailing into sunset" /> </p> +<sub>Iranian patrol boats → bridge alert → CIWS engagement → sunset patrol. • <a href="https://youtu.be/KhCj_zjbSps">Watch full video on YouTube ▶</a></sub> + ### What the Pipeline Produces Each project goes through: **story → entities → reference images → scene images → 8s video clips → narration (TTS) → concat → thumbnails → YouTube upload** — all orchestrated via API or AI agent skills. From 777d6636a6cf2293c09064d4c10afb03b8bdfb85 Mon Sep 17 00:00:00 2001 From: Tuan Nguyen <tuannguyenhoangit@gmail.com> Date: Mon, 28 Sep 2026 18:26:33 +0700 Subject: [PATCH 37/68] docs: add play button overlay to showcase thumbnails for better UX --- README.md | 4 ++-- docs/images/thumbnail_f15e_rescue_play.jpg | Bin 0 -> 282703 bytes docs/images/thumbnail_hormuz_play.jpg | Bin 0 -> 264509 bytes 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 docs/images/thumbnail_f15e_rescue_play.jpg create mode 100644 docs/images/thumbnail_hormuz_play.jpg diff --git a/README.md b/README.md index a133db9d4..6211c3e2a 100644 --- a/README.md +++ b/README.md @@ -48,10 +48,10 @@ All outputs below were generated end-to-end by this system — from story concep <p align="center"> <a href="https://youtu.be/DNroTtRKyUM"> - <img src="https://img.youtube.com/vi/DNroTtRKyUM/maxresdefault.jpg" width="400" alt="F-15E Pilot Rescue — 36 Hours Evading Behind Enemy Lines" /> + <img src="docs/images/thumbnail_f15e_rescue_play.jpg" width="400" alt="F-15E Pilot Rescue — 36 Hours Evading Behind Enemy Lines" /> </a> <a href="https://youtu.be/KhCj_zjbSps"> - <img src="https://img.youtube.com/vi/KhCj_zjbSps/maxresdefault.jpg" width="400" alt="Hormuz Strait — US Navy vs 6 Iranian Attack Boats" /> + <img src="docs/images/thumbnail_hormuz_play.jpg" width="400" alt="Hormuz Strait — US Navy vs 6 Iranian Attack Boats" /> </a> </p> <p align="center"> diff --git a/docs/images/thumbnail_f15e_rescue_play.jpg b/docs/images/thumbnail_f15e_rescue_play.jpg new file mode 100644 index 0000000000000000000000000000000000000000..20b50d1ba81b8169ee901a01478f42509c36400f GIT binary patch literal 282703 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�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 literal 0 HcmV?d00001 diff --git a/docs/images/thumbnail_hormuz_play.jpg b/docs/images/thumbnail_hormuz_play.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6eb415fdada0770d985e1cf1d19f02a6c1639e10 GIT binary patch literal 264509 zcmbTdcRZWX`#&5rMp3J_XlWI#t!AXEHL9v=)@~^^YStbxYE;!MS|zBxtG1e@f|l5` zHVtCLij*XtTR)%g_j$dZzn<Uk7B5L$=f1D`KG${5b<U>F7C{&9YiMhL$jCq-GT;Yv zHVaY*QIM0LzkrJpcu~<%QBhJ-(SgC#G#BVDT%f0;r)OYfxyZoC%t%jv@zO<RRyKBa z_6tlLoR`=*S=iXw&Tm3S0gR!fqNSpuWn-XcVEaG5&N@KMG~`26APTZ8AaZ6h3TCpi zZV&|ElZx!$1^VwrMh@^u4W^-`qX!7;E`rF(C@9D&DbBeDsDpw3gD9D)ST0McQM2kl z1z+)ClMYMDr4hVS-O2uV7%L?6%rl&p?h*$l7x&d`!q-JaW#w+kD<~?d-@T`ysil42 zz|hFp#Po@ot=)5bhZl}cUa!1;eEs|bB3?&EMaR5}O-^~AnwI|IW5(ya{DQ)w;*!#@ zHMMp14UJ9B-@Ceh^dNit`bS2`#wRAHre~IxS60{lpw~Ax_x2ACk8sEMzbEH%kpXi4 z&-EX{{y%at19Fj5Qc_TY&*dT`_XU0_m?^0)OHs3^>4TqouwIc4qhY&~lv~|ND=70A z%l^!BnC_C0?9$b}bJ6}u_Ww_?@c%2x{#UU7SFRb*1qw32cofVa7>KZDO|d~-YXTFG z&OmhT*lU>&gMMbh+u8}bFVj{atA;V8mN;ACiolSbY&*Y)t>zno%t2Iztlh`LBuW@Q z<9(3I$X>P*W}_93&zLjjT;X#v^co#Az{#G0-e;E^k!-0{c{X15Auy2LsxuI)fp8a8 zD3hzQeRuf`v?te`?9NldJGR&F4lb&I+3Nk(@{4W%<%Pk1({lUk=AV5$c?Nn@VzQ(W z-%pD;gm;VrA1jj;8JAMB?>APe8d2I;=oe0YkHE;mKdh!Nsm8(A{v4A?!oZVs0C_%X z2wqt}JR$7?oMOT_(cug#x3tmNyeR{cA;h$TfD}+=dC|?Zu;4&yJ|Ck80Uz3)fh0H< ztfhb<TNIJVI$fT4wNe~gdn!FfuKmM`$>MyB7bzteNtD$iT}vUcO}w4lmTx=*RlYd` zbx-<pr}Ib1Hu6MUEpkI6CDxeAjY+nVdJzF!s1sfM8L0l8%J41L_RiB3?+|E9_Zete ztl3oEmJ5SweOSL5$Gm}me9{VAQ#;CNz{fMf!ZRo&sWFc_cmEWfftXDe@$^g69A1{2 zw{2^y0S&TG$V$-1k!$Lk+}w##i*MZ^TBYwNoU3DH6c>c;;^k>IAf16UktFpp_mDw; zj?@nMnM&m(*&wFVW6MmAkC$7q!D4qtR>i`lrN+3O0G98n=sw5Ai@@!f=%g&Hox#5O z!*J6wr&-)xY-ImlF-EN&vkW20S<YoGDRg<oOIi9vMJ*+I-&|<8Km2sP{j1%c_vDO9 z1c?*%{T<iy_K7!#r+2LhPNmt?;O`Nf?Gp*b2g`%12%})RqUjc2t`Nh3gr9Qu$GY0) zA{QCr^CB|ZONUAN!LIEGA)3FM;al*<Z|SqQ@+wPE*x%|Xl3HcnLt<12|9sBPGJG6M zprzU<iD2@z)83}>Z^|DP=GdVadjIz#vkR3X!N%vh@NWOG7flRPA@33?!^aR^E6zap zf#(*aE`Hk3MJKDv1lP;xGmyaKn38LL9LNKucd%hnR2>fgq$uRjV3u8`Z|0ePR5}o( ziS&h4!y{~jN!OIHooM-sfci5E<hOzs*GI*QG0_+m7{RISYy0peZAqqqG5aQ>$=$ST zOP-C23M-KNaO2OUKA2e*0r_(zqz}RNxWgJ_;VaX12I?uTZU5RHDadsiQnP!y9uM1R z52o-Xi;MyPfvS~%D%Sf&BM5zQQg;=nQ4Pp~Eh2tU5mnvBRl>JxtqHDWI;XOJ&s3fr z8!MiH3WouvnsFPsVjbYI<r?(kOy<#&;*&awHSQmPBmVe=^Tf{7GyEw@uvUVRu0)(F z;q53s4H!V%gCVfLjIF_W&^zccLpK^@bn(%y&gLQfJ=_e4la#8hm8E(vj*Jq(h5tRn z;8elS#g-^zgeuB{oPl_%EF$F>nd3#D*GP;OZ|H4~wWl&+i~!Y-6Ejt0zL8*ZdZ)y5 z!m=+RzYrYn;})Dc_?KU_<L3fuo^bX;p}`^()lwmBi;HN&^^;bKHI9igxYQpksUN}Y z{nLrN7utc4Ajug(rj<K8;JxbRa~tS$<&{m9-?Yqwx<dme!l$<q9oo@4|NCq#3U9YS zlk$U9cLstloq<*iA=5J71sqP*pPYf(v4E;dk3G1_!g`pTs-zh~=+XJ~F9n2R9d`4- z35?d$>fi4!E@0G2v-g1Kl)O6?@iXAH#y|{IEa0o6IKstl{>I+zSiiW79gD{&CqUFn z08v}I@XJp&`ztDP2y(b>Em*X>+<6A-HF{`0{i%zliDRZ-k9h0t8R*?)vt>yq$N>>t z8qv+82(hk!m=qB5OwWf~oPlbxqXqlS=L`~_0C2P{T1AlAjXt*B&PXQ`6V5;}Rjy49 z;#xhPQb*;JH3FIB{yq03%0@{B_uiC}hFAMep?L2Y>SKdGG`Z;se1TmwWU!6b2RZAl zSM>=n0kc&ZU+!Ped?vGxH-9<QJBqRaSPg$tMnI+^Pv!ld#xwjW!|VRDmB^_K-sls= zb)2{-3;0?qRBez6#57TE?jVS0v7JbGs!L2f`C<J>WdQcPine*xi5p2Ios0MA4D@y3 z^{_VJ(@0xjs8egy??nG~KT1Q^eoc#&(F%#DdVke1?C=kJU8hoh26dz=l-|ORb45qv z9I#&#@TBpB4fMI@G2?Ssza5z9yUYt-5%Wb;qol`e)keg;K69K4wgYwIS}uh-XYRAx zG^&dpK=0<N$-%drfQ7v`NBh+}Fu#qS{q5aUGCbuDjy2jmR%sy(k~ksz$E9bWg>?W7 z<^)4f{G9qJfu->Od=79-WEWZ`BW%|6>&XU+{%6zyiEFk?arxK~xbeRTsDo@xF8N}D z%R*THvH9)EAOQz1avG{{r9~cpGca^K16>acXhkW)YG9G6o^IYDtt#t)!|QTv{aBLM z?Kw5Y5eet2;as2=6vndOkk4yc<X1iei9+AO*6yAHLzUm+EU^*UpB_zURtiT0dNs_( z{<LC*957F`?-BsKY2~!I<;ken%ineg-MD^RLFni(Z)$Xd`Fya<C)`u4r+af$tsc?$ ze6X<#;91d;c`i41%Kg{v|G8l~eHL0+ApYp_@}ohmjd(AesnM;dvaub1opUXz5A2iy zv6BbHjyF#TDukPte(q8B3FcqK>-$rKcu#ywPv4-RG6NE}j6VXMvQTo6nuVxdN-L*m z(hL%q>>g)Nqq}TaadUbJC(i%8FJ9>I#2_xK@lV22y=tq8BCi3at<$CIgu?-YjX&o@ z4B$)I1o_P11_Ru$f0NwC^FGDG8h5SjbM9a-RnZxcP*pz2{$Bu&7N!6b#@gV)OIz88 z13I(Ez<1pyIo6w!j<}KEmJbrmb8d`ixw8eHfe_BAZg1PzAR^=Pw(UvRV29iT-{1Sn z8kFLsVM}WGKoVR|!fjp{h!EW~P$a|B))@#nUy$%mTxPQ~5VoFhLyr&%=Ks=up2|!G zX<~QEUZvqq%I!@QjFQZt$S;&}4zns_`y(!GPBG}Kc#fPatCpL>7*Y5hyRlw)2Hh>y z$zu4zzgd4|Ek%VFaR$=+UaXh+Bl^LsqY7xMYDbZH`QqeaW#~hO`P}T2jdP6|=i)h* zHo)>3i2(ZkQ^<r^Cc0AekOiI8K{5n9Gy-8cC_!SAh?dl98N+Y?M~h4ya3<Whu>@k> zKg>|qypS1}@>s*Lk%9uF`L$@u;$X)k!)<GA>03|Nyi?g>8jK`w>63nX8LxUop;L@` zlf8ptIs<W6rsy@@71bPw<DK+gnzJlSGWf#FbTCu#xM<31#N_t@ju@>XC={4GE;pjp z%izHzjE$|{Jp<W7n4Vm|c5K#rlmP&@wE-S(%)uNPTneUK&fB|H!StR*vfz_ICL>~6 zwlz+f10{~`QA*$Xxiou8p>5pM=T|lQ40Lb8k%(wfQ8=|P`j6K!Ti?Yj2{+nEMGV<i zcupFV3~Vk03~xQ1ve@78+a<`LqZ4!n^!5NzuH?B*pMh@ki66<FfnJ`&sMzE$s&o)5 z>H%CSdG=voL}*dM_XJzLFMrp5@1^0Xa;cFsN01)Vb9Z80ycCXxIFGgOZovun0+rYI zUG2r*weXJGj`r6)^;wxM0NlM3U^zZ}`rz)icM0<u$dVO6=8~&KL@mwjf%&3j8B#sK zMeD@q!wX@)BA{T!f^3Zg^FJ%9V}Sq=q0_xO&Ol4I*Ue*2jSG<0^Zy(_0dTpT*OYUc z*2lQ>!EG=31Rf;eCjzG;hCCt;^Vhq+j1~OeOTj|!@Dj@&BZ=PUrY+D5ouN-6r57i- z-8vuj_|G`<-eTOC7?+AIb?#{Nv%eqF^jM0nZo7FW_`e%xa{v+71B31qg8!37ZtOkj z?Yhh;W5DAXM+TA1o9_DJrHW2F19hqTd4)^JJ%CTXIETt74aCeKd2#L5ad+i6|6pMg z^4wQ{KNGGrIl48ZL4hShbLKvdwrNS=bDM7H;<s9B8-LT|ZvQr$5N!m(`CvCM5Nixi z{+_#W^RdpXYyuUi6Z6DGe_0v~CL99XJ}naLUc=Ka;qj+dMF9Bxn*kwseQpSB!z|{I zxD^DTQ7T5}yILn<llpcABGj<ieM`9?o%Rzetp3gm*Q%+Cumj9y0tB((=ak6iG1~v8 z=O)GdYKz|68TVc%rF24_`~{~1j#auyY(BA!3=_F{?ek#Mg@-GNhK7s-VcL7{3P-jy zE1UvnAf<3W$s!66LbbLvGmyy&{azdErTJj_&lxD;$+_iA2e1j+ko^MyXMzE?S*@}? zXpC2q4D;)MdUPBY^znD>{yzAD*U8U>=Uc^{fky8FF6jtg(su+aG_|e}Yk`l>ZTp}_ zgyTCdRQ>hU1e=M|Ob&vmrEpGT>lvu+y!I(fczvR+Vqrz}J%5Dd5~o7J{-9r8GBk3R z7a$E5^8R1aoFL&5sqET$qWnM7pH)`KRyo6n(fF|@!71oUET9~ne8vWjh2t6cp6n`K zGp_;W*oHja0N``dp3GH`?T8Ol)W>Y4$)63bHRh5xSvcMUlllybI)j;;=bRwNKvfmH zW$WVZM=?>}bs5?2#3ndSwdw)K=D)g`^R`u;MAAG5bIs11G-sfn^Et5X&j1WA_=jpn zbQb?SNDkiE*Zg9od9j`H6-(2pRbIl$W;WrTGGLC-0Lx9-@ey$U?UwI;(9(Ne@ok6a zY-2JFA>@a&4;dy3kVLt2-!D^NWQt}Yv~B`O+6H{_Zt~@eA2FRO6ER$mwFXRt0@<p@ z5y23^-P2Bwn~P8W<uyR6aL^@1oSl1=;Q!Bw*E>xsZx`FU(g^1csA~Bz1R|bGbW|~3 z{yy)diMavz5-`Kl$=p5zWw+`q9RGvhbrY6wBp=j?LWH4HVLL-nz~R>*8Hr|{egvZr z!%YBjnBx|HauK$7^gn<<^gOXac)xUCbw?@wbG()hqr>kdp2dk68gev{F105C5y8$A z#5Zh0vT{2E?Jfh#npgHlx~8&9@$EAOSR`)o{#yLBbSaLB5VQbaa0HZVsEf_kHVE?w z2&v2_==#1)RwM1QvqcQ?qW1xh>-ytBvp{!Pu;CE^Upyxtg)f;nTJA`I2@F7ayFDZM zkPN+{FU@Nct0*|->%bPm>1gAy%>h520eF$^!lHEe>|6fpdX=+|Ry4>U11>U{yaM2H z;rj|H*je44yT^Wj#{<>B8$m2snG`q&$&)zu&8jpR<b8E!SE7cJcgb3U%{K)U-h|uN zai@J3NXM67Kp16rWT5j*r_SdN=dcD+l;e7EsG{G;-|6FlUK-3)JOD@w&V%F~cK0FQ zwPqMr?mR}SUri(RCvvZAs~7+=@-i>cEgA=;eK#xN|EOQ^gGLV`<WR&zU=72&?GZTs zu!MTc#v7w46iELuGo2ttQ~})4x$1NSU^+E~cVkQAT65>_`2q&!@z^EGqiy5Y3fti? zR^P6RJN#ZrSxQ47KmM0%CpGN12MXQCfQI0Ea#J)@hwN8+ZUvkq+z%P#d-Er$=M40{ za^wqBw*P-o;30%w_OoAOi)yx#*BK~&(%ygqk+o6Y<&G|5BWAi)tL*Q1e7>W^56^lK zO#vc0WwiOpU1=9!MIBUP5YRetp|FsseB+gBsEm<Or)u^{K0}A>DEr$OJYPti%0qB7 zkSyj@AcY0SV-`X|rR^UtJ;z%l%gk5gW%7&NQdF{W7e#*XrQRiqzInd(elg+<v{^(; zCg6Qsif|ByeFWaG@{3lAaTwpx;GhsL(B=Jba?DApLzHVO5}bZ94NAgK4zCGX(K7YZ zqKiwW?8w{iD38<ohlFUVrk2o4+>zFMFcAYb?=er74xk%pctvG|eds@6@c4=#1bt92 zPbSVNt#MEP(#tG5bF+C+rUYMU3xe;FX)a3T75n3vMXcdLc7MaxPS9cwBG9*}>6YWV zt$2!%KlrkC*`@k;q1ls3jpn-zyzg=Y7Kf?diew5{WbXzTXa&tMRDVtKS@g(8vd`h4 zfksLo*XAXIouX3niCHu$RZq=qi5C+jid8a(#kl0XYHNurp<2(F<ch8_Q`nJ>Rd~8P zG0`w3)2{mb(DkiIe;v2TNXxew8O-pu_2E=pE>HArsV5RX$^D%5w0uzKPtEP1YE-3S zX|+?&watf20TjP>x9UJS)G4r$`U>xB8eO-R;?M-Kfr_JC9&&1TxQv-`+qDaLcxoUs zM#nSlQ&#F=F3)elW0bX7^3GG~#r<-nKojxwGWY&<b@Bj*93aJZ7MJ94djPpF%h%7n zlSQ!~L#>oVVjt8i+U3vZ4YRZyZ*tl9noKdY>Z4XqNg4zunUj*3mC9F06NNJn=Gj-b z8z{>>iU^El>-W#$5B*i_zwW$z9jiqF#Xys^R=95_UsSUWu=`?X$COboag#!^WA#<( zwyV!#L?7lcO`ancQkddo;x+Syk{-QPsYmpl`P*P{rqNG30TC6O!<>-t0T=VjhN195 zQLz{GP2l2n<=BaLzWaVFMNTCu8p?5DsQu52PNpJS`#fA7sz+Y-WWoZ+D-{OSJVu^M z7glj)UbHme>XXO6>167MLx};g(E|dWo>G6gtA(z{`z$iHpijmgn<wV+#&?}OCWp!L z!{08%I!kJpQ1CgayHaaIZYc#CSpB{=1XawT`?_sAS!FPp5#7H+5l;0ai85%Bso>r< zCP6NN$6s#JNzX(e0(i$n?07()Oc=8gYV?W_b0*2#ett^o_^|Lroc9+xckmY+p;Xbu zGk@g|`!Kx`7j%}hG~MT8Zzt-gSfT_4t>gi%WHKA)G;}O_8C#K8#M$!c!TS*<h}+19 z3bJPcc{yAD3Z=)2!twr_PKWJMRDOJaODCDrC~<s_avmRDI<Ucx(SImc4$z2k*=hnY z_{ZI;K@Y_5<MJ)zAM}wf4N&FS^3`yU(Oe+G9)Eto85hE?;TMqbYv`wlGDYulX`cvC zO4ONUC+H{KAAEm=ydPnhxaaQG$F}rJP3YB8>Bo(vg!{U48ve37MoGcqgVJ6{CChC> zar<Ht9-Ty8MQKG8b>Xsy#=g~}4J*>jquGMrPc=1x?OW5K%Aa!oPo8>w)tCo}hd*{} z!;6Zc@9sE=O9vdXgFkr0Ie_<bSfGCi>mow6{MxR6kBa+x0+x#&f%uCu3W_%`op`rQ z%Jd3`UzHGK4b8cbqFtLht?g{5MQeMM8`eu1qEIQgB+&(XYhBkK=N$-(mQ*s^sHT1H zC>~jRu|(m~j-U9HFfW4XX~q$-CPUdzEYW-7A`RbEP3_(jJ>_#|5_9z;i~o&45I2$) zC@MkQmSXTuDY%m{IwboH6me7q!B=6?%h_AGD_Jsk@u?L4+^=CT-i$0-blvcu=}`pl ziS(FM2?}1I)nUDagN)BiprLzjA2m&Q^9grxJJlYW7>IG&u70bY<z8u8%?yks>SKio zEU?9b?C?V^72P7IbdsQsLR6mDrNZ?Dk6JFeQY?pu0NE7d5w@Mc8ogvr2qIR$3{vxF z{&W{xzwP;~OVpCa+;lK-R}{Z<#fdloo~-aNOjmZ<dhP!#X|J82WQ+5M9FR{i5r5=Y z{oI|k1(t+pRCxA+{CF1Uvw`Vz`r*qu=>274rC<hHfHM#LxkruatEZ;|eacD78Hh@V zSecG<#XoqZOSdJQ5TwU5JH^>6@f@rz9<y~@*#K&aPAr1N@l%Zm$%FMXYtyB(`UkZY zgoRRmXPZ4Tv32c7e|6k39%S>sP?=O(gQ&a>%6L`earnb%bo{j_qetvl4QY>Ej8(0- zu>&oCSEG%WL097K9+?M5eZ9O!AI99l>^kl@)RXg>S~12d5q*3C87>O?wM=_uQq4_B zK>*W3&Hb%lxBwIVC8AnRCf`)=wgmvK{h3Fr#uFcz--3mBxg8JLlh%E>^Cz&by`8)( z?IjqaBd9;89oiRLMP5Ca6Ve--m#ElTzVs4G=r1nvfCiU_|9tjjmwPQP%pW{9?*DS2 z52*pwszlz$=Bb$TY5(=~TO2=?VAN!L&7z>l>szpS$w4vCPyeHDJFf#mp`y%^aYh() zh!W%z^Lb>Wn{ypx!+4bRYR%Jdk#(~564%Y1NEa+DjZ8T6uu|Q0c;Fj3+bTk@;8mG_ zKk(NnjWj1G_A;h1MUZ#zfuqIBA;wob%;ty85FKW+%aKy*L7u<hRW05S_ObO4&N|XB za>EPV7qagM)qlRIFKOh*Hz+DGG%V)o-f#k+F(6ZP?eHyz+>Tdx{}O~~;=`1sQL$Xq z6hOmBrRDoQ<z(x6R|=1B#kqPM^K-_CZ}A7;CW=8-#DzX2hge{xEKg&ybQtHDS`D1t zRlR#;M){l=3{BJ-Z<1fP*@!&Cm1BquCX9J&s;LvdFPejF1#?!7b<vj-c~@G+a`!Xw z4W^Tni;SNWuUpY5@UEIj?aA~E;pw~5mEMM3?Iezu>-PMmSyAmO!L2lwFGMVSg=`C+ z-osyk@cH?y-pjMry<#qhE5fNu8q~Hp#<^Uei|FXjelQ_ZnzJQlx+|0-Md(rqF}h=T zqx*}H&vFq2s|%lL$>f<8fa=9u%D2W}i{3Wu0_%@Xsy5@1>tZn1Y_)aU-`$-1l1jD& zqS&ov&`068S5RkEZL8alZ2C5#%`*^V+vOWyoNvirn|}8*N~&K8v=XIB$?mdGBd|D` z!*#cXKZ`~#-#))G{D%w|14=ck^ifV&kIY2ASQ29V!n<mkE#-uf5>sudDRfvzvAs|n zYtm$qle*We3gclslClB5cCVvI)?XN^DfjR$ojXusbRSc)fFEYRyW{iKZXa%zCdU5Z zAOck(7xmBs<rG*1n+QABEHXnhzx7dHOUVo>s?<{%Vin|hs6f~Z{)nzq=vI>zLO#n( zM0jlI|J5w!`coBS8m~c{FU2pZWdAO@U!O)BbR>I}kPB5d+@|Ja>d#(%*Rl`2J`_}N z?Qg(Xv6ccjWp*N2YtXNdN>OnTx;_^>xEA@IH4IsC;S40MC%E5HocfTdLc2DOv8hm* zQG@qjv{i@qV<#UIXK`NKYQ%g+7maP414375Vx?}_r&C+-OGV5I4SNj6aLe|}ZMEfE zQ*w{NU?~#2vvXuKMesZi<-wB%i705z<UFt;l(Gxdmy=Hp8ii5@8OaLOEg$@~VEu8& zJl@HFML+o=_^6oERyFjnq%lKKcyHkDU*U)`!|frD`8=1T9@zJ&AI?c};a<q2!WOu= z*N&)q#H<_-$X~U^a8uRrPQOAg5<ljm*tsGnrMQxW8Oal3jJWbaD2elt-#WvU#ZV^B zjfX0WD;ZA@`9w@_+|p|B_`Ub2R<N2V+6mqi$-k%#^Lg8vxMd<0;0-O6ZrnDWji*5c zWq(gBewu0LD|@tcNpu_9!yqeBV15ztVbS+6|DspK<OCw@8DeyjE$#!lsKVj}%{J1> z30PcG!Ic=(Un!d2_c9Oy1@C^ZAZA{ln?O_tkRdCKdx8q|X$1H`U>=Hu`+B7q*M~AH z6#ufZVU2&$Sl;`6aq$?VcG(lGHj*D)9=LeSZgoeAQ8AZp0-Pus$GVF#n*O`!Tci~b z?}yRfzMv_m;bWpueQjRq@nr$q2B)fTLMa1KZ6y1c|F<-wgG43nkGyDvM~`TshSbnl zaX<ha&6>CvuS2|3w}X%aY{hVSF(o6*JT880nCbB{!tYPfyRgl`kUD)HcZ-Z9?T#N$ zK05gKLcvacDH#3BlyH@k(f2_u9w@FN4~{FHTq?LSN$o)<i*cF{@vTm)lq@Yorz#Kg z5)ZYdurd#=O-U0Kcc&JCYcz|D^L2R_?h^wN&_B#()zY43W>Rm&eyI*;1d>bDBU77K zoLl#-BO?|`h`L-JdNvnHbu!Gh`7Py8O5VLusMrk+YH4Mg*l(01t(l^=UA3DF>II`m ztdz07&o!-_t48H6dqI>r#=-{t;~q!#ZYiS)C&u+zL3{Pm?#d4A9!Xi10kRxP%^*`2 zMrl}u(b(?OyHutuG%HX{>dV_-Q<7z7p-!Ky)0Q$b(G>=%Z`PE0_GF~D1<2wYS~X5q zzD9ggT_8HG8Dkv3*K7U-towLNrc>dB&Z6t<tsQT^Uai&RQf;4KE5#&DjL}!k5{iYr zB5{-C^4q%++HHASL*{_WERM<?-S2z!3?l+3>_F9h;G$f)r(_3`?A0@GbLyi~TesG` z?_GX8pW2k?l&mTKGwP~dl^4ch3)U>!fv%dU&1n+<JDUtb@{Trhh)nU_za{{tjHfx= zcvLODuXtjjTB9WO{0=P!c~tR|WgCkT5LWGZn>!W%hg?z*ZdM|s+{laO4KO~$`j^rg z>>}@nIyOBs@uA&__#yT;elBSM*zEG}T@4#4=_^X}B>Nkzl(BX7>&tJJIsxupPe!I+ zK26H_gyYLL;B;(n=CpuJ<mlWfzs;v~I;qZfNAmWG9j>_YW`qQ|N?o1WUL#7XHmCzv z+HhSRd<>K=W~S1T3dj{B@tge-NlCLO!ye4j%?DXXVFlFvq4`^(U?HrS_*JP){-a!) z>tyJ#b^j9A&a$gEjDD+`_Bnogse+Uzhq#iUAq(##LGVElO?O2yPZghEfyXpXB!=E2 z`<dfU7jueGui2xr!l}|%Pvda1-S5T@1rS{X$KN;lO)l9#B*!Yn{tWc|`igT<%F?sr zf@30?V98PWY?(klqUcM3N51`?Z_!|ej5@jtao)lS74)tqi87l2mML8}wg{IDW@4*+ zQO}$}8J09ETp3*2(&hOI#TS^-T<t0p3DvXhEiMS%9vq=vjpG-&_R(1CPs8uOThLO- zjhs#lLa`#@`XzLj+7}kjt_-EHcVFUGu_86a0{ngzJfAe;9Be(d0*qicl5hW}J)$ne zlsIyI{mvC8d?-h6w#aM4i2TA{cJ*7s)xZ<T#K)`E`v-BS2JKJlY`H!wdwM148x<r7 zgeq2uT$vf@R1G!qzkF2_i$*9LD#vv;MtHGi<Oxx|;pEz)a?^J5M~%TxFsgqj`Y4iv zMHvLW_;O|*Izd}J%pU(pmX6b`xHGW|Y1Tp+++QF1OeUQDy#VCEJ68DnBqS=cel;o4 zV++=kI_VJ?^K{?;ht?qHUP?oIg_2ebS0}2HK{GsJ2NC!zYltPPkCNZ(F{6ft|MsKR z%G=-ur)2SmlDAPS_lD^9*?AIfD^>~N3(6Mo*=D0H>^WUGNkzdb?w<nPpRA?!GJgkq zYJ>S3kE=BHLK@rnu*995N8j#5rUtAvUpTe<(<(uted~z*^nG4xoOFX=xVI4fD$8@w zzJ6GC&g@7qRp|MzhUc8<JQww;U1(V4je9!cMq`++@4FulVcKV)XA9E^B+deVwE*vI z=jj)<ML*}dCmDn(q!4BDR(lP(6PSU6v-+j$VBMmR_<YUVq8|(&;<^89?l09NFF4WK z+pdGEuAPCRrt!4E?t#~Li!;#JL)cywsvR$Cz1{bjpfP;78@a$hP@}HN9W*{RAD5ke zoj9oW%eb^F3KY5>zeMeKrDe2*Xoa1OIYe>#!SyB%o!7mg!unyZFI~51r3QFFMqwxX zXQ06r2yTOz4zv?E!NTQd<jOsYVh_K&)#{{mT=51=u}<4rRH;zZ;;Lfci)jlD{E^s$ zuIB76$eWPM^+SiBROVkaBZ?&BuXn;)>+M}L6Z>g*R^mV*BuITjhyBK$*LQ2YYy#m0 z#Xbj4o7h;@{_Lgj4}QLcrSZzLiiL%p_HQlU{Dk$cyO`2ND$vY7J^I;D7g)Z4HE(Bu z9Kq>dW#jovBo6N%!0{re=nyu10y3?gO_jrMp(|tcq$b9DPWXOnyf(`s#n;s<nW^rL zUh$md+TtGjJxRHRMbD}FHOPBq-sMFMk?Nep%~@v5Y8+OCdze^BV-OBG7@uEms>3%i z-djWHzPd2Kc$x!(0E^dHa`(Qjo1dHReiCP;0_S0=nS3On@UaQVr?O{c%sdC=FlO>n zDX6(7!}CwTrT0{~!Pa_aMm&vu8yOD2^zOju0xBPBY$ZH$F5K+>X-=0Dfk>6rRIx?W zzF~f@!v8RUJ3}EBD^e(*E9B__io=yXT8k0R9P`0-$0h0&6_?@aAIrEGRq<YgeMh8I zI&Rcs;<C-g;(Iyzv8^>2eaCv1OZwr|{)>}pjyAuhZM3%BHAGYHR5Mg2U7fZd<OvF$ zysA<g4U%HdYVnesO9TmcIxFAP8mjsroj2L~YBHcjm;B08BMoRfnPI4ZjG8N*O$l%O z(ZIZgTx+L|$HGjOZ<(YExh9`8<IY}wpYXL09Cl;e8zJ_{syZWoT9o=sF;8+6G{Nb` zH?NMK0Pg`Re<o=yp;<(}iGHp|Y-5NvZ@?t~=$FJqnE{uLhAJ)!Ukb>(Ys1>!%K43^ z+x=phj7rC)@(p2z$@debvNue90|>?u($aTZkH0*EE1`E)91FQ5X9_-}<9OcllDyyN zfBV!U|9gWUE{|_I+Av!E6#*_LV8l@tbuBzEcWfGAhl57Ku&@fsrhAWQo<Ec6?a?c^ zH>qxy1WDUm85$2~B#(1diFnld9ii#kem|Z*XXGVs<{2pEu~TZFgL)$sW<3zH@x<)Y z%@&uz{xHL8Pj}F!HjZ<^`8R1vhcz={qAiG6*e0O++0Py-I-;R{r14@JY4paU(P1nZ zJSr#ccnv9(++?zp-4$$rn<M5QCV)3?-mv1XwY|E%&y+SlV9Hf^_!~`^*Ytdg5$4}= zbLpK-X9&-zEW@P{Wd`8~_3<MUGnXUdWyuVgtiT3+Dj9?`&>1K^0CNT+gFgq>3NHRE z4>G_8_$_qbPj9Y`HhBArf)eS%2oGgVBK~nzG8seSX7O}vDL}B@1?h2Tu>Q4gnfRSG z9k#(QjZa^4i=H%NZ-_aXy~({|(Q2uz8^5DlxVad9*LgQ=Y?1u7un@(tt8fJz25E5H ze&Tzo7v$A6Av^o=DYh_57ZGu3`L#wxS|idSDQfEoBtT-eE`U@!5ZE+3+Enp33xDj% z_hjfr5ghZwZ2e|hXFA-%6OxzYAs<pZTpa#TB0eYb>JixUa1Y#g{WK)vtT<|6*hG8? zGk*=QSX9$ju$Vlb8H*lt2odr~Y_UDcN|s-IXmrqnnCn96Rq5}hiOi)q7zi1eBTWG6 zIMPwvc2yPeQ(d01dr=Up`<SJ&oJJu0cN~k9bu6qF5~U)7h2h?{0lPxp%P(cRNi<`S zZR3Q3IUx+CwA7sIn%;%zqGGzhjFHStQ`BufS`@IQme;7?AgBN>RVd=OQX5n()OP2( zty(ve{rFJ8ZU#xA`d)q@lh<LtP<f?LOLc6ZyHe6`qx170I}T>4RgXu7Y66~tMm0l( zqND+hr`M;^sz+C<$>Pw7ei+^Bz}lcu)Z_MTh*`jO`_<#a+|+*Q>j@9+%iji3EM)gb zD%gM&2-OAxLTGS&mWOulgygr&`yp0Y0fy4IO;iqnWj|L_&wK~OhvGjCJPDlTO?67C zH^uE@j^&|BCkA$${Lv$otxa62nMU@ZhyWuIF|KBx^~WN8=ms;VVg(c$W1?Fv>S1)P zu_2Uj(EXY}K>&Ot>&4ugw(|WYD8n~>mJ6I){FpQxPxYH&<BjJ2fW<qN4lXSlO)L;0 zqKb*v3pHZNHt^#g$Zj-(368_J2Zro`J;Wx4HcsCYgJzN2L!(1>X`CG!2H!wU!d$Xn z%-L5FQYkwx(r&CWb)A7K3^Q2YHCz_p&D=8*dMmWT?vm%Q)3EmFCzk*@?7puht;d63 zX}sZj8%FQGIsBgZRNSXXq$$p(5V$bxqaKzy1fytI851w(Na`gzoz@4ijvf_1(X<|I zRsKu=KBspn9y~en;ZgQlZ0nT^yvL=3w?b)_Q-3_Gr(L`-_MAzti@ZWQ5uPO(n%96I zab0@$O@x9X!$!UK!fHlMO-7=6i`Qhmh!<GoLGEv<*$V0#t4WjC3bro_eO$OQ{f#K~ zc<767>zAbNRjV9b%UWHfh;vA&c$Ihewxou~gXAAlp|_Sx7?G-i9UG_u4O<~k7~N#r zlo&P-3#^4kZ%wT-2K*@-ih8vF2DCz+uNBHAD9F29&e_Q+xK@~~ar^L3V(c#v=#}h< zVuwPJcDOb&B>aQtN8zHUySEvHK`B4(4ggh>!N>jXfRNf>&$U$!v_mJ~Q)2o`x8_Q< zLG+zmo1&kzv=$FA8u@j>eZ1icgi@8&xB!w7eLt=0`%hn|(N*_-FLzb<UNmWV*mhX# zq4k?lM2}CgauhkolIIz``5bA594Qll8jcm;iOU|XgGqk9aZL+ZpvQG{qO{Dm!K{X} z7nfJ^=><ZShCkI_Rf8$y$VxQ=*oQT%GzW3A_Fl=5N#2A~Pjs>?SavD&v0o8LwDaA* zoj?)av|%P8qx|lXr=&m1?S7L>#aJBr@7VnasA8E<ub%$oOlg;FMWPbnXNsBe5E)8; zqRh;k9Djifig|WZ{86cf77}fo#KWFgw#wX#mXrH*aTVdeYUgoSa_x&C6A~IMnj1NM zu)AS=bHFdpyxzi_vqJ0e>%}EMzEdFeq#m^8EmcF+`Em=r@o;^V=y_dR`gviIYW+v` z{Z${Llft~#tgEEgOmp<;B}IDM7qBR2#v_%qr!}!JP2cZ+7L<31RdeC>&~KfxM=9>^ z8eL8C2Sb%&W7<oQ9<lcdeh)p-2*EK;#tt=nKszEi2W-mH6v42Eb*^Fw0xSWHRAQT# zw(Nq;_F7R9L0r)BB%{{UiFsknmwIg%ewk1>YsN5M?Ua@@1m|z#dqGmh?tCj^;4pn6 z)F9v7l63!$)?Q|@dcsGZ_WK8r1de(5>%7~3r_Ue+?=qYqiMHwtbnPCtozz-+20E-? zZn3b`R!Y-T|K0grb#U9+>tGJH2(&xYViou=52a%&fexUalJs`$1GgD3-5SKE9`m}r zvfqp`eZ{YbY%CrhniSYiwZonuge~X!$7O&rxdy&Y-Pp7?mo+~KO~PNs3NJ^MlutP+ z*;ji``d)faAkMq?QClE9a1q$b-X&kRW(D%bg?HT1;Xzboodqao%1J4t*Q<$Pe|_mP zmi}@bmae!E)2dr|d2ifHUrRJs2hfZ(5DavOQKk!#W@ZNAZ`H?Ohp*(uMZdmEZtA0Z zWMsGH1oUeFaynU`a32bufjoc)82o@DeDMRMPI_PENp8s*=nK$cLa=Xt4&ooH`?-B} zE-PdZn*KXPo(X?VV%uPp#L56L2A+fv?19C0#vWp6%o!*Nr4BjfZv@&d<WBiC?(y#L zbR`2aPQ!rJa9rJRo?}IjZlPs!ykNs*{*B-$d<S8`9U+eO-F}MYp3y;F@{`dYm-Uk# zwIpUqEYT>XC6oUEe|y&M<%Q81GcXe7Ghi*EbxpztW4mw}00tz8=YAP`M*2R!dik-U zwdDOd$@l<>J!Xi-uj<+JpHf^X53AYJKzOGj0k#*|WtRP}jnDDc38Y(0*15!GEAbw6 zCFtt=Vlv}rWS4v7`FRv6gEUX22?kAjQIQ@w&eF=xN{{HOBv`Z=-Q^vU`!y7|<0i|Z zyAMuN7IIggeJQ0!@OW$1T=b+44j7ZZYcBL^+gRw~qSv<3P66{Be}eMlXVg_E)OGy! z9vwUyaUt3H8uO;FC%v<;;8jLi2mVDy;wGvKHARn0#aAu9Wa{B|i;=~@B03FAROGcy zT#bj{>@oZr)62!X0%h>`{qd8&>Mfi%2(rjSzOUo$MO8TUSM;ElOaW&BDF`9rz0~Tl zsOZCiE5npNX_tm)x=SU=KS%NgQ~8<3RvP#O2yRG@<#9V<j6)Ow<9~rWJ=j~;<pE4s z1K(>-gW<1nZ0pT-pNJB@r`z%4A-^uZc%*D1tn#g<?A(M;_S$jg#Ls7-=P+>B3Y^6+ zb^@&xzprep<Wq39Pt*N=y5>D9Z3_p479VE3jSJrc;rA2Mnk2vBX{r9v*6Pib<VtXm z9qZwhc1@TIQxpW-*lwQ?W5p3Kp|roElN@-L;%epP?&0f)SM!X{Kw;bjA7Vm~;k98o zOWFl=ZKma2TD0xEiiDS)aHZ`oBPWZB9rxu8VMe?1;lmna&uxrh<+5R?3b|)+nbY;x zUm`-4AZF+mP5C4)+oaedyBS@C>|<BtAe_F1W6u}&6Q8mS73|3PQU9UY@Y<HSrIlQ* zHq!^@+oI)9zN(>r?~Sy&k@()68c-l(Wv#1lTMGoI`u4@QF6Ju@-6@z{3Lv-Dwywgj zY*@oY`s#OrrC&eR77CG-Ah5FHidEp>4L&EF#t#6%P!@$BJry7gFVtv;+3)Sfc+Z*- zaDVs9%iL(rOlP=+qbpzU%_&?i)l>Ph(nuVp$XIK;PEZ{U5hEz>2}jhuS}1b%VKp7t z3>ypW8j1*KdPa3sQ9KW5I7sMikF=7HUY3Y(kqa;3>!RTMr89iZf*P5#9uhrM7W8}% z2wx@@iee`pGH$}lSeBK`TroUf0v1_3Fji1(@R42w<dTXBcC;JR8Tius<~Kn*3J+#M z0sh=EyMQ?ENn(Mwj0YCySJT<}HUTNOSvoN6R<hPCDwkZJt|ajqQti9Vae5a|@o?`? z*s>1OR@S55ryMgai9h$79^V(eNUhexv}Tz=P&xzQ@_B(?2kp;Hr}5`dS+)zT^Q-D@ zJzZ2EB}W4X4qAitLxVAWUg=(As|j`?0zo>&@H3Dj<h3ejGRU#QFGWYm_>I$Kx|nmh zwosv5k5373iot^Q$pQtz+kXW`RWO(n^b;@i;_7>l{31DLf(7K4eY<hHYi{;5{W6Le zDh^Am>RFifSxV_LNs0({Jpj5ZVmG@UT5R0%dM41CH8OUrSn+1nQ`aaNG(~C4{?+!E z06Jx+<k#!Pr1<Zx!6<?5W;IUXzmo~S9ouB_!+R(lyzL@p%0*%~f8WNjP_k!7P+H0t zlnA1<VVqN}vYF_MoqMxM<q5CedVL1!yccu<-FldJ1`=9h?|PG>uPxI~&$hbb19XXQ zy3JUVqL>)ZK#QAhBpEfJBryybrAWYQ1p)9KQPPed2pQH-bpG`x-D_mcG70|;K-ywr zp&kKA_#Xm!5}(281ODdS=mcU<;XmZn-qr0KRMsC5Us+4A-SZ;x>7MGG6SQN!<<CG| zc_cpVQynj$^#;WR|My_)+ScN{49g$=-ym-_NwffY!ryqjZ^FsDbBj5DCulD1@`j)w z+&dwBeiJA3nDzTY3l5nB7sbPplBU&mzyc<R(zl_`z@$khpL80G(S#f_slX@MN?)($ z*Im=Ms8Y|G$kTl|XnHkHmp9fZwTbeT+_IGvRwFy-iH<j04MpP(k9wLus7%6xjAOq= z23MJ(*uCAi+H$0({1?Wt&l?-vjb*uR?95&y`;CTW`50SmPa`#sze4pEiwLZ4zzHGb zZZx;=JAy(6d*Rz++3+bR->M5=MWr4u8Q<dZqyZ}`sF=6`%JakHirx@}lQv5G&LzW% zEoOK1s<H+NVxuD}#*JQCO4Dmj59b^5+cK4<!QT12raM60Ca6KMn%N1izfnsnh=RH& zF#Le$!X?0HAKJM>E(9q}5S%OF-=SXlj?DCL^GB=ZwbN8WO~vl!gk>TEOm?Ln>DmO{ z!3H;UGm-m6bjin7yeu=-wL9&(&BXP{V@nGb34-4WVaL`LHaXQOYd1<68wxPFPH$M% zd|rP;$$U5Ib*vm+&MWf9DoRHVRj$3F7!`@2LgiM~KU$W&Hc{{TZ)q-yO}V&`-;r*4 z)=DR(`@&=Fr82u<HFGg1WXZzeJ5che5=%(pR(P3C-};I4FP(BD1#3UezgOSw&rdUY zW}0U88(kMbokOV~VTmHJ+;An<c$c4nhA1Av{_@kAMy-4nPyOV}O5#&K)nd#*Mr#4t z!5Dyvh-~bA$jl>N@#>{vAc-h}1M|k%7N3Ye`;T9zS+^_`x|o3OL9AZ(4E<ts*PLz7 zNl!_^+=khm8<SE10H!=BX%um<;G`t)KzLF=q@ixij<yn26(73N^ghg&dA|_k@s0N) zl&13pJ<=Z3qMKvtSJO3vcvE^?{MFq32_2medYbX~L|68OGe`m6RbVGrP1QEla(i?} z^;4YkWUV%*jn>CGx9cbe4THmgi7btRvY~zt-4{Od@_RgZ>+k8uSlewW0n?usLVw+f zh{q4Y>DsXnoERQ+`oNDG#_MO$&FvCkc>H*#cuY>)=6#DDwX(4^sPAaY@91DRcJih~ zghY?0JkYzC8%s0>f){w#m$?DQaRAlv&_rczw)B^h0_SYbA_B_-E?4i{vMw!rM-hlY z?o!no0KHGhXb3qLQM0UrVs&JAo;R%vSDJNxTpOj3_-&h7l6HoPGVZWy=2z?@?1c&> zG@B(1c$9;|8EE8*SoX(bxvyIxG9(m?y$;5OxBqkV8NAkNs=u0;8%llG=6)K|AW<V& z%Btbo=WT*NIHxM*3}pZIz>)u}Oz4O@0nrxQI8GaOhkwp_qCoh%SZ0cGiv062HW4B8 ziIH#W6Zv>;UdHcDbz|o4eK=%=WfV}Y8YY`&%>L58#PE}BcVYgsHtLs5Sa#3nw58|j zX&s6LOw!)*yBsVmT3k+~TIlC#<7HufyJ!W7T3oh`(^WZkpMIU{+?9k_Gl{NmS3l{$ zAMn9^aLE<u6LvZ1u=c{+H%Wkg?4fblZOM~M*^#a*BjY&jK$ma@L0n*o<hSa<A+Igx zakvfBlo@;`!Yq9`y?ak~o<4rDqAu*&yRu(JiCT)LY*>%*?u#^_3}W1n3bfGAM5A`( z)k~#G?UC(^_uQU8r~7f?x)RkrPKqhI17Wkr0Wab|{J4qg(_?~n@`c>M*I$OkkpwrC zEKmoW&kl~rWu}sCxlZf?GceBpdkORicDJ*e_HAa|rr1AlK2nPPzP+RWSE>x&$=YI2 z<n{@u$Jt$kvNZI?Urh@Loi=Mt5z2bo1VZ{2fHNS&&&6|ao_^oDaQ#+K4&OY?Wx2kZ z{w6e4Ls3W^>?wB468||P#heU(4~xRR8wqk&F|#jYS)ch9R7`JAoA9}MO|N=o2px+P z(|P@x*CvJJVYLUee9!@W`L4IK1u2&W-NSnq{K&`SdTuqheEE7i$!R@L+=uZ}kX;nW zZGBpZ8H)sxg1v`stm|JLx$|nAx!vh3Nr%-Apv;3tex^k|vyCEykJA~Q82doiTpz1z zf*Y~egm*X+f75WwK!^cLPxtJHgx$BciFxfSNH44G<#x6izd-eGV^!uZmxj~5exHzS zY6}GGdcvxaTU8YybJpx`b-Szss@d36jih^rUs$;Bggmc(y%Hsu=32@a@TIg&C^cIC zB~xY_PY}yqHWG5N?IU*gyIEC?B@M%Bj>tvmg|C^K{O}pUy{a!NR6t4d9AC3cBbeRY zb_K})BiYB~lPiyFBx)$>LW#Vw#1Je~7m6WB9NU^59dz~c^g8#=&)ZRh{gScDEPBSa zV>K+=tI5uvD+O8izoJMq;menCRk57~$ZLF@k*JlM4$d&_U8udn^kH^vnsg)NhHr*? z4$Sz;Lztj-`A4?M&>W`Dg|`r_PF4IFi2g=lTZCHO9wPgq_&(m%OQpZ9@RCttwjG1D zqMy}**2ocXh6aN>zGafOzx85=<5|z*V)SF_e27&R=EMy=(PlyX3b$#eB8|=Se`{~3 zZx~X&tj>JP?2tL~V2UYCEC;-M@$k3j&oLIV$HMkEvrs>IoQH-=C?y5h1#|h4BVSbv zD(c_n&ChE_2uaC^A~XUi@EL1Ck~5QC?VL{SOoS&d#k0#C(^<?u2%iq$e;t(or9+fz zaw>u;jdo*_qp&^sVBvn!=Vt$%TKVC!EQb!*)XIwWw$2iLHV0nMXtcdXuq9BQG&F_) zAFxp?+*9x2ghvJhz&o$Q9Hrr_a!cc?C+D+38_-)CE?>DjZLNO>s*VM6x_dvYeNRoG z3tp^yKpw4js=Y!|Zv(QxPJrCLC3>ZO>uAplr`(QRL&fjBlqi?;NwU4g@zRTVI(&UC z$)}njX)^b)YMrqSSP2V%LjX2tBDYVa@UbH!zx68Dor!gYi{w9+DVv#&^TbsfbG45t z_S5G7@HAe@xW>R1%V%Dx#zox-iA7v*9~p@HRM`LW&o|*$rS2YyAaH|l#XW3I_kzoi zxn9znj9=RpNBe_Xg!p?;30j#0%dM0rN-HE1-S9x|EBPIZlVk|~YWlW_7v25l%82@V z7i225Xer4R_KBOos&Tk+$jC}k`8oyUh&vr<C^y-{rA3_HLXjGaNa3RM)KX7=qrdHh zkcSLGY9KvT(>(Wvz0W|LPB@k)PV)96%(fwuiiwv!`JR9|!AaTQ>uN2voRzMoZam6< z5osr?M1EVyWEz4sS5;*ss37&W|H2QmFiQz!zuB>s?~8=!?KlY{R>-{9FZ&7)m7LS! zsl>M~Ucd3{A&AdYd(q?rK4Q6j#+&mno8Gjos`%IP^%;eqyPocpFY?5-&p=1q4sQx4 z+eGoZI(XkDF-M6b=$(z1#+-UG_x0w4zg7vQj8Y<~Li$61M&&Q42>5fi3ubdX=D}Xb zgKk)@ikj@xkDLh^V(ywdD}2(b_M1pfvIA+caf?Ao*ez8EP;$3B!s2k)h0O^pUPAZN zh4$HoYqYocm**u1nQ9{CwlYiz%p4}E6q^8IzPy`nS5cX~MYba^+d{h2ZnB>5acdsE z7K|h?(>}0M+cPcCipx+nIZSJ`<^XV-B<XkOQWMtg-68y9t<9IPd2?Ex_*ljx;mwY~ z$t|6W$_LsAsoPbyf7kZjHT;m6Ua?Bh#AhujpOSa~^|b5(XMhdZe!hPnOndypr;Tfm zF?(4TD)H)X_Yi`UpNlDv5qT(g8oVdGln@C#N#mf4Uvl`R_uQpzt-!#1hA)eu>j7nP ztI~_{J?)I`PN->=8F0#2_6I|L&88L21ch$loc4sN+TW$b!vou1bfc&rWo%<##lVt& zkwf)J`O>4zRk+!H`&%oq30VCrH^%k!YZJk0sSjd(l7F4DITUmC4fxgvWXexSS#&Hd zeWXnKvfdGwaDcJWTygvv1RU~<ADv|ePP=U8AIg{IyCxLQl4zft>N5TPprSf;IPnK4 z0c7D_WiZFwQETiTlBn^YqCg$d6Dsv&F4F`?eg=A>H?6tiu$8@30W9E4PSj4jNJvn< zcP?6J?ehOb&(PnS$7wLAtG-0Ez$o2(hY3wk5fi+=PRkp%opIVlqQ9?2L=dh(gYLGU zTrndY;Nenk7dGC;r>#>tQt!NcxILYvo=ZVdgn5*?z4)w3*1<I}BSt+gT<NG{=N)$- zTbAi6Vw_$?5lqM!zOL0HwGFhX=urqAvF*B7tA%w?dO}4uT)W-#(N%R;I**WrioD~E zH{MF}1mbcOALQ34^l@&-CSSi*uW(!$59RWQqGbDOu?eAy12@4xZIzV0_8ZhpZic)4 zjgmnXZ5UL15g?~MDz<;~-o}TpnV2D~@_I&l(Wg{AvVlsFouVaItFLp_P)GT?z!B;F z+#9Er!g>o^H(uV;ajr?{m2jx?=vwntEpWsrU+Meg)qVfZ>wR(Wm;AQJj2r}PAre+c zGWCnvn@%lnd&o9U^j}?moxFN-RBVxwU7+PxD5XFUQM7)VZ=zy{7-y~KLIxyjyQ^kx z)+T$bi@J8be>Y1Z99wjwh?DyNq3NvSntI>=KO_}lfV99!Q9`6da-h<!k|IMv5fBg& z>5UMOkb#7Xq;w9Xb99JwcZ|+aW570l$M^U1`xDL{kDZ-!-&Z`Z*LB_5iFyZ{)A_pH zO14VTXW4&l8(ZG@=5}Cx5ZkBPuZAhs_{Gr1g|xh_ANBJ3r|#wC-}GAC4qG)c^=`dp zS$@0Sqhu3@xxDf%`)7|Mg6{1OCrKG-c;}9K*77fUY@7ak0k3?@&V|b#5deAgU8Rk+ zNjplay}~Nb?JtthB<DU}!5ed%Z2w7AmW5t=v;0YZZ1<bkiAIf@S+He2g`)<Y#SbPi z$d8F=k!6=hG*p@9K|GSCnS!ZcmC$?_sofaLP=h<~L@NeYLl<eXT~z<6ffCxUW_0f& zTPtOH6D_FwHRugxe-4J0L?1NB;^OB6Y&obW2%_>0k^)r9V1rtMXdyOndz(paU5RYI zjyB~syYqxQ{D@lMUY~>AiIj6Om}B$}-NzY4WO|_j%khEL%||-HeeZdAM{H|r`KVMH z!JEcY4%)ANOwu)-+?}|8mQd86O+Ed_v-^iO7nl1&(&`Dj_Uv^5VKnAx;&f1jBE61; z+P;ZIDs8efkHVFzJ^S)|o9WYrf?z|-q80MEFVv5Tq8Sak2*KUe#_i-f#J2#I%I^i9 z%-X>%Ej+;|S+!r^SO}&nJ63=5O&*nFie&{0)Mnv0*3#J57t;9w->(hC>Cs8V48Tt~ z9b7Q_NkETxJ^zBT%O{p|I}-atgR4`)8&0@F063@NUr2-iHu-<ogTu!&_LmSJkvZFP z?YX2|bB{@lfV&x_dmU&oFNA5ULlJ#?f%ZSn6-Dsc!cta_va3ZG$8#VzNIEYkT^33t zR#d(~Y*4}xhcdE<u5D{GMSz*zN9?RMl>v97>3(4k^xUS)0iIew?P)Lmbt|;peiz~L zy8CBL^hsbXc7ONc!r!Y9r+zRIDgy=MT{Xv-#@??tB<kzuT#XXEd1=Q+GBDM5qK{LK zz&g^2o$s7RxA|Y%`g3Q2J7E^9rRgWl1|mKgbH$6p`VMlJCb^HbsY!aA_!A}eYQ~s@ z!dqOID6L+s`f~hs6t^PI5drV%h@>WsHBq`U;GeBk)K$9CXJ$Ra?6SUNjG@2xQXmEs zJbQ_T=TGK1njJ{IKcDyE5-tq!nGXYJF7EEDrtC4i7iT`8={e=GMdBGzQ(M8RsJ4OW zAFX%%0CN`<vQ_4=QI%v}ujILX)$gWmx+gL>iJg>i5eAD&!<u+Tk!Dia4!e)ybVjDi zM&YFUKr?$wrA&8{fw)T7ONy-xZ6&xzENZrh^^ZjmNJ@K0F$qwFNm;IN)s}!Ui13*Q zSl05l*WY};TpbnMzpm(Y3W~#<4e4mBm9O0zd6)O|8E_N!Ug}Mf@EK{Zl4S{%F4a(s zX)l77OPzXI4t%kOb`I=D^`r0t60PM+`@t$V560RRUHl&8)9Su@*>a&=)53esA^7|x z8vSrIHR0%U)r?BEs3<$>&H?=Eq9J&ocv}wgawPo=`^s02D|QL|dKWGpEEP0L(V<P^ zz;~DXX&}hqzunC(XV2KC*9x5+c<3)bv6W`ryZYK`3lf|v8@Vjk>Pm&rA+Hm+*RE`0 z-?0lf58k^hu>DB7Oh8~l7Jmx^p+Qbf;I<B2KL-797V+14Qfc*Ey|MY4Ds{==R_$Mq z-NgPgxE7-2WfPbFQd)!x2%lohXzc6qemk5Rq)&bpYd>39Gw}0Djf%yMhd;B~*haT1 zN?%rR8<Gpx$aZ_prtuxjWWT|aKZ|T{VjnqSXP5E(uqky!T)YfPdFeGRWn&vXwkPK` zdp5>nVR0%Atb<4a2v?IJV)80t^O4y$7KiGV!1FIaxJZJ?^FSo=mJZRM3og6ZIFR*} zo?6CzSDiT&u7+r_hF|T&ZezfqaEaHYXLp<&t4@moKoWf9PFx7M($&;@$!(Z80XBg- z5N><znjs&$w3MKk;~wMRg4u>uE&#HdQDXXEkUfMIZ+(+ux^?Equ4q)OCxcjkZ|T)E ztO5yPI{|FikJpU`OWyr@Y9&@y_*Qi;)XJ9!am}*T<yKd1Jm$}6J){<>8ofcZvEi?g z<`Kuf6JwwkP5(H8t=k3gKjhijU(nD#?8*3>Q7n2UlcZ0*JOS`bL;_q2-rM(?b3X_% zjKCSg%3;+2q3VXRqIbyL2!#jbIMZsW4Nt@gPLre{nh8G0Ohq>jWIYem6EUQ&M)a~U z*SWLwSm&++R=Tp@HkbTL@>?HY&R_4>ne0$Ny|=NLQ%Tp+`)fqel(>0XW5fYC1i~VN z4gh+}sY3}K%e20=75*aI11VyeU}*u>p)Y~o)p)D#`*NNKw<keTTzRi}b8oLNe1d{A z$6&-8eXm4Qvcp7F8r`fs7T1|$XTp+#M~Ro9SPR#{tVIVEY4QdA>c60s2t&MITJz9f z&>b`f<RY{MfGI3zW**pD@~U33o5utA32}_Xm7L(`%t7E=f9kb4)`Pn?t!;B}ZVebn z>u(^mpqJr7n=lSImlvY5j@i@LL18SfzDjqpRj)vs{cVw|Ja_o{gf*3DGt}mB+T_9# zl;bZbTnbF^-(J|3`h#NL#*waJ#|w++#Xj5TTK0P0`E+TOk@k*}p)d%m@28Q5wJ;1U zqI!?wxS^rte0M=$CVYE);j<TzohV|W0Q<~z^cVC{86l^_G?+Oqkldi+pkcfat^8T$ z$A|kazjug0=4c@iXp@Fd!~^D=G6r#QPFNx4kYrvXD#CUhyfHA^rwbjK^FLmGmZeFQ z4@+P$6)X4y>Q)|LS-%Uw%jfYy&QvP7Cu{X6N?@7m)XdQps7ruKIRyRnU9UJ-x^p}+ zwfA6tu+vRVk;g$0$=xvql4KGaa(7_q(~2QfXQ*VxEKT6ur()IDEj*#dOn*Vm1rlsq zXlyjz$*3NBE0lE_I^9VHy#{-NXkl(*k9~dsURECU_6_GB5*K_P9CFE_-#5q-a<MpG z6YhLXfz}(6$ET%qTEN3Qu|p8gaO7;tzF9r8!|VGa+z_jgo(PSR%^s-q10*1n+y@H; zUP#$Q`}L3h<y&`qvbutU^xHnoK(I`J)c@1A%I9GZU4K`d^3gX7e=6!jZu7x^#Kudd zbqAYnw?dzzA!*^zUtin&pRXR3T+@l}e5a^QCdq)HVA*SrGNJ~?Krlm^g%`Vay9yj7 zHJ%R>bXT1iQv*LXXLXTCMPY{ptPc~qtgbS`%n>b)Du54h@PlF{+OL}<{Ig&^+0V2x z(?mQLIE06+Z$K>kw=w%+K4}C&9*&WH>DrZ#RQpHK*H1VIPSs%Xp#f7xDQ5?rhyH&- zI(yK?SPp2F^)F2#?J3Y|r*dVrLH)Hln!6Ba)eCxf6+Y#&UL95mCf*E66};sEb$Xq3 zlFhMiC9L}KlIS52O5eiL6}u3`50IJxMFAzB3ma^(8kXaaqtm)Lgh}5ch(;(SVmh2@ zlJFicy*xm^5OS+<vcagk`5N=0ON3ggR0%VQnG6qJ?t7)|yHse+cYV$Llx!*()OLg# zU%(5dQt!BBBPK0@dwXC>FdLl)N->EfK5S0@^`{FKbL?3m=%6QYZz9j4NGuls?5Bu@ z9)xikL6853FdsF3zh!=*#C1|aiwndoO0=h4uzE-kg}&4eB`u;~L(X{7Oo$zeQJ_+u zs1t--UszO{HyZ8ItMCSpeBlO7Nu+9~Fa^BwD7Pj2DuB?4E2PRjoSA%xni3=4EL(kA zSZQo3Pq5{x&-uugjnpU&@VdpoZ7=aox7{S;dlUh0)g34MI3y?>+fTWGiU6|%8vsv9 za$dSidr2!jzP^-S7O}td+T0;OW4t%}d^9pXn1IBCd`t%j*96)gbfK#sDr60XFAeSP zSKii8<@3uMSRB4}9%wbTn*I4v*@fmJn8E=@r*!S7m)XPWr_V&SDx&+Rg+R}Z$l{_` zqT*)1IHhM<S}xr@keFV_B@d%tN_=E%x`VFdOw150e3`xZ1Lt3`+9Gm!C&T3XCvN7z zo=a%{6BJ&=ewVvsTgvf6lW^s5ad2XEXRl7cOs8}VTA}>TZsH67?K!}ERn1GLu6F`o zFZhd*vNEJU?;yBM=@(6W>=p&!v;85Kcvk~#d0TD{GogT*r*Z2`%?`W)(V_@-y}mGA z&})Y6irf`{LvYJft=90By+uc?y8r#swZpnHqh>CK#Q=HoT}OfpuneEf^=86n>Rv`j zKCCMpwTaavOL#6tc9sqefv=8!62*q$I<d^Ka>Q;&aYs(OxQxD~-Dr9^=!v<DhMkeZ zbGv!yB0t*Gq6~(FVJ-XaJS8~e{R?=n9BqhSe%^9JF${=2GjA1hH=iLf`{8@CPyGej zKB%qLG{h@DO#V*);U}hc)(bU@m@->TK<=DkA+6R|E5cdV#>ZZb-cUnUSZk5%t(-t5 zn+McQxIw56@Kk17@bbcLAr_-k^H}JY<A<Yeg@97wRQKKZE(~nYL|(B`V{UG8KC}iM zg=T$k82A@-wLuMoV32<%tz9iG^IFwAEg&|xP?~{yLYeZz*cl-6qf9@DpO$NuxPpgY z{!mh09Qs}QG&A%raO+4ZNNbj6m$fqRq)Pq#4-lXBT;J1K_O>Qz#Z+)QN2gtFl^q~k zNwD~a$zSAo3tDcf1U?A|XqHYTD%$#9*iu(}x7gQqIk$2LpRwc@j32gWWu!Dzj8@fn zOUS0xK#OU;FtFGArth@7tMQWO<6W)9cL*TdhcwWl+V}#dwpl&JFvz$*W8QNXF({|A zOqla+gtn7zpk9QUnB$h04ZFW&l0P5h3*bJW!MB!RJopF8opGRQe{*g*<M-@z?hJFZ z$@JP$QgNG{5%{(a%b#0Kw5gk3*HlpxwF0sibimKo#ojsiy5q4N84{&*E`~e*DbFFo zs)|D5X=7pGIL~=RTMtGsj&<WN$Vl@jC#B-H#QT41?Ybf1MSqU6lDhj}(9dO5gXkh4 z6cKPGBz5Kjb6Z#jNRbgu*eumY3Sto^0WW!jXu1Vz_`mW;MSw_fv=a~lAulB1<JN*h z8R6+z;_<>Xr}v7erGYN!@^;y&@VK<KK4xNW*`EP7i$3Ru7XT0S1stfZw>o3pweZN? zr~6|{LeMy$?pph@Zy|!Gd_t4{px8dRhLt0FdP0Tg!<$}4^Rx**px7MYc}sWhH7U8G z{4a>97ka*&)@@Qym<^27y8S;OH^y(+55bG)5@H9!(r`R+K#DfsL^e_h+mQ&1g}K$y z^8N<jp9F#bL|j~uXn~s-bYEH^hGhZemJg^tFq`8miBQWoylD&GS{l9}b5i<~rm$z1 z-{nIE_6_j@hRqdY9uOA7v$4ga+`#_0>|T*|raN?Qyec&}f!Nrg(dp!w8p{!ka4oXs z)*@nZd+C^8Ld0KVTHnAe%EiI%6*cK>3Z`qq6$nd2RHF&ZGaae4_^$<i@_2oB*PPFs z51jJ1b68RxTr?L#8JY_UAn{eStQ40(Jw(L=o-#-nK{<cx%U@7IS!Lp8)29&RMkS$t z(rOMr(7{<%=CkHI)3Z{Ss<Be>MgEoG`4{c1xrE<QR!Lgtuq7mcMF4|t+rMV{Z2KI0 z5E{7_?2)~dcn~aNAM>RkRHO5)n!vqofe2zH-W5X>Uj7<z3}M}P_x*kGtA53q4{uzq zG&AK61$GOJa+2N>^p{3hKg(QrBk9fq5Gn8$M9bYKMK1v@Vyu!tHXhkY;u$)jQ+Zm5 z_~mF>!JrquE`8f%mO;hUAYS-gF14YCKN=>6Xwij(XZ$RPaSdj2F%T2%Fx`jWs$?$@ zf4$<^4rYuCoR!G-y-osR#mlz$pw}9>pnJ-|3+tE=I55No;?<W8LsM@Lp_g8HshEw* zMD`l9kMD-Rz}8`|pKV9HvR{^K*>%_>2;%-sImzqX_StpOT=6s&j>r-}c-s0AS5pN! z<1FywXppQbWK*;-t~sGVt~ii{5%}6B4);N;r++~kOZqz=y_VW(!=d19b?R*9=m$qL zBwE0O-Z))?T(JLJT&t)7XlU#nmh?S#Ag1yhV0M(b@!$Y!dV}3%kmeFa8U_X^r>?T` z@Qi3cSA!5@V=Y_n2hC#VXq5_Lpq#emUuLfc&X<IPtPza!-^IH(sCiN=%QoIQy!+*# zw_S5gN*?Kt|K5T*TgxI1iUhnD$jh5Qn8~y`J<T%YufZ1?dnx;#ze3Gee8yZ3oHe;8 zEG%3-j#7Ke5~{!xl+wo{>-1}=`sOzfNF>uDQOuCM@^$zq>W_xPi$be8jernLl-qEj znvO`PdjJ@cVv?#V-Sx*%IsdlHL%Uu1lL4Jfq0Y6H1ERz1n$y#3zcZsem-A*z-n~O8 zl&!_}d&|<sXlT5Z&-K502D=}X$0l%6uu7(MWLm;*6WF6%5Y_J%*g;nk>LMWI!4++A zufz0Jk4#B>+O{#|ch1spdOSOewQf+Z=s@wccar-i&#Iyxp<jH_RTF&YJ|k=S!iSvX z@1Xl7YkfM?vmfXm+I&GRc(I<*FVc`3Z3y|D`+>HZ9hb))s?xxjI7G)^{{^1%`7WhU zR}MnK_fCsIdQRvHk0yWQ_nBup6bv`Jvds^}w{AVu1TlW`U2cqoh`%=_7eF&-c%P4j zeBz;YREn*+*1^hYr<EPpjmu}$N&c{FAR3%nQM0LM7aJE#6gjE)oQ3j;#K_7#v<1d; z3T-();8Q;TP-xWs03iM+rgo1O*Gn9C?BoP(r%|@jkErRTlLkX)8EOdyA@R>k!K35Z zHGJ{lZ>FD2#aiCD_tRNwwL5~?sT(aT81wk*0+Y{2QBt}$jUfhTqGRKwwY0F4aGAsV z^6P=tpR*mYj;3vWes@4eEjJp@7j(iiEw1J5rVZ!DT8=#sNM0*e<k0!E>$>}*_RLsA zyIUC;Y3Z=4L9^T3VK#iy!m}V78QbF8T1EA<nnS?p<~s5y$wyhMTtoE!3#7=0=#w~v zfG{BJV=ulqy<(o%yr%${4a~F47vMp!JbEcQ+m`CB=K3S|`FviJ`TB6tY|R|fGHWGY zAV*=;e2fnjBbkagKQUblVvi;s4UP`*wOx`n$z2BUk-{*iQrB{!t%j<%iVr}dfW#WB z5BOttKzj)}`v0gbtiwRYZh&wKTXDjnNtcU(4fX)r_CIZ=57rIZuDm0G9XeiEvS<>5 z92htTlTv`xdyvk-)HNKsVm$`k9)}S@6Su|@vT#c1fx?&@5d)C2iSab77Wz!7&u~Ev z4W!wFW<79f$btM=ElJ=%kTyZO%nHRwoj@-@FkruLh&mwX*fsHApl@Dh@<+7K5|BU? z(6_-^l6w%gv~mvr>W$#?5&MxeKeuA!clcH(S|#=5U@g}30Nf#cBjKkP_2b%6VdCul z`Bra;a5R-<nmcUh`*EiO*)fZ8+{2pOIu#%r4YDJ3OfT$gFYVfQs>lU8E4^I4IV?2N zOXYOk#?$#7^z&qpsvunfn0I2fQF)`M2+E0H&;aT;g$oQ$r-t^~7J1&eT7t>xo2?o} zU0ABDOczb_p_EB}pe)n{q6erup8G<VU{X!YKszHCydn+bpS@1>yg&ZiWJS5LW|E6> zRC>?GpWUnpJ_Ey=P~j6Y9ARJ*lbUyq1KaQM>99|(%q{M297{h#F8^_y4eAT!U8G!x z3j1+ky@$W&#(~}Ml1l+YNvSdYPL7iAlFB|i<f)Z!Jfr+nDTtL!I)F?ETRYec%a|Vy z8}ik@x7H?KRSVpE8iCuEy*o}W;*KO$dZSt-sM3%N)rP?hDjO~`y~;ZBC4tw!?%*=} zV<4|?Rg<W#6K`0RR=fAKY9?i0Kmd1NF5G&8m%V`E!7cN!1h*WAJH>;4LAjwkc0lf@ zIFTbqo#fB0?zLV6*G06v@k8KH*9Zz&yGK+{buCV`2YF1gY{FwnTeAM@KmwG3kMMK9 z;C-FQ)Vnt4_3nIKD^55j<KqxArzalK>~!>$bVYp`hfle9jc;O4R&GjI*<@5Wlw`I+ zlT`XeH^F#*Po(8UJB*1ys~EdJGqZ)&Fu40|w&NE0tTr3*$S}KgeVfuR6L1D{_(v)? zNj=uWU)UekA;XfC9VbJ2$r#%M$YwK@{h#7ZzznYwn{Etxi1VB&^@`u0*0qSc=-x63 zThZr*GDGdataP?Z)0=y%IU~Ye^4n!ic2GSg=%Vb_ylhLk9}j?M(<qDf;B@dI9!b1^ zUhvgYs{z~6xIZz9EYQ==eH6<vEb=x*qL|OBm%#Z%v5wy;5zJZP?RXv!U5xZ2c;I6Y zTNKdad{G>Ebix@K@N6u4@T&*BI8qzr{87UBU(ig_Vd{Em)s-VuAdLNu%3Uw^?W)(j zHC0WuBNEQRb}jA{#n(~FH5B%FHog--c@{$8RzUiqqJU`SyMPg_@Q?Ebezmn*_MMQD ziZm#9q*P9L_8EjpQy_(5j`Qf=`X*7VA?b=emYl?Fzbjp6wTYY83{!fNYgsyZ=hI%h z)k8(PUv`V{Ett^0-Z<1}=wbl`G|(wA^=sd1WVc}#(K5_!y6|Fkeu2GKtxLcL95~wk zGe7~5y2?}IB(TE6D~J_ORDnDW75`7nB?!o3+3*nJHj2n|asnF<P!h&%Hxpz2Np&Wv z5G$gG<T$MW?WNvU1IZ6Sej5-$L=fxHD}yRxD~LZ-n6oQ{U}CJ4pS%}neK(9J?Y-$S z^i!0m-_`S~VWDWsmhH`_#t!p--sJ3^;NnNaZ%mh2KwQ@%j+G%A$Q{Q!w6=$+=k?-- z+!{NJ631wTJ69H?6+B8FKf&IIg$a>Cb#S76j7qZ!iiU!idj<O$H{(L46_QdtY}Hwj z6is+1=C{%`fz84JqHEA;!~4&KH7Z5w-9J!sOI8*hLo7!4SWE6w+R!V$YPvxzD+;L& zEBdtmZyEA6x|@_oD!iW4h5*L36hio3-TDt^aU+i9Q0byTjbQQ`Ne{CmM-2S>7o?%= zPZmww?o}2D$Io@Optym{^Z;A{u$KxNRMC=Gl0`H7AP3M(44QQUc9zwt3x>PY2pCu} zEO4Qm!uKzzvM~#J#yK6)F#O6yh1FL-EokI-k6QF{(T$))w=ZnzCByTx>}2FzCfxTI zUNC8*maMBqB5T)jRx?%J5`TIi$~Hbs`&18j-d*EZcXTIoqo$CPqDvNl;9taxRwL;e zeTIiUG1sf;POC#teDHR_ZzvfoI)CvDeh)sDN{1DrU29P$Rwfr{UY8R5mWHR&T!Ibi zXUChemd>aK@`bS88+>nK1cC&xtc-n?nc5t&D%1LL?_%r>csi6Qe5jZT7Xb<w50<zm zqdB8F>dLl(mq7lJ2H-K}!sCqiRHp+l>B=T1=K#5Dm&y|alY-DY+#MI9=GDJ#?|w2P zW=kSBPl8w=TG*R-Q`{HLB9w&1(t9%;*Is81@N*2_h5s1aJ{EI_MWV493p~|;?CSLZ zgO{lpW6LrfcQ<vRzROY!7*G2fafSHva`ag`n2q=g&YT9kvT})bFs&v{D$ZYa@6A`P zAK$c+c)@Qf992F}EW7TE6hsya8;zI;;fBNGuMx!VAdF#yBR}inpC|AJf$u9$EE*#H zIN>1p6iFHzED@KhoA)QNnXYi<kKcyd7RUx|{Pa;m&i89(k&3R&9g%t%-smylkx)cn zaDOHcJ20Td;O7-&dra7`Zg!9f5-(`cwfke40kQGlmHFy+$CtYK7kUcAiI=`7r`~*X zZpJwH7JZc@I!VwNZFre`KawhY$@!H&KW_G}79S%fj(t(825RI~=OPazUmu}>d}PTS z$PZ26qFyTJnBPMUwjUA;irPiyvKw44Z?_2e*pCIEM!*eZ&;$@1@Zl{_Rmg!%vYeRy z;vg~2b#<dj>f@ZGNo(<nm&I3QDK*Wm3yr2tz~^exEtHM_*ezN>Z0J7wN??X93KJw; zr^4Dzai%~PyM*;<lyh92`}xQ&$}O&rf01k~$P5Df@@RHq^zp%8ka6U~T09vpVAC3L zai7bN9G~c~B%S{kv?*A*!2;}`3J4TL5=uKy^nenD5(A*A$l$KmfI`q4TI}opqdG2j zFj{)sngjc35r$|;8*eNbR<$v@cW<qJgK$G?w&8{#5JGN`=(iXdxTRJ;OO8sm=dxE8 zkxz~%FWa;%)vYzOYMOEq2tIw1Osd>RVAaL%Jo9tFM;4U!wq<02Qs-a(mIU^n$C2x& zY*E{{3Z&gy0-e7J@B<#G`oRuN@5{5^1s)f_4kFvl#5pPRBs0QNZ{^XVDLIrCx>)M@ zIgd0xO_{Oke0*ICC;|950B>Q#WcB>R56;d0yTL6TK5PUQ|5Nx3tB%j@uer!E<VlIJ z{-?@PkPYK_RZ#6)Go_gpASWkST-@_}6WrCr7&LdHXeih1RC9GOR_rC0LeS+UB;tWJ zFuxs@R>5jugKa*6Oo0J_==8^9fc|>eD{}e1cX3_{s$DeR@>xrHv)sqZ0EcLK27Rpo z6;t7a=<@+oV$}=TwLh)9EWGQ4dTo{}8`0H2{NgpQ6RosML`loHD)W^UpRw0|>^o|r z5v6{2of%5GDTR12PiDqaCxC~MGlCgMJAWz>e74-Hi>`U3dH+&6G|p^~jRl_xT!tGV zoSr=!FixLGY)ls7>eJMW{sc!5fE^ID;7DnQH-2$_^?9Ct^~Q56QssFz(vbjI%b*1n zKU?f~MOr#lpuV96ZH<BOd$}9Hc4{=J8By#wmS#WWs42%fzac_2bBu2g4evyO7yQl} ze(26s`2B_nj0j8ZNY621P1NGedjpkCB0t`Gd$);m_%>p_GD`~X7EE+{RErMnhb=9H zB%dfeD}-DeR}PzM%C7)+Hu_Vl0P#EN#^zpq;<HOTF^H+CQlcq3<ui{vFjcCm5MrZ7 z1d$Sm0t62u;1@RWk`Lkmto09zpnr(7+pCQc6AX{iUlW03Hs~${-_iJ()G3-qWMlDP z9W`qK>{A;MtydR-4H>Nv8#RUdw}S$?kR51lBmlRrHauR&RbSZou%_J27OJ@?C8+f* zK&6KIpm+hiJ+5+duwvI%ujXm7oN-n3-t-c^saBRzciUtT7-Q{mVb=MQ_zf;DfeQJz zWnzFp2CEH@USEdo9Fwl1YnZlGXunyezdB3$tydu&_l0@iK!H+C6=Lr-(yHK!Y!E2I zyP8)&EfzJcNbKBVU6FamX9|fWY@gNRbFuZt_*(~smROB~%XLE@hUMNLZTpa3lHJPR zuT&GRptJW|(YFwbWq(1J`cszEsQoNPia$l{0OPRgZZ*dmY;Yr0b@r`J6g9I!@Vreg z(w}nZaR)S}(B!f9y3Q{Fl9%uyi%S6X9%8X7?NAfWgP8O&BntZw$`6WG@V0HG5)T+( zC}Y#jwqOL-36j=+8~Os=`xlh83rn!R^<o+k##S8z{gypBPCpb&yzU1Y9(jmo!S1!n zPL_K48X|d?=cEuyN&AIKcqjJYrGXHJ_s?z&X^!-$JriEi>puDmn&!j;Mh!4H&&Vq? zu>HBbDjzMoHMd01=J7VA9jqDdibX~l`u*!5dS5_dr-{pcfiBnVc&7lEO40v}Rsvzk z8wCmb<Jd0v74&Ppgc$=(xq-^azV%M`hc8dH|1#q0!epP*?Tl+({0TNv_i*=6a&?2p zZUWv4byD`Lvs7+-?y!Oda_C|Lgc{CI;J})NpD3ak00!p7sb0C;mEcv7Y8M;ooast_ zqh1<VdGGPUe?d?neZ!rj3F?=<lltrP>ohUXhyGbt$(sYKB$@C`hh1LCv|HYZ?1dN_ zt7#Zy0h-5u147V4!~t_P46BI_tirkfzTKdsBX9>8m2KUewr6D9SJJh{);7o5rZ+tO zRPoc^$FQ~7>q^mG3o|T#{M3^zyt?k!anZ~{pnE+@<=AJf^V_Tq-vZ2xd~IUS7DrU1 zEzZPqt;kL}Ce9e34|It1XO>T{>2w{3=fczr9B|d8rLSH1wPT_~%rAjg9Q)iL<R|e5 z)GY`yM~8swB)X_cYF^gr`x@|EmYEe39)~l)kWki)KZJnc91hPzw^I!EmcCB$tECab zVT@jM`c23eVR)M;1m<TG0EU95x2X_3ev(6g@ifb|nsYw&z8?%oO3ePGaw2;pWXOMp z3@qs@a!;DiRehkn*Fv7x>GR0Dw_16tZUv)UlOyfCn>v;~v^f=b7O+zNn4~WI0wXNU zO?e-3kHzLLh+8f5TVmvujr@@`>zW*GMXJ_RaHFQEvmROSe8%Tf2?PJl+(Cm)^V0HK zmt2Y?y_(wRJaTq8=BT$)_qfJ5k~D?uaLW0!Jvdh1M2{ZK`IvKia`Zy+{ljZfQ49!$ z_ta~h?x~=hSJg5$@~YbMr+fEud&!;eZI5S$jLQmy4m8T{0qTCRquK2q{*>;?w~kRC z-2n~j=&5_C7}RRquG}_ik7DGGZ}f{h+WSf2v+p}aZp2@VO6grmb=cAUHF)DidyHdw zw>HJFHXj8h|G40f`@-hqcP@foJh}`{$h%dy)3TW)1yDYrrt<yXg#7m`p$#9C0dD0a zNllfsb9p^LK5ue8KZ|wimhE8FFg=VsH9nYQGwI!-2DRXDO>zDQ8a1OV`)$*&dPh_U zM$?~Fpx|ifq^1Bl5IyuU?BUPiSAGu?b8Zb^UUyMdz6JdSxu}6;zju3RwGstU>vue6 zy{|{!)%YlAL+Hla;mtlCHFiv+nbV`Ji7efvKm|7T?iKr}2{}aeH_w+o?>io*kLT6& zpL2Eg``^;gUOX=RG85av!WK_2ZNZr%_Qp3jy0hfLt=Y>fCaPf>iysOZqqyjan?Ik{ z-+kjE8I|_CvUm?9PXTsZ!@LON=z24D;V^o`e34%CVNcn3%biZO9_6j(uf6j3X$DrU zR^)trs!x_tGxJe_Y1ZIkOS=^Hs&v~(P{O?x`?yE6m|H7YUk{d#x5qL$1mrv9g+-dl z1IJT3T-Mf88Eo7wO?|$`WF@Y1*S)CCdnK_D@okoZV}JPDu6tJP=!1NLe69;q=eh2g zDEnynU5lKvXwbT|S>nE@aLi31jp>j9d13ahRf}I=$hte_JG5moV+@o<>VMO8S)D37 zNE>`K<P%&+TAxr1bAR-Gyt>(?lg%emBfv98-;9Lf(`PC^4mgAz%3jz4hGQJ)!{f&T zc*c6dAG(cOMl&@DFFMdr!|ovjU{z?WKI}{i5(@c0T~#&9(z1&5Tr1EP_jt3e{{TXW zoX-89kZP!Cp9#_3n2#a({|ArWrGy<lUJU+hZ+Z%R4<M@oXb=+uBUK4SfEWJJAg2`s zRZ3k`VLv_Qzv~O6%iw|CxO~JU+8?Nfr5CRfWNabPn!9P^5sJpsrFWGyF{itqfxgw( z<HyCqT}hSWDZcqLm1DnVrnK+99;^DI6GiXKxkyk3OoSpag`l3-@w!RQSvgzrVO>bn z;6w16S}QOxw^I}_3{#&M*qW{*pE0=-Z^~kYy236^Yqe;JWCsplp8T9|uNAUG=uf)< z&9)A>QyiPo{NyZeBJB@PCQbg>nBUEdQSPyi<Eep^{tS48j`);3eBq*JxSwd=obn$y z*J!+X_~je-g!E^~22_{2xyu7#=|pvH%^p})_0F{=@bu$W&eXyzhpHq<yRVm}lep!) zBxHu`(nC33aPnQrhM?Y-9#HU^<c0Fq$b)=G9?miT*RDGpRb4mRa)wPX0%eaBKCGcL z5(i*9gzLmSKSgls!VJ)hmH2^1d}r_E+K0RbknkrRAfUUDEY9m`b@(<Ok<6)xVs^T- zVM)2Wovi6h`&%1FfgEq7CDC+Ym-T&@!R?T6voe<p?z+vy;nYxzAALU#uEZXZhEU&B z6!0}OcphE5n6t0LMds9a_z|4T_5d}8z~2D3wqPf48rVNa_XW@gv^_=rIx+29ZVbGq zhhqqZjgEmNZGj)u^ycy^x#OzqX_lz`g&SXU=H`1zCG)J`YlK56QdNSAoR8BNgJ}A_ z1S;RAtRERJe}=&hgxk{?y{ewkpIcP=-(NdR)OEObWM{t}-BR|iXM<w-z%+jmG9%o| z_IR_ps!Cxr&OthuJcM}85b#BTn#TJWH3!@Ag`6E${{^8%4UpQu!pDaD=eW2E#dK&? z(gQmbH($IdvCJWP=NfBe0vh`(VT<`HbfhT-x#*prhdX``TwU{-g0GA`eE7J;_e((( zVmsT(u`bAZvnBKGkV2>iwfrL~@G{-MCUMGOyfIKl$=#W;U+(p)UhvX<6z%y|O1)y` z0WZ(YAG+O&iPp5sevg6AfZMo5G@Xy0wmS<cA0~tQK1^8im>LMv-(ah#m!3c@Mqo%1 zVeLr69a*4c7LS@BTp<AQWRNHjKhpLt-#HlsFw4qsvmLs3js0V#-@0T87=qS8e=fEc zS9Kr}DPz&_`LV{q%Z`)!=pSE}zL9Uy-_d-lh1ys{|493s1jP;PQXkx<{0lOd{j4^! zbwdylhSA~)J66P&FSGtQuwNPoQ?kvv=dAd&ECR=ST}TdOahZGUSMHqtd$VyPM^iJ_ zuaZT$3C0Sk&NjZ-KnljqAa%GKkVjmHD<fLf79k7-(a}Baron85(4;SrZ!=nM{8v*W z2#bgT9U}jFHn~zR?iKzXFe62UO>?nyTRbH?!waXE>vka%rxY8!ale!uhccbhP?M=3 zTY^@b5t67o(k?)=2tHU0&=|4fNaAV|pT+{_gCA{;a6z2OfFofzPz|7X2hvG9hbyny zo@@6s07G8Y-y4zm<+lk}FEmvjekK!*p@t{SJ5*m@&7kHk+fYeZtCPiu*9CT$<m#Xm zTS-b2g+lMWjXo%jS3dn{s@6&Eh`{m1%CT&S(6O0BwWl*YU8r<yD*?-zG}9Q+U}S&q zRVZAm?R1)!*Y&27L>j|rNHeAEN^-f2Hrx-vgwT_7#br^u)S*>t<FEW^z#_S7J%qE4 z3?O!eFr=x*mp7(8@8&eFz%xnBnUFGcEAoO|f)sjkOeNpv_ZM_QZck#zEJ6R{MGt(= zFVz?vMd0TK09XV*51a>nei*97b;??Re_PdqNuBT+eoS!2EG|SNiK_dE;|CK<nmhjX zxa^6Vejc8w9VbgmeQA+2T9xFoYATS{hA5={l+ghvJ!f!V{i?G-+|&~$Z33kaWoW>m zWf0pcd9j!Mu6{A{D&g)Zqe0Jp%A3p+zGy4p^cN9LjCIyZ{L_0jCBuq_ctOp!34A!v z!i-*4-w|3I+=cag00p|gYbQHl3|C3G0RNl2&>~1;L$p#~h)i#PWdL}Y8RG6w^C-zc za2$imLj4Dx0oWU}=()K8?GLJ2<idfle#kD_a^urwxm`NU07prjuaZw<xw~?WuP1w$ zw|SQyHV~jqL#vNT9V6v&&)*<+BLMLj8~ND|F{Z&VpCC^xRN?aae%xEHMO8`H*m9@l zN$5M9n7HUbJK;1PQrOm4-0fr<=<_NH1~rBfHA2CjS08UFPr?}+u#Xe*p28tbV)$#z z>QPUj70&wchtXuIbHSSUT|a+TwAHtX?lkNZL`WL;7qHs;;D_^!w=<S%GspS(-pw%Y z#Dkrq4GC09A4cuhODAk6{N$Z{8E50#e<3q~l+Y3|(Ln$n?^(qMlRAhG0O=Di>N;M0 z8N3SxX*%wHfAjM7b>S4WH{$9)1iiC>)yhE5NVi+h^8jEdXTDD4_ko#IQ035t0W}v! zhUMOJytueKXWGER?t1Zpml+O=4=HjeuPn*T-M%}KID&c-%NIBlHW=V^N{;ivS3f_P zSVVtp@USs^g?jO&k27Un4<jmLcU}}Yfkm|~;BTsbok2SfL>Qsw<w|2uF2pqcQ)x*1 z`7!h@BZAMfJC#~JQn;U?KY^+x!Oa2z(0aaogJyUh3w^e^9S@B%%`r-t_=9x$0hYQI z=q>9@Y{~3hrtQ<!{|r7aboi~%sp<Ujmv0DlqfZ~-y{t<UX{5m}2nhZ^tRt9Me-I4d zAK<z4fbide@pS!wJ|gSOAoWojHY?dWK;aj{66Y&7!?|J`0eFC5?05YG?(fi8)a&Z% zOR~ZxqE%_F_ClkMhqKX=!wG}2$#y33NOHoF))Vppozbk=9{lIamEU+m*dg5$qYK!F zPT7VKf>9OJ`?yydv>);v$PorZ{JNHfsP2+ypxy#6OV%kr6Fy=sK77MD*9c4a9Z6h| zUcLc*%rgm-U#q#Z;CPc-#*`Nh{Hw*1_YQoTl_@sxMx4#!1+^PdG<Nt2txc9$9&qth zMQ{#jXr5-Qm63ZqkTbE1GPCxpz~M_2UwIS5%>Dp{J-4X2$KBj|c?ouWeY>2>-3n~( z$K%XG$B__P3ZshQ?j0${Cm#3K(VJ$_B{TToKsO#%;tmK+yhSsJu`YIK;BJGw7?*o( zO+c7IRrhmpSfgL6x^7(kXqd3)D})LRTL66>+>L(;3}jjSsk5eJ1Dw7>;xGh4v&-ur zQSTL<#$SG%pK7d)bCKH-4pM!InSGDin4m(7Ll>)09c}SyujtM1=1OwxlA@>&W#xpl zPnB#*moLAIB~5b1s~+4A@vUB9dI;!hrzV!D34koJJ%0%`^R$hjc7~Yi?D?V=Bb0HQ znj{aaKmN$UawZAvHuOhSq{=m2Wc-vPZ5l#~oal6tik3hxRwoHS!$@pSWN@t#S8-Y& z)`vFGgEmzN#LGc-c<HTlJfzz!(a(AL)WDcH0nI}_!dfk_tNx0CG+s$2U251~woW4P z;scj<d06JeXJeZS<OO?pjn9(`=Nx@ZY%j6~HgcN*E$B<EL>QkE`|-?6fla1}g@QUe zK>h8^+o@DzEV&s#X*qB&UumQtV8``Kxqg@Mk#7wydBHDE0=rI7YrxC}z?;*M@_ZRY z&#w?0lvJBIi7}*`bKfak&L1Wod~y34^QjqfI);EwKUDV<$gACG#~d?%H=ZSi1Fz~X zqNjK(4R>euKjtHXhmvS!((o^f4M#{!|3`<G0`=kmrs1eok8{A6pie}$5a+r=a3NqZ zDKr6n%m5Ny2rDVsyUIyl*QPQ0YtraTjDS07ClEX$d*OUx1jcs`L@eM$w$jeE#SwC* zxP9E^+nJP>9BgaU6!sa^Ta;uQh(|U-QuJylabhl<c7`+vA#ZrR`29X@;kGkQswYbQ z-A5(;xREuGeW|UL*$(7j7y4Ras=SSJwY~M(yH@B<@e?~ctJZW@-uLtMkd2e$n{Ngw zINwOP=2~{#yri}C#D-p#7lg1ZS7#<W12z|B)nCvTMeIJQZ5RN%ie{_O@WVR$uvq|f zK^L7)oJh0|fL_RTX`L7bptoU9R4<tADHyN*UOV8TfbGZ#k*zzF`C7D7^Ed=svSLk; z!1^~U>1SGWgY)k2kt)Z`5=p(5TVDT$x7+4rTouFu9ZvFRUsxWT=c68V7f32C;1a6j z5arb!?3!lSsvOYig;)Y%^1Jr%nDPzbW7KB(a><wJ(>4h<hfi|Kdr0p$g<IBaMo?*3 zA5TaY;?2`%4|CtdCfK;e&bn(?){ETgnQ}p>!+u!^;9lU(?;uvJ$^b?zYF+v?RUIMK zWFILr!(X=TSvsS}F~jBgg%S|vfv}<{!9c|Ak++4QB6xb{&0EcXonU0#d*whw3+kps za{C&;$5FGfIfz0s0$vqvAr7zB1GC@637;(srmG1-DCl-DQ0Lc+J8Qs8a5y8(2lRoz z9~8qr-*FjY{0pj;N=t8nELlJ(W>Y-PPSyTZ=}iva4fZYR=8!AuRIjuNAIfqYnlidx z9hgQ;%2}%j5|JcU>v9*jEb)5xWcCzH7fIgwj39fKaY0F%U!a16Nq<r~uwOs>*-V=@ z=IXvfIT2Gl?zTHv42Ee<X|;WTTA2-IlCFeY+=ZOwiK*17?*sEO3Y9V!2k@fvC}R1A z1>RnFuEu<0d}#N0LAsXYv0}~hG5&E2w`R8Cg+0L<yS__%@qFGZvz2YP0Pmk(88pAq zBB=P$n6AsVp!9nA=#}bpUfs7k%W<<OrN)iD9dBur=ufVJn|(}jua|GAt7>?WC)sCV zUa1;I?XFKu9OerQutTjPVnf*kQ1DwBEh-I1>U;LDq>K---cUetP>}Dvs?AsG*uKM@ z%$3wzX9MQew|vFIU3ELM88O8jcDAcq?}JI_4tWvzQ#$o$wr=N3a^-?(xU=kSy#Q>( zW9Dz=L9}jt_g^iHrrp1#SIg5>L3ho&D|UPQyI|21F0Lo)=S&VfF901bNrvuJ)Jls+ zese}PMJ&MGG#Bo#wMo)9O6ZZ_G&tuvwB^xT;c?`6N#-pxWqv9!pYf_$U^td-gQ?2E z-AFN-keV7_)XtMW`tXE5u&}H|!)G0xeZQaH(C;|6QR8ut*8byn#p!_TFkAY1EoA92 z&EZ>wNUG>#VG1MGmqs6LxgHPEFLn8#g-XUQGO=0Fm#!?rWtbA{l4dwn!2Cr|*HKHR z8S3BFpf@4K8qS2OZmui9v4PaZm16DQE$f5lrp58w?9+x;_9~T8)c1t31CFHug;Bux z`O5yfd97Baw-4MRy2oXLZ;B;HYd2?C$H#MQ`CN?eCeePfxE`Z!y%9e>dUSo}##J@; zj#rIU*C8pM=l!8W<;+&WaRb@!PVd@X3p`=@_|qlZo$WaXdGhgT_M^A-3MTn{Ho!Ru zG@memU3#3oFWNuFxJ{m$#0v)+{YvOmFna35X?khLOwgk++<ie<*}#d<PN2F`r#ybc z&E$jV^+-ej_2cNuSM$fbE9>L6W61~6(&I(y?vuwvkvLlJCv3sgsWkn{>RK*=T&ceP zqDi60ffK1yyQW`=hSqaiCDQM880_x4KiMmht_gBKGm&lJ^HM^H*p&xm9YbULE}d}5 zj!-QEN16zHSaHXjIIMB4mYMu%+uVQbmh=-_B|Yk9{Cmd;S2UKKzul)dA<(N7p{LCy z(cX~4r<~0Nr$W0x7n2qa?O<1-+w;I~(X~eb$v2bBaJ)UV5eQCp_X*d`kdu*1p@{YQ zBj9?8Xh*xBePbwz<9OBH3rSMn{r}x;u>EZdk{|~bmq$%F2mD1k=c>ZMT3qWx;E<cG zZzLd08tn52YF`v#0Osi#bzf*ZT{ypc<qX^!##xn{whx#LWYYOQ=`tM>|Hc>Si2V=E zOgec3LY*#*{cbk1ow50KNDLraUP_BX(6ww5BPB@joM)V;+Q!ds0THd(z#*yxx>%WZ zXhFITRI*w15Q}Q4ZzV=5sTgu0n$6v3@hl^?9iN=<r2(-<3xlgWv?EgKurRj|nV*c% zAwJ>BK??veNw{Z^^8wp(O5`0T-JEHy!qoa3F_2z=c(wgOiCpbunAy?-f%yxh3_gDz z8Hkjc?=)=hKyJcno|eHP&{z}Tuunu)>W}>2P0uR#;%p_pd2yJ&ckvHkF&@gf^(+UO zEc=Z9Xt}EcaN2nO7QJe=(-;eWiDySzWI&DVt<(7pY-gCm5{!N`NhspYuaRQgiV)RK zCYdXZ%86)J;P$?v!O$fK63|QjWq{$UA$F|dyi80=sqIq+=sf76jMQ?Bnz707dC$Cl z+u`ob+vZte!Aa{tX%O7n1d5&_7%w|R+8o~hDZPtAu;hI!p{0<zGZ&z#hY=XBKI59e zgb`THx`I0(5I>>CZEv}pkgRYaRrg=MUuQLm*jPwsdi@FXG4(DtHZ2{Wwm1R|in%Z( z$r~C@3oq%uQ@Me^N0j~d4_N;jI9bwz_AH<)1$usLg}<Sz#XZ%_^60G@YTK+w^o{+l zK;^(@SX=5Xp!S<xlAZ2|<6KMr(_Nk9{Ku1_oIHp;gEz*j)2mpA0Qlt~QG&)Z!zIsX zB@VHfoMG9U`^(6S(*AEi{vO!5kOGehGQ5#Kh=EJtugol?TGQCP6n0+GIqBB?5|4_P z;JDH@D@i>W2n$%av|mC{Eb@wMtqYQEoMn>q;yU6gE7NA<$z&&po{LRNClQ2*H3Vwl z+&5ty=76H~q4;s*hnHg+(=^YjLE%)sX)?eOSwDA1_}v~wY8C<Oh$U1--cMr}sEGng zIQtf?)Z~mDSmsX!NNiu*ZPU&I!T&nf{07*wem|(=BzX{?x#ISx<Cev2leeY=A*c9> zV?C{I@=>#+U5Dqyj0>3G{Q#i;-`@L35HVwGpqQci@HdRSN!W_ii>`!*`dO6>ZbBVt z{W5u#lXKrRpD!{^a*vuF3)p+mofOHL9*Pa>1!=83j@i;sqpsmyL#HiFUuzcscZzHU zA5wZUWj$KYK9u;@>4c4R+3f&JcuD;Jeploi(?3Dr!D!UYPk9Dhoze1-@cXW;r{|!n zraotNLFY3(OdhMNRo;qlLH#2gP#oDm(jfq~^;bqI$@-`Yvt_xFHc%7LnNk4%K?oLr z`h>3Qkmbzbf@*WY8Jn=lji{gjR=B#W`m~v3aS_KcF*N$XGF0S4vgs&mtElszJMC`K zPUuQ(%nv>Fm(vDd76GqE_ja*tf*#7E!?^H0@6^6xq=JL+$7|Oa3<V>87>@2e+Ef!f z2U~94R#Lj$Y-KZS?qwdC;H}EO;h$ft9u!&Yqxii<Y>Eazo97d)(CQUmKOx{i(Fh4; z^jHrJK5s!IHruWtIWpcvNkjt{iUytvrX%JxAZFx6LtRc4Zxw1oauKCaNLg1a;(}Zl zz#{vE3$s9Y3pwe|`adWF7?Q!HMqEw*NF*LGL4vMbP#k&Ve*&3Lh|;mr8Xi8%2XGu0 zTm$VwlJi4THN5wiQCuK0oZu5Ku7Cs%7?u4t5V6I#2wK26JC*rhgXjf=Gc%6IaU@x6 z*KU}*HwGNu#DcvY-{iki5>bjen6<hWEs3;p29D<|+>5+84mKcvYxp%y&l8n^23m6H z5C9Sf_Dh(0(Vx^0-_s4<inyWzs_@YuFwx`n%!2d#u@9f49Ex4worJqs_1reYuqIAy zcEF_p^%3V|e5quOI=f!lI}QJyl5ejPW0K7nho9q7UDnsJ+{tFCHxB3%mS(hJz0v-b zIK|g<Whoh1HkX_Gsb&8lrzMsiyvL_34nudKK=|AxdSp+cwZPy;m7Zabnz343mQVHb z``DGj5<WTr`aHRHSel#Py>EFpOoj8$028q@-#q;^ZODuuW7Zn@7bL6Ll1akg(1dq& zh$~*0wp7JmN&9Wqyu$=_hihk#4707f+&NXqrY-OCaxuL1Zb7Y8!NLw77R@_!Qv^KD zCu|=pl4yP$P>P={g!9nEhsfQT*%}n(If!Ep09$E=k;os6ylos9r%N9<jA)R3i2+~T zI%iE!eHohTAp5!1r;DHY`Pntgwru85gggm6xDRI`zz#eEPwv>({i>@eiv<%-f;2eJ z8Lp@KoXe3eGpEC+;DTL5T0nhp{@C>ibTMy%exMaO!#dOPVaVIkGs4+sG|)KYD2|~Y z4U6Tv=ruzx#@^1wbsx~n(=E*`gR7^-`yP8n+^+)8<GlGZsqc|ARv5RXh<23-*Ydf( z(M8f}clx8kLC`|uDGvr(n-oSo1stmL-*smN3VP4T*mHlUz3MxW2cOwogD;>N8BRwt zA!oN(fH<>3WyGOqqdrx#!3TrhG)-8(oqO!Dgl00wquQpet8?^j%j{}QE7p6PWom43 z81i&h49ufG0<I?ZFNmwFJ#C8QN@YEJSvHO8k9e$kP@g@Y_+|1EGI}(Y^P)`C&@win zvKc;zK2-ge6i$}s|DRZfJo_!ALXHpv2}j_>{^g9~ywFs1u;!%;;tJ*n<?y+eKe~ox z8BK*%KUE4dTydICfAoUFy}2KHJ~p90efJtzW`*qRv0$v~`h0o}i;dd4?6Wm_-eh0X z^a#tN%i>c3os^0=F?=wj6+H8}#j<#|(Dk_o{LO7a_Ym_vqjqf^Weee!hY*u$`}+=W z2vSTaXqj7w>h)S+Sbr|1cQ@~Ou+<66kiG{rN91yc-^c|OX^hi#R~Bn#km^*^6;)yW zsP}34E8_aMOxk<Y1>IEcBOjKgo8lHy70m7-2VC)Do-N7`x*#+JdCc66p}ibz%Afo^ zF&$l6`PQ{Z&^jci{h(I+;w7geiTn7B9Bz7+#w4whr6|!Gt)4M=XatZ0EJQ9VOLcFG znAwMM5BOQUR*XzWqZrf{gA{p0*U;AxEwX5PLl&n;j$dK)>6NLb^9K$S6Rf3WTW(zM zD2;d0uQ*hejwV}&ts@CczDuui4}@_U4fqi8!q4EgJBCVM>2rIXzQ=bltDf2v?FJ6= z_De}$JZcpEhWEtwwxTclNw_WzP`@^{<{7dP`ZE0cPJ#K!D`gAhhc|JvNt;a@S$t!7 zz`s*|J!r7zBW3_|*nJ%ye*XEoaGe+W&S6C&7!W2fLORjrByoZ%_Ot~SHa!v5VCa=- zsq*!5LN8;TSyvAe{azP{Y&5MHp{yc%K*~Qj#b}26c^9o%IeH>JS65;ggc&=fr=HyW zC%~kt{2+jbVZ2r7{oZ2@qk^T>v$sqq-X&1PG1V{y{6DhZDxk@S{U4^gdoV&mq#J2a zq!pw)l#=d_5z-9;f~0hVbT<Peq*EB(ut|-4{`dFy9=@kL+V1<>m7kDSrD9BgD0c*1 zNt8r1?={8obPuU<yK{_MTi`I=(umjXLq|Gr+h^ZJw`ZUkShk(Z)&w^I^_dIe5Fi^T zi_a4ba#$M86M{FlMJ`x7irnP2k^Z{;t;ipbE&2AfxES6y$LX$<T^A(BZQsd7f@~wz z&wG)ojT1Avc2k>;4SuyTTC_$?6sz2LDBu9U#4cTdGumGee%FSCAQ&}fn<yIRZG73H zUeLUFk=d%gQ{umLstaGeyh(bhe-z-RN>wR1)E78jniEWBi9`dTN~7AnMZpDO+|xdN zM#caQ!wnK0A#2vQ*qk4AQ-AD3WR>S6xbMIQ_}*kOdugfc=2%^`iyZah^k5+IVK2j9 zCc*d!43XaBHpBw01plV`EI_R8rc+{f-*;MGiKZK>auQqlJShmnh2+G_y$IhfDbJm| zxHvO6HMS&_W^dc#r2Gss{GNw`LZ0>}2JZ7n#kK7yL-Uk#HI2(!VD6i#8&9)PzwwT- z>$8$u=Wj-B^Hev(ryqT@;r;xXEbGY*YY^w&Rqo(L^Cqb!BjGysufkRm-l@h+Dr60U zCKgwhbjcEDI-}SkduFUHqCK>oa{L$;#HC7<+(#u;b7`_b_DdLi7BJV8y%qrW`2gVP z{2mEp?DgfR3=ydt#Q#S|LrjZLYEJkioxN3ko`g_F14{&L9bhA);&2CpEB<(@D6tpd zAMeDRF6<wM$U~Y1WZ{#Hlt3kaTMJ~N;$KU!y1plp<80Aln5|<aG2>}=Opn3(@u2oi zGlk~W<|7&3PWYoJ5>Xi_w!lkZWE;oK<y`Ap0m0$^jvd-9HGIv=RJXDRx~bd09T7M- z$A1hcM0P5spYfg67IlVs!k}*CSlajKNZRM{VBANoxo43;c6e*T)#T45!-mAYBJF(6 z_n(!4Ov(#_;JIZAzMpDlS9KOV^oAjFX0I=lnqMlZ7Li}Z{r?tD6LqA^bV*SyshI1Z zV>x8PX=DrQ=F9=Q8zZ(1ebRlB%Kw3k@~I@0d*P-z?*&s=IrB?b$DJ2#gUNoBmoTzi z=Rf0`Bk*Lw!O&-L!zF45{CapKo%4VdW&a&3q?3v9jk(!@%yutjFDyO3$wU@IMid|i zbg6i^_*2KOFh$xKaLNaNjgFB<NhWKTzVTl=1CF?y^IJaZ6ILmAv2Q@Y(c-G^py(zV zsqOW^_dL774Up}vx&2u)wM^{hICIo2xiTXD+^))KKhN^l9lDeO>(Cv((@XfpP3Ww} zTo+`^L6&6DS*0~YYi8P6U1)DS!t_nwC;@8UsBmtLjhM=Ss+uQ|HFyv<Su*)-wb|1i z+<hEDUok-kpxwOXx-|{tOK88T1}y)yy>QhbBf+}XL3^y)WKFfi>Z>YB0@(WnrMg7e zkQY`5UnFBaaUbNX(If4CD2z^Vp=Mc%+9-EusRkWAd9+cIvtH^Pou#3!;AN^9iyy0N zbU~vK30h)tsy~5`a1n#nv5ps`aE#nlWp>?T*oEv#91yQBOJl9FD0f^B`viaGgh`Sp zVd&5{qL!HDD+AHIQ(8Xy>>`7QCem#YkD!4*-5NotE_l5N%@zMR?foOWo)<sFwOwt$ zp@%%_%ERJNtBwz(z5!DMLzOw{c<YckA?e7<i=F2+yy-KBlGTBu^#?&&Br{*UMC;HQ z0i%-y&~`RzPXn4;!)4F*iNN;>8|y`OJh@*CV{A7`HNqWknt;zB4#1&uI=sn+$`m>K z+w{S?@P;*Zd{&u3blF7IFi~k-k&CZiBK+8hE#mjiL^g&udT5Tv{nB3u+{i{2UhqgO z9VjOYobdY0iD>c(j~v!ckDlyV{e7wKRwZqxKMKidJ*GpurK7-Zp&AkLuco;nM*7mv zYQLHXDa`~@W*b*`3#R2SMr-gFSR$r@t5btBE@;w3-6&=_p{;#%^lG}tf%o|H%A>%U zw#rLEkL(&Dv^P^i8`awx9q9{6ta(rV`(-hR&AFFFVubmsI_Na?6`O@goINGY-z`v~ z*9Bup@A4UZB1zp)XY+!>Mg@i;G4{|CXg3#N#w+MgI$OimX~_~gw^-zBf|@e-uf*-2 zBxts9ud=w|Ag{S@*J%gPjKQ41Q`AouXO2tW3VP4+E%^=2b!954(d&<?Q1tM-1>dG4 zUYb{08lTjk-kXYUM0$|9tx@D$*Vr}1u(+~f05I;*Vo3rFscZTplNs%x_;@R=YPM1I zw2h8eQUct2awtIodg)~mC9Q7VGFlQzm&06Z?&%ydQLkN!fVAKzUQ;E_#PPmj8mzBj zTZGeRnHUA46dH>4Sm+3t-51eGUEkxqib`lV|8`Z*GM8fDmX?>kI5n<sXR_#+g83OR zwZAQMXUE72$Ji3cu6OpijJLh6-eU)WEo)S1%IH1JH9ao9J84P(E%)65RQs6-{ScW? zBM!72;yc$>GbU)L;D`GKyorsbRdphM3BC06IivTe4`smknRgxT<Vh}mD4|=HBk-{P z<U6eO$?8@@GBfd5ka$7@{aL}n<giLe03BP3HWhz>pO~g^Qq`rM=~CV<%_crZieFH1 zD}O&YUG-qlg&YyDuj-7Rr#viSM~Mhe6&n7K;`3#PZ4R%FqfaDXx<YA0jB<Tl@mHBe zkZg_Rra?JI{H~V>ue7GUzAf)3PT!-WBh6ns;zvgt&AdEtF+ie%Y|A5ivN!=JJzDCS zIp>#^tr+@hkt5~3N4BlGQIZ@F_cFbQy5aOkzsesCbL9oH7@9R9f7AvfF0(x|-{oM* z4C$gE#lbfvm+r3A*>;<*EyWicj=Q!ZxZe&Eujv4wnb`vAm~)e}@OxIKtD{Zf9Wf|4 zyBc?rS6yOuy^|#kapF9Og^i{Q?6B{zA5foXH*vf0A6^7X%t*;2SO#f%8|+-%TSckw zi}@!>UwiNq#IJz#uv12vmUc%PZCbrAD5~0t%{J~Rht_?AEG-*;FhsTPnCbdEjUQf@ z>u5$~J&_Qv5yR{NKdAm*qy*4v#a7bZo<+gMo74chZWs7`@gHa92|pRs4h4mdb?I{9 zDPGANI-AQF^|da{7*08Py6YKWa4jq);!0FjJ{t9ELYbwIE{5`I>5&|JTPfn1`gwsm zdphp=Np{fR_)BXt&wiOiKWR#FbfvRph_aqk-ooX6Tw%#q4Cb6xZfM2Ly`Fc?R`h;W zsp;s1yWF8hEtikFNd?VFwO@YL6I#;RYnb^H<uo<~wom-bnIr2s9crpEJdFj^zGL8n z-aIP!Z}i)k$5-ZrRE|_kdNNa{2~X7l`7S_*W)#ece7(IioP_ch$v1SbAL~@(ne`&i z>E#hG8M{y_Wo#aiIMfJ17V0#j^vUegRuW!6;i>j0gH}99w+(daw$W`!9#qesc64Og z=I_k0Suq%0UcAsj@A60v-Qi7okO^L_dL7gJ3XtbJzR8rZUbtR6jU-&oc<t^_I1@1j za~bO!W2`N@8Anp)$?*D00xJ6a5QHvLdWR8zuwr_@-s(Gnvx&PjPOYd0?pJoA19+|7 zOln%gl6sSg?yYR0InpsHH0s&@AY2yi1#FHe%`t&rrR&xE6+-t&TIl;5I60AZ@m2fQ z4Nf>&%~dyxm1LhU>S3JfI%X&yl>N22s+(-w(mRDx?858bPAuP4cjv_2q{yoE!qR$4 zp2-6#kh<GWw!@nwU9W+q+YoIm^oIWJvzSfnA||t-JUC&RwQLUcL(qn-qj_ioFgm*c zF(dw8%m4-YnUsS4#b2dTA$5SiuK~_t{0A7&hp)bSjxfLJN7Bk+Z*PYCF+oP{0VG^( z-4Fmd=7W9=^muCM^4M0RYnt~go3}ES{JzG)*2Sbiirw}?=iXu|X>f~_<x_5-Oo)E* zqa?hfCyGUl;qGM`2tY*@5UVccg2dVWjFec@^c)m^>A{awCe6Z9zN+kb3724N@QRD~ z81|v%*-XQG1rj^b6R|OFqanSfkD@%45NOz`oNb>1SmrW<c8rbxLpl2p;IN(hdF?Iy zyvEY)lbcV#t5}>}Ew-54u|7twSL~gk8@<L$HzP>uwe5rOUbx5qJ^!d)l3+T+<JIsD zG=#dGmL*f<6|4UeUNCLMDA{jhsG0ELm}ru{$j{lHgA2q{LogO<8p5T28Q57(Fh1%A zdjhY|M9LNp-QLKBxlkfmpfZezm#t-LqPad!CC8*6UWJBux>u_7Sqw_c*duM9DaZeZ zGHnQXq3=2U6}~<dvElQ6HxVnS(eQzT`s`<rIMCjILpH*IH?T<^=n$}@L2j2v)7bgv zEC0HED;J&``zj0D8_O_PTxbD%b8t!0nj}nJcDEKO765S=1eoypTZ-Lq@4wi&&Z%n$ zl^pA`1XqtI`Hc8K*gb!RNJlVC$?IAyOmDg%orpu3;vY@m5Y0J#VB;5C2bGOXGeS1r zj3JuOGu;>p%hvxM>yxbatt2Y1I#!`cgr`h*`|;+(6Y(o_t@6AufF&5^HRKcuzm!M% zcyQM%u(mE)aA#_h7%(wKpb%hA%arxL(Z|#3ULmicGo&vYl0_+5{K5H~>agT(t-w6V z8^&}$;!{jS9`TCgO;y*d)Q1YCQeQRWgr?soRher9CKs)_F)#~68yq9a+|oC3WKMH7 zS__wJGSC_^2V01W@j~_0Q+6)G#Q3wbZ<30NT}!BQ)F|Ph`~<)tB1e%_Sdc9zq$J}F z=)d?bU%Qz^Qb+`vz+Ik+035+~6+HF?772a9-sb3EURea|`q8jId9})gjpfNv8axoZ zyxGh*Knx20-AgWPO1$k7;pJp>tB_6S!1X~7#FjNmqw{fv^&U0NoB{{|$x{XmOtVp) zGl?|RkvDf(4hKni&r^CG!xMI1UcS*9lY8aZjL~&}h*vuML>ch@R5wj>&aW8`_z*(5 zPyIW=?m(B0s!P*!&FrD2CzCyQI=!qztWL;!;};(unpj$A^uhqk7v^TN8GC)zs=-W6 z7qtNeoTynhphCa&Em!fskc@H1HF=6?sa3tW#HGd)GNCHm=J=b7AE9aBLpyPq5SqlE z<2meE`F?EDQ=0kadG&npU8JsMc;AUR%JXKj>?5-%E1Ir|F#FoAJMq55@lsEU_O1;! zcA>~NBUt#A)Tf^tcB|iB?r(e~#t5q>dV}47)mWiYQs{Y5>3BbQ!~awvLyVNXF+ke= zJjo}Q;wwI0G<xS|vSMbRqQuRYmTqmC9F!2C|0t@|*L%;EM+iK#|NH+CpU9%`G~{N` z#pPzfB*GwoVdwW=TxBNVM#v^}o4DadX&w|<n2(sR0_CB!1fDsPp=VAh#pdVdR%E6? z*hSmK$C~)3P4^=mYpNWI`-fni;6ZIi4H6<byF!!)*iwca1ih#?9evWZAm@`DR!<ue z7v3?~Z^W!%hYxH3Ejz)Dt?$#WcIqjMndfUqb22$r9_<m9NXxCoP6*@uNdU-D;BQN^ zthNCo9B9KB0{M|2ihXZ~Hbf9pp<9z4nt62i4o*h*V%Gf3nYO5jt`o@7W9`)r^XNSK z4-P7A&F%3f#=k*{%0H6F6>&rm`tcCkNm;d?Z_AV3$>(gE@U@`O5se*PP0@vzGS;;B zPyOa=bTGsJiuuaz;(u`pOsDW=2s-4j2Kk!thPL(pLRaLOoI;H3z2Ea;iN@FdO}o@U z?>mK0<CA_Vz{6_MNNT!RrM}r*sB4mbyJ`5xDR|n}F365474$ihX*fL!!^H+f@6h-s zm}1b!p1ug1MOs216Ry8S*&5~Y;kfwM-_cH~F;{OsEfn;mnjra~M>hDn7*1kPkp*=s zqb!w6M_=~1U>dd@?(tk{O!wXfr6C96mCKv?8JFgow}dQj+WbykcrVyU`zeGJm2E9U zC`30jN`lz8b6HJ{TE~{JF3h<C4UpQlwe~h=UCX>-XPXQ-Zp$P}n#Y{>ipPg-ozfbs z)<CYs%)<uyg8YXBU|){V>4h)n1COEB_cc&;y#bFR-C(pac+*?e>N&Sfw5s3m3umPt zd{6&`OdhLe4-S_eDdV;o2a*zGu^(SoA~m+LBY~SDxi3U}U=;{u?WvnN-W9aU26loJ z0crly9w%T7G7NkVhYm8X+B_H`lA?jZi0~-Y*Z+Lo?AQmN-~)>qs?PelRfJ`drMW~u ze8sfK_WONk=>2wSFVX`&<ntvH6Kd$F%;TjJ7k++^{LK`SdUN|C94Jknq9Mpi|K}B1 zbjC8^7bQK!%m0_EFHbj6JuR~s8Q*Ax_hnhost8<B7~X(@SJ=!LBMgaVY?V#$>Lotb zTb)YqDQC^NUDU#Tk)_aNuUZd_4-=G({a~)D!lS}T3_h5n91oO%o3<o*I;R+^C3MP< z1|OcIoS9`xp>6?I*ihBOucp}+w!wqubcO$?y7^b|M5l{NhGG%j&Ohf@gTYRu7J+-K z1)1E}R58=*2UZ}AsQczW69Zp&*WbbW;7%l%(s#3e@jj<;SILn4g_Syy1ni)^PPPsH zB_f(kC47##{+sC)`aO^iBS(-RU@#b1`!ClP{1>p{$cqP)N6LjB+{ZU_r!pK!)%)j* z!TX5r?&h8vf>bq@wT{YHgsCbP{1W@U*gpo93Vm*1+Gl~xjWVEJXdnts$#~zf451>} zJj^ZgeXt^MH+la{p;`NoYfOr|WU$z{+D)n1$JvIREvceTsd<4wxoYXi^rM~v+j>KV z0mr&_y!UmrTHNdS11Y`g%x$HILH5`hk%2a*e0b>^eM*X}>sJy&w`bM{YLYfi8j?2{ zUbO>z;R0)ht)hyqgG*P{Ywdbc4_jqJ7c|e)GSbZm+b}N`&q>AQls3W{fZ`!A9u*~@ z_~sriCvyM$0Vv}AMm?ZMrTXT%XXZ#GWLvt>Dr;tMuFM%rOAcRY+71i*HX+#XxQBjS zePP;+D`j4aJB#h($VSzO#=mN7h9O~y3IjPZYm1n{h-W&oOZ(@^%_%CGT`R(bAmG$8 zsjxPBo#|QRaTvn4xxA#8iXG-bS8-=xMS8_tSK7YaHuu>#TuTS+WV|Bx*r@&4ar!7t z2f>?CXe=^SR%v*&cq};kcb!$aXg-69c&f(+2{d$=T!15)^X$GPgiK*4$PE>@)YmPd zk0%j*O4hSTii{@ZY0mtskDh-<1$&mC4;#>G_}kIS-(|Od+Hy6Z{>$F_Mj<jSfMM)G z^LeR9=BYkVlOns5H+}2JYo1R9D-EJIcRK-jzm$~_j0GreCcWWOk~hX)x*+sa4UhHg zs5gJmC<ZXi_^~MuC9Ja*XyZLkK5*H4YnAwT+Z?YNh%S$)b4_fwEd|pdTYe91P|fpt zCYTL;a&z&r*<+1>da<;Ad^7ciDGZnLENw03r`XZOMmxRF;E07XIL}{8!v5pF5o6%< zL@(SxgUG>~Dw};ojs1_8HJZ>ij|4hT@gr)7!8hvohjQy1v>pVU9jXxpA+KR+gO?>- z(ffh1aIMP~SmRE|a>s+Bu~z{mrFsA1xk{45tu<^(_I1R|m_~3hiMyaUW5S1N8J!aP znJ1Z;nGT7RW1RBZW;!(*BjX?CPTQIpsfK7F(qm$jkK_G8+dp0n7@u@}RhHoPaeu`a zX<zfVwz-P*=1DOCfIA+M1G9w$uk9Ew^x^^l0IYSwqWT?F@(mFixfSLkWzOk^s(iIM z|3mStw)!f2J@YMKX;1$QIEG=;BFfGb(~!o4i@%T>ea@~oq`y1%k?8$x$!@JucMkvV zGXRa#6<;}J50*y8^UzS!#F#DNBvfXc_EU-Hz!?wUPkS%fLjxsRKB>^{L%Noqu$!Hb zw;H%xo!b(3?^2FNMdl7ynO8?}X-3Pt-k@nXaPx*K|5dGLDL+(@|8kwqVC2lcCJR@+ zSS8=e9N1i${x~aTzB7qF=wIZ}IMtG!`{=4X^L+<3<TEZtn4mP*Y0-miAnqAZ@D84L zNPtAI`}l0nfEmi}!f8mUvZaj8nB-r<7-l#n1qBY7_U#!5Y1jUlGmP!#O^`D;xVhO= z-ZL9u4?IkacTAgp5ha3e>>%l+#lf1b)avz40h=w3gkN%L@AYY68C^HI(dR5}2~NcP znfUYPE~p$*&P#=SBEzEiO837~X9y1%_=vPr0ajmY<Du>o8f@RMS#PC+(|?=&-1{XH z&e5lPbL_6CM2bl2`(5?rwJXNc{$GUKt${o7)jjP!_A{=^gBj9%3mW$L0e-Pf9diZX z1Xm5#Az$qDX}ib!LBvCUA}#0n34!cLZo%M?g_ufYZwln~m0B8mmOyH|@Rmu>Gb=MF za*yX!NKZ)ydr@$*X4~qyWsXg%XUlpl0S;yqz5sN*6L#?k{;%EF2H5cpGFS}%wYvY+ z#s8+!$A{KIKho$;cI<~{ZV1s(6qbt8BZj_l1^K>Ag?__52#69-<N^G4yLFHl&A=Bh znPrUSJ@d-4$)o4I<E3T&ry6Nd471u{uL&I6BBY*%C+31o#G2#5_uE}_z|k1TiI<N# zb$3!s5Bs+mYIjng{wxD{=Dl91YDfWU=m?e=<+NVq49nrK9E$l8j+*Ho!K}y^s|RP^ zD~bC;$#41{-NjFpYJ&P7=pp?EQC~f)7%?C16VLZI=6SkXV=d&lN5eySix`DqklzZw zE!>MQ%|JVh1T}x$so9%-0UIZ@w9(=1yC_97oX3ELx$>G?sHiNj+mCOgPpE;i$V>Ri zc1^rbFd3pHst(E=iEA4ese9u)wh^`RjnV#GW{&1rgk?GQ+0r?XQo5-<(!CfQ))z*+ zSp8HsoFc#XvNQO_2pZ3Bh~-iCp_Wp};e6Zz<IF{3Fh7!UD<hZZHullD$TxUZgxmOI zcOvt~c=5UADJpw?-EYRV!DqZs;-SCf9|5PrRJAx4VpFVeEd)6FQ^r4;$X6s=sX~7m zQ6|LtK<t-~zDEE4Y4Z#XuOu4&;D)ZJ=`Z!GenL6_`*eQQp1c71Z54bG$oo|PjBgzH z8eVJ^HEfP+wD~g4zVVG{4c-{tohrzH3U<JPopW6qr~Thxs#apg35+)$l5e-<7GJRD z7NcMtKL-<sg@|2(pDDe6_mP_L6AOpf)>C+}Rj5WNl_Y3{SL<spfZZcdrt2p4WSGp9 z7!$5Qdv0K5M5Z_F71?guDYnQGQfc7ko-&QC<Mjm&_t}`s`+U_AL~kU^LdZr<JMN36 zFzMi*rN_6@*l+El*tKsBfXN9RBu^ZdN7RoJf5H#pS=a8}s_y~zJ2S>`yZ@oIEdao8 zO7rP=c|@c#7`1XY#SCN^NgJ{<1C@uDLGcfarRH$Gq{K}k8IC{-cuOuY3)3CSu+K9s zVayua`5@MnQ|@^2Ns5yN<;Je-5@o;yz7SP*DdRf&4*iTTy~IxEyq0#m>3_iAV9qy_ z0cDY=7_K8RH1BlrC<ssl;_+fs7+TQ27O}rfxcay$Dyh?e$~Zv{{+thH(;@9E`AlM! za&=R^p7c|*r9|ydQA+%hNO}D_H2jGRqMdFeg~hrg?m0Y7ukp!9NjtJb|Ib8*b|iY8 ze@srqZAFR3_hf-YX^)RM>dNAeRoWA7PKPf~!xU5;=o)LW%?J&f>jlB2*R@G1Gx8Ft zJ>P|MzUh^`jW0cww=AO4<?dDtPOow)NNz_@T<CNu!RTjap|q|s)u)lv09*~d=xpl< z1Xa(#O&!7WFptGX=bskEs5uBzg>@{UF{m^bukTE#w1%U1rIuhW<)6J00^(A@o#2sE zVo6Cln@qW%{y1(qVUYer-7;p@M<8RSgei3FfTkwswbD1i(FU0RcB^L%FP0oJFV|0F zFN3#l3tsJr@On$Iym4Nc_)s=tgE{XmeqCUvDTIYborqHdqV|Brli2<6?K^pElT+28 z>1Y|B&@DOtfaWDdG&Fnn{(x&(N-pr1!NKDf_KabrT>W@2sQ|nhem%_Yj_ho!cTCqT zt@af{dHI9al}b|StsLv)zeA+q0lK)>?kloS_J8uF!V2znUxK6#{<AwyRAKkXS2o~> zGJKP=A`uAJ)3G9O8`hvN8YiL-HP_3C+SeCKZk1~m6vrT6YOg9C9z%EG`7;|7rU0(< z=a%_o@q-2fE~z`;b||!T^;j9Z*5&*LJ6|>HbKp+0(%yUFV^eZiVsL35uVj2YBtl2o zfP^klL7gOg^!XdA<<t%nj8<kQo#x{1Ps>mF5DoMs`?OP{HcN$C!ooOLB@9yJyvI7> zSIadK>uNAT;@4on!a^tv=N=M4n;>ktu9TO{C9%z<u3U4+6Ac;>f2>THjHBAMMQgOn z=3v1s0_Y(L;r;--W+r>S;z0aa*L17DPdZ@H+uEcO+Yzzx9qKGcFE(i)K;H)5uln#% z@2-Jfqdv@IXm+U`Ia8##$@;5hxiCU)^q~Hu#A0d1)&=<?t?PU<pzI!{I)_7evsNR$ zDCNz%Qxd>_`T|fue<nfZ0=!w@2gA9h1l5rZ8ez){7Lv|5kW~_%oGV&9+;um}<yWsQ z@hZ9jaM3qL@UZ=A>Vi}K@NMx|xPRwuT1Wr_^WXKOs*D~kGxu_B6Y-2#Q&vhCINN*P z`4#`Io0x41=+>y{-}7{sGnu{38-47L+~#VV*>*+LkN^6IQ)U?^k#BU^!+&(o7$qa| zC^sv`w^tYC<fU)??&}_l7}h(D8{J#fM1D*USeSI@(h-f++u=VEo;4F`tqxVoclTG_ z2}<}I6L$29cCKzv{||k(bHY_iK<|B`Z#@yc7h$T*^0Hj5n5)Ij$d9qk$XiMN<f_6> zdZc)9L~bVP7Pv1Psa8yh)#x}LG)y0<Yf+>@SxQvDDorgfJI;J`o1RT|;;{k@q^t0m z&PFLY+pl)LE8X6C2v78$>WI_XofI-1xKNgYg?IxPf;cr_O;66{ST?ia^h9{{lo(43 z%k`a&5W2`S;h<dTkoF&{2h5iv#cIfuqh3PSkH);k(HeK*6OMxVb&h(~<d$K}Xw@|X zl_@#-Wx_ey>-J9I8TdBG$gJN<Y=$gRsjrzN!ZdRb61f4Kptox@6yRVze1>$gu^>o= zfPv=n77GS?1}q14IW6AfNFx7K95JUh$6H5sGD!VvZD5Wky=%(q#~1d`)_$L{P<GhS zMJ{Q2UX1gLB~^WP7!jINyk4?gC<z_bEiI#INg^;OsFk@e%jFmxRQ8BCf}#Pk8s<qx zjbvRm_|eP7f9m@apctgrHAAjS>iz*svm^Z3T8R^v)*St9-7}%sk-Ex~Z)$<4Q)oe< zIXlzP#q&5>tsWFx#f1^&U3Y!{`3{hDdR@Jb@`@$L>y#7e#%<-bT@OnJd-NYF+0VCp zXAaK+1TQN>%}g=*DE8cg(+Ps{qL{wX-0NNWsDOR152P!v$ZFq+9jx8yv?-iNotb!w zU%@FmJ@yg<KDP>+qZ_l16PS=EVv97`=#D4L^-(rBut0gwv4|wR%5OAJ85VA-cD8bh z7qgW6M^ECH_+$rZlGAqK#HP(htFqDc1PX63cJl0RN)en+H0y)nP!0R(<&%c87Vnun zc_;X)NHS#-IJ9rr+ek59m{MOOLrx-mv6bq}i}=0ndv`8kgI?yhl>elw6jZqiiHcI! zPkFjbw8n}oKn?vOzyJO^ZdG_0YUq&@nl#?f^S2p$a;f=~Z|in$SvX5$DEGNY(C6nj zgo&A-J4@TrLPJod1m&iPO;A24D5#Tq<i*fxd3^h3StYrqfpNH`Iy|owhGnQEoBoAw zAV}gv4fvJE9Qd|YbWQH5fQKhjyA7$BYLIMLeReH2xmss(#xn-}G~H}mkL=v3v3VW@ zbjSg6l?gJ>n|Yrwc;Srabl!`P9VICkdmdr_8ob6;UBc<LJ@0dya#}6=l7~a#*dH3v zLu}+%8JOIC8E@0w+P^^*r4}J4*QqF0M*s+{wCW<L6Q$n307{rsAV5~dB|ZPy+)lox zoDeU_F9pEwRA4v#lvf)$ql*=Lqqr<JUKIny6i1z9%aPg6f_h&j5ya85zm&dJrRrZm zBK$H+D*gURl82~>toT-rJNzj7o06E`Z@$uGh@INqUDcAR*Q=fP;q>#SI_t@ajxKx` za*eFYbfY`~Ro|h+Gx{GY@_bFJz|J8(*=V11_>lCG#+5GV^6^A(U%oMPQqvC?Fdtgi zUbj1T*9sH}*UWK>F_vyHy7%de3utw@(lzZ?!#fq`z)+9s@x8|CI8z(ev|D}G2*ysp z=chNZ$O-bT6(5*5igS@4x|WR;WuX7oLxO?%{l>&gWa1GAKK<W~glrH1R7VC{mLX*a z7CXWXj>crZwZ7cb37o}}+9`XwPFzSTw+GlKkS}}@5;whD5R4-@(s`S%oVk-W=D}=v z%n<LTyD@5{EaxN=0(9==aA32t84eVdKoR)4F^}>4MiS$urT&_1$G}UmwYJou7NP0) z+dbH_(4ESyJ*5|J>DH_zmABN!r2*eng?HGvRRe46_Pz3{JYAwUailc2g2-;S6_a)d zUGzEtb*Qhw(%`oM(QJ22DwX)!9y=IUS`d|`biNA{t9m#^H<TS4G+LM6oP_)6fOK=J z3^YcxMs3Y6>GDqoRB8B^dM4`WCQzc@$#EBbVF)j%s}01Y{cG1U<vyHZaDI}C+JC#> zy`E8BxkX-Ks+&ElrPq9a>c0K6NL%?|ZB#b!(+XmyK6J!C=*B_9%BOHbQLaTU?8@XL z?v!MwY6)e;=0ead=V}6?_&9d5Z3kycl0{KlXPfgT`f1P$wmTix0;#aUp4Iqm0%N;g z4D%P33gmh1&18zY^+Q*~u01U9clw1%8Mrd*ONDAQWUvE<1-(zVJ!VZt`!Os7buwV3 zwj{136Frk&qMv&G(Uwb;XSCnANTApN8T$S@jultHEuH{&yPwH<teeEEf%-O9Sx)?D zvC7mJkBoS%GhaRZsFkXZMD*&({)cg@0c!YWw~UU^xN{&{Vaz{hE2TmpZR{yQ5Z5wW z!$!3#%(9e=cYl~%%;ccV-Xz)<->xuDOSDvAlhR#T1wVpax~e$f9VyI`rJ>x2=lc$d zTfCQuF(FI*d{c_d8}r%r-@Uj+sc)@(`s!3t|8ySE+q2EN-?7M~|CkT#PGZmOKj~#K z<(8o)?Oh-C&$(wp0b7tLsYe!R5P{Ua;hawHcc6hayD-cVffKECx4t9O#xMA^k0*w= z5?Wl&c-Yd?94l9h91}F9tmJtMQf`u9(tEw?`f5WI3!(*d<pOtC4)cO}?fGJ1IF!|^ zI6zqYUs8>cU2-k4YUnOQ+4|=cZ{<4P@3mj+!Hc|wg)H#|fJ}-i46Y&u);2|bPt<;) zMaUb4`8rBb9aE11Yy#s0NMoH9Jjqt^meTfB@4}f9rSE5d5xtwz<0Gm)C5`>l@@JOY z+V|qb7*mH=?qD|jmD1>ltSWa(@#o~0j2O~BFoE7TM|Tvd{DE>MUUBwtJ<3*#`+M(l z+xNmEEZ+r_KXBI<l@gonF1%W^TbGE<vVAG20XZ;yy?hZ-Q#(xemqENS8Pod1mKAGq zZ-!rO)Fh)%Ev5z?nn3<@v(4Xxpd2eVmn{Ww${il{fQ7}`iRq~FeXH|4ITa509$nk# z4@56^ezyR=tOzoH?si^28gmJgqoH&aL{AiWEQi~McR3+CN2r5okv<L%A|v_Kxe$o| z0}l)|P~pg+f?<h~N^J4L(x_X4;;+%HX6)Z?5)oR_*|XDF|EH&aqCbkiwEVm@U8vO> zA3^^!I)tJgVD%*JTUWgG6c&iT1wkrR%e)L!Ti8VecfW|8-5Bs}jZ_K2EQ+QGT4p84 zK~wGn4f~l@JWxN+$k6sSAQZmcv)|N)8QsiWJrvjw6v=Y_`t$=mBsl%Bx1lB~zDN8- zX@`Bd7bIFz<jbJ;{gj7Km2c%-6rKAQre=etveZ8V0?z~3W&Gqe{{?x*=bckn?p@H4 zxNHQ^S;gq?p4MEP{zDS=Qz69mA!%g?dT;h^HK*e?O5}U?2Z@^_xweEfy6xmdnh=j< ztT%@edQ>r6qt3Z+%llbc94elQWF&?klmgAe03uPs4m>d=$)Oa4O6YzX>^FLr<4P=t z?QRdjU*Uc$l<3Po*Br#4D`nZI<rjr83EElcn~C2)tJbiAQ}+jeq(tljSbe#D$dl&s z78d2VmK|w|aZu39Dbu%lW1Y&5NbDw}KPR|#_6YsaFR-KbHcI%}MMU%Koaq{h)N4#z z$+uNZjr=ViGJj<$#ar8sEt~5~I~_8+6}ij!-m}iLw^<JxJ#CG0(%c|kRNEu3=Q{gG z+%Ji}w<4KcNrd@ZO}6<w5YEtG+ILp_Y&0^t4l9fwOgy1Aa*kx82k=RUGsDq;$NI~c zXIy=xt08-6zyz>C6*k2m;)*3?>_hjFL~Qiv!qB5NYYqGUW9i0z<ySi{1@Pae-tQ(P z;s;CrYUK_7kOd8uIe+lErCMQ42_v>2SzsouB5;>nM5GymDJwYGJ%%2QEz1r?w;iC% zps=5udw)AI(JLyc&Cn3Kd09^-Zt&Y-5<6p`r-rK~9O_z?5rIUH>>JsYwIK$KIf$KP zjpg>sD$7#CFa9oB#R&>3F|~$~CMd;Jcn0x_Z7j)LC%wSlu}QQH(Ye!`<QYV<dYn&m zrDkCC+ps0!+n5k029*WARTdTw_@zQ%k5B%#d#1S7;N{yKosyTQ&E8D`jXP{Ki{(3$ zPEMAWNrN4_8J&);RPMNz?AY;?(*5*rYSX3YXbYY;WmT^<R?$`ebjdy#`A!WEauMih zV0N|M-1Oo6?0Q8Ig4!p}nk*2eeD<-X-g>9i|2~kH@8r9`Z**yUs&_zD?sp^2oS?J0 zh65Ma5Vv~>>Y0`?^25jQCcLYcjr4A*0iO#4m{<Cyq%l1!a$WElpsySWyA06(9Xg0! zs@f@WC3~2T&c%T-cir8ER9BV8QUy+i?WQdO?FH!f-iTR6*5OGRJ{(1wz?_}gZkjKn zLuh662_G0TDp8ogS2FVw*;&=J$8Om^5kr{D?@>2vyt18|+(N)k=&QAUXc#Z#n7ohf z7X0Y^#CL@2COj2WOB$q>_!aqyf^$y<0~TE6Xy`8|Uw!3geJw4aYiMEZO1u?oKcxQQ zC+PBpbdn<;wBv2v=vrd)pJ?yl{G-{%KpxmM&EqG;<Yq({_9wdlpHEIVRVP(P?_K+Z zBD6L)WWFEd%d3|78~943TNP0>yIA=(XUBH_z2cXmFYvwGcFZn>Lqg9V-?)@%+yq3m z=Dtxp0GU{!p^EPYEL>3d%0hbyYj{K$>3oT`;QMLP<3>O3mMQctyu+bjGzhv`7A$`y z^ClJv+UZ4VG?_{&XKXJDE_FENK5s#AK)zW5mt?3=S2-Yl{ywuj&*r1|$OKX>2Fg|< zN7m#!7r3KEjlPlNI@V?qWWB(V1QWg4wO#CCp&arp-{Iiy5vYqwQ`HLZDm+dTW9nYq zU$<&jYyWp0nNPx%=V2=Iqim>b{{Wl0YiUa(+FT#roYf||AIG01F4>ZUCha@y&rL0d zQh>N$S|2}Xk8=B_lc`-5hO-+VA*W-BL1dr4Fs9~XLL`RA+4I9&zMPCiy0^x#E!r_< zgvg`+!Z0t~#|T_o_`>_QzgIQ>kJMWA4avp*;)kqAQ9x}lr%THqukF#nw{fB>AU>dw zsc-xHODL;N)o!Htp}q2a#vK6VESzjFv@EA-JkdAT`<75S{01Db_~LCfw)u&ESV%#h zhEW{zoXx_wQftg-8-}jA^G|nO{r{3QAc*Qi5sGMk%Q~>mbR}z+^s(+mg}xqRuU+4y zicm=V&9LoQIkP8|Z8=~KK(4rsh;335<ox>{9mc@fsPgX`TIX+dsv&-HqWd`ImT%wW zHg>GK!kV*d`L8nmG1)(SUgs2P=I>J}G~F6vKQql^$kvlMJmQC4<4LQS9qqd7_UxwF zr<x-OyT7Mhu8*<m2m9~$3~)mCYB~+tUAC6lgVqG4+sZVy$XrQ%(2X)ew^sqy$6@sW znL-Gb|90~)8-2S&zucurn}`@v@a3@4pDuCA$4Cy>+I3X3=$13?EP*g-4f||9+;_7z zLrRVzyOxXTsf<F)d!<N2j-*$wQMz`TE!1ER-?M(jqqPVs8Qqh=ZOmi)sL$0W4#HSc zAdWn%-CeyomVeq-Qq8pP;P8-6N?#gitk_bPzC6<Ei4w+$p>D<M$wXieeE%6W_3M4R zcFNjSoy>w1p+_=3(blwjUiT}LI*Y)W^?%V<&{v8Av5xm#r~^59UBS9Xc3T{u*z%ax zFNcLR=d^HC{>k;7#MbKA?4J9!bV^4>!N`tZyRNXb%nR1jB^BK3zkZz%D5^5jXs`5e zeZol8bS67w-kdqeBdPtXb>7kH!60>YUx3x+p_GMFNh)-)S1xKm1FcR2>x=mH^ArHq zjj0=HYaNo3#oJ-|TB9&FW-9!68dPhTDiy?NUt;;Mb}@j*etq3web@u%Gp+J8%1+@U zSAPD`J%xKmuGTV%GSlne^p)U0RB+#bo#_!tLeUK_{8txv!!Cfk`X4`OO1VDJ6<W{P zQ+hB7l27v~PYTs9Xp4vH-@hPX6`r9R&91~i=x(Z@Mz@b`my;6n_~E{now#C2lZLLB z>wwiXshOuvjpb$JlEJLYfkDkRou9QcCFPw<iDBm)C?%2W%mw+1Z*Usl*AkYP0x9<O zP@ApOAJTJ+i{pA1`=Nx5)mqUlnMi0^e>D5DCNjmtQ(bgq@+dq}*660qA=(b{()9Y? zbx-|9V{{t|lPNL;utYm%tW6Do>9JuEStQ=se8Dt3$|Y2+u05D9c$EPa`2o(Tj0}LQ zBCO}F8;$*%X_&rfO>;`Epnl588gu!P+m&-bbGx}B1cOFgU93#^^Hd=%Rp&+M)`TF^ zlY2Sts{6KfScZ`r<2vp@mS_xo1*i3dn@2(C)RP{$;OZ<0^jB5igUl(Tauz_{<f=Ti zHC_!jZBn(}5>hj%CZmrZ;bVp`Hd6hvKASeCYG|nkEU8H$jNe*iC?rr=HG)yiRvugf zW$KY$4+_;CAHLGsWY*bfniNwtL~k1wu`$|*h7MHhwErikR9l~IDno|OVmbg)9%XTb zC2sc?{+bxikmM;#{Mo&tl*RW4xvow>NPcQ_-FA%-%@BXEl1EgD8V%<@d~0n_)B`6I zGwGjxN6N!=0q*NpzBfCJmqh;;Q{fO;Q82|!ARFLyym=#<W?5W(AGDO+!q5F?G{sd} zGt5sa`|*Sc!9tjC)4QT`*!J7hcusz4csGeqeofqzQRHAvcy3f&`e^hu%9}HJ!Y=>& zrBfdny`?`Nc0K0ME6xmOkr@LZQQX0Cu{9E22ou+)tTo??SFfG4&4cceZ637G==}gl zp_3v_Gan?tMch$9qQX!>q^@+h`4zwsv1~p6pp1%oWCzsd5U+ICz9b&d|E}lO2;A>w z+D;-9e5M}?QWx;zyjClFBtPZ{(ZAP`F3wFsj!WrV(nX~2hU7(l$$ImsToYibC|OLD z${qU`q|DrF-7JfZgc!7Z;kzQ_{D-Yoon|o9m$;Mu+>FRS(|sVYqlH9W%Yp;>nx4nz z9a$WHTo4bbw01@)nhfFI(aW)afrYrDjs#Z64Vz%u#U>I{ewg{zqz?d-A`;{EiKo8N ztGah6L8)nTYvMnvWzAx;qqL9Mvmw-zHZ`N3?`zj?bmBfBd;r?m)av~#-II(%meg<K zVltNC(;UH+@X>Rw>ySVJxKR!<_96Q7Ry}YE6*)!NMjHfE4h<6P#pO$M*sawhnh?E5 zG_Bv&*aS--t>)&HkOmlkKPOcOeLG+@s$-86w({1ScUlPTr|Y1-a#=H4g$~L#O~;=J zS4jrRES+WyTQo&0(B`vRMQHXva-D6i;BQ@gZFX77@6*rBqn^3od-=<Q`<6;zj3q@l zglxzvhp4pEBT>94&01K<{##Cw)}qQuWqSr4`~3*BjyUk=_ud@t&>bEaro7_gf)~8j zKKkgJZx+O*(w2u}q-*kuKIwhF^YyL%BZWpk0~mgLdf3{b5p~rqc<r?&VjL$aww;Xj zYu8yb$5m`ftZurF)Rc1eASDWw_+OnvlvpBIEi)+i8(7=P@S-qMh|hrb_=k_o>{C9( zfiD!&nBUJ8#0=0Q7rT@{JDhA${othgJz|o+(T7s7^+q}}VA1Dv30RrDXnxR$h9R2+ zq`N#!Mb5K)oSf(UIEVJvBS5P~bSk$Pm*#T8<N2skEJXmi1IN^I!2iQ@naAhW*4NY- zcC6L2sYq@`byW0aBCbW^{(O`$0az{yWL-uUUUxvS6OH_wAw(THv{k0%p4ly99Z+^- z{w`>Q5kJoLYawfTlhU5cND>%uH$`5QJ3xp;aBG`1NNkRe7af#ZMVHKnoA~?nWM9+c zlZK#-PgblMtcgrcj1h1p%qqL0o=tk^w^9!V5J$;2ReKy61@+{Xo@AT6b{ljeNfb`; zAdf(CRf%ViY;l<Kd_j3T#23|)DZn<_l*iOa*3TKKLOuCW9vyIgON1?5ji@A*Naba4 zMy!i#>-%`OOy0_{fTG-oCERB=wG<HNVe7eOYxy^g!*+JTFK3(mXeD{x;>YMXze-32 zpq0Tjy#p?2?}qro9%WEiiIJHK&y@eBA1Uy+u+obk1!o^!wi57ut98Toj-TotWL7?3 z^1OUO=RGs3kE7`CY-yfrwZR2zG#Ll^G`P7tnKnD*Ww1n*D8^Nm1h>eTb}l&zD`T`S zr5L?~+ILl>u>aBZ?O{XODM>7p25rVRKS<)sf`aGs399SP3g<mn%(n72w)qil|G@DT zuq(>@I45{xKkAH9coUdRcAp*>(9&~Q+wLVfbgkvhqpG2P&E`3G+3-7bEVxr;e!n?s z(h1+Fafy3)IDKCKBY>X$!6FT<b<nlq9AwA1#j1ZaYsscQ!$oLo{A!Jz8kcq(68-Z^ z`HvHrGckNwuTrg@Ujp^WyaMK?28t|;Zf>9TKJ)T8aHEh;&<8FO-LIp$uekKPdpZ+m zSEZa&ZTje=q$l;_c9O!!LpGRy(E##Hm)F~E=49iU8?WGA=|d_Wj`!CE86cEbCtYYb zQY1>2=H)JM+dk4s=DILp%#TB;Pq~bBv%Qi#M3RLALS?j9Id>NhGK>F15nBE24yo%O zQ(crnYepWx+N?GL6)XW0!F+ganKCl2)c1#m!(Yjdk^dG9sy@)U3M`2qT-E`|wk<6r z1Is_;YdM;$xu4Hf=2_;=;5c~Fj_t51x<+f9M#H=w*P3L2Cn=P6k_Ouz&~h!H>>uc1 z`P5cKE+x&WP9)G%=Mm`r7VfIO-~Bgn|6~X9Rca*ZnM@KKpLCtof4^w8Nz=u~67QQh zw6mz*d~?xv5gJVNr-#f}5c(0G80Q6{N^x|yX=_N>^)uq1GDu1F5dbd*_u@R_6eVH$ z{<rF!0d|~uk|T~p_~hEe*M4g0&7QXnn`)6@SjnVA5x|9`DvPM4eC#DzCh0bwL}$!( z2jCX}ncU+9@;v>l4RqMX=Xm^JZCCmui1ny8>hzKyH7AP67VAyQlmY2%H{j^PV^;(q zIy>QYx-)^YrAA5)j<+6${dTkpu4G<prgDR5g5ucW<}OIvKEQ@GP;={y&uC7Haq9?R zK`%<Sf$e78YYU^`_q10Y&oYDZFAL*`wssG<$!8=*cA?>8>jGr)Y!~m4&d_JPtZf^F z^}-n3`G?n*>$2J_XL^^<>O-UM)j=%}=o_7~WRQOSN5LM(HdFlm`^J-rh!-Cel~Y&6 zC9KCASkb5Wh2qJ$(Esy9`K=5u=?#6<EVQHY*Wq>+J}GHvHPDP695Hy+FI7KwfYxn! z!;GZd`oXvY9n8GHjcod>p}WYMubCQf@-9Oze$Nu6eoC}J?C6qwqeq?!sg?LaN!C~C z_si5+C(*}yp@q_hv^wtBGF3H6S-rNs@jZ0#=ela&w4rC7ru^aTr?K|lj@;PYwB&*v z8oGp_i!EZ>{t5%5zfdV364lV{RCY`Q(tZpt?8UC4o7uR2b9@<8`?FGC`L|JKi@Cx< z!qBo2daG|+f7J!?3OrI~T9zc?if~_tzE!FOd}lQ}ohX@Ng0#Cd^Ixu|enc<&xOHiH zb3|2clqPJ%^uw!cxmw$=HtMQ^Y6V`P2+*92I2>G11kY>|2|H<>51fn`>AY?^x6I~~ zbkoPiAj1;M<ElZtPK?YiRmQ*E%X=asW^Qv?wgmLk12y3w5qjf6BlU_P-o|pSzh;KT zsbb`=_@t>^W-qsC19?L4ufKS3m00)m!bg0;bkO--^@)RXK+PNyIpy9XFgxY{49`E( zLPB<A!=)@M31yWK^pS-S<_u%s;=6U!v=ILs0+@GQ`5Y`iL?{iY82>|AmjFseK48HV z)x!YC4wYiuVI=m2e3&`EGACODmDV>KsL6A7w6Q5Fk7|aWn4_j5>q4g*uIl-VUbT0= zTshem1pO&KZZ{iYkLzLg)$i9AFm_md%1Cz;bTO!99TYqOK|cza93k)Euv*BLz#I{_ zhGg%aF{Gh4N*EHmN!i1JY&Dv7Z2qC9&@}6qagUj0$wc+JFcNh*$eewU7`=@%kgfo* zU<QyyLyM0J+mYl^m$(+}Z?)Z8D%RXxv%n3)=?Yxtg^1zSGjuq@T9-j!Hk9?%#5zFc z;HpNLRnOYdZ6&Kw#DYxK<vBnY3|}pC?)8hFXJzpN$?f1Q+nAGOUz^k%zI!^vFlW=z zEX;)MlE}dha$@f~w{BWof~k>qY(c}qYhJroLl*jr@Lo!-?P^wpj$K=Mr(ur4L^sT) zD4@k65ap@nOx9YK{KO0gAyU1XA6{FV@RYOoPGmTI>^Iuit#5Ew9G3DaH?x1hW~%oz zMYLE-`KIH=!f(ILFF-Hs`cwol$^ZLwdV7+09r1wkC^Zvk`w2ll;y;yOS(%_=BI;dw zzw#2F05>Vq6-Kt}w)Ewyt{gfbi(0rYMP6Wa`#kmEIMBm8?aoc*X7uf7KH&pJuK2$S zy9Gww(814~ALBY4emYpfHj{dr6MsBt9pBrAbg?*zWPYtVPy0CUd=a8@(e+DIF(o{? zy?^(B2~6N|^?ERZ?-Qv@W+;$r@L>N#an^{+W(@brk1!LM6%L?hpb_z&t&<sau8&gr zM!`+t5tb+j={7xxYNj)#Q?g@Cv5ckUol-`X1F_~8Oa?FYd;Pj!5#eli1aovA{{4GV zv#A$&{t2(4c0u1eaayydb?(e8AZDkvHO5D3woO6vT&0h4cZ2Dv=9%h{ytz1!EB4-t z?Y)1XyNSi^9u{!zLEnN52Gp%FYIPvW;%z&_w@hn(8z1H|v?dQem3~ZKB2O86A8+Ba zlTaqBhqT?w5AUM0%E)H?+T<j-DiBh?Jfh678~@C@H04Ge0}57(@#S>&vgesSd@wgv z@8Z?fCZ!Y?PLufr=m<EtMBGn~_erVTP<!JQeQZrdfl$#<9+GUVI#9)U*?JKEt?m`n zK#x*n7-Dc(uX_Y-)sY&Gxs)S)RC-$7q7nmWqCfo)1(=~&%-J7(khA~=*0gJrOa@d8 z_cg<%K!y(l{9e1`mJ?bFpRo2w#YV4_dvmY_K=SxOiyRhJ+Mbotl=r;@Bg^rnr3^&H zrn3@Nole!tCx%m@-!5Qy`O1LlwMx<Iv8dKv#*!xYjBI87sBGqm;p+T8mk-k}k%oBP zic85f#a@@o4kIB_fk|Sc(V-+Jh7>;r#Rh7EItJJ(%a|wR6BiNa5Bs~F3cQe=Z4Jg< zISLkfs^{ju&J|tKZ`2@IPY=5x<^J?FBn+LX2RRv3Dno|E%~kW|8bq!GO%65C5O8dp zlkl&LBqU-rQ?s*X+ub@bv{3U^#D-T;TP4MKPLtX(u*_uuVCml0o(6GEDUI||F{v9_ zqup~Eek3g@PZYtM_e*hD`4Si9N-A{HuP)k|_dL*TM<dFNGQ{{;;vl}Z>EsnppC*AL zjK07V#chP2>#B7izcF(#AJ5n2{VaKZ2mSJ|mPB+9kyOcvaTGgTmQ;0hjT#>WI~@#Z zpFsOPx?Ljnh-da(ks4i_Vz=n0sYb-y_H8&{Eg4Rr%IDcmOodB<v_AwXu|?&9`f#U` z`IdjkuwiS(7xi}sZKFFip1p8Q!hrq`!jW|N+&~`vOw-8<g}u@6LVAuJt7hV-Xnqh~ zqCv=;KC_W-C?N7-4Lh^Ev4>lqmu#7`eC)~K$U5hBOjQBjO~*HYq}&X5+7|Q7(`Kg} z{-h=-6}!}xA6b-Wbr$|Vn%+B}%Kv`@SBi{ClI>JPR<idwX<2bX2yrSaWM#&2j?82g zp{$dvWSnd=j(y19dmP6eImb8-XS{#+=llEp{&nuhInI4v_j6p&>v>)L(q)CcP@;2d z9CGDFW%oMmWh+fek*M0*pA4vt@<h|9=;11|>e7vt#B&>rkR#4Ss?-khLgR&S##TEJ zo}M!d^nq|eVzS(3RPssgD82JnZ4yL9Rtt%<>3Md4nT?<SN;%V$#sICO0$rkE8!MFh z^r|j1<8dZZ>Ie`$mt22ORmWk@kgwwPhJ5G6UHk+iKJS#8-dGX~Joj_OXXtct0>MT$ zS+XQRqaDHQLsqM!vJU?4U<IqVTlx}0nMpn{XgrbkV)$ReN#2HjSFwxqR_WYYVQ7}Y zNM8C7brZEb7|EfsO$tF`hD<=6NY?L9;5yFXlk4b_TJpmsOMn&{A$J#`uKU7phM+dg z+3#5D_3Z!qYDl8;K8DEu_V_=BI~A1SY1(J=kUYej88W4PX0>f*+U;tZs%%oZbbSBe zk+L$j58R|^Hx3kVoCIuiqjU~jtzp<#R#Uf5gJ_Y|HGbU*CX;zNSIohgsZl_4Sjs_Y z4dd9Y_|<tDuE^@;9fx)}9-bm@jrh81ybUOanx;y>Ua%6je|WA^zJ;+~xvL+)d#=8# z=nNp}^%Ql*qnB)Vs^Db}_CDe{MJ+8x*s*}w2q(#H0#_1d{K}o(!8e|r82s-J9izEF z)>U%0Rk=){je3l#lKiJ;FGi+H8Q<|QKQVxZ<P@omErBzEl>kVhuVTws&N^BgW4*Yv z_g)dONwNcm9AO)nwmet_n3+*}X`cE2tx*4`B+eBphdj6_*CY~6dg!^PyRw$H9IyHG z^N*^=k1l6deu#K)_q%0$F?aT7<xT4IVjfFB;+)-X*U*hXK*$Q(pvRRX*ODJPr)sKM z@c68$^{}d|VZmW#^uMr*Dp=L?G?ClHh_p*&)`6wj>CNBj@ki=Ushv}AMFF0f{*uT= z#1C=?GxS!1&j<LIRl(`K&8>H?5%ZQhuA}8k$6&?bAD=pEi<NS(<*_<I$Q!>n@wTG< z7Y>xz14ZEOBFM|qB#Cwq8&!Cz_d-dP9P7rZW0k#Yo{C9w;@e01$Ks`~^b3Twrq`qy zRJ3o#hM1t0M0s2k=y*VP$!*^yur*@6(W}CD&ux)@X1k;yzqGFm0g-KkUP_X*c%VMB z^_Fw!V|bs~3t;KTls<teugM@B=wQg<gbC(~s!FC1oA#X8doR1^Wz->(COxpnpGTQj zW{n=oEhPkIyw%J3Lb2Sbzx^&^kPyosma=>d^`$8OEq>%Hj#F}NqcUikdHMxwOI@1; zDxqQ_N&i-{pr=m^?j=e8p?y_~1#u(B!HnhOZ%U7(d2RYhlin<%aGUN&Pvb=Hf;(6b z<-ewcw~uw`+v=!H21_SM&Oh{+PvFvW`EjX!{2Ct8X__doVgLTuEOPM?=6NpJaw*az zk?A!f=;;4ov_jQ3C}TH9HLU7vAw8!Y8HwNlPC_uF_?TCv|IY9~r1M0=zV1qO;s@Ub ze60Ju1xxx?x8mu<*H71av=!57qQv!`EJDUI$2aA&oTYe`5nX2YHK1xQj3Y_)?oEYf zADv)`vAE_UiU##@Gr=M!=rlW%5IZmW<jc#o+E;fu6PHadsQpv8bAfR$&@Eo!pTw7< zmuP_)+b)~g-ujehPusRlq`^Pin~61v&eE+aIqYw9T5YGVoeBl~8YZvn)_ped<1^&0 zx;Qns4s!;cdu_T%pk*hhlH#f{7_HP~adH&=-9t|Hvi^nhUaDM~!Ipj$8@MFFBaNaO zNGD<2f|OI{o3lj(V}oyv=*<qqIouHvx~z7D)<BEA*jR^6C49*|srL-IeUo)Re|OYk zj=D!g#@Y{66^A8%Z*-uIIX1t7@?#5wPAf_7w4Vq@!~p8N8MJo7QyIeD&(%Cu<8mN9 zKcCVar~dprGb;<Yu*n-mFotn#EGU!H@bc(Qi=aNQjhfxdi+3x}gI(i7+r#5NQV3Kr zg7_mXp6|iPjz4mA@kS1{<q|ZT4Mp@$zWPIJXsQLY^y}|2=~tK#rnHAX%b4k6I;-ky zaiSWz`X`jHu7Nk`c};4+R7;8R27}3`@8_kAq0f_y0(p0Jh;psg>xoBhs7QpwxC~Wd z+0Q1+M~~%Z3Dc$xWNU!2NX<)rKk4ogE6o(dqQwbpXSDHt$4^p#s=ov#LX{yHp+ezM zjX=n~1ih+;0xMo<+?5;R*TNGx-u1(?&AYx`Wbd89-ARu4H6v^L_OP<L*(v4sGk{5# z?myW_%^kX}gyNi;4f#Q0bM!l}s=5F(vF%UnK(o(wDVErrRa;Fo0D^89+(pAOh7Pfr zaXs}bD|T%L0o#>R4}S99X>I3dJ~}m&YeO??vXfPH2GJy67}W@o*fHlGfopv3Rrk>} zIjL#1CW_25kp*_O&<ADCfa2cxtzLZjPI$~<*6PQbrK7bbLtSzwPMhhJ&E2`fBFMeN zBrfmY8Bw9L3`_PXM0Fox%8sFutW8|kn^3a3P&LokX<=i{_N>Dzf9x4MgV5PWqoI(G ze+H*C+k%)AwQPyjAwKs;k8;^-Zit3>RPxbv&q=<-8qa&%^}`R?*fS`=a{vB;l{WMd zf7WaIu1z{gHF5VMVL|_abC<wNF#>!+@t^m{tug_&?Wc7$DH2iU>`7fM#bF9S1JH^# zC07%WEkkf|V(u(i^L}lXl3Pu}vl3B@N0;i)T~gq<t1i5~nmGL*156df23K`!_*ya! z&djuA(m~<s5--Xa3vfu??pO7hXtQ_wTbXY?`#Ol7cwYFe^kAb7(Y{SUB}X}O@53AS zf4El__Xhuh?k6bPmNmiO+_=o(1yw7?{Pv85t1km-eHk!w8uIP8-U-acJvgo@l8$V- zcDDUmuy5JUqGDn43+KdA-dkNWvPT;7U$?&G^O;pI`e1K2D+WqE#&^`{YS9j`n@@p$ zF|4PDcr%SL@hebngiyQ*=$6sT&~T;8A&|-+K;IAnzebQ(6S+8~18B5f2GSKq$xg~K z7Oq4;e7E0$x0@?$=_iJ_8b5;TJ6!;v65w5QOW_X)@F!o8m!3uYv0pJ@Y2^nQO9M-Y zAAn5{IFCDFvhzR(Cw!UZ$FQfJy8S4gJx+Emj6;FL%V(yMk<L;G5YpP4uant+*|}*j zeJi%T-Js>BeDup;>j$6LnHR?DTE1(|g`8MEnMY<es_~MyMqQK^%GR^AfIT58fX{BX z4$$Pdm7$!jHL41;cGGsYc&<>L7e2EK&A&%6Zl2Mg%JrSzT)^!(ZfHJmhV)mZ-ZApC zY*`j_mexS~n&Yc`KgGP{L)A|c@rCW2=dIz~#G^hi*U;|2>qBU<kFQHaEp;!I13&f! zHFcqISo&f`S7PBdNQ8c6#`UU~-Sphz`BVT*+`P8`75AP`6kJ`yrq<#eWu@i2*<<#7 z)*I9L7mfamdnIZbAMEnZPt8`)DrxVH_tq}0ve=bNwtrbq#0hY>Pz=vD)<+LbW0ta1 zylRuc(&X=V+%qEdn4kMD!XD}Z_~g}Nu72k5s#^u|;bJi_`J{BZuf5L<w{xW2LrgWZ zkvY<Wd=Hu{@ekt!-C4)^YDoO|rSYz1UO}m%-`7Q#+=vs79cq8njD_=WSy5)SmG*~4 z%U@m<;4oj^+=6QoNNy;_XQQ|GR>x3)+@%cu4@z*J>o?1K8HDCH9vE&uOqKAw@~0-p z^QBOHgv;#tK{!W2U1E5uCFWJ?zk{`ghHS&4-)ihDNzzS(sBg~8$eCiCaYm8#{hwCy z%?dWQkHq4M=OP@q1}-q8bYRV|+)89wCX3KwHZFb@4b+6ce(Q#;>6Xbe>i|`b&9K!0 z-h89djD7-~NfV-GYaNy<X7M~=;T=u-&=vvMyvKo<HiVF48lp7GZ9;C#@FBtD|0}RC zJZZ7&uKuTu^g}<nQeeZ4x`<j1h&YRb>p1CtN7Ab;lb7Y91cv_pSxs&6{w#3~c*|-8 z4_WAt;PgHjOAQB}gJn0sNxQXKB$3YQT?icVsr10%88!XU&I-1-h&E2i_@;N8lj*0A z(-MEb8!g@W`4{|`!(-1k;rT=OLqWTNQxS+aQL+79&!ntg7x;fFnbsvP&0@bNuPZ*A zZ}+=gGx2)%nn<1cW+x(}mypqVUO`LnJ7+=GCCKSTgf)G*hO{6+`$3o5oN=$RxauZ$ zU3T}AnCry~XI5sRq`)JzWhA+mt&_)fxP8Ri%hJ7J(MD)|%i{ZJk<(XwqG0>)ZemY~ z4YTRfu$3j+-J%^WZ``i&nr3i_^@P>j?o-Y%?2vO2x*Blv7>uN|Pe7a@XBHO8&__*; zDCk9{gXu^6njTt7x)R&ZVY|mmp#P0u#Vk)DKu#AwQtrJ8OkEztxAZ!An2gTO)Nc?c zIBI-oAB*&%8L7u3Yo4>e?B=UI=Ao%n_tIXVD+a`8Y{XCS(D{TqiBRv;$zf0>Y!^ge zCi#*d*KjVo#hY~od|%w=<#MUyt*gKGnYG?zzsx^w$sq~ogVX(J_tXwu)-%}4yI|Rw z?345VF;sB2qS;z0>VYcTmV~a)$fB)F`bgzYVEWp<V4rlxNmxEXlXW)1J5Wf(BLC|n z(}I<zsRr0&cju#g*WT%>tUuWj6kt2DRj+Eh)TUFPXt8A|9UPk*kk{{i=BrJPnhMz@ z>-+g@*-PumFfIBhFOm(Q!F-1660lDMqEMyDw{r@690;@|e0*O<6f5L8N3<wkC*l{n z4aUd_6#B4e0&+_jM7C@})kL?)OXK!-uNTa_So_sv6$FOs>RSlDj_}SK&WbzxK2-0C zu|_I7X=#ok*5~uC<WF3YvB|jY+lF^G-mkpIb1wWURSp@H9(AZ8kTTZi{-&l5|D5X& z<sHe7U5<_-OITHd2%>bJ<YlxJ?vTyuiq>1Vs~<PouSb79b1r~STl(l35YAP5QA`_R zp`6t4<@Lm4w|{l0*gI4?0kaOXx9d$MyXDn<<C&R~N=dqF&EZ7mhvS|Ps}qXOckHlm z<-$7xTD0AQpAj9SqMg@WdCRTub=-2XVL<6@!|o&IP-lJZ2`{PUIHR-ehLeqQzUiUC zY>qK`wcS=vcZJ@kcm$pIv_7%N3DeRNkgw4ZDwF<0i!K3{aU(X*uO+E4DYi4VQXl#` z3h71;RMfA15q;fhKx}T_sy8dOh$Z=u|M*MK0UPzztr8TEQHk+>eMjWW(pkZH@RoG< z+oz32pEz^=T|{KH5(-=X=8CWnK?t^7|C`(#xZ$r@*a_2qHs9KuxcYl)Dt}DGwz}d1 z9y)hj&7@_8#Dgac3g7}!TxOin`M2t%Yv%WU!G4;@TN~fbHB!7am2)mRG<Zy=mxbX{ zuz76E<M7p%LD#+)_p|ZJrv?pk(T>1yRdc-?3o2DH9N{=~ip(_EO-og85#GwH74_~J zY<lgqYX4v%bLo`$5n9XLsy1lncKzRPFKsDqU;l$7qpJ!&%Ke+{oXrod!dA*#gw{WA zJ{xj+eEGt9&bAF#kHA}v&x56BjhghGUT|JJSez)<WKfI?9vY1Sode|D<L8%J83-D| z^ryp_>2vP=I3bSnPm*5sPi{%6d}%1!U7RU7xqi205Zz>ll@6FYyb_}VpW~WTel^CI zU=Pgh)<)}Byc5Q6HmCm7kw6<z3_+>s8s3+?7&+>WOEdHgUc`lCMaFfF;%_*bzWe7h zApQ7`E-TYrp%-}N2kHK)ohPq+lDnk8SN?vL@#WxS&*<vHuRMIh*R?-}w<g5+Uil=h z-xWw#+IwTpclAk-U)ez08doI+%T&+iVkRnDHwbK1^xbKHpRK(uDV>46UlX?J5E|Ys z`mwWVWI5$Trz%^oz<Lh%R7B%w*D|+`{SH=Qvf9y2P`^m@6H&<IwO6r@2(5jso2hXT zhT8T2*QQ;6&KHfWAI=$f*KxEEEqLffmnP(0vevtICN#+6b9(K!xSZ0#OfdUwH{{J; zRBP*h3~9~C-B`=b2(K4$2fMH=AmJ?AAZImk9~jZIkVC`Cjk1SGF7lwX^HbO{(gIQ2 zZb(Z$-9hLg#sy!|@(_0l8T|-U=$GnKIf}#`&*@^^FzApKc=ka-XuRjN1WvUB%Dp9W zgUA^vI;I?dPe-=DwILfK|C`CHjA4lbP%;XHwF|();F>SLZ`Az2>i>@Isi|eRd9{-1 z7$cEntS{b}EsdAKXmoqk`wJUpqh$Y8ji@;LvoUIc#r^UQo%@jlQ<r;)!P6(&(3m$^ z`u+4~0V355=A!b){CodGzBkVo1C2_}NX8>{4WN6H4<w+r$Pon}U~f_uMUPEywkE58 z2mTg7F`}vte>_Q@sC9mdnto~8@|jLBfz<@Q`;fpE0WO!wdy1O(SvzpGo0N|*-9exN zgAHMvWTfH9cfpqxRZ-*2-yg6tZ$3x1LqQ-x*JjO{g9qUci05Vi@0_PM?tqHW_ZEsp z4c1vi9PD@0A^C6<K%VHB9J(M!#C8FS*T}4rcvJ8R$G*7kQY>u13UQXdz$)FzoM)B8 z0#%auyU2W`*dS>d*me#}BP$mWP+?jxV!kOg>6bVm^$Hk(zqfqi>}uv4TM{)LIT%{F zha?hV#fvqTVVns_Cr?4EN7;`3`4wAt-cS187CdpnNP4XC%5PXokLWLXQUfgyJ)_<w zP6j%T1dpyI_9Dl~)aArV>?7M9#A<i0&zWslHi+=_{9p$p%9)<&@gKwCE6WYvXtx?| zw}W*$t0O22AiyNCAJ_*cQg)?@avXB>y4e9_GB{S{KL#(P=qlU84lTc50`om#6VCkX zzo7VV+k!OQftDCv$Wj)seSKH<_FJ%tAX19H{4+fqp}YEJ29O_u(4wkd`$DGOT6$Q| zt3J_xcO5G;Vz8rsr1c)9V}&F<;S_QcVWg!W*_5)L+G?Dho-VYOy?9kt4qjg3>K+(U z(8dOBV(dSorlWD~$T3OgEw@4BQoc(A$q7Ods`%eIMdRXR>|q@o*3J7QbVv}Y<S(JO zEURg>9l7)s3?cHY13TF`L7K(Ze+&<8<#q|P^Lh@K`ffgy`KINdd6wzSQg+IzQhD^r zGml5-6h5~KUqJWmk;UKG>0%czqmLUkrU3szqUGj~xX;vLPwt}oz}~uVl4YD-y4zcY zZ|Y0`=8qww80QcXIab7?hDGF?3|ZenZkTl&X8xhVEzl>P)0v3RgUTm{gs=8=R`Xl` zF%&gC0rbyT(c=zF1h>l0=>CtbwG9Org|{Ed^iNSqm|6g3?Rpy6$C!9%<4L<Ly|*`2 z@{g7V7C}zNp-#cpR2r>Om+Gh+2Mm5NhkEECxv8vLL@$aHx&2q?KZeh%=%0AZ$qfR8 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¨?DFOPReA<4IYN<kmGREYj+{fP77uGv>DL77O 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 literal 0 HcmV?d00001 From 76c4d3f8036df2703e53e76bea8e64b8c6a81e6b Mon Sep 17 00:00:00 2001 From: crisng95 <crisng95@users.noreply.github.com> Date: Tue, 29 Sep 2026 04:33:26 +0000 Subject: [PATCH 38/68] feat: provider-neutral platform + Muse as official review provider - Provider abstraction: media providers (flow/assistant), per-role AI providers (claude/agy/codex/muse) in agent/providers.json - Persistent provider jobs + HTTP worker protocol + assistant worker - Concat/finalize, duration targeting, thumbnail/TTS, review/regenerate all provider-aware; job ownership/state hardening - Muse review flow: review-sheets -> vision scoring -> review-submit, shared 6-dimension scoring with CLI/SDK backends; muse is an official (opt-in) reviewer, default role stays claude - Skills/docs updated: Muse support highlighted in README, provider docs, doctor onboarding; regenerated skill command targets - 439 unit tests passing --- .claude/commands/fk-change-provider.md | 2 +- .claude/commands/fk-dashboard.md | 31 +- .claude/commands/fk-doctor.md | 2 +- .claude/commands/fk-gen-chain-videos.md | 114 +-- .claude/commands/fk-gen-music.md | 247 +----- .claude/commands/fk-gen-text-overlays.md | 147 +--- .claude/commands/fk-import-voice.md | 118 +-- .claude/commands/fk-monitor.md | 418 +--------- .claude/commands/fk-pipeline.md | 492 +----------- .claude/commands/fk-refresh-urls.md | 119 +-- .claude/commands/fk-review-board.md | 79 +- .claude/commands/fk-review-video.md | 224 +----- .claude/commands/fk-thumbnail-guide.md | 88 +- .claude/commands/fk-upload-image.md | 124 +-- .gitignore | 1 + AGENTS.md | 12 +- README.md | 92 ++- agent/api/flow.py | 23 +- agent/api/projects.py | 107 ++- agent/api/provider_jobs.py | 247 ++++++ agent/api/providers.py | 30 +- agent/api/reviews.py | 227 +++++- agent/api/tts.py | 63 +- agent/api/videos.py | 226 +++++- agent/config.py | 23 +- agent/db/crud.py | 269 ++++++- agent/db/schema.py | 50 ++ agent/main.py | 2 + agent/models/request.py | 2 + agent/models/review.py | 86 +- agent/models/tts.py | 5 + agent/models/video.py | 3 + agent/sdk/models/video.py | 1 + agent/sdk/persistence/sqlite_repository.py | 4 + agent/sdk/services/assistant_provider.py | 215 +++++ agent/sdk/services/flow_provider.py | 538 +++++++++++++ agent/sdk/services/operations.py | 889 ++++++++------------- agent/sdk/services/provider_base.py | 143 ++++ agent/sdk/services/registry.py | 104 +++ agent/services/cli_providers.py | 26 +- agent/services/post_process.py | 40 + agent/services/video_reviewer.py | 150 +++- agent/worker/_parsing.py | 46 ++ agent/worker/assistant_worker.py | 235 ++++++ agent/worker/processor.py | 121 ++- dashboard/src/pages/SettingsPage.tsx | 4 +- setup.py | 7 +- skills/README.md | 1 + skills/fk-change-provider.md | 18 +- skills/fk-doctor.md | 33 + skills/fk-gen-chain-videos.md | 10 + skills/fk-gen-images.md | 10 + skills/fk-gen-narrator.md | 9 + skills/fk-gen-refs.md | 9 + skills/fk-gen-tts-template.md | 7 + skills/fk-gen-videos.md | 10 + skills/fk-provider.md | 121 +++ skills/fk-refresh-urls.md | 21 + skills/fk-review-video.md | 76 +- skills/fk-thumbnail.md | 13 +- tests/conftest.py | 18 + tests/unit/test_assistant_provider.py | 173 ++++ tests/unit/test_cli_providers.py | 33 + tests/unit/test_muse_review.py | 167 ++++ tests/unit/test_operations.py | 74 +- tests/unit/test_provider_aware_projects.py | 104 +++ tests/unit/test_provider_jobs.py | 314 ++++++++ tests/unit/test_review_regenerate.py | 153 ++++ tests/unit/test_video_assemble.py | 307 +++++++ 69 files changed, 4995 insertions(+), 2882 deletions(-) create mode 100644 agent/api/provider_jobs.py create mode 100644 agent/sdk/services/assistant_provider.py create mode 100644 agent/sdk/services/flow_provider.py create mode 100644 agent/sdk/services/provider_base.py create mode 100644 agent/sdk/services/registry.py create mode 100644 agent/worker/assistant_worker.py create mode 100644 skills/fk-provider.md create mode 100644 tests/unit/test_assistant_provider.py create mode 100644 tests/unit/test_muse_review.py create mode 100644 tests/unit/test_provider_aware_projects.py create mode 100644 tests/unit/test_provider_jobs.py create mode 100644 tests/unit/test_review_regenerate.py create mode 100644 tests/unit/test_video_assemble.py diff --git a/.claude/commands/fk-change-provider.md b/.claude/commands/fk-change-provider.md index 9639d96ad..38ac02551 100644 --- a/.claude/commands/fk-change-provider.md +++ b/.claude/commands/fk-change-provider.md @@ -1,4 +1,4 @@ -fk-change-provider — View & Switch AI CLI Provider (Video Review) +fk-change-provider — View & Switch the Reviewer for a Role <!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> Read and follow the instructions in skills/fk-change-provider.md diff --git a/.claude/commands/fk-dashboard.md b/.claude/commands/fk-dashboard.md index a2ec9c86f..abc8cf2d2 100644 --- a/.claude/commands/fk-dashboard.md +++ b/.claude/commands/fk-dashboard.md @@ -1,30 +1,5 @@ Show live GLA status in Claude Code statusline. +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-dashboard.md -Usage: `/fk-dashboard` - -The GLA statusline shows real-time project status at the bottom of Claude Code: - -``` -Opus 4.6 (1M ctx) ctx:14% rl:18%/5h 67%/7d | GLA: ✓ext Operation Hormu 40sc img:40 vid:40 4K:26 ▶0/5 -``` - -## What it shows - -- **OMC info**: model, context usage, rate limits (5h & 7d) -- **GLA info**: extension status, project name, scene count, image/video/4K progress, worker slots - -## Setup - -Statusline is auto-configured by `bash setup.sh`. To manually configure: - -```bash -# In .claude/settings.local.json, add: -{ - "statusLine": { - "type": "command", - "command": "<project_root>/scripts/statusline.sh" - } -} -``` - -Requires `jq` and `curl` installed. +Arguments: $ARGUMENTS diff --git a/.claude/commands/fk-doctor.md b/.claude/commands/fk-doctor.md index 813338ea9..e968e50d8 100644 --- a/.claude/commands/fk-doctor.md +++ b/.claude/commands/fk-doctor.md @@ -1,4 +1,4 @@ -Diagnose any FlowKit error and prescribe a fix. Knows the full error taxonomy across Flow, extension, FastAPI, worker, and YouTube. +Diagnose any FlowKit error and prescribe a fix. Knows the full error taxonomy across Google Flow, the Chrome extension, the FastAPI layer, the worker, and the YouTube upload pipeline. <!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> Read and follow the instructions in skills/fk-doctor.md diff --git a/.claude/commands/fk-gen-chain-videos.md b/.claude/commands/fk-gen-chain-videos.md index 9cf64ef06..0a763cc2d 100644 --- a/.claude/commands/fk-gen-chain-videos.md +++ b/.claude/commands/fk-gen-chain-videos.md @@ -1,113 +1,5 @@ -<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> Generate videos with automatic scene chaining (start+end frame transitions). +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-gen-chain-videos.md -Usage: `/gen-chain-videos <project_id> <video_id>` - -This creates smooth transitions between scenes in a chain by using the **NEXT scene's image as the endImage** of the current scene's video, so the last frame of scene N matches the first frame of scene N+1 → seamless concat. - -## How chaining works - -For any scene that has a CHILD in the chain (i.e. some other scene with `parent_scene_id == this.id`): - -``` -Scene N (chain head or middle): startImage = sceneN.image, endImage = sceneN+1.image - → video plays FROM sceneN.image TO sceneN+1.image (the next scene's image) - -Scene N+1 (next in chain): startImage = sceneN+1.image, endImage = sceneN+2.image (if N+2 exists) - → continues the chain - -Last scene in chain (no child): startImage = lastScene.image, NO endImage - → plain frame_2_video, no chained transition -``` - -**Key invariant**: at the cut between two consecutive chain scenes, `sceneN.video.last_frame == sceneN+1.image == sceneN+1.video.first_frame` → **concat is seamless**. - -The `endImage` is the **CHILD scene's image** (the next scene's image_media_id), NOT the parent's. Chain heads (ROOT scenes that have a child) DO need an endImage; only chain tails (last scene in chain) and standalone ROOT scenes leave `endImage` null. - -## Step 1: Pre-check - -```bash -# All scene images must be ready with UUID media_ids -curl -s "http://127.0.0.1:8100/api/scenes?video_id=<VID>" -``` - -ABORT if any scene is missing `${ori}_image_media_id` (UUID). - -## Step 2: Set up end_scene_media_ids for chaining - -For each scene that has a CHILD in the chain (i.e. some other scene's `parent_scene_id == this.id`), set its `${ori}_end_scene_media_id` to that **child** scene's `${ori}_image_media_id`: - -```bash -curl -X PATCH http://127.0.0.1:8100/api/scenes/<SID> \ - -H "Content-Type: application/json" \ - -d '{"${ori}_end_scene_media_id": "<child_scene_image_media_id>"}' -``` - -Logic: -1. Sort scenes by `display_order` -2. Build a child map: `parent_id -> child_scene` (scan all scenes, key by `parent_scene_id`) -3. For each scene `S`: - - If `S` has a child in the map → set `${ori}_end_scene_media_id = child.${ori}_image_media_id` - - Else (no child = chain tail or standalone ROOT) → leave `${ori}_end_scene_media_id` null - -**Affected scenes** (those that need an `end_scene_media_id`): chain heads (ROOT-with-child) AND chain middles (CONTINUATION-with-child). NOT chain tails, NOT standalone ROOTs. - -**Common mistake**: setting `end_scene_media_id` to the PARENT's image. That makes scene N's video end at scene N-1's frame — when concatenated forward (N then N+1), the cut between N's last frame and N+1's first frame is hard, defeating the chain. The correct frame at the end of scene N's video is `sceneN+1.image`. - -## Step 3: Submit ALL video requests at once - -The server handles throttling automatically (max 5 concurrent, 10s cooldown). The worker reads `${ori}_end_scene_media_id` from each scene (set in Step 2) and passes it as `endImage` to the API. This triggers `start_end_frame_2_video` (i2v_fl) instead of plain `frame_2_video` (i2v). - -```bash -curl -X POST http://127.0.0.1:8100/api/requests/batch \ - -H "Content-Type: application/json" \ - -d '{ - "requests": [ - {"type": "GENERATE_VIDEO", "scene_id": "<SID1>", "project_id": "<PID>", "video_id": "<VID>", "orientation": "${ORI}"}, - {"type": "GENERATE_VIDEO", "scene_id": "<SID2>", "project_id": "<PID>", "video_id": "<VID>", "orientation": "${ORI}"} - ] - }' -``` - -Build the `requests` array from ALL scenes in display_order. Do NOT manually batch or loop. - -Poll aggregate status every 30s until done: - -```bash -curl -s "http://127.0.0.1:8100/api/requests/batch-status?video_id=<VID>&type=GENERATE_VIDEO" -# Wait for: "done": true -# If "all_succeeded": false → some failed, check individual failures -``` - -## Known Limitation: Concat Gap - -**Problem:** When concatenating chained videos, the endImage frames of scene N overlap with the startImage frames of scene N+1 — both are the same image. This produces **10-16 static/duplicate frames (~0.4-0.7s)** at each cut point where nothing moves. - -``` -Scene 1 video: [action...] [endImage = scene2 still] ← 10-16 frames -Scene 2 video: [startImage = scene2 still] [action...] ← 10-16 frames -Concat result: ...action → [~0.8-1.4s static gap] → action... -``` - -**Mitigations:** -- **Trim overlap** — use `trim_start` / `trim_end` on scenes to cut the static frames before concat. Typically trim 0.4-0.7s from the end of scene N and/or the start of scene N+1. -- **Don't overuse chaining** — only chain scenes that truly need smooth visual continuity (same location, continuous action). For scene changes (new location, time jump), use ROOT without endImage — a hard cut is more natural. -- **Mix techniques** — alternate between chained (CONTINUATION) and unchained (ROOT) scenes. Hard cuts between different locations feel intentional; gaps between continuous action feel broken. - -**When to chain vs not:** - -| Situation | Recommendation | -|-----------|---------------| -| Same location, continuous action | CONTINUATION (chain) | -| Location change, time jump | ROOT (hard cut — no gap) | -| Dramatic moment, reaction shot | INSERT (hard cut — intentional) | -| Dream/flashback transition | ROOT or R2V (stylistic break) | - -## Step 4: Output - -Print table: -| Scene | Order | Chain | endImage from | video_status | Duration | -|-------|-------|-------|---------------|-------------|----------| - -Print: "Chained videos ready. Run /fk-concat <VID> to merge." -Remind: "Check concat gaps — trim 0.4-0.7s overlap at chain boundaries if needed." +Arguments: $ARGUMENTS diff --git a/.claude/commands/fk-gen-music.md b/.claude/commands/fk-gen-music.md index 6c9b524d5..6a1a8559c 100644 --- a/.claude/commands/fk-gen-music.md +++ b/.claude/commands/fk-gen-music.md @@ -1,244 +1,5 @@ -# fk-gen-music — Generate Music via Suno +fk-gen-music — Generate Music via Suno +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-gen-music.md -Generate background music or songs for video projects using the Suno API (sunoapi.org). - -## Prerequisites - -- GLA server running: `curl http://127.0.0.1:8100/health` -- Suno API key configured: `export SUNO_API_KEY=your-key` -- Get API key at https://sunoapi.org/api-key - -## Workflow - -### Step 1: Choose a Template (Optional) - -Browse available song templates to find the right style: - -```bash -# List all templates -curl -s http://127.0.0.1:8100/api/music/templates | python3 -m json.tool - -# Get a specific template (see style, tags, example lyrics) -curl -s http://127.0.0.1:8100/api/music/templates/cinematic_epic -``` - -Available categories: Children & Family, Love & Romance, Pop, Rock, Hip-Hop, Electronic, Country & Folk, Cinematic, Motivational. - -### Step 2: Generate Music - -**Three modes:** - -#### Mode A: Template-based (recommended for video projects) - -Use a template to auto-fill style tags. Provide custom lyrics or let the template's example lyrics run: - -```bash -# With custom lyrics + template style -curl -X POST http://127.0.0.1:8100/api/music/generate \ - -H "Content-Type: application/json" \ - -d '{ - "template_id": "cinematic_epic", - "prompt": "[Verse]\nFrom the shadows they emerge\nAcross the ancient sea\n[Chorus]\nRise, rise to glory\nThe world will hear our story", - "title": "Rise to Glory", - "poll": true - }' - -# Template defaults (uses example lyrics + suno_tags) -curl -X POST http://127.0.0.1:8100/api/music/generate \ - -H "Content-Type: application/json" \ - -d '{ - "template_id": "lullaby_gentle", - "title": "Goodnight Luna", - "poll": true - }' -``` - -#### Mode B: Custom (full control) - -Provide your own lyrics and style tags: - -```bash -curl -X POST http://127.0.0.1:8100/api/music/generate \ - -H "Content-Type: application/json" \ - -d '{ - "prompt": "[Verse]\nWalking through the rain\nSearching for the light\n[Chorus]\nWe will find our way\nThrough the darkest night", - "style": "lo-fi hip hop, chill, piano, rainy, 90 BPM", - "title": "Rainy Night", - "poll": true - }' -``` - -#### Mode C: Description (AI writes everything) - -Just describe what you want in natural language: - -```bash -curl -X POST http://127.0.0.1:8100/api/music/generate \ - -H "Content-Type: application/json" \ - -d '{ - "prompt": "an epic orchestral track for a military documentary about naval battles, dramatic and heroic", - "instrumental": true, - "custom_mode": false, - "poll": true - }' -``` - -### Step 3: Check Results - -Each generation produces **2 clips** (variations). When `poll: true`, the response waits for completion. - -```bash -# If poll was false, check status manually: -curl -s http://127.0.0.1:8100/api/music/tasks/<TASK_ID> - -# Poll until complete: -curl -X POST http://127.0.0.1:8100/api/music/tasks/<TASK_ID>/poll -``` - -**Task statuses:** `PENDING` → `GENERATING` → `SUCCESS` or `FAILED` - -### Step 4: Download - -```bash -curl -X POST http://127.0.0.1:8100/api/music/tasks/<TASK_ID>/download -# Returns: {"task_id": "...", "downloaded": [{"clip_id": "...", "path": "output/_shared/music/title_abcd1234.mp3", ...}]} -``` - -### Step 5: Use in Video (Optional) - -Add the downloaded music as background for your concat video: - -```bash -# Get project output directory -PROJ_OUT=$(curl -s http://127.0.0.1:8100/api/projects/<PID>/output-dir) -OUTDIR=$(echo "$PROJ_OUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['path'])") -SLUG=$(echo "$PROJ_OUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['slug'])") - -# Mix music with concat video using ffmpeg -ffmpeg -y -i "${OUTDIR}/${SLUG}_final.mp4" -i output/_shared/music/track.mp3 \ - -filter_complex "[1:a]volume=0.3[bg]; [0:a][bg]amix=inputs=2:duration=first[out]" \ - -map 0:v -map "[out]" -c:v copy -c:a aac "${OUTDIR}/${SLUG}_with_music.mp4" -``` - -## Extend a Track - -Continue or extend an existing clip from a previous generation: - -```bash -curl -X POST http://127.0.0.1:8100/api/music/extend \ - -H "Content-Type: application/json" \ - -d '{ - "audio_id": "<AUDIO_ID from clip>", - "prompt": "[Chorus]\nKeep the fire burning bright", - "continue_at": 120, - "poll": true - }' -``` - -## Vocal Removal (Stem Separation) - -Separate vocals from instrumental: - -```bash -curl -X POST http://127.0.0.1:8100/api/music/vocal-removal \ - -H "Content-Type: application/json" \ - -d '{ - "task_id": "<TASK_ID>", - "audio_id": "<AUDIO_ID>", - "poll": true - }' -# Returns: instrumental_url + vocal_url -``` - -## Convert to WAV - -Get lossless WAV from a generated clip: - -```bash -curl -X POST http://127.0.0.1:8100/api/music/convert-to-wav \ - -H "Content-Type: application/json" \ - -d '{ - "task_id": "<TASK_ID>", - "audio_id": "<AUDIO_ID>", - "poll": true - }' -``` - -## Generate Lyrics Only - -Ask Suno's AI to write lyrics from a description, optionally guided by a template: - -```bash -curl -X POST http://127.0.0.1:8100/api/music/generate-lyrics \ - -H "Content-Type: application/json" \ - -d '{ - "prompt": "a song about a cat astronaut exploring a candy planet", - "template_id": "children_adventure", - "poll": true - }' -``` - -## Check Credits - -```bash -curl -s http://127.0.0.1:8100/api/music/credits -``` - -## API Reference - -| Endpoint | Method | Description | -|----------|--------|-------------| -| `/api/music/templates` | GET | List all song templates | -| `/api/music/templates/{id}` | GET | Get template details | -| `/api/music/generate` | POST | Generate music (returns taskId, 2 clips) | -| `/api/music/tasks/{id}` | GET | Get task status + clips | -| `/api/music/tasks/{id}/poll` | POST | Poll task until complete | -| `/api/music/tasks/{id}/download` | POST | Download all clips to local | -| `/api/music/generate-lyrics` | POST | Generate lyrics from prompt | -| `/api/music/extend` | POST | Extend/continue existing track | -| `/api/music/vocal-removal` | POST | Separate vocals from instrumental | -| `/api/music/convert-to-wav` | POST | Convert clip to WAV format | -| `/api/music/credits` | GET | Check Suno credits/quota | - -## Models - -| Model | Max Duration | Notes | -|-------|-------------|-------| -| V4 | 4 min | Highest audio quality | -| V4_5 | 8 min | Superior genre blending | -| V4_5PLUS | 8 min | Richer sound | -| V4_5ALL | 8 min | Better song structure | -| V5 | 8 min | Faster generation | -| V5_5 | 8 min | Custom model tailoring | - -Default: `V4` (set via `SUNO_MODEL` env var). - -## Template → Suno Mapping - -| Template Field | Suno API Field | Purpose | -|---------------|---------------|---------| -| `suno_tags` | `style` | Musical style descriptors | -| `example_lyrics` | `prompt` | Lyrics with section markers | -| `vocal_style` | (embedded in style) | Voice character | -| `bpm_range` | (embedded in style) | Tempo | - -## Tips - -- Each generation costs ~10 credits (5 per clip) and produces 2 variations -- Use `instrumental: true` for background music (no vocals) -- `poll: true` waits for completion (~30-120s) — use for scripted workflows -- `poll: false` returns immediately with taskId — use for interactive/async workflows -- For video background music, `cinematic_epic` or `cinematic_emotional` templates work well -- For children's content, use `lullaby_gentle`, `children_adventure`, or `nursery_rhyme` -- Generated files are stored by Suno for 15 days — download promptly - -## Important Notes - -- Suno generates ~2-8 min tracks (depends on model). For shorter clips, trim with ffmpeg -- Each generation creates 2 clip variations — listen and pick the best one -- Credits are per-account. Check `/api/music/credits` before batch generation -- The `[Verse]`, `[Chorus]`, `[Bridge]`, `[Outro]` markers in lyrics control song structure -- Use `[Instrumental]`, `[Soft]`, `[Powerful]`, `[Whispered]` tags for dynamics -- Style field: max 200 chars (V4) or 1000 chars (V4.5+) -- Title field: max 80 chars (V4/V4_5ALL) or 100 chars (others) -- Prompt field: max 3000 chars (V4) or 5000 chars (V4.5+) +Arguments: $ARGUMENTS diff --git a/.claude/commands/fk-gen-text-overlays.md b/.claude/commands/fk-gen-text-overlays.md index 498669005..1e0eeab33 100644 --- a/.claude/commands/fk-gen-text-overlays.md +++ b/.claude/commands/fk-gen-text-overlays.md @@ -1,144 +1,5 @@ -# fk-gen-text-overlays — Generate Text Overlays from Narrator Text +fk-gen-text-overlays — Generate Text Overlays from Narrator Text +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-gen-text-overlays.md -Analyze narrator text for each scene and extract key data points (dates, locations, statistics, milestones, costs) to create `text_overlays.json` for `/fk-concat-fit-narrator`. - -Usage: `/fk-gen-text-overlays <video_id> [--language vi]` - -- `video_id` — the video to generate overlays for -- `--language` — target language code (default: auto-detect from narrator text). **All overlay text MUST be in this language with proper diacritics/characters.** - -## Step 1: Load project, video, scenes - -```bash -curl -s http://127.0.0.1:8100/api/videos/<VID> -# Get project_id -curl -s http://127.0.0.1:8100/api/projects/<PID> -curl -s "http://127.0.0.1:8100/api/scenes?video_id=<VID>" -curl -s http://127.0.0.1:8100/api/projects/<PID>/output-dir -``` - -Sort scenes by `display_order`. Note `OUTDIR` from output-dir response. - -## Step 2: Detect target language - -If `--language` not provided, auto-detect from the first scene's `narrator_text`: -- Vietnamese diacritics (ắ, ề, ổ, ử, ơ, etc.) → `vi` -- Spanish characters (ñ, á, é, etc.) → `es` -- Default → `en` - -**CRITICAL RULE: All overlay text MUST be written in the detected language with full diacritics and proper characters. NEVER strip diacritics or romanize.** - -Examples: -- Vietnamese: "Chiến dịch Tapalpa" NOT "Chien dich Tapalpa" -- Vietnamese: "Tiền thưởng" NOT "Tien thuong" -- Spanish: "Operación Tapalpa" NOT "Operacion Tapalpa" - -## Step 3: Analyze each scene's narrator text - -For each scene with `narrator_text`, extract data points that fit these overlay categories: - -### Overlay styles - -| Style | What to extract | Color | -|-------|----------------|-------| -| `date` | Dates, times, timestamps, time references | Cyan | -| `name` | Locations, operation names, people, organizations | White | -| `stat` | Numbers, quantities, distances, technology milestones | White | -| `cost` | Casualties, monetary values, damage, human cost | Gold | - -### Extraction rules - -1. **NOT every scene needs overlays.** Only add overlays when there's a clear, impactful data point. -2. **Target ~40-50% of scenes** having overlays (e.g., 25-30 out of 60 scenes). -3. **Max 2 text items per scene** — one primary, one secondary. -4. **Keep text SHORT** — max 40 characters per line. Abbreviate if needed. -5. **Prioritize hard data** — numbers, dates, names, costs over descriptive text. -6. **Avoid repeating** the same information across adjacent scenes. - -### What makes a good overlay - -Good: -- "22 tháng 2, 2026" (specific date) -- "Tiền thưởng: $15,000,000" (hard number) -- "Guadalajara, Jalisco" (specific location) -- "25 lính hy sinh — 70+ người chết" (casualty stats) -- "Net-Centric Warfare" (tech milestone — keep original English terms) - -Bad: -- "Mọi thứ thay đổi" (too vague) -- "Tình hình rất căng thẳng" (no data point) -- "Chiến dịch tiếp tục" (no specific info) - -### Special handling - -- **Technical terms** (Net-Centric Warfare, RPG, DEA, CJNG, FIFA): keep in original language/acronym. -- **People names**: keep original spelling (El Mencho, El Pelón, Nemesio Oseguera Cervantes). -- **Currency**: use `$X,XXX,XXX` format with dollar sign. -- **Casualty numbers**: pair with context (e.g., "25 lính hy sinh" not just "25"). - -## Step 4: Generate text_overlays.json - -Build JSON object where keys are scene `display_order` (as string), values are arrays of overlay items: - -```json -{ - "0": [ - {"text": "22 tháng 2, 2026", "style": "date"}, - {"text": "Tapalpa, Jalisco, Mexico", "style": "name"} - ], - "8": [ - {"text": "Mật danh: Chiến dịch Tapalpa", "style": "name"}, - {"text": "6 trực thăng — hàng trăm đặc nhiệm", "style": "stat"} - ] -} -``` - -## Step 5: Validate and save - -Before saving, validate: -1. All text is in the correct target language with proper diacritics -2. No text exceeds 40 characters -3. No scene has more than 2 overlay items -4. Scene indices are valid (within 0 to scene_count-1) -5. All styles are one of: `date`, `name`, `stat`, `cost` - -Print validation table: - -``` -Scene | Style | Text (40 char max) -------|-------|------------------- - 000 | date | 22 tháng 2, 2026 - 000 | name | Tapalpa, Jalisco, Mexico - 008 | name | Mật danh: Chiến dịch Tapalpa - ... -Total: X overlays across Y scenes (Z% coverage) -``` - -Save to `${OUTDIR}/text_overlays.json`. - -```bash -# Verify JSON is valid -python3 -c "import json; d=json.load(open('${OUTDIR}/text_overlays.json')); print(f'{len(d)} scenes with overlays, {sum(len(v) for v in d.values())} total items')" -``` - -## Step 6: Report - -``` -Text overlays generated: <project_name> - Language: <detected_language> - Scenes with overlays: X/Y (Z%) - Total overlay items: N - Styles: date=A, name=B, stat=C, cost=D - Output: ${OUTDIR}/text_overlays.json - -Ready for /fk-concat-fit-narrator -``` - -## Common Issues - -| Issue | Cause | Fix | -|-------|-------|-----| -| Text without diacritics | Language not detected | Pass `--language vi` explicitly | -| Too many overlays | Over-extraction | Aim for 40-50% scene coverage | -| Text too long | Not abbreviated | Keep under 40 chars, use short forms | -| Overlays feel repetitive | Adjacent scenes have similar data | Space out overlays, skip adjacent scenes | +Arguments: $ARGUMENTS diff --git a/.claude/commands/fk-import-voice.md b/.claude/commands/fk-import-voice.md index 6772e0fa2..c1b479838 100644 --- a/.claude/commands/fk-import-voice.md +++ b/.claude/commands/fk-import-voice.md @@ -1,115 +1,5 @@ -# fk-import-voice — Import Existing Voice as Template +fk-import-voice — Import Existing Voice as Template +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-import-voice.md -Register an existing WAV file as a reusable voice template for narration. Auto-transcribes the audio and registers it in the template system. - -## When to Use - -- You have a real voice recording (WAV) you want to use for narration -- You want to clone a specific voice rather than designing one with `instruct` -- Complementary to `/fk-gen-tts-template` which creates synthetic voices - -## Prerequisites - -- GLA server running: `curl http://127.0.0.1:8100/health` -- `faster-whisper` installed in `/opt/homebrew/bin/python3.10` -- WAV file placed in `output/_shared/tts_templates/` - -## Workflow - -### Step 1: Locate the WAV file - -```bash -ls -la output/_shared/tts_templates/*.wav -``` - -The user should have already placed their WAV file here. File should be: -- Format: WAV (any encoding — pcm_s16le, pcm_f32le, etc.) -- Duration: 3-10s ideal for voice cloning -- Content: Clear speech, minimal background noise - -### Step 2: Transcribe with faster-whisper - -Use `large-v3` model for accurate transcription. **Always use `/opt/homebrew/bin/python3.10`** — it has torch + faster-whisper installed. - -```bash -/opt/homebrew/bin/python3.10 -c " -from faster_whisper import WhisperModel -model = WhisperModel('large-v3', device='cpu') -segments, info = model.transcribe('<WAV_PATH>', beam_size=5) -print(f'Language: {info.language} ({info.language_probability:.0%})') -for seg in segments: - print(seg.text.strip()) -" 2>&1 | grep -v '\[ctranslate2\]' -``` - -**IMPORTANT:** This runs on CPU and takes ~60s for large-v3 model loading + transcription. Be patient. - -Show the transcript to the user and ask them to confirm or correct it. Accurate `ref_text` is critical for voice cloning quality. - -### Step 3: Register template in templates.json - -After user confirms transcript: - -```bash -python3 -c " -import json -from pathlib import Path - -templates_dir = Path('output/_shared/tts_templates') -meta_file = templates_dir / 'templates.json' -wav_path = str(templates_dir / '<FILENAME>.wav') - -meta = json.loads(meta_file.read_text()) if meta_file.exists() else {} -meta['<TEMPLATE_NAME>'] = { - 'name': '<TEMPLATE_NAME>', - 'audio_path': wav_path, - 'text': '<CONFIRMED_TRANSCRIPT>', - 'instruct': '<VOICE_DESCRIPTION>', - 'duration': <DURATION>, -} -meta_file.write_text(json.dumps(meta, indent=2, ensure_ascii=False)) -print('Template registered') -" -``` - -Template name: derive from filename (e.g., `vi_male_narrator.wav` → `vi_male_narrator`). - -### Step 4: Verify via API - -```bash -curl -s http://127.0.0.1:8100/api/tts/templates -# Should list the new template -``` - -### Step 5: Test voice clone - -Generate a short test sentence using the imported voice: - -```bash -curl -s -X POST http://127.0.0.1:8100/api/tts/generate \ - -H "Content-Type: application/json" \ - -d '{ - "text": "<SHORT_TEST_SENTENCE_IN_SAME_LANGUAGE>", - "instruct": "<VOICE_DESCRIPTION>", - "ref_audio": "<WAV_PATH>", - "ref_text": "<CONFIRMED_TRANSCRIPT>" - }' -``` - -Play the output for user to verify voice quality matches the original. - -## Naming Convention - -| Language | Template name pattern | Example | -|----------|----------------------|---------| -| Vietnamese | `vi_{gender}_narrator` | `vi_male_narrator` | -| English | `en_{gender}_narrator` | `en_female_narrator` | -| Japanese | `ja_{gender}_narrator` | `ja_male_narrator` | -| Multi-lang | `{primary_lang}_{gender}_narrator` | `vi_male_narrator` | - -## Notes - -- **Transcript accuracy matters** — `ref_text` must match the audio closely for good voice cloning. Always confirm with the user. -- **CPU only** — whisper large-v3 and OmniVoice both run on CPU. MPS produces artifacts. -- **3-10s audio** — shorter clips lack enough voice characteristics; longer clips slow down cloning. -- **One template per voice** — don't register multiple templates for the same voice. Update instead. +Arguments: $ARGUMENTS diff --git a/.claude/commands/fk-monitor.md b/.claude/commands/fk-monitor.md index 36a245873..4de6a17fe 100644 --- a/.claude/commands/fk-monitor.md +++ b/.claude/commands/fk-monitor.md @@ -1,415 +1,5 @@ -# fk-monitor — Full Pipeline Monitor +fk-monitor — Full Pipeline Monitor +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-monitor.md -Poll project pipeline status every N seconds, detect state changes across all stages, send Telegram notifications, and optionally auto-download completed upscales. - -Usage: `/fk-monitor [project_id] [orientation] [--download] [--interval N]` - -- `project_id` — omit to use most recently active project -- `orientation` — `HORIZONTAL` or `VERTICAL` (auto-detected from video.orientation if omitted) -- `--download` — auto-download new upscales to `output/{slug}/4k/` -- `--interval N` — poll interval in seconds (default: 30) - -## When to Use - -- Long-running batch: submitted image/video/upscale jobs and want to be notified when stages complete -- Unattended generation: step away and get Telegram pings at milestones -- Debugging: spot stalled workers or failed requests early -- Auto-download: pull 4K upscales as they finish without manual polling - -## Prerequisites - -```bash -curl -s http://127.0.0.1:8100/health -# extension_connected must be true -``` - -Telegram notifications require the `mcp__telegram__reply` tool to be available in this session. - ---- - -## Step 1: Resolve project and slug - -If no `project_id` supplied, fetch the most recent project: - -```bash -curl -s http://127.0.0.1:8100/api/projects -# Use the last item in the array → id, name -``` - -Derive slug from project name: - -```python -import unicodedata, re - -def slugify(name): - # Strip diacritics - normalized = unicodedata.normalize('NFD', name) - ascii_only = normalized.encode('ascii', 'ignore').decode() - # Lowercase, replace non-alphanum with underscore - slug = re.sub(r'[^a-z0-9]+', '_', ascii_only.lower()) - # Collapse and trim - slug = re.sub(r'_+', '_', slug).strip('_') - return slug -``` - -Examples: -- "My Project - Edition" → `my_project_edition` -- "Chiến dịch giải cứu F-15E" → `chien_dich_giai_cuu_f_15e` - -Get output dir (also creates directory structure): - -```bash -curl -s http://127.0.0.1:8100/api/projects/<PID>/output-dir -# Returns: {"slug": "...", "path": "output/...", "meta": {...}} -``` - ---- - -## Step 2: Resolve video_id and scene count - -```bash -curl -s "http://127.0.0.1:8100/api/videos?project_id=<PID>" -# Use first video → id, get scene count - -curl -s "http://127.0.0.1:8100/api/scenes?video_id=<VID>" -# Total scene count = N -``` - ---- - -## Step 3: Get Telegram chat_id - -The monitor sends all notifications to one chat. Ask the user for their Telegram chat_id if not already known: - -``` -To send Telegram notifications, I need your Telegram chat_id. -You can find it by messaging @userinfobot on Telegram. -``` - -Store as `CHAT_ID` for all `mcp__telegram__reply` calls. - ---- - -## Step 4: Send start notification - -``` -mcp__telegram__reply( - chat_id=CHAT_ID, - text="🔍 Monitor started: <project_name>\n" - "Orientation: <ORIENTATION> | Interval: <N>s\n" - "Stages: ref images, scene images, videos, 4K upscale, downloads, TTS" -) -``` - ---- - -## Step 5: Poll loop - -Run the poll cycle in a Python inline script. Each cycle: - -### 5a. Fetch all data - -```bash -# Fetch in parallel (run as background + wait) -curl -s http://127.0.0.1:8100/api/projects/<PID>/characters > /tmp/fk_chars.json & -curl -s "http://127.0.0.1:8100/api/scenes?video_id=<VID>" > /tmp/fk_scenes.json & -curl -s "http://127.0.0.1:8100/api/requests?status=PENDING" > /tmp/fk_pending.json & -curl -s "http://127.0.0.1:8100/api/requests?status=PROCESSING" > /tmp/fk_processing.json & -curl -s "http://127.0.0.1:8100/api/requests?status=FAILED" > /tmp/fk_failed.json & -wait -``` - -### 5b. Compute snapshot - -Detect orientation: if not passed as argument, read from `GET /api/videos/{vid}` → `orientation` field. Fall back to `HORIZONTAL` only if API returns null. Set `PREFIX` = detected orientation lowercase. - -```python -import json, os, glob, time - -chars = json.load(open('/tmp/fk_chars.json')) -scenes = json.load(open('/tmp/fk_scenes.json')) -pending = json.load(open('/tmp/fk_pending.json')) -processing = json.load(open('/tmp/fk_processing.json')) -failed = json.load(open('/tmp/fk_failed.json')) - -PREFIX = video_orientation.lower() # from GET /api/videos/{vid} → orientation field; fall back to 'horizontal' -OUTDIR = 'output/<slug>' -TOTAL = len(scenes) -TOTAL_CHARS = len(chars) - -snapshot = { - # Stage 1: ref images - 'refs_done': sum(1 for c in chars if c.get('media_id')), - 'refs_total': TOTAL_CHARS, - - # Stage 2: scene images - 'images_done': sum(1 for s in scenes if s.get(f'{PREFIX}_image_status') == 'COMPLETED'), - 'images_total': TOTAL, - - # Stage 3: scene videos - 'videos_done': sum(1 for s in scenes if s.get(f'{PREFIX}_video_status') == 'COMPLETED'), - 'videos_total': TOTAL, - - # Stage 4: 4K upscale - 'upscales_done': sum(1 for s in scenes if s.get(f'{PREFIX}_upscale_status') == 'COMPLETED'), - 'upscales_total': TOTAL, - - # Stage 5: 4K downloads - 'downloads_done': len(glob.glob(f'{OUTDIR}/4k/scene_*.mp4')), - 'downloads_total': TOTAL, - - # Stage 6: TTS narration - 'tts_done': len(glob.glob(f'{OUTDIR}/tts/scene_*.wav')), - 'tts_total': TOTAL, - - # Worker queue - 'pending_count': len(pending) if isinstance(pending, list) else pending.get('total', 0), - 'processing_count': len(processing) if isinstance(processing, list) else processing.get('total', 0), - - # Failures - 'failed_count': len(failed) if isinstance(failed, list) else failed.get('total', 0), - 'failed_types': list({r.get('type','unknown') for r in (failed if isinstance(failed, list) else [])}), -} -``` - -### 5c. Diff with previous snapshot and emit notifications - -```python -# Milestone thresholds -MILESTONE_STEP = 10 - -def milestone_crossed(prev, curr, total): - """Returns milestone value if a multiple of MILESTONE_STEP was crossed.""" - if total == 0: - return None - prev_m = (prev // MILESTONE_STEP) * MILESTONE_STEP - curr_m = (curr // MILESTONE_STEP) * MILESTONE_STEP - if curr_m > prev_m and curr < total: - return curr_m - return None - -notifications = [] - -STAGES = [ - ('refs', 'Ref images', snapshot['refs_done'], snapshot['refs_total']), - ('images', 'Scene images', snapshot['images_done'], snapshot['images_total']), - ('videos', 'Scene videos', snapshot['videos_done'], snapshot['videos_total']), - ('upscales', '4K upscale', snapshot['upscales_done'], snapshot['upscales_total']), - ('downloads', '4K downloads', snapshot['downloads_done'], snapshot['downloads_total']), - ('tts', 'TTS narration', snapshot['tts_done'], snapshot['tts_total']), -] - -for key, label, curr, total in STAGES: - prev = prev_snapshot.get(f'{key}_done', 0) if prev_snapshot else 0 - - if total == 0: - continue - - # 100% completion - if curr == total and prev < total: - notifications.append(f'✅ {label} complete: {curr}/{total}') - - # Milestone every 10 - elif (m := milestone_crossed(prev, curr, total)): - notifications.append(f'🔄 {label}: {curr}/{total}') - -# Worker stall detection -if (snapshot['pending_count'] > 0 - and snapshot['processing_count'] == 0 - and time.time() - last_change_ts > 120): - notifications.append( - f'⚠️ Worker stalled! {snapshot["pending_count"]} requests pending but 0 processing.\n' - f'Check server logs — may need to restart the GLA server.' - ) - -# New failures -prev_failed = prev_snapshot.get('failed_count', 0) if prev_snapshot else 0 -if snapshot['failed_count'] > prev_failed: - new_n = snapshot['failed_count'] - prev_failed - types_str = ', '.join(snapshot['failed_types']) or 'unknown' - notifications.append(f'❌ {new_n} new failure(s) detected: {types_str}') - -# All complete check -all_done = all( - snapshot[f'{k}_done'] >= snapshot[f'{k}_total'] - for k in ['refs', 'images', 'videos'] - if snapshot[f'{k}_total'] > 0 -) -if all_done and not prev_all_done: - notifications.append( - '🎉 Project complete! All pipeline stages done.\n' - 'Ready for /fk-concat' - ) -``` - -### 5d. Send notifications - -For each notification string: - -``` -mcp__telegram__reply( - chat_id=CHAT_ID, - text="[<project_name>]\n" + notification_text -) -``` - -Send a combined status summary every 5 cycles regardless of changes: - -``` -mcp__telegram__reply( - chat_id=CHAT_ID, - text=( - f"[<project_name>] Status update\n" - f"Refs: {refs_done}/{refs_total}\n" - f"Images: {images_done}/{images_total}\n" - f"Videos: {videos_done}/{videos_total}\n" - f"4K upscale:{upscales_done}/{upscales_total}\n" - f"Downloads: {downloads_done}/{downloads_total}\n" - f"TTS: {tts_done}/{tts_total}\n" - f"Queue: {pending_count} pending / {processing_count} processing" - ) -) -``` - -### 5e. Auto-download (when --download) - -When `upscales_done` increases from previous cycle, find newly completed scenes and download: - -```python -# Get scenes with completed upscale not yet downloaded locally -newly_completed = [ - s for s in scenes - if s.get(f'{PREFIX}_upscale_status') == 'COMPLETED' - and s.get(f'{PREFIX}_upscale_url') - and not os.path.exists(f"{OUTDIR}/4k/scene_{s['display_order']:03d}_{s['id']}.mp4") -] -``` - -```bash -# For each newly completed scene: -mkdir -p output/<slug>/4k -curl -s "<upscale_url>" \ - -o "output/<slug>/4k/scene_<display_order:03d>_<scene_id>.mp4" -echo "Downloaded scene <display_order> → output/<slug>/4k/scene_<display_order:03d>_<scene_id>.mp4" -``` - -After each download, verify with: - -```bash -ffprobe -v quiet -show_entries format=duration \ - -of csv=p=0 "output/<slug>/4k/scene_<display_order:03d>_<scene_id>.mp4" -# Should return a positive number (duration in seconds) -``` - ---- - -## Step 6: Stop conditions - -Stop the loop when ANY of these are true: - -1. **All upscaled + all downloaded** (if `--download`): `upscales_done == upscales_total AND downloads_done == upscales_total` -2. **All videos done** (if no `--download`): `videos_done == videos_total` -3. **User interrupts**: Ctrl+C or task cancelled -4. **Max iterations reached**: if `--max-iter N` was specified - -On stop, send final summary: - -``` -mcp__telegram__reply( - chat_id=CHAT_ID, - text=( - f"[<project_name>] Monitor stopped\n" - f"Final state:\n" - f" Refs: {refs_done}/{refs_total}\n" - f" Images: {images_done}/{images_total}\n" - f" Videos: {videos_done}/{videos_total}\n" - f" 4K upscale:{upscales_done}/{upscales_total}\n" - f" Downloads: {downloads_done}/{downloads_total}\n" - f" TTS: {tts_done}/{tts_total}\n" - f" Failed: {failed_count}" - ) -) -``` - ---- - -## Full Poll Loop Structure - -```python -import time - -prev_snapshot = None -prev_all_done = False -last_change_ts = time.time() -cycle = 0 -INTERVAL = 30 # override with --interval N - -while True: - cycle += 1 - - # 1. Fetch all data (via curl to /tmp files) - # 2. Compute snapshot - snapshot = compute_snapshot() - - # 3. Detect change for stall tracking - if snapshot != prev_snapshot: - last_change_ts = time.time() - - # 4. Diff + emit notifications - notifications = diff_snapshots(prev_snapshot, snapshot, last_change_ts) - for n in notifications: - send_telegram(CHAT_ID, f'[{project_name}]\n{n}') - - # 5. Periodic summary every 5 cycles - if cycle % 5 == 0: - send_telegram(CHAT_ID, build_summary(snapshot)) - - # 6. Auto-download if --download - if download_flag: - download_new_upscales(snapshot, scenes) - - # 7. Check stop conditions - if should_stop(snapshot, download_flag): - send_final_summary(CHAT_ID, snapshot) - break - - prev_snapshot = snapshot - prev_all_done = all_done_check(snapshot) - time.sleep(INTERVAL) -``` - ---- - -## Console Output (each cycle) - -Print a compact status line to console each cycle so progress is visible: - -``` -[cycle 12 | 14:32:01] <project_name> - Refs: 5/5 ✓ | Images: 23/40 | Videos: 18/40 | 4K: 10/40 - Queue: 3 pending / 2 processing | Failed: 0 - Next poll in 30s... -``` - ---- - -## Common Issues - -| Issue | Cause | Fix | -|-------|-------|-----| -| Stall notification fires immediately | Server just restarted, processing=0 briefly | Stall threshold is 120s — brief gaps won't trigger | -| Downloads fail with 403 | GCS signed URL expired (~8h TTL) | Regenerate via `REGENERATE_IMAGE` then re-upscale | -| `media_id` missing on refs | Ref image generation failed | Check `/api/requests?status=FAILED`, resubmit `GENERATE_CHARACTER_IMAGE` | -| Scene count shows 0 | Wrong `video_id` | Verify `GET /api/videos?project_id=<PID>` returns correct video | -| Telegram notifications not sent | `mcp__telegram__reply` not available | Ensure Telegram MCP is connected in this session | - ---- - -## Next Steps After Monitor Completes - -| Scenario | Next Skill | -|----------|------------| -| All videos done, no 4K | `/fk-concat` | -| All 4K downloaded | `/fk-concat --4k` | -| Need narration first | `/fk-gen-narrator` → `/fk-concat --with-tts` | -| Upload to YouTube | `/fk-youtube-seo` → `/fk-youtube-upload` | +Arguments: $ARGUMENTS diff --git a/.claude/commands/fk-pipeline.md b/.claude/commands/fk-pipeline.md index b09d1373e..a52df9784 100644 --- a/.claude/commands/fk-pipeline.md +++ b/.claude/commands/fk-pipeline.md @@ -1,489 +1,5 @@ -# fk-pipeline — Smart Full-Pipeline Orchestrator +fk-pipeline — Smart Full-Pipeline Orchestrator +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-pipeline.md -Auto-detect project state and run the correct stages (continuation or full run). Handles batching, parallelism, retries, downloads, TTS, and Telegram notifications. - -Usage: `/fk-pipeline [project_id] [orientation] [options]` - -Options: -- `--upscale` — include 4K upscale stage (TIER_TWO only) -- `--tts` — include TTS narration stage (parallel with upscale) -- `--download` — auto-download 4K files as upscales complete -- `--concat` — run concat after all stages done -- `--notify` — send Telegram notifications at milestones -- `--interval N` — poll interval in seconds (default: 15) -- `--orientation H|V` — HORIZONTAL or VERTICAL (auto-detected from video.orientation if omitted) - -Examples: -- `/fk-pipeline` — detect state and continue most recent project -- `/fk-pipeline --upscale --tts --download --notify` — full run with all options -- `/fk-pipeline <project_id> HORIZONTAL --upscale --download` — explicit project + orientation - ---- - -## When to Use - -- Starting a new project from scratch (after scenes are created) -- Resuming a partially-complete project -- Batch-running all remaining stages hands-free -- Want TTS + upscale to run simultaneously -- Want 4K downloads to roll in as each upscale completes - ---- - -## Step 1: Resolve Project and State - -### 1a. Fetch project - -```bash -# Most recent project -curl -s http://127.0.0.1:8100/api/projects -# Use last item → {id, name} - -# Get video + scenes -VID=$(curl -s "http://127.0.0.1:8100/api/videos?project_id=<PID>" | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['id'])") -curl -s "http://127.0.0.1:8100/api/scenes?video_id=$VID" > /tmp/fk_scenes.json -curl -s "http://127.0.0.1:8100/api/projects/<PID>/characters" > /tmp/fk_chars.json -curl -s "http://127.0.0.1:8100/api/projects/<PID>/output-dir" > /tmp/fk_outdir.json -``` - -### 1b. Derive slug and output dir - -```python -import json - -outdir_meta = json.load(open('/tmp/fk_outdir.json')) -SLUG = outdir_meta['slug'] -OUTDIR = outdir_meta['path'] -``` - -### 1c. State detection - -```python -import json, glob as globmod, os - -scenes = json.load(open('/tmp/fk_scenes.json')) -chars = json.load(open('/tmp/fk_chars.json')) -PREFIX = video_orientation.lower() # from GET /api/videos/{vid} → orientation field; 'horizontal' or 'vertical' -N = len(scenes) - -def pct(done, total): - return f"{done}/{total}" if total else "0/0" - -state = { - # Stage 0: ref images - 'refs_total': len(chars), - 'refs_done': sum(1 for c in chars if c.get('media_id')), - 'refs_missing': [c['id'] for c in chars if not c.get('media_id')], - - # Stage 1: scene images - 'images_total': N, - 'images_done': sum(1 for s in scenes if s.get(f'{PREFIX}_image_status') == 'COMPLETED'), - 'images_pending': [s['id'] for s in scenes if s.get(f'{PREFIX}_image_status') != 'COMPLETED'], - - # Stage 2: videos - 'videos_total': N, - 'videos_done': sum(1 for s in scenes if s.get(f'{PREFIX}_video_status') == 'COMPLETED'), - 'videos_pending': [s['id'] for s in scenes if s.get(f'{PREFIX}_video_status') != 'COMPLETED'], - - # Stage 2.5: review - 'review_done': False, # set True after review passes or max cycles - - # Stage 3: upscale - 'upscale_total': N, - 'upscale_done': sum(1 for s in scenes if s.get(f'{PREFIX}_upscale_status') == 'COMPLETED'), - 'upscale_pending': [s['id'] for s in scenes - if s.get(f'{PREFIX}_upscale_status') not in ('COMPLETED', 'FAILED')], - 'upscale_failed': [s['id'] for s in scenes if s.get(f'{PREFIX}_upscale_status') == 'FAILED'], - - # Stage 4: TTS - 'tts_total': N, - 'tts_done': len(globmod.glob(f'{OUTDIR}/tts/scene_*.wav')), - 'has_narrator': any(s.get('narrator_text') for s in scenes), - - # Stage 5: downloads - 'dl_total': N, - 'dl_done': len(globmod.glob(f'{OUTDIR}/4k/scene_*.mp4')), -} -``` - -### 1d. Print detected state and plan - -``` -Detected state for <project_name> [HORIZONTAL]: - Refs: 5/5 ✓ - Images: 50/50 ✓ - Videos: 50/50 ✓ - Review: passed (48/50 good, 2 fixed after regen) - Upscale: 39/50 ← in progress - TTS: 50/50 ✓ - Downloads: 39/50 ← behind upscale - -Plan: - [ACTIVE] Continue upscale (11 remaining) - [ACTIVE] Download as upscales complete - [SKIP] TTS (already done) - [QUEUED] Concat after upscale+download complete -``` - ---- - -## Step 2: Stage Routing - -Use this decision tree to determine which stages to run and in what order. - -```python -stages_to_run = [] - -# Sequential gates — each stage blocks the next -if state['refs_done'] < state['refs_total']: - stages_to_run.append('REFS') -elif state['images_done'] < state['images_total']: - stages_to_run.append('IMAGES') -elif state['videos_done'] < state['videos_total']: - stages_to_run.append('VIDEOS') - -# Review (after videos done, before upscale) -if state['videos_done'] == state['videos_total'] and not state['review_done']: - stages_to_run.append('REVIEW') - -# Upscale (after review passes) -if upscale_flag and state['videos_done'] == state['videos_total'] and state['review_done']: - if state['upscale_done'] < state['upscale_total']: - stages_to_run.append('UPSCALE') - -# TTS — parallel with upscale/videos (independent) -if tts_flag and state['has_narrator'] and state['tts_done'] < state['tts_total']: - stages_to_run.append('TTS') # runs concurrently - -# Downloads — rolling alongside upscale -if download_flag and state['dl_done'] < state['dl_total']: - stages_to_run.append('DOWNLOAD') # runs concurrently with UPSCALE - -# Concat — after all downloads + TTS done -if concat_flag: - stages_to_run.append('CONCAT') # runs last -``` - -**Parallelism rules:** -- `REFS` → `IMAGES` → `VIDEOS` → `REVIEW` are **sequential** (each requires previous) -- `UPSCALE` + `TTS` can run **simultaneously** (spawn 2 agents) -- `DOWNLOAD` runs **rolling** alongside UPSCALE (check each poll cycle) -- `CONCAT` runs **after** UPSCALE + DOWNLOAD + TTS all complete - ---- - -## Step 3: Run Each Stage - -### Stage 0 — Ref Images - -Only run if any entity is missing `media_id`. - -```bash -# For each entity missing media_id, submit GENERATE_CHARACTER_IMAGE -# Batch 5 at a time -for CID in <missing_ids>: - curl -X POST http://127.0.0.1:8100/api/requests \ - -H "Content-Type: application/json" \ - -d '{"type":"GENERATE_CHARACTER_IMAGE","character_id":"<CID>","project_id":"<PID>"}' -``` - -**Poll until all entities have `media_id`** before moving to Stage 1. - -**Retry rule:** If a ref gen fails, resubmit once. If fails again, warn user and skip. - ---- - -### Stage 1 — Scene Images - -Only run after all refs have `media_id`. - -```bash -# For each scene with image_status != COMPLETED: -curl -X POST http://127.0.0.1:8100/api/requests \ - -H "Content-Type: application/json" \ - -d '{"type":"GENERATE_IMAGE","scene_id":"<SID>","project_id":"<PID>","video_id":"<VID>","orientation":"<ORIENTATION>"}' -``` - -Batch 5 at a time. Poll every 15s. Submit next batch when current batch completes. - -**Failed images:** Resubmit once with `REGENERATE_IMAGE` (forces re-run). - ---- - -### Stage 2 — Scene Videos - -Only run after all scene images COMPLETED. - -```bash -curl -X POST http://127.0.0.1:8100/api/requests \ - -H "Content-Type: application/json" \ - -d '{"type":"GENERATE_VIDEO","scene_id":"<SID>","project_id":"<PID>","video_id":"<VID>","orientation":"<ORIENTATION>"}' -``` - -Batch 5. Poll 15s. Each video takes 2-5 min. - ---- - -### Stage 2.5 — Review Videos - -Only run after all videos COMPLETED. Uses `/fk-review-video` to catch AI generation errors before upscaling. - -```bash -# Run light review on all completed videos -curl -X POST "http://127.0.0.1:8100/api/videos/<VID>/review?project_id=<PID>&mode=light&orientation=<ORIENTATION>" -# Poll until complete -``` - -**Interpret results:** -- Scenes scoring **7.5+** (good/excellent) → pass, move to upscale -- Scenes scoring **4.0–7.4** (acceptable/poor) → update `video_prompt` based on `fix_guide` + `errors`, then regen video -- Scenes scoring **0–3.9** (unusable) → update `video_prompt` based on errors, regen image first (`REGENERATE_IMAGE`), then regen video - -**Fix-and-regen loop (max 2 cycles per scene):** - -```python -for cycle in range(2): - review = run_review(VID, mode='light') - bad_scenes = [s for s in review if s['total_score'] < 7.5] - if not bad_scenes: - break # all pass - - for scene in bad_scenes: - # Update video_prompt based on review errors + fix_guide - # e.g. add "static camera" for camera drift, "no brand logos" for logo errors - new_prompt = improve_prompt(scene['video_prompt'], scene['errors'], scene['fix_guide']) - curl_patch(f"/api/scenes/{scene['scene_id']}", {"video_prompt": new_prompt}) - - if scene['total_score'] < 4.0: - # Unusable — regen image first (cascades video) - submit_request("REGENERATE_IMAGE", scene['scene_id']) - else: - # Poor/acceptable — regen video only - submit_request("GENERATE_VIDEO", scene['scene_id']) - - # Poll until all regens complete, then re-review -``` - -**After review passes (or max cycles exhausted):** -- Log scenes that still fail with their scores and errors -- Proceed to upscale with all scenes that scored 7.5+ -- Report skipped scenes at end - ---- - -### Stage 3 — Upscale (4K) - -Only run after review passes (or max review cycles exhausted). TIER_TWO only. - -```bash -curl -X POST http://127.0.0.1:8100/api/requests \ - -H "Content-Type: application/json" \ - -d '{"type":"UPSCALE_VIDEO","scene_id":"<SID>","project_id":"<PID>","video_id":"<VID>","orientation":"<ORIENTATION>"}' -``` - -Batch 5. **Resubmit failed upscales** once automatically. - ---- - -### Stage 4 — TTS Narration (parallel) - -Runs in parallel with Stage 2 or 3. Requires `narrator_text` on scenes and a voice template. - -```bash -# Check templates -curl -s http://127.0.0.1:8100/api/tts/templates -# Pick template name (e.g. vi_male_narrator) - -# Trigger narration for video -curl -X POST http://127.0.0.1:8100/api/videos/<VID>/narrate \ - -H "Content-Type: application/json" \ - -d '{"template":"<template_name>"}' -``` - -Poll `output/<slug>/tts/` for WAV files as they appear. - -**If no template exists:** Pause and instruct user to run `/fk-gen-tts-template` or `/fk-import-voice` first. - ---- - -### Stage 5 — Rolling Downloads (parallel with upscale) - -Each poll cycle, check for newly completed upscales not yet downloaded: - -```python -newly_completed = [ - s for s in scenes - if s.get(f'{PREFIX}_upscale_status') == 'COMPLETED' - and s.get(f'{PREFIX}_upscale_url') - and not os.path.exists(f"{OUTDIR}/4k/scene_{s['display_order']:03d}_{s['id']}.mp4") -] -``` - -For each, write URL to temp file and download via curl: - -```bash -URL=$(cat /tmp/url_scene_<order>.txt) -curl -s "$URL" -o "output/<slug>/4k/scene_<order:03d>_<scene_id>.mp4" -``` - -**Important:** Write URL to temp file before passing to curl — avoids shell encoding mangling GCS signatures. - -Verify each download: -```bash -ffprobe -v quiet -show_entries format=duration -of csv=p=0 "<file>" -# Must be > 0 seconds -``` - ---- - -### Stage 6 — Concat - -Run after UPSCALE + DOWNLOAD + TTS all complete. Delegates to `/fk-concat`. - -Invoke: `/fk-concat --4k --with-tts` (or appropriate flags based on what was run). - ---- - -## Step 4: Poll Loop - -```python -import time - -INTERVAL = 15 -cycle = 0 - -while stages_to_run: - cycle += 1 - print(f"[cycle {cycle}] Polling...") - - # Refresh scene data - scenes = fetch_scenes(VID) - state = compute_state(scenes, chars, OUTDIR, PREFIX) - - # Submit next batch for active sequential stage - active_stage = stages_to_run[0] # HEAD of sequential chain - if active_stage in ('REFS','IMAGES','VIDEOS','UPSCALE'): - submit_next_batch(active_stage, state, PID, VID, ORIENTATION) - - # Check if active stage completed - if stage_complete(active_stage, state): - stages_to_run.pop(0) - print(f"✅ {active_stage} complete") - if notify_flag: - send_telegram(f"✅ {active_stage} complete for {project_name}") - - # Parallel: Rolling downloads (every cycle when upscaling) - if 'DOWNLOAD' in stages_to_run: - download_newly_completed(scenes, state, OUTDIR, PREFIX, PID=PID, VID=VID) - if state['dl_done'] >= state['upscale_done']: - pass # downloads caught up — keep watching - - # Check if all done - remaining_sequential = [s for s in stages_to_run if s not in ('TTS','DOWNLOAD','CONCAT')] - if not remaining_sequential and state['dl_done'] == state['upscale_done']: - if 'CONCAT' in stages_to_run: - run_concat() - break - - time.sleep(INTERVAL) -``` - ---- - -## Step 5: Failure Handling - -| Failure type | Detection | Action | -|---|---|---| -| Ref image FAILED | `media_id` missing after request COMPLETED | Resubmit `GENERATE_CHARACTER_IMAGE` once | -| Scene image FAILED | `horizontal_image_status == FAILED` | Resubmit `REGENERATE_IMAGE` once | -| Video FAILED | `horizontal_video_status == FAILED` | Resubmit `GENERATE_VIDEO` once | -| Review FAILED (score < 7.5) | `total_score < 7.5` in review results | Update `video_prompt` from `fix_guide` + `errors`, regen video (max 2 cycles) | -| Review UNUSABLE (score < 4.0) | `total_score < 4.0` in review results | Update `video_prompt`, regen image first (`REGENERATE_IMAGE`), then video | -| Upscale FAILED | `horizontal_upscale_status == FAILED` | Resubmit `UPSCALE_VIDEO` once | -| Download 4KB (XML error) | `ffprobe` returns 0s or non-numeric | Re-download (URL still valid for ~8h) | -| Worker stalled | pending > 0, processing = 0 for 2+ min | Print warning; suggest server restart | -| TTS no template | `GET /api/tts/templates` returns empty | Pause; prompt user to create template | - -**Max retries:** 2 per scene per stage. After 2 failures, log and skip — report at end. - ---- - -## Step 6: Final Summary - -``` -Pipeline complete for <project_name> - Refs: 5/5 - Images: 50/50 - Videos: 50/50 - Review: passed (48 good, 2 fixed after regen) - Upscale: 50/50 (1 retry) - Downloads: 50/50 - TTS: 50/50 - Failed: 0 - -Ready for: /fk-concat --4k --with-tts -``` - -Send via Telegram if `--notify`. - ---- - -## Concurrent TTS + Upscale Pattern - -When both `--tts` and `--upscale` are requested and videos are done, spawn two parallel tracks: - -``` -Track A (main agent): UPSCALE → batch 5 → poll → batch 5 → ... - └─ DOWNLOAD: rolling on each poll cycle - -Track B (sub-agent): TTS → POST /api/videos/<VID>/narrate → poll tts/ dir -``` - -Use the Agent tool with `oh-my-claudecode:executor` for Track B: - -``` -Agent( - subagent_type="oh-my-claudecode:executor", - prompt="Run TTS narration for video <VID> using template <template>. - Poll output/<slug>/tts/ every 30s until all <N> WAV files appear. - Report done when complete." -) -``` - -Main agent handles upscale + downloads. Both finish independently. - ---- - -## Console Output Format - -``` -[fk-pipeline] Operation Absolute Resolve - Cinematic Edition [HORIZONTAL] -Stage: UPSCALE (39/50) + DOWNLOAD (39/50) rolling -Queue: 5 pending / 5 processing -TTS: 50/50 ✓ (parallel, done) -Cycle 12 / next poll in 15s... -``` - ---- - -## Common Issues - -| Issue | Fix | -|-------|-----| -| `extension_connected: false` | Chrome extension disconnected — reload extension | -| Stage stuck at 0/N | Check `/api/requests?status=FAILED` for errors | -| Upscale TIER_ONE error | Account is TIER_ONE — skip `--upscale` | -| Downloads 4KB XML error | Write URL to temp file, re-curl | -| TTS `torch not found` | Set `TTS_PYTHON_BIN=/opt/homebrew/bin/python3.10` in server env | -| Worker stalled | POST http://127.0.0.1:8100/api/worker/restart or restart server | - ---- - -## Next Steps - -| After pipeline | Skill | -|---|---| -| Mix TTS into videos | `/fk-concat --with-tts` | -| Add branding watermark | `/fk-brand-logo` | -| Generate YouTube SEO | `/fk-youtube-seo` | -| Upload to YouTube | `/fk-youtube-upload` | +Arguments: $ARGUMENTS diff --git a/.claude/commands/fk-refresh-urls.md b/.claude/commands/fk-refresh-urls.md index 7415b864f..35e3d1e6b 100644 --- a/.claude/commands/fk-refresh-urls.md +++ b/.claude/commands/fk-refresh-urls.md @@ -1,116 +1,5 @@ -Refresh expired GCS signed URLs for all scenes in a video (images, videos, upscale videos) and character reference images. +Re-sign expired media URLs for all scenes in a video (images, videos, upscale videos) and character reference images. +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-refresh-urls.md -Usage: `/fk-refresh-urls <video_id> [--project-id <PID>]` - -## When to use - -- Before `/fk-review-video` if videos were generated hours ago (GCS signed URLs expire) -- Before `/fk-concat-fit-narrator` if downloading from URLs instead of local files -- After any long gap between generation and consumption of media URLs - -## Pre-flight - -```bash -# Extension must be connected with flow key -curl -s http://127.0.0.1:8100/api/flow/status -# Must show: {"connected": true, "flow_key_present": true} -# If flow_key_present is false: open/refresh a Google Flow tab in Chrome -``` - -## Step 1: Get project_id from video - -```bash -VID="<video_id>" -PID=$(curl -s "http://127.0.0.1:8100/api/videos/${VID}" | python3 -c "import sys,json; print(json.load(sys.stdin)['project_id'])") -echo "Project: $PID" -``` - -## Step 2: Bulk refresh via TRPC - -This calls Google Flow's TRPC `flow.getFlow` endpoint, extracts ALL fresh signed URLs from the response, and updates scenes + characters in DB. - -```bash -curl -s -X POST "http://127.0.0.1:8100/api/flow/refresh-urls/${PID}" | python3 -c " -import sys, json -r = json.load(sys.stdin) -print(f\"Refreshed: {r.get('refreshed', 0)} URLs (found {r.get('found', 0)} total)\") -if r.get('error'): - print(f\"ERROR: {r['error']}\") -" -``` - -**What gets updated:** -- `horizontal_image_url` / `vertical_image_url` — scene images -- `horizontal_video_url` / `vertical_video_url` — scene videos (original) -- `horizontal_upscale_url` / `vertical_upscale_url` — 4K upscaled videos -- `reference_image_url` — character/entity reference images - -The server matches each URL's media_id against `*_media_id` fields on scenes and characters, updating whichever orientation/type matches. - -## Step 3: Verify refresh worked - -```bash -# Check a few scenes have valid URLs -curl -s "http://127.0.0.1:8100/api/scenes?video_id=${VID}" | python3 -c " -import sys, json -scenes = sorted(json.load(sys.stdin), key=lambda s: s['display_order']) - -# Auto-detect orientation -ori = 'horizontal' -for s in scenes: - if s.get('horizontal_video_status') == 'COMPLETED' and s.get('horizontal_video_url'): - ori = 'horizontal'; break - if s.get('vertical_video_status') == 'COMPLETED' and s.get('vertical_video_url'): - ori = 'vertical'; break - -ok = 0; expired = 0 -for s in scenes: - url = s.get(f'{ori}_video_url') or '' - if url and 'Expires=' in url: - import re, time - m = re.search(r'Expires=(\d+)', url) - if m and int(m.group(1)) > time.time(): - ok += 1 - else: - expired += 1 - elif url: - ok += 1 - else: - expired += 1 - -print(f'Orientation: {ori.upper()}') -print(f'Valid URLs: {ok}/{len(scenes)}') -if expired: - print(f'Still expired: {expired} — may need to open Flow tab in Chrome for flow key') -else: - print('All URLs refreshed successfully!') -" -``` - -## Step 4: Per-media fallback (if TRPC fails) - -If the bulk TRPC refresh doesn't cover all media (e.g., TRPC response is partial), fall back to per-media refresh: - -```bash -# Get a fresh URL for a specific media_id -curl -s "http://127.0.0.1:8100/api/flow/media/<MEDIA_ID>" -# Returns: {fifeUrl: "https://...", servingUri: "https://...", ...} -``` - -Then update the scene manually: - -```bash -curl -X PATCH "http://127.0.0.1:8100/api/scenes/<SID>" \ - -H "Content-Type: application/json" \ - -d '{"horizontal_video_url": "<FRESH_URL>"}' -``` - -## Troubleshooting - -| Issue | Cause | Fix | -|-------|-------|-----| -| `flow_key_present: false` | Extension hasn't captured auth token | Open/refresh a Google Flow tab in Chrome | -| `Extension not connected` | Chrome extension WS disconnected | Check Chrome extension is enabled, refresh Flow tab | -| `refreshed: 0` | TRPC returned no URLs | Project may not exist on Google Flow, or auth expired | -| Some URLs still expired after refresh | media_id mismatch (upscale overwrote video_media_id) | Use per-media fallback with correct media_id | -| `get_media` returns error for media_id | Media deleted or expired on Google's side | Re-generate the video/image | +Arguments: $ARGUMENTS diff --git a/.claude/commands/fk-review-board.md b/.claude/commands/fk-review-board.md index 825ba11a8..4bbc260aa 100644 --- a/.claude/commands/fk-review-board.md +++ b/.claude/commands/fk-review-board.md @@ -1,78 +1,5 @@ -<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> Start the Scene Review Board web app for visual feedback on scene chains. +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-review-board.md -Usage: `/fk-review-board [<video_id>]` - -## What it does - -Launches `tools/review_server.py` on port 8200, serving `tools/review_board.html` — a visual review board where you can: -- See all scenes grouped by chain -- Play scene videos inline -- Tag scenes: OK / Regen Image / Regen Video / Edit -- Write text feedback per scene -- Export feedback as JSON - -The board loads scenes for `?video_id=<id>` query param (or a hardcoded fallback inside the HTML). Always pass the current project's `video_id` so the board reflects what the user is working on, not a stale default. - -## Steps - -### 1. Resolve current `video_id` - -Priority order — stop at first match: - -a. **Explicit arg** — if user passed `<video_id>` to the skill, use that. - -b. **Active project** — read `GET /api/active-project`: -```bash -ACTIVE=$(curl -s http://127.0.0.1:8100/api/active-project) -VID=$(echo "$ACTIVE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('video_id',''))") -PNAME=$(echo "$ACTIVE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('project_name','(none)'))") -``` - -c. **No active project / no video_id** — list recent projects and ask user to pick: -```bash -curl -s http://127.0.0.1:8100/api/projects?limit=10 | python3 -c " -import sys, json -for p in json.load(sys.stdin): - print(f\" {p['id']} {p.get('name','-')}\")" -``` -Then `PUT /api/active-project` with the chosen `project_id` and re-resolve. - -If still empty, abort: "No active project. Run /fk-switch-project <PID> first." - -### 2. Kill any existing process on port 8200 -```bash -kill $(lsof -ti :8200) 2>/dev/null -``` - -### 3. Start the review server in background -```bash -python3 tools/review_server.py & -``` - -### 4. Open the board with explicit `video_id` query param -```bash -open "http://localhost:8200?video_id=${VID}" -``` - -The query param overrides the HTML's hardcoded default, so the board always loads the project resolved in step 1. - -### 5. Confirm to user -``` -Review Board running at http://localhost:8200?video_id=<VID> -- Project: <project_name> -- Video ID: <VID> -- Scenes loaded via API proxy (localhost:8100) -- Videos served from output/<project>/review_full/ (fallback: raw/) -- Feedback saves to tools/review_feedback.json -``` - -## After feedback - -When the user shares feedback JSON (via copy or file), parse it and execute: -- `ok` → no action -- `regen-img` → submit REGENERATE_IMAGE requests -- `regen-vid` → submit REGENERATE_VIDEO requests -- `edit` → ask user for edit prompt, submit EDIT_IMAGE requests - -Use `/fk-gen-images` or `/fk-gen-videos` skills for the actual regeneration. +Arguments: $ARGUMENTS diff --git a/.claude/commands/fk-review-video.md b/.claude/commands/fk-review-video.md index c7d89339b..8891855c6 100644 --- a/.claude/commands/fk-review-video.md +++ b/.claude/commands/fk-review-video.md @@ -1,221 +1,5 @@ -Review AI-generated scene videos for quality using Claude Vision. +Review AI-generated scene videos for quality. +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-review-video.md -Usage: `/fk-review-video <video_id> [--mode light|deep]` - -Default mode: `light`. Orientation auto-detected from project `meta.json`. - -## Prerequisites - -- `ANTHROPIC_API_KEY` env var set -- `ffmpeg` + `ffprobe` installed -- Scenes must have completed videos (`${ori}_video_status = COMPLETED`) - -## Step 1: Pre-check - -```bash -# Verify server + extension connected -curl -s http://127.0.0.1:8100/health -# Must return: {"extension_connected": true} - -# Verify video exists -curl -s http://127.0.0.1:8100/api/videos/<VID> -``` - -**ABORT** if extension not connected or video not found. - -## Step 2: Check scenes have completed videos - -```bash -curl -s "http://127.0.0.1:8100/api/scenes?video_id=<VID>" -``` - -For each scene, verify `${ori}_video_status = COMPLETED` (orientation auto-detected from meta.json). - -**ABORT** if any scene is missing a completed video — tell user to run `/fk-gen-videos` first. - -## Step 3: Run review via API - -```bash -curl -X POST "http://127.0.0.1:8100/api/videos/<VID>/review?project_id=<PID>&mode=light&orientation=${ORI}" -``` - -**Parameters:** -- `mode`: `light` (default) or `deep` -- `orientation`: auto-detected from meta.json (`${ORI}`) - -The API will extract frames from each scene video, send them to Claude Vision, and return per-scene quality scores. - -**Poll until complete:** -```bash -curl -s http://127.0.0.1:8100/api/requests/<RID> -# Wait for status: "COMPLETED" -``` - -## Step 4: Interpret results - -The response is an array of per-scene review objects: - -```json -[ - { - "scene_id": "abc-123", - "display_order": 0, - "total_score": 8.5, - "dimensions": { - "character_consistency": 9.0, - "prompt_adherence": 8.5, - "motion_quality": 8.0, - "visual_fidelity": 8.5, - "temporal_coherence": 8.0, - "composition": 9.0 - }, - "errors": ["Slight motion blur at 4s mark"], - "fix_guide": "Acceptable as-is. If re-generating, add 'sharp focus, crisp motion' to prompt.", - "usable": true, - "verdict": "good", - "usable_segments": [ - {"start": "0s", "end": "4s", "score": 9.0}, - {"start": "5s", "end": "8s", "score": 8.5} - ] - } -] -``` - -### Scoring Dimensions - -| Dimension | Weight | What it measures | -|-----------|--------|------------------| -| Character Consistency | 25% | Characters match refs across frames | -| Prompt Adherence | 20% | Video matches prompt description | -| Motion Quality | 20% | Smooth motion, no artifacts | -| Visual Fidelity | 15% | Resolution, clarity, no banding | -| Temporal Coherence | 10% | Consistent lighting/shadows across frames | -| Composition | 10% | Framing matches camera direction | - -`total_score = sum(dimension_score * weight)` - -### Verdict Scale - -| Score | Verdict | Action | -|-------|---------|--------| -| 9.0–10.0 | Excellent | Ship as-is | -| 7.5–8.9 | Good | Usable, minor polish optional | -| 6.0–7.4 | Acceptable | Cut usable segments, regen weak parts | -| 4.0–5.9 | Poor | Regen scene image first, then video | -| 0–3.9 | Unusable | Rewrite prompt + regen from scratch | - -Errors in the `errors` array are prefixed with severity: `[CRITICAL]`, `[HIGH]`, or `[MINOR]`. Any `[CRITICAL]` error forces the scene into the 0–3.9 range regardless of other dimensions. See **Known AI Video Errors** section below. - -## Step 5: Act on results - -### Poor / Unusable scenes -Regenerate the scene image first, then the video: -```bash -# Force-regenerate scene image (cascades video + upscale) -curl -X POST http://127.0.0.1:8100/api/requests \ - -H "Content-Type: application/json" \ - -d '{"type": "REGENERATE_IMAGE", "scene_id": "<SID>", "project_id": "<PID>", "video_id": "<VID>", "orientation": "${ORI}"}' -``` -Then run `/fk-gen-videos <PID> <VID>` after image is complete. - -### Acceptable with good segments -Note `usable_segments` time ranges for manual editing. Use `/fk-concat` and trim in post. - -### Character drift (low `character_consistency`) -- Verify all entity ref images have `media_id` (UUID format) -- Use `EDIT_IMAGE` to re-anchor character appearance: - ```bash - curl -X POST http://127.0.0.1:8100/api/requests \ - -H "Content-Type: application/json" \ - -d '{"type": "EDIT_IMAGE", "scene_id": "<SID>", "project_id": "<PID>", "video_id": "<VID>", "orientation": "${ORI}"}' - ``` - -### After fixes -Run review again to verify improvements: -```bash -curl -X POST "http://127.0.0.1:8100/api/videos/<VID>/review?project_id=<PID>&mode=deep" -``` - -## Modes - -- **light** (default): 4 frames/second → 32 frames per 8s video. Fast, good for initial scan to identify problem scenes. -- **deep**: 8 frames/second → 64 frames per 8s video. Thorough, catches subtle artifacts and motion issues. Use before final export. - -## Output Summary - -Print a table after review completes: - -``` -Scene | Order | Score | Verdict | Errors | Usable Segments -------|-------|-------|------------|--------|---------------- -s-1 | 0 | 8.5 | good | 1 | 2s-4s(9.0), 6s-8s(8.5) -s-2 | 1 | 6.2 | acceptable | 2 | 3s-5s(7.0) -s-3 | 2 | 9.1 | excellent | 0 | full -s-4 | 3 | 3.8 | unusable | 5 | none -... -Total: 6.9/10 | 4 scenes reviewed | 0 skipped -``` - -Then print recommended actions: -- Excellent/Good → "Ready for `/fk-concat <VID>`" -- Acceptable → "Note usable segments, trim in post" -- Poor/Unusable → "Run `/fk-gen-images <PID> <VID>` to regenerate, then `/fk-gen-videos <PID> <VID>`" - -## Known AI Video Errors - -Battle-tested error catalog. Claude Vision flags these in the `errors` array with severity prefix. - -### CRITICAL (Auto-fail, score 0–3) - -| # | Error | Description | When it happens | -|---|-------|-------------|-----------------| -| 1 | Character Drift | Character morphs mid-video (extra limbs, breed changes) | Common after 3–4s | -| 2 | Breed Swap | Similar characters get mixed up | Common in multi-character scenes | -| 3 | Role Reversal | Wrong character performs the action | ~50% of action scenes | -| 4 | Brand Logo | AI generates real brand logos | Any scene with objects/signage | -| 5 | Character Count | Wrong number of characters rendered | Crowd or paired scenes | - -Any CRITICAL error → scene scores 0–3.9 (Unusable). Rewrite prompt + regen from scratch. - -### HIGH (Needs trim/regen, score 4–6) - -| # | Error | Description | When it happens | -|---|-------|-------------|-----------------| -| 6 | Camera Drift | Sudden unwanted zoom or rotation | ~60% of scenes after 4s | -| 7 | Object Morph | Held items change shape mid-video | Action scenes with props | -| 8 | Reverse Motion | Character does then undoes the action | ~30% of motion scenes | -| 9 | Human Hands | Anthropomorphic characters get human hands | Animal/creature characters | -| 10 | Scale Break | Characters change size relative to environment | Dynamic movement scenes | - -HIGH errors → note `usable_segments` before the error timestamp. Trim or regen. - -### MINOR (Acceptable, score 7–8) - -| # | Error | Description | -|---|-------|-------------| -| 11 | Prop Count | Small props change in number | -| 12 | Clothing Detail | Texture or pattern shifts | -| 13 | Background Blur | Garbled signage or background text | -| 14 | Accessory Loss | Small items (earrings, accessories) appear/disappear | - -MINOR errors → acceptable for most use cases. Polish optional. - -### Prevention Patterns - -| Issue | Fix | -|-------|-----| -| Character drift | Simpler prompts, add "steady camera, minimal movement" | -| Breed swap | Use high color contrast between similar characters | -| Character count | ONE dominant character, others in background | -| Reverse motion | Regen video (luck-based, different seed) | -| Brand logos | Add "no brand logos, no text" to prompt | -| Camera drift | Add "static camera" or "locked-off shot" to video_prompt | -| Human hands | Add "paws, claws, hooves" (or correct anatomy) to prompt | - -## Cost Note - -Each scene review = 1 Claude Vision API call with N frames. -- Light mode (32 frames/scene): ~$0.01–0.03 per scene -- Deep mode (64 frames/scene): ~2x light mode cost - -Reviewing a full video (10 scenes, deep) ≈ 10 API calls. Review light first, then deep only on scenes flagged as poor/acceptable. +Arguments: $ARGUMENTS diff --git a/.claude/commands/fk-thumbnail-guide.md b/.claude/commands/fk-thumbnail-guide.md index bd59fff6f..f8fa6152a 100644 --- a/.claude/commands/fk-thumbnail-guide.md +++ b/.claude/commands/fk-thumbnail-guide.md @@ -1,85 +1,5 @@ -# YouTube Thumbnail Guide — Hook-Worthy Design Rules +YouTube Thumbnail Guide — Hook-Worthy Design Rules +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-thumbnail-guide.md -## Required Elements - -| Element | Rule | -|---------|------| -| **Text** | 0-3 words max. Bold thick sans-serif. Yellow/white on dark. Upper half only. Never bottom-right (YouTube overlays duration there) | -| **Face** | 30-50% of frame. Extreme emotion: shock, anger, fear, determination. Direct eye contact. Never neutral/calm | -| **Colors** | Red + Blue, Yellow + Purple, Orange + Teal. High saturation. No pastels, no gray, no muted tones | -| **Composition** | ONE focal point. Subject 40-60% of frame. Blurred/simple background. Rule of thirds | -| **Lighting** | Dramatic — rim light, golden hour, high-contrast shadows. Never flat/even | - -## 6 Thumbnail Formulas - -### Formula 1: Reaction Face (Best for drama/reveals) -- Tight face crop 40-50% of frame, extreme emotion -- 1-3 power words upper corner -- Subject reacting to something partially visible -- **Prompt pattern:** `Extreme close-up of [CHARACTER] face, [EMOTION], [BACKGROUND ELEMENT partially visible], bold vivid colors, dramatic rim lighting` - -### Formula 2: Before/After (Best for transformations) -- Split screen: state A left, state B right -- Clear dividing line -- **Prompt pattern:** `Split composition, left side shows [STATE A], right side shows [STATE B], dramatic contrast` - -### Formula 3: Contrast/Clash (Best for military/underdog) -- Two visually incompatible things: massive vs small, hero vs overwhelming enemy -- High visual tension -- **Prompt pattern:** `[SMALL HERO] facing [MASSIVE THREAT], extreme scale contrast, cinematic wide angle` - -### Formula 4: Mystery/Reveal (Best for secrets/twists) -- Key element partially hidden or out of frame -- Text: "?", "Nobody expected..." -- **Prompt pattern:** `[SUBJECT] looking at something dramatic off-screen, [EMOTION], mysterious lighting, partial reveal` - -### Formula 5: Stakes Frame (Best for military/survival) -- Single character against impossible odds -- Environment communicates extreme pressure -- **Prompt pattern:** `[CHARACTER] surrounded/outnumbered by [THREAT], tension, dramatic environment showing scale of danger` - -### Formula 6: Number Punch (Best for stats/history) -- Large bold number dominates 30-40% of frame -- Supporting visual behind -- **Prompt pattern:** `Bold number [N] overlaid on [DRAMATIC SCENE], high contrast` - -## Psychology Hooks (Pick 1-2) - -1. **Curiosity Gap** — Show aftermath, not cause. Show reaction, not event. (+50% CTR) -2. **Emotional Mirror** — Brain mirrors emotions in faces automatically -3. **Stakes/Urgency** — High stakes without revealing outcome -4. **Contrast/Mismatch** — Brain flags unexpected juxtapositions -5. **FOMO** — Implies viewer is missing something significant - -## Genre: Military/Action/Drama - -- **Face:** Determination, shock, anger — sweat, grit, intensity -- **Colors:** Desaturated cinematic (khaki, olive, dark blue) with ONE vivid accent (fire, explosion, red alert) -- **Composition:** Wide establishing shot OR tight face. Show tension point, NOT resolution -- **Text:** Power words — "DESTROYED", "IMPOSSIBLE", "UNSTOPPABLE". Numbers for military stats -- **Avoid:** Revealing the climax. Show the inciting moment - -## Technical Specs - -| Spec | Value | -|------|-------| -| Dimensions | 1280 x 720 px (16:9) | -| Design master | 1920 x 1080 px | -| File format | PNG or JPG 85-90% | -| Max file size | 2 MB | -| Safe zone | Central 90% — avoid outer 5% margins | -| Dead zone | Bottom-right corner (duration badge) | -| Mobile test | Must be readable at 120px wide | - -## AI Prompt Template - -When generating a thumbnail, apply in this order: - -1. **Subject:** One primary subject, 40-60% of frame. Specify exact emotion -2. **Background:** Simple/blurred/single-tone. High contrast against subject -3. **Colors:** Two dominant complementary colors. Vivid saturation -4. **Position:** Subject at rule-of-thirds power point -5. **Lighting:** Dramatic rim light, high-contrast shadow, cinematic -6. **Text space:** Clean zone upper-left or upper-right for overlay text -7. **Avoid:** Busy background, multiple focal points, pastels, neutral expressions -8. **Style:** Military = cinematic color grade, desaturated shadows, ONE vivid accent +Arguments: $ARGUMENTS diff --git a/.claude/commands/fk-upload-image.md b/.claude/commands/fk-upload-image.md index e852f6a74..fe5b99c39 100644 --- a/.claude/commands/fk-upload-image.md +++ b/.claude/commands/fk-upload-image.md @@ -1,123 +1,5 @@ Upload a local image file to Google Flow and get a media_id (UUID). +<!-- AUTO-GENERATED by setup.py — do not edit. Source: skills/ --> +Read and follow the instructions in skills/fk-upload-image.md -Usage: `/fk-upload-image <file_path> [--project <project_id>] [--entity <entity_id>]` - -Useful for: setting channel icons, covers, or any local image as an entity reference or scene image. - -## Step 1: Check health - -```bash -curl -s http://127.0.0.1:8100/health -``` -Must have `extension_connected: true` AND flow key present. Abort if not. - -```bash -curl -s http://127.0.0.1:8100/api/flow/status -# Must return: {"connected": true, "flow_key_present": true} -``` - -## Step 2: Upload image - -```bash -curl -s -X POST http://127.0.0.1:8100/api/flow/upload-image \ - -H "Content-Type: application/json" \ - -d '{ - "file_path": "/absolute/path/to/image.png", - "project_id": "<PID>", - "file_name": "descriptive_name.png" - }' -``` - -**Parameters:** -- `file_path` (required): Absolute path to local image file (PNG, JPG, WebP) -- `project_id` (optional): Project to associate the upload with -- `file_name` (optional): Descriptive filename, defaults to `image.png` - -**Response:** -```json -{ - "media_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "raw": { "media": { "name": "uuid", ... } } -} -``` - -The `media_id` is the UUID you use everywhere (entity refs, scene images, video start frames). - -## Step 3: Apply the media_id - -### Option A: Set as entity reference image - -```bash -curl -s -X PATCH http://127.0.0.1:8100/api/characters/<ENTITY_ID> \ - -H "Content-Type: application/json" \ - -d '{"media_id": "<MEDIA_ID>"}' -``` - -### Option B: Set as scene image - -```bash -curl -s -X PATCH http://127.0.0.1:8100/api/scenes/<SCENE_ID> \ - -H "Content-Type: application/json" \ - -d '{ - "horizontal_image_media_id": "<MEDIA_ID>", - "horizontal_image_status": "COMPLETED" - }' -``` -(Use `${ori}_image_media_id` / `${ori}_image_status` matching project orientation.) - -### Option C: Create new entity with uploaded image - -```bash -# 1. Create entity -curl -s -X POST http://127.0.0.1:8100/api/characters \ - -H "Content-Type: application/json" \ - -d '{ - "name": "Asset Name", - "entity_type": "visual_asset", - "description": "What the image shows", - "media_id": "<MEDIA_ID>" - }' - -# 2. Link to project -curl -s -X POST http://127.0.0.1:8100/api/projects/<PID>/characters/<ENTITY_ID> -``` - -## Step 4: Verify - -```bash -# For entity: -curl -s http://127.0.0.1:8100/api/characters/<ENTITY_ID> | python3 -c " -import sys,json; c=json.load(sys.stdin) -print(f'{c[\"name\"]}: media_id={c.get(\"media_id\",\"none\")}')" - -# For scene: -curl -s http://127.0.0.1:8100/api/scenes/<SCENE_ID> | python3 -c " -import sys,json; s=json.load(sys.stdin) -print(f'img_status={s.get(\"horizontal_image_status\")} mid={s.get(\"horizontal_image_media_id\")}')" -``` - -## Common Workflows - -### Upload channel branding assets -```bash -# Upload icon -/fk-upload-image youtube/channels/<channel>/<channel>_icon.png --project <PID> -# Upload cover -/fk-upload-image youtube/channels/<channel>/<channel>_cover.png --project <PID> -``` - -### Replace a scene image with a local file -```bash -# Upload the image -/fk-upload-image /path/to/better_image.png --project <PID> -# Patch the scene with the returned media_id -# Then regenerate video from the new image -``` - -## Notes - -- The upload goes through the Chrome extension's `uploadImage` API to Google Flow -- Extension must be connected with a valid flow key -- Supported formats: PNG, JPG, JPEG, WebP (auto-detected from file extension) -- The uploaded image becomes available as a media_id for use in video generation, edit operations, or as reference images -- If `media_id` returns `null`, check that the flow key is present (`GET /api/flow/status`) +Arguments: $ARGUMENTS diff --git a/.gitignore b/.gitignore index 35e1ef44d..74ec96ed8 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ extension/_metadata/ .omc/ .agent/ flow_session_project.json +.venv/ diff --git a/AGENTS.md b/AGENTS.md index 0b6ce5fcf..bc5238214 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,7 +8,10 @@ Base URL: `http://127.0.0.1:8100` Before ANY workflow: ```bash curl -s http://127.0.0.1:8100/health -# Must return: {"extension_connected": true} +# Flow mode must return: {"extension_connected": true} +# Assistant mode (MEDIA_PROVIDER=assistant or provider=assistant per request): +# extension_connected may be false — no Chrome extension needed. +# Check provider status instead: GET /api/providers/status ``` ## Critical Rules (MUST follow) @@ -22,7 +25,7 @@ curl -s http://127.0.0.1:8100/health 7. **Cascade on regen** — regenerating an image auto-clears downstream video + upscale. 8. **REGENERATE vs GENERATE** — `GENERATE_*` skips if already COMPLETED. `REGENERATE_*` always runs (clears + regenerates). 9. **Image Material required** — every project needs a `material` field (e.g. `realistic`, `3d_pixar`, `anime`). List available: `GET /api/materials`. -10. **Server handles throttling** — worker enforces max 5 concurrent requests + 10s cooldown. Submit ALL requests via `/batch`; do NOT manually stagger or loop. +10. **Server handles throttling (per provider)** — each media provider declares its own limits (Flow: max 5 concurrent + 10s cooldown; assistant: max 2 concurrent, no cooldown). Submit ALL requests via `/batch`; do NOT manually stagger or loop. Check effective limits: `GET /api/providers/status`. 11. **Video prompts use sub-clip timing** — structure 8s video as time segments: `0-3s: [action]. 3-6s: [action]. 6-8s: [action].` 12. **Character dialogue in sub-clips** — embed speech in quotes: `Luna says "Goodnight."` Max 10-15 words per character per 2-3s segment. 13. **Scenes are mutable** — use `PATCH /api/scenes/{sid}` to update `prompt`, `video_prompt`, `narrator_text`, `character_names` after creation. Don't delete and recreate — patch instead. @@ -82,7 +85,7 @@ This project has reusable skills in `skills/`. When the user says `/fk-<name>`, | `/fk-brand-logo` | fk-brand-logo — Apply Channel Branding (Intro + Outro + Logo + 4K Badge) | | `/fk-camera-guide` | Camera Guide — Cinematic Video Prompts (Veo 3) | | `/fk-change-model` | fk-change-model — View & Change Video/Image Model Keys | -| `/fk-change-provider` | fk-change-provider — View & Switch the AI CLI for a Role | +| `/fk-change-provider` | fk-change-provider — View & Switch the Reviewer for a Role | | `/fk-concat-fit-narrator` | Trim each scene video to fit its TTS narrator duration, burn text overlays, then concatenate into a final video. | | `/fk-concat` | Download and concatenate all scene videos into a single video with optional TTS narration. | | `/fk-create-project` | Create a new Google Flow video project. Ask the user for: | @@ -102,10 +105,11 @@ This project has reusable skills in `skills/`. When the user says `/fk-<name>`, | `/fk-insert-scene` | Insert new scene(s) into an existing video chain — for multi-angle shots, cutaways, or close-ups. | | `/fk-monitor` | fk-monitor — Full Pipeline Monitor | | `/fk-pipeline` | fk-pipeline — Smart Full-Pipeline Orchestrator | +| `/fk-provider` | fk-provider — Media providers: choose the generation backend | | `/fk-refresh-urls` | Re-sign expired media URLs for all scenes in a video (images, videos, upscale videos) and character reference images. | | `/fk-research` | fk-research — Fact-Check & Research Before Scripting | | `/fk-review-board` | Start the Scene Review Board web app for visual feedback on scene chains. | -| `/fk-review-video` | Review AI-generated scene videos for quality using Claude Vision. | +| `/fk-review-video` | Review AI-generated scene videos for quality. | | `/fk-status` | Show full status dashboard for a project. | | `/fk-switch-project` | fk-switch-project — Switch Active Project | | `/fk-thumbnail-guide` | YouTube Thumbnail Guide — Hook-Worthy Design Rules | diff --git a/README.md b/README.md index 6211c3e2a..2f5b02393 100644 --- a/README.md +++ b/README.md @@ -248,6 +248,68 @@ You can also pass `flow_project_id` per project on `POST /api/projects`. | `FLOW_PROJECT_ID` | — | The Flow project every RPC is scoped to. Required. | | `FLOW_ALLOW_DEGRADED` | `0` | `1` lets scene chaining and r2v fall back to plain i2v instead of failing. | | `DEFAULT_PAYGATE_TIER` | `PAYGATE_TIER_TWO` | Carried for the DB and dashboard; no longer selects a model. | +| `MEDIA_PROVIDER` | `flow` | `flow` (Google Flow via extension) or `assistant` (route all generation to the AI assistant). | +| `ASSISTANT_PROVIDER_TIMEOUT_S` | `1800` | How long a request waits for a worker to complete its provider job before failing. | +| `ASSISTANT_PROVIDER_POLL_S` | `15` | How often to poll the provider-job row while waiting for completion. | + +### Assistant Media Provider (`MEDIA_PROVIDER=assistant`) + +Routes every generation call — reference images, scene images, edits, i2v, r2v — +to the AI assistant instead of Google Flow. No Chrome extension or Flow sign-in +needed; the worker, skills, dashboard, and concat pipeline work unchanged. + +Protocol (persistent provider-job queue + HTTP API): + +1. Each request is inserted as a `QUEUED` row in the `provider_job` table with the + full prompt, orientation, input URLs (`source_url` for edits, `start_url`/`end_url` + for video, `extra.reference_urls` for reference images). +2. An external worker (the assistant) long-polls + `GET /api/provider-jobs/wait-next?provider=assistant&worker_id=<id>`, claims the + job (lease granted), heartbeats while working, and finishes with + `POST /api/provider-jobs/{id}/complete` carrying + `{"worker_id": "<id>", "result": {"output_url": "<file:// or https:// URL>", "media_id": "<uuid>"}}` + (or `/fail` with `{"worker_id": "<id>", "error": "..."}`). + Only the lease holder may heartbeat/progress/complete/fail (409 otherwise); + complete/fail are idempotent for the holder. +3. The provider mints a UUID `media_id` when the worker omits one and records the + output URL — the DB rows look identical to Flow-generated ones, so concat and + upload keep working. Expired leases are reclaimable, so crashed workers never + strand jobs. + +See `agent/worker/assistant_worker.py` for a reference worker implementing the +worker side of the protocol. Video upscale is not supported on this provider and +fails loudly. + +### Post-production (provider-neutral) + +Concat, finalize, and review work on clips from any provider — each clip is +normalized to H.264/yuv420p + AAC before merging, so Flow and assistant clips +can be mixed in one timeline. + +```bash +# Merge scene clips in display_order; trim to the video's target_duration_s +curl -X POST http://127.0.0.1:8100/api/videos/<VID>/concat \ + -H "Content-Type: application/json" \ + -d '{"orientation": "VERTICAL", "target_duration_s": 60}' + +# Concat + optional music/narration mix, marks the video COMPLETED +curl -X POST http://127.0.0.1:8100/api/videos/<VID>/finalize \ + -H "Content-Type: application/json" \ + -d '{"orientation": "VERTICAL", "target_duration_s": 60, + "music_path": "/path/to/music.mp3", "narrate": true}' + +# Review scene videos, then auto-enqueue REGENERATE_VIDEO for bad scenes +# (bounded: at most max_regenerations regen requests per scene, ever) +curl -X POST http://127.0.0.1:8100/api/videos/<VID>/review-regenerate \ + -H "Content-Type: application/json" \ + -d '{"project_id": "<PID>", "mode": "light", "max_regenerations": 1}' +``` + +`target_duration_s` can also be stored on the video itself (`POST /api/videos` +/ `PATCH /api/videos/<VID>`) — concat/finalize fall back to it when the +request omits a target. Review accepts `file://` clip URLs directly, so +assistant-provider output needs no download step; the Flow `get_media` +fallback only runs when the extension is connected. ### Image API @@ -532,7 +594,7 @@ Ready-to-use workflow recipes in `skills/` (also available as `/slash-commands` |-------|-------------| | `/fk-review-video` | AI vision scoring of generated scene videos (quality, consistency, usability) — see [AI Vision Providers](#ai-vision-providers-video-review) below | | `/fk-review-board` | Visual scene-by-scene review board for feedback before locking a cut | -| `/fk-change-provider` | View/switch the AI CLI, model and effort behind `/fk-review-video` | +| `/fk-change-provider` | View/switch the reviewer (`muse` = the assistant itself, or an AI CLI), model and effort behind `/fk-review-video` | ### Reference @@ -540,6 +602,7 @@ Ready-to-use workflow recipes in `skills/` (also available as `/slash-commands` |-------|-------------| | `/fk-camera-guide` | Camera angles, movements, lighting, DOF for cinematic video prompts | | `/fk-thumbnail-guide` | Hook-worthy thumbnail design rules | +| `/fk-provider` | Media providers: choose the generation backend (`flow`/`assistant`), run the assistant worker, troubleshoot provider jobs | ### TTS & Narration @@ -575,12 +638,26 @@ Ready-to-use workflow recipes in `skills/` (also available as `/slash-commands` | `/fk-dashboard` | Live status in the Claude Code statusline | | `/fk-doctor` | Diagnose any error (Flow API, extension, worker, YouTube) and prescribe a fix | +### Muse Support + +Muse is a first-class FlowKit agent, not just another skill reader: + +- **Skills run natively** — no shelling out, no slash-command wiring. + Muse reads `skills/fk-*.md` and calls its own tools directly, including + vision on files (`muse.read` for contact sheets and images). +- **`muse` is an official video-review provider** — no CLI, no model, no API + key. It scores review contact sheets by hand through + `POST .../review-sheets` → vision → `POST .../review-submit` + (see `/fk-review-video --by muse`). Opt in per role with + `/fk-change-provider set muse`; the default role stays on `claude`. + ### AI CLI Compatibility (Skill Consumption) Skills are `.md` recipes any AI coding-assistant CLI can read and follow — this is about **which agent reads the skill files**, not which model does the work: | CLI | Instructions | How skills work | |-----|-------------|-----------------| +| Muse | Skills auto-loaded | Native tool calls (`muse.read` for files/images) | | Claude Code | `CLAUDE.md` (auto-loaded) | Native `/fk-*` slash commands | | Codex CLI | `AGENTS.md` → reads `CLAUDE.md` | User says `/fk-<name>`, agent reads `skills/fk-<name>.md` | @@ -591,18 +668,23 @@ that is configured in `agent/providers.json`, not by `setup.py`. ### AI Vision Providers (Video Review) -Separate from the table above — this is about **which CLI backend does the vision analysis** for `/fk-review-video`. Three providers are supported and swappable at runtime, no restart required: +Separate from the table above — this is about **which backend does the vision analysis** for `/fk-review-video`. Four reviewers are supported and swappable at runtime, no restart required: | Provider | Binary | Reasoning efforts | Model catalog | Setup | |----------|--------|-------------------|---------------|-------| -| `claude` | Claude Code CLI | `low` `medium` `high` `xhigh` `max` | aliases (`sonnet`, `opus`, `haiku`, `fable`) or any full model name | Default — works out of the box | +| `muse` | — (the assistant itself) | — | — | Official — Muse reads the contact sheets with its own vision via `POST .../review-sheets` → `POST .../review-submit`; no CLI, no API key. Opt in per role (`/fk-change-provider set muse`) | +| `claude` | Claude Code CLI | `low` `medium` `high` `xhigh` `max` | aliases (`sonnet`, `opus`, `haiku`, `fable`) or any full model name | Install the CLI, sign in once | | `agy` | Google Antigravity CLI | `low` `medium` `high` | closed — `agy models` is the whole list and agy rejects anything else | Install separately, sign in once | | `codex` | OpenAI Codex CLI | `low` `medium` `high` `xhigh` `max` (varies per model) | codex's own on-disk cache, plus slugs newer than it | `npm install -g @openai/codex`, then `codex login` once | -Provider, model and effort are set **per role** — a role being a job an AI CLI +Provider, model and effort are set **per role** — a role being a job an AI does for Flow Kit. There is one today, `video_review`; the config is a map so the next one is an entry rather than a schema change. Model and effort may both -be `null`, meaning "whatever that CLI defaults to". +be `null`, meaning "whatever that backend defaults to". The `muse` reviewer +takes no model or effort — it is Muse scoring contact sheets by hand, so +pointing `video_review` at `muse` disables the CLI review endpoint (it +answers 500 with directions) and the review flow becomes +`review-sheets` → hand scoring → `review-submit`. **For `agy`, model and effort are mutually exclusive.** Its slugs name their own effort — `gemini-3.8-flash-low`, `gemini-3.1-pro-high` — so setting both is diff --git a/agent/api/flow.py b/agent/api/flow.py index e74647cef..5ed6d0e65 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -442,7 +442,28 @@ async def check_omni_status(body: CheckOmniStatusRequest): @router.post("/refresh-urls/{project_id}") async def refresh_project_urls(project_id: str): - """Bulk refresh all media URLs for a project via per-media get_media calls.""" + """Bulk refresh all media URLs for a project via per-media get_media calls. + + Provider-neutral no-op: when every stored URL is local (file://), there is + nothing to re-sign and the extension is not required. + """ + from agent.db import crud + + urls: list[str] = [] + for video in await crud.list_videos(project_id): + for scene in await crud.list_scenes(video["id"]): + for k, v in scene.items(): + if k.endswith("_url") and v: + urls.append(v) + for char in await crud.get_project_characters(project_id): + for k, v in char.items(): + if k.endswith("_url") and v: + urls.append(v) + + if not any(u.startswith("http") for u in urls): + return {"refreshed": 0, "found": len(urls), + "skipped": "no remote media URLs (all local or none); nothing to refresh"} + client = get_flow_client() if not client.connected: raise HTTPException(503, "Extension not connected") diff --git a/agent/api/projects.py b/agent/api/projects.py index c46105a3f..9a6f33c36 100644 --- a/agent/api/projects.py +++ b/agent/api/projects.py @@ -1,7 +1,10 @@ import json import logging import re +import shutil from datetime import datetime, timezone +from pathlib import Path +from urllib.parse import urlparse import aiohttp from fastapi import APIRouter, HTTPException @@ -150,11 +153,9 @@ def _get_repo() -> SQLiteRepository: @router.post("", response_model=Project) async def create(body: ProjectCreate): from agent.materials import get_material + import uuid as _uuid - # Step 1: Create project on Google Flow to get the real projectId client = get_flow_client() - if not client.connected: - raise HTTPException(503, "Extension not connected — cannot create project on Google Flow") # Resolve material (support legacy style field + material field) material_id = _resolve_material_id(body.material) @@ -170,19 +171,27 @@ async def create(body: ProjectCreate): dupes = [s for s in slugs if slugs.count(s) > 1] raise HTTPException(400, f"Duplicate character slugs: {list(set(dupes))}") - detected_tier = await _detect_user_tier(client) - - # Explicit flow_project_id means intentional reuse. Otherwise create a - # fresh real Flow project through the current batchexecute endpoint. + # Provider-aware project identity. + # 1. Explicit flow_project_id -> intentional reuse (no extension needed). + # 2. Extension connected -> create a fresh real Flow project (legacy path). + # 3. Otherwise -> local-only project with a minted UUID. This is the + # assistant-mode path: no Chrome, no Flow sign-in required. Generation + # requests for it should use a non-flow provider. + detected_tier = body.user_paygate_tier flow_project_id = client.flow_project_id(body.flow_project_id) if flow_project_id: logger.info("Flow project reused: %s", flow_project_id) - else: + elif client.connected: + detected_tier = await _detect_user_tier(client) flow_result = await client.create_project(body.name, body.tool_name) if flow_result.get("error"): raise HTTPException(502, f"Flow API error: {flow_result['error']}") flow_project_id = _read_flow_project_id(flow_result) logger.info("Flow project created: %s", flow_project_id) + else: + flow_project_id = str(_uuid.uuid4()) + logger.info("Extension not connected — creating local-only project %s", + flow_project_id) repo = _get_repo() @@ -344,6 +353,7 @@ class ThumbnailRequest(BaseModel): character_names: list[str] = [] aspect_ratio: str = "LANDSCAPE" output_filename: str = "thumbnail.png" + provider: str | None = None # default: DEFAULT_PROVIDER class ThumbnailResponse(BaseModel): @@ -357,18 +367,17 @@ class ThumbnailResponse(BaseModel): @router.post("/{pid}/generate-thumbnail", response_model=ThumbnailResponse) async def generate_thumbnail(pid: str, body: ThumbnailRequest): - """Generate a thumbnail image for a project via Google Flow API (synchronous, no queue).""" + """Generate a thumbnail image via the selected media provider (synchronous, no queue).""" import logging logger = logging.getLogger(__name__) + from agent.config import DEFAULT_PROVIDER from agent.materials import get_material + from agent.sdk.services.operations import get_operations + from agent.sdk.services.provider_base import KIND_IMAGE, ProviderJob from agent.sdk.services.result_handler import parse_result logger.info("generate_thumbnail: started for project %s", pid) - client = get_flow_client() - if not client.connected: - raise HTTPException(503, "Extension not connected") - repo = _get_repo() project = await repo.get_project(pid) if not project: @@ -380,8 +389,9 @@ async def generate_thumbnail(pid: str, body: ThumbnailRequest): scene_prefix = material["scene_prefix"] if material and material.get("scene_prefix") else "" full_prompt = f"{scene_prefix} {body.prompt}".strip() if scene_prefix else body.prompt - # Resolve character reference media_ids (error if any named entity is missing media_id) + # Resolve character references (media_ids for Flow, image URLs for assistant). character_media_ids = None + reference_urls: list[str] = [] if body.character_names: entities = await repo.get_project_characters(pid) valid_ids = [] @@ -389,51 +399,78 @@ async def generate_thumbnail(pid: str, body: ThumbnailRequest): for entity in entities: name = entity["name"] if isinstance(entity, dict) else entity.name mid = entity.get("media_id") if isinstance(entity, dict) else getattr(entity, "media_id", None) + ref_url = (entity.get("reference_image_url") if isinstance(entity, dict) + else getattr(entity, "reference_image_url", None)) char_slug = (entity.get("slug") if isinstance(entity, dict) else getattr(entity, "slug", None)) or "" if not ((char_slug and char_slug in body.character_names) or (name and name in body.character_names)): continue if mid: valid_ids.append(mid) - else: + if ref_url: + reference_urls.append(ref_url) + if not mid and not ref_url: missing.append(name) if missing: raise HTTPException(400, f"Missing reference images for: {', '.join(missing)}. Generate ref images first.") character_media_ids = valid_ids if valid_ids else None - aspect_ratio = _ASPECT_RATIO_MAP.get(body.aspect_ratio.upper(), "IMAGE_ASPECT_RATIO_LANDSCAPE") + provider_name = (body.provider or DEFAULT_PROVIDER).strip().lower() + registry = get_operations().registry + provider = registry.get(provider_name) + if provider is None: + raise HTTPException(400, f"Unknown provider '{provider_name}' (available: {registry.names()})") + + aspect_key = body.aspect_ratio.upper() + aspect = _ASPECT_RATIO_MAP.get(aspect_key, "IMAGE_ASPECT_RATIO_LANDSCAPE") + orientation = "VERTICAL" if aspect_key == "PORTRAIT" else "HORIZONTAL" tier = getattr(project, "user_paygate_tier", "PAYGATE_TIER_TWO") or "PAYGATE_TIER_TWO" - logger.info("generate_thumbnail: calling generate_images prompt=%s refs=%s", full_prompt[:60], character_media_ids) - raw = await client.generate_images( + job = ProviderJob( + job_id=f"thumb-{pid[:8]}-{aspect_key.lower()}", + kind=KIND_IMAGE, prompt=full_prompt, - project_id=pid, - aspect_ratio=aspect_ratio, - user_paygate_tier=tier, - character_media_ids=character_media_ids, + orientation=orientation, + reference_urls=tuple(reference_urls), + extra={"project_id": pid, "aspect": aspect, "tier": tier, + "character_media_ids": character_media_ids}, ) - logger.info("generate_thumbnail: generate_images returned, error=%s", raw.get("error") if isinstance(raw, dict) else "n/a") + blocked = provider.check(job) + if blocked: + # Keep the historical 503 for a disconnected Flow extension. + raise HTTPException(503 if provider_name == "flow" else 400, blocked) + + logger.info("generate_thumbnail: provider=%s prompt=%s refs=%s", + provider_name, full_prompt[:60], len(reference_urls)) + raw = await provider.run(job) + logger.info("generate_thumbnail: provider returned, error=%s", raw.get("error") if isinstance(raw, dict) else "n/a") gen_result = parse_result(raw, "GENERATE_IMAGE") if not gen_result.success: raise HTTPException(502, gen_result.error or "Image generation failed") - # Download and save to output/{project_name}/thumbnails/{filename} + # Save to output/{project_name}/thumbnails/{filename} project_name = slugify(getattr(project, "name", "project")) out_dir = BASE_DIR / "output" / project_name / "thumbnails" out_dir.mkdir(parents=True, exist_ok=True) output_path = out_dir / body.output_filename - if gen_result.url and gen_result.url.startswith("http"): - try: - connector = aiohttp.TCPConnector(ssl=False) - async with aiohttp.ClientSession(connector=connector) as session: - async with session.get(gen_result.url) as resp: - if resp.status == 200: - output_path.write_bytes(await resp.read()) - else: - raise HTTPException(502, f"Failed to download image: HTTP {resp.status}") - except aiohttp.ClientError as e: - raise HTTPException(502, f"Failed to download image: {e}") from e + if gen_result.url: + if gen_result.url.startswith("http"): + try: + connector = aiohttp.TCPConnector(ssl=False) + async with aiohttp.ClientSession(connector=connector) as session: + async with session.get(gen_result.url) as resp: + if resp.status == 200: + output_path.write_bytes(await resp.read()) + else: + raise HTTPException(502, f"Failed to download image: HTTP {resp.status}") + except aiohttp.ClientError as e: + raise HTTPException(502, f"Failed to download image: {e}") from e + elif gen_result.url.startswith("file://"): + src = Path(urlparse(gen_result.url).path) + if not src.is_file(): + raise HTTPException(502, f"Provider returned missing file: {gen_result.url}") + shutil.copy2(src, output_path) return ThumbnailResponse( success=True, diff --git a/agent/api/provider_jobs.py b/agent/api/provider_jobs.py new file mode 100644 index 000000000..251484df1 --- /dev/null +++ b/agent/api/provider_jobs.py @@ -0,0 +1,247 @@ +"""Provider-job API — the handoff queue between the FlowKit worker and +external media providers/agents (assistant, HTTP workers, ...). + +A producer (the worker) creates a QUEUED job; a consumer (an external worker) +claims it, heartbeats while running, and completes/fails it. Long-poll +endpoints let both sides wait without busy-looping. + + Producer flow: POST /api/provider-jobs -> {id} + GET /api/provider-jobs/{id}/wait -> terminal row + + Worker flow: GET /api/provider-jobs/wait-next?provider=assistant&worker_id=w1 + POST /api/provider-jobs/{id}/heartbeat (every ~lease/3) + POST /api/provider-jobs/{id}/progress (optional) + POST /api/provider-jobs/{id}/complete (or /fail) + +Ownership: heartbeat/progress/complete/fail are accepted only from the +worker that holds the lease (claimed_by == worker_id) while the job is +live (CLAIMED/RUNNING). complete/fail are idempotent for the lease holder — +repeating them on an already-terminal job returns the existing row. cancel +is producer-side and rejected once the job is terminal. +""" +from __future__ import annotations + +import asyncio +import json +import logging +import time +from typing import Optional + +from fastapi import APIRouter, HTTPException, Query +from fastapi.responses import JSONResponse +from pydantic import BaseModel, Field + +from agent.db import crud + +logger = logging.getLogger(__name__) + +router = APIRouter(prefix="/provider-jobs", tags=["provider-jobs"]) + +DEFAULT_LEASE_TTL_S = 300 +POLL_INTERVAL_S = 2.0 + + +# --------------------------------------------------------------------------- +# Models +# --------------------------------------------------------------------------- + +class ProviderJobCreate(BaseModel): + provider: str = Field(..., description="Target backend: flow | assistant | ...") + kind: str = Field(..., description="image | edit_image | i2v | r2v | upscale") + prompt: str = "" + orientation: Optional[str] = None + source_url: Optional[str] = None + end_url: Optional[str] = None + extra: Optional[dict] = None + job_id: Optional[str] = None + + +class ClaimBody(BaseModel): + worker_id: str + lease_ttl_s: float = DEFAULT_LEASE_TTL_S + + +class HeartbeatBody(BaseModel): + worker_id: str + lease_ttl_s: float = DEFAULT_LEASE_TTL_S + + +class ProgressBody(BaseModel): + worker_id: str + progress: int = Field(..., ge=0, le=100) + message: Optional[str] = None + + +class CompleteBody(BaseModel): + worker_id: str + result: Optional[dict] = None + + +class FailBody(BaseModel): + worker_id: str + error: str = "" + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + +def _serialize(row: Optional[dict]) -> Optional[dict]: + """Parse the JSON text columns so API consumers get real objects.""" + if row is None: + return None + out = dict(row) + for key in ("extra", "result"): + raw = out.get(key) + if isinstance(raw, str) and raw: + try: + out[key] = json.loads(raw) + except json.JSONDecodeError: + pass + return out + + +# --------------------------------------------------------------------------- +# Producer endpoints +# --------------------------------------------------------------------------- + +@router.post("") +async def create_job(body: ProviderJobCreate): + row = await crud.create_provider_job( + provider=body.provider, kind=body.kind, prompt=body.prompt, + orientation=body.orientation, source_url=body.source_url, + end_url=body.end_url, extra=body.extra, job_id=body.job_id) + return _serialize(row) + + +@router.get("") +async def list_jobs(provider: Optional[str] = Query(default=None), + status: Optional[str] = Query(default=None), + limit: int = Query(default=100, le=500)): + rows = await crud.list_provider_jobs(provider=provider, status=status, limit=limit) + return [_serialize(r) for r in rows] + + +# NOTE: static sub-paths are declared before /{job_id} so they can't be +# shadowed by the path parameter. + + +@router.get("/wait-next") +async def wait_next_job(provider: str = Query(...), + worker_id: str = Query(...), + lease_ttl_s: float = Query(default=DEFAULT_LEASE_TTL_S), + timeout_s: float = Query(default=60, le=600)): + """Long-poll: wait for the next claimable job for a provider, then claim it. + + Returns the claimed job row, or 204 when the timeout expires with nothing + available. This is the primary endpoint external workers poll. + """ + deadline = time.monotonic() + timeout_s + while True: + job = await crud.next_queued_provider_job(provider, worker_id, lease_ttl_s) + if job: + logger.info("provider_job %s claimed by %s", job["id"], worker_id) + return _serialize(job) + if time.monotonic() >= deadline: + return JSONResponse(status_code=204, content=None) + await asyncio.sleep(min(POLL_INTERVAL_S, max(0.1, deadline - time.monotonic()))) + + +@router.get("/{job_id}") +async def get_job(job_id: str): + row = await crud.get_provider_job(job_id) + if row is None: + raise HTTPException(status_code=404, detail="provider job not found") + return _serialize(row) + + +@router.get("/{job_id}/wait") +async def wait_job(job_id: str, timeout_s: float = Query(default=600, le=3600)): + """Long-poll: wait until a job reaches a terminal status. + + 404 when the job doesn't exist; 204 when the timeout expires first. + """ + job = await crud.wait_for_provider_job(job_id, timeout_s=timeout_s, + poll_interval_s=POLL_INTERVAL_S) + if job is None: + # Distinguish "no such job" from "timed out". + if await crud.get_provider_job(job_id) is None: + raise HTTPException(status_code=404, detail="provider job not found") + return JSONResponse(status_code=204, content=None) + return _serialize(job) + + +# --------------------------------------------------------------------------- +# Worker endpoints +# --------------------------------------------------------------------------- + +@router.post("/next") +async def claim_next_job(body: ClaimBody, provider: str = Query(...)): + """Claim the oldest available job for a provider (non-blocking).""" + job = await crud.next_queued_provider_job(provider, body.worker_id, body.lease_ttl_s) + if job is None: + raise HTTPException(status_code=404, detail="no claimable job available") + return _serialize(job) + + +@router.post("/{job_id}/claim") +async def claim_job(job_id: str, body: ClaimBody): + job = await crud.claim_provider_job(job_id, body.worker_id, body.lease_ttl_s) + if job is None: + raise HTTPException(status_code=409, + detail="job not claimable (held, terminal, or missing)") + return _serialize(job) + + +@router.post("/{job_id}/heartbeat") +async def heartbeat_job(job_id: str, body: HeartbeatBody): + job = await crud.heartbeat_provider_job(job_id, body.worker_id, body.lease_ttl_s) + if job is None: + raise HTTPException(status_code=409, + detail="heartbeat rejected (not the lease holder or job not running)") + return _serialize(job) + + +@router.post("/{job_id}/progress") +async def progress_job(job_id: str, body: ProgressBody): + """Report progress. 409 unless the caller holds the lease on a live job.""" + job = await crud.update_provider_job_progress( + job_id, body.worker_id, body.progress, body.message) + if job is None: + raise HTTPException(status_code=409, + detail="progress rejected (not the lease holder or job not live)") + return _serialize(job) + + +@router.post("/{job_id}/complete") +async def complete_job(job_id: str, body: CompleteBody): + """Complete a job as its lease holder. Idempotent: re-completing an + already-SUCCEEDED job returns the existing row. 409 otherwise.""" + job = await crud.complete_provider_job(job_id, body.worker_id, body.result) + if job is None: + raise HTTPException(status_code=409, + detail="complete rejected (not the lease holder, " + "job not live, or ended in another terminal state)") + return _serialize(job) + + +@router.post("/{job_id}/fail") +async def fail_job(job_id: str, body: FailBody): + """Fail a job as its lease holder. Idempotent for already-FAILED jobs; + a SUCCEEDED/CANCELLED job cannot be failed. 409 otherwise.""" + job = await crud.fail_provider_job(job_id, body.worker_id, body.error) + if job is None: + raise HTTPException(status_code=409, + detail="fail rejected (not the lease holder, " + "job not live, or already succeeded/cancelled)") + return _serialize(job) + + +@router.post("/{job_id}/cancel") +async def cancel_job(job_id: str): + """Producer-side cancel. 409 when the job is missing or already terminal.""" + job = await crud.cancel_provider_job(job_id) + if job is None: + raise HTTPException(status_code=409, + detail="cancel rejected (job missing or already terminal)") + return _serialize(job) diff --git a/agent/api/providers.py b/agent/api/providers.py index bc8e5f43c..304c1b76b 100644 --- a/agent/api/providers.py +++ b/agent/api/providers.py @@ -35,6 +35,29 @@ _PROVIDERS_FILE = Path(__file__).parent.parent / "providers.json" +# ── Media providers (generation backends) ─────────────────────────────── +# NOTE: this router also serves the CLI-provider config API below +# (which AI CLI each role runs on). "Media providers" is the separate +# concept of which backend renders media: Google Flow, the assistant +# (Pax), or any registered HTTP-capable provider. Kept on the same +# /api/providers prefix because the preflight docs point here. + +@router.get("/status") +async def get_media_provider_status(): + """Status of every registered media provider (generation backend). + + Returns name, display name, availability, and capabilities + (including per-provider throttling limits: max_concurrent, + cooldown_s). Flow is available only while the Chrome extension is + connected; the assistant backend needs no Chrome. + """ + from agent.sdk.services.operations import get_operations + return { + "default": config.DEFAULT_PROVIDER, + "providers": get_operations().registry.status(), + } + + def _read() -> dict: """Read providers.json and hot-reload it into `config.CLI_PROVIDERS`. @@ -112,8 +135,9 @@ async def get_providers(live: bool = False): data = _read() statuses = {} for name, binary in PROVIDER_BINARIES.items(): - installed = shutil.which(binary) is not None - tested, error = (await _probe_version(binary)) if (live and installed) else (None, None) + # `muse` is the assistant itself — always available, no binary to probe. + installed = True if binary is None else shutil.which(binary) is not None + tested, error = (await _probe_version(binary)) if (live and installed and binary) else (None, None) statuses[name] = { "binary": binary, "installed": installed, @@ -182,6 +206,8 @@ async def patch_providers(body: dict): provider = body["active"] if provider not in PROVIDER_BINARIES: raise HTTPException(400, f"Unknown provider '{provider}'. Known: {list(PROVIDER_BINARIES)}") + if PROVIDER_BINARIES[provider] is None: + raise HTTPException(400, f"'{provider}' has no CLI binary — it is only valid as a per-role provider, not as the active default") if not shutil.which(PROVIDER_BINARIES[provider]): raise HTTPException(400, f"'{PROVIDER_BINARIES[provider]}' binary not found on PATH — install it first") data["active"] = provider diff --git a/agent/api/reviews.py b/agent/api/reviews.py index d5e7fcf87..2165586b6 100644 --- a/agent/api/reviews.py +++ b/agent/api/reviews.py @@ -1,11 +1,38 @@ """FastAPI router for video review endpoints.""" import logging +from pathlib import Path from typing import Optional from fastapi import APIRouter, HTTPException, Query, Request -from agent.models.review import VideoReview, SceneReview -from agent.services.video_reviewer import review_video, review_scene_video -from agent.db.crud import get_video, get_scene, get_project_characters, list_scenes +from agent.config import BASE_DIR +from agent.utils.slugify import slugify +from agent.models.review import ( + VideoReview, + SceneReview, + RegenerateAfterReviewRequest, + RegenerateAfterReviewResponse, + SceneRegenDecision, + SceneScoreInput, + ReviewSheetsRequest, + ReviewSheetInfo, + ReviewSheetsResponse, + ReviewSubmitRequest, +) +from agent.services.video_reviewer import ( + review_video, + review_scene_video, + prepare_review_sheets, + score_review_answer, +) +from agent.db.crud import ( + get_video, + get_scene, + get_project, + get_project_characters, + list_scenes, + create_request, + list_requests, +) logger = logging.getLogger(__name__) @@ -20,7 +47,7 @@ async def review_video_endpoint( orientation: Optional[str] = Query(None, description="Orientation: VERTICAL or HORIZONTAL (auto-detected if omitted)"), scene_ids: Optional[str] = Query(None, description="Comma-separated scene IDs to review (omit for all)"), ): - """Review all scene videos in a video using Claude Vision frame analysis.""" + """Review all scene videos in a video using AI vision frame analysis.""" if mode not in ("light", "deep"): raise HTTPException(400, "mode must be 'light' or 'deep'") if orientation and orientation.upper() not in ("VERTICAL", "HORIZONTAL"): @@ -50,6 +77,121 @@ async def review_video_endpoint( return result +@router.post("/{vid}/review-regenerate", response_model=RegenerateAfterReviewResponse) +async def review_and_regenerate_endpoint(vid: str, body: RegenerateAfterReviewRequest): + """Review scene videos, then enqueue REGENERATE_VIDEO for bad scenes. + + Bounded: at most ``max_regenerations`` regen requests are ever enqueued + per scene. The worker queue picks the new requests up; regeneration goes + through the same provider path as the original generation. + + When ``body.scores`` is provided (Muse-scored review), the + CLI/SDK review is skipped and the VideoReview is computed from those + scores instead. + """ + if body.mode not in ("light", "deep"): + raise HTTPException(400, "mode must be 'light' or 'deep'") + if body.max_regenerations < 0: + raise HTTPException(400, "max_regenerations must be >= 0") + + video = await get_video(vid) + if not video: + raise HTTPException(404, "Video not found") + + orientation = (body.orientation or video.get("orientation") or "VERTICAL").upper() + if orientation not in ("VERTICAL", "HORIZONTAL"): + raise HTTPException(400, "orientation must be 'VERTICAL' or 'HORIZONTAL'") + + if body.scores is not None: + review = _review_from_scores( + vid, body.project_id, body.mode, orientation, body.scores) + else: + try: + review = await review_video( + vid, body.project_id, mode=body.mode, + orientation=orientation, scene_ids=body.scene_ids) + except Exception as e: + logger.exception("Review failed for video %s: %s", vid, e) + raise HTTPException(500, f"Review failed: {e}") + + decisions = await _decide_regenerations(review, body, vid, orientation) + return RegenerateAfterReviewResponse(review=review, decisions=decisions) + + +def _review_from_scores( + vid: str, project_id: str, mode: str, orientation: str, + scores: list[SceneScoreInput], +) -> VideoReview: + """Compute a VideoReview from Muse-submitted scores. + + Same validation, severity rules, CRITICAL caps, and overall computation + as every other reviewer backend. + """ + from agent.services.video_reviewer import _verdict + + scene_reviews = [] + for s in scores: + try: + scene_reviews.append(score_review_answer( + s.scene_id, + {"dimensions": s.dimensions.model_dump(), + "errors": [e.model_dump() for e in s.errors], + "usable_segments": [sg.model_dump() for sg in s.usable_segments]}, + s.n_frames, s.fps, + )) + except Exception as e: + raise HTTPException(400, f"Invalid score for scene {s.scene_id}: {e}") + if not scene_reviews: + raise HTTPException(400, "scores must not be empty") + overall = sum(r.overall_score for r in scene_reviews) / len(scene_reviews) + return VideoReview( + video_id=vid, project_id=project_id, mode=mode, orientation=orientation, + overall_score=overall, verdict=_verdict(overall), + scene_reviews=scene_reviews, + scenes_reviewed=len(scene_reviews), scenes_skipped=0, + ) + + +async def _decide_regenerations( + review: VideoReview, body: RegenerateAfterReviewRequest, + vid: str, orientation: str, +) -> list[SceneRegenDecision]: + """Enqueue REGENERATE_VIDEO for bad/critical scenes, bounded per scene.""" + bad = {v.strip().lower() for v in body.bad_verdicts} + decisions: list[SceneRegenDecision] = [] + for sr in review.scene_reviews: + if sr.verdict.lower() not in bad and not sr.has_critical_errors: + decisions.append(SceneRegenDecision( + scene_id=sr.scene_id, verdict=sr.verdict, + regenerated=False, reason="verdict acceptable")) + continue + + past = [r for r in await list_requests(scene_id=sr.scene_id) + if r.get("type") == "REGENERATE_VIDEO"] + if len(past) >= body.max_regenerations: + decisions.append(SceneRegenDecision( + scene_id=sr.scene_id, verdict=sr.verdict, + regenerated=False, + reason=f"bound reached ({len(past)} >= {body.max_regenerations})")) + continue + + scene = await get_scene(sr.scene_id) + if not scene or not scene.get( + f"{'vertical' if orientation == 'VERTICAL' else 'horizontal'}_image_media_id"): + decisions.append(SceneRegenDecision( + scene_id=sr.scene_id, verdict=sr.verdict, + regenerated=False, reason="no scene image to regenerate from")) + continue + + req = await create_request( + "REGENERATE_VIDEO", orientation=orientation, scene_id=sr.scene_id, + video_id=vid, project_id=body.project_id, provider=body.provider) + decisions.append(SceneRegenDecision( + scene_id=sr.scene_id, verdict=sr.verdict, + regenerated=True, request_id=req["id"])) + return decisions + + @router.post("/{vid}/scenes/{sid}/review", response_model=SceneReview) async def review_scene_endpoint( vid: str, @@ -58,7 +200,7 @@ async def review_scene_endpoint( mode: str = Query("light", description="Review mode: light (4fps) or deep (8fps)"), orientation: Optional[str] = Query(None, description="Orientation: VERTICAL or HORIZONTAL (auto-detected if omitted)"), ): - """Review a single scene video using Claude Vision frame analysis.""" + """Review a single scene video using AI vision frame analysis.""" if mode not in ("light", "deep"): raise HTTPException(400, "mode must be 'light' or 'deep'") if orientation and orientation.upper() not in ("VERTICAL", "HORIZONTAL"): @@ -109,3 +251,78 @@ async def _detect_orientation(video_id: str) -> str: if scene.get("vertical_image_status") == "COMPLETED": return "VERTICAL" return "VERTICAL" + + +@router.post("/{vid}/review-sheets", response_model=ReviewSheetsResponse) +async def review_sheets_endpoint(vid: str, body: ReviewSheetsRequest): + """Build contact sheets for Muse review — no AI CLI needed. + + Extracts frames and tiles them into contact sheets persisted under the + project's ``review/sheets/`` dir, then returns the sheet paths plus the + rubric prompt the reviewer should answer. Muse reads the sheets, scores + each scene, and submits via ``POST .../review-submit``. + """ + if body.mode not in ("light", "deep"): + raise HTTPException(400, "mode must be 'light' or 'deep'") + + video = await get_video(vid) + if not video: + raise HTTPException(404, "Video not found") + project = await get_project(body.project_id) + if not project: + raise HTTPException(404, "Project not found") + + orientation = (body.orientation or video.get("orientation") or "VERTICAL").upper() + if orientation not in ("VERTICAL", "HORIZONTAL"): + raise HTTPException(400, "orientation must be 'VERTICAL' or 'HORIZONTAL'") + + name = project["name"] if isinstance(project, dict) else project.name + persist = BASE_DIR / "output" / slugify(name) / "review" / "sheets" + persist.mkdir(parents=True, exist_ok=True) + + scenes = await list_scenes(vid) + if body.scene_ids: + wanted = set(body.scene_ids) + scenes = [s for s in scenes if s["id"] in wanted] + characters = await get_project_characters(body.project_id) + + infos: list[ReviewSheetInfo] = [] + skipped = 0 + for scene in sorted(scenes, key=lambda s: s.get("display_order", 0)): + try: + info = await prepare_review_sheets( + scene, characters, body.mode, orientation, persist) + except (ValueError, RuntimeError) as e: + logger.warning("Skipping scene %s for review sheets: %s", scene["id"], e) + skipped += 1 + continue + infos.append(ReviewSheetInfo(**info)) + + return ReviewSheetsResponse( + video_id=vid, project_id=body.project_id, mode=body.mode, + orientation=orientation, sheets=infos, scenes_skipped=skipped, + ) + + +@router.post("/{vid}/review-submit", response_model=VideoReview) +async def review_submit_endpoint(vid: str, body: ReviewSubmitRequest): + """Submit Muse's per-scene scores; the server computes the review. + + Accepts the same JSON shape a CLI reviewer returns (dimensions, errors, + usable_segments) and applies identical validation, severity rules, + CRITICAL caps, and overall computation. Feed the result into + ``POST .../review-regenerate`` via its ``scores`` field to auto-regenerate + bad scenes. + """ + if body.mode not in ("light", "deep"): + raise HTTPException(400, "mode must be 'light' or 'deep'") + + video = await get_video(vid) + if not video: + raise HTTPException(404, "Video not found") + + orientation = (body.orientation or video.get("orientation") or "VERTICAL").upper() + if orientation not in ("VERTICAL", "HORIZONTAL"): + raise HTTPException(400, "orientation must be 'VERTICAL' or 'HORIZONTAL'") + + return _review_from_scores(vid, body.project_id, body.mode, orientation, body.scores) diff --git a/agent/api/tts.py b/agent/api/tts.py index e2d3d068f..680de8bd6 100644 --- a/agent/api/tts.py +++ b/agent/api/tts.py @@ -66,10 +66,18 @@ def _validate_ref_audio(ref_audio: str) -> None: @router.post("/tts/generate", response_model=TTSGenerateResponse) async def tts_generate(body: TTSGenerateRequest): - """Generate speech for a single text string. Returns path to WAV file.""" + """Generate speech for a single text string. Returns path to WAV file. + + provider="local" (default) uses the bundled TTS engine; any other + provider name dispatches a provider job (kind=audio) to an external + worker via the media provider registry. + """ if body.ref_audio: _validate_ref_audio(body.ref_audio) + if body.provider and body.provider.strip().lower() != "local": + return await _tts_generate_via_provider(body) + SHARED_OUTPUT_DIR.mkdir(parents=True, exist_ok=True) import uuid as _uuid out_path = str(SHARED_OUTPUT_DIR / f"{_uuid.uuid4()}.wav") @@ -92,6 +100,59 @@ async def tts_generate(body: TTSGenerateRequest): return TTSGenerateResponse(audio_path=audio_path, duration=duration) +async def _tts_generate_via_provider(body: TTSGenerateRequest) -> TTSGenerateResponse: + """Dispatch TTS to a media provider (provider-job queue + external worker).""" + from agent.config import DEFAULT_PROVIDER + from agent.sdk.services.operations import get_operations + from agent.sdk.services.provider_base import KIND_AUDIO, ProviderJob + + provider_name = (body.provider or DEFAULT_PROVIDER).strip().lower() + registry = get_operations().registry + provider = registry.get(provider_name) + if provider is None: + raise HTTPException(400, f"Unknown provider '{provider_name}' (available: {registry.names()})") + + import uuid as _uuid + + job = ProviderJob( + job_id=f"tts-{_uuid.uuid4().hex[:12]}", + kind=KIND_AUDIO, + prompt=body.text, + orientation="VERTICAL", # unused for audio; required field + extra={"instruct": body.instruct, "ref_audio": body.ref_audio, + "ref_text": body.ref_text, "speed": body.speed}, + ) + blocked = provider.check(job) + if blocked: + raise HTTPException(400, blocked) + + raw = await provider.run(job) + if raw.get("error"): + raise HTTPException(502, raw["error"]) + data = raw.get("data") or {} + url = data.get("url") or "" + audio_path = data.get("audio_path") or url + + if url.startswith("http"): + # Download remote audio into the shared output dir. + SHARED_OUTPUT_DIR.mkdir(parents=True, exist_ok=True) + import uuid as _uuid + dest = SHARED_OUTPUT_DIR / f"provider_tts_{_uuid.uuid4()}.wav" + try: + await asyncio.to_thread(_download_url, url, str(dest)) + audio_path = str(dest) + except Exception as e: + raise HTTPException(502, f"Failed to download provider audio: {e}") + + duration = _wav_duration(audio_path) if audio_path else None + return TTSGenerateResponse(audio_path=audio_path or url, duration=duration) + + +def _download_url(url: str, dest: str) -> None: + import urllib.request + urllib.request.urlretrieve(url, dest) + + @router.post("/videos/{vid}/narrate", response_model=NarrateVideoResponse) async def narrate_video(vid: str, body: NarrateVideoRequest): """Generate narration WAVs for all scenes in a video and optionally mix into video files.""" diff --git a/agent/api/videos.py b/agent/api/videos.py index 1a57e5c5d..bfc5be79a 100644 --- a/agent/api/videos.py +++ b/agent/api/videos.py @@ -1,7 +1,30 @@ +import asyncio +import logging +import shutil +import tempfile +import urllib.request +from pathlib import Path +from typing import Optional +from urllib.parse import urlparse + from fastapi import APIRouter, HTTPException +from pydantic import BaseModel, Field + +from agent.config import OUTPUT_DIR +from agent.db import crud from agent.models.video import Video, VideoCreate, VideoUpdate from agent.sdk.persistence.sqlite_repository import SQLiteRepository -from dataclasses import asdict +from agent.services.post_process import ( + add_music, + add_narration, + merge_videos, + normalize_clip, + probe_duration, + trim_video, +) +from agent.utils.slugify import slugify + +logger = logging.getLogger(__name__) router = APIRouter(prefix="/videos", tags=["videos"]) @@ -22,6 +45,7 @@ def _video_to_flat(sdk_video) -> dict: "horizontal_url": sdk_video.horizontal_url, "thumbnail_url": sdk_video.thumbnail_url, "duration": sdk_video.duration, + "target_duration_s": sdk_video.target_duration_s, "resolution": sdk_video.resolution, "youtube_id": sdk_video.youtube_id, "privacy": sdk_video.privacy, @@ -65,3 +89,203 @@ async def delete(vid: str): if not await _repo.delete("video", vid): raise HTTPException(404, "Video not found") return {"ok": True} + + +# ── Concat / finalize ────────────────────────────────────────────────── + +class ConcatRequest(BaseModel): + orientation: Optional[str] = Field(None, description="VERTICAL|HORIZONTAL; defaults to the video's orientation") + target_duration_s: Optional[float] = Field(None, gt=0, description="Trim the merged video to this length") + output_filename: Optional[str] = None + + +class ConcatResponse(BaseModel): + video_id: str + output_path: str + url: str + duration: Optional[float] = None + target_duration_s: Optional[float] = None + trimmed: bool = False + scenes_used: int = 0 + scenes_missing: list[str] = [] + + +class FinalizeRequest(BaseModel): + orientation: Optional[str] = None + target_duration_s: Optional[float] = Field(None, gt=0) + music_path: Optional[str] = None + narration_path: Optional[str] = None + music_volume: float = 0.3 + + +class FinalizeResponse(BaseModel): + video_id: str + output_path: str + url: str + duration: Optional[float] = None + status: str = "COMPLETED" + steps: list[str] = [] + + +def _resolve_media_local(url: str, tmpdir: Path) -> Optional[str]: + """Resolve a media URL to a local file path (downloading http(s) when needed).""" + if not url: + return None + parsed = urlparse(url) + if parsed.scheme == "file": + p = Path(parsed.path) + return str(p) if p.is_file() else None + if parsed.scheme in ("http", "https"): + dest = tmpdir / f"dl_{abs(hash(url)) % 10**8}{Path(parsed.path).suffix or '.mp4'}" + try: + urllib.request.urlretrieve(url, dest) + return str(dest) + except Exception as e: + logger.warning("concat: failed to download %s: %s", url, e) + return None + p = Path(url) + return str(p) if p.is_file() else None + + +async def _assemble_video(vid: str, orientation: Optional[str], + target_duration_s: Optional[float], + output_filename: Optional[str], + tag: str) -> dict: + """Concat scene clips for one orientation; returns assembly details.""" + sdk_video = await _repo.get_video(vid) + if not sdk_video: + raise HTTPException(404, "Video not found") + + orientation = (orientation or sdk_video.orientation or "VERTICAL").upper() + if orientation not in ("VERTICAL", "HORIZONTAL"): + raise HTTPException(400, "orientation must be VERTICAL or HORIZONTAL") + + scenes = await crud.list_scenes(vid) + if not scenes: + raise HTTPException(404, "No scenes found for video") + + project = await crud.get_project(sdk_video.project_id) + project_slug = slugify((project or {}).get("name") or "project") + out_dir = OUTPUT_DIR / project_slug / "final" + out_dir.mkdir(parents=True, exist_ok=True) + + url_key = f"{orientation.lower()}_video_url" + tmpdir = Path(tempfile.mkdtemp(prefix="concat_")) + clips: list[str] = [] + missing: list[str] = [] + try: + for scene in scenes: + local = await asyncio.to_thread( + _resolve_media_local, scene.get(url_key), tmpdir) + if not local: + missing.append(scene["id"]) + continue + norm = tmpdir / f"norm_{scene['id']}.mp4" + ok = await asyncio.to_thread(normalize_clip, local, str(norm)) + if not ok: + missing.append(scene["id"]) + continue + clips.append(str(norm)) + + if not clips: + raise HTTPException( + 400, f"No usable {orientation.lower()} clips " + f"({len(missing)} scenes missing video)") + + fname = output_filename or f"{slugify(sdk_video.title) or 'video'}_{tag}_{orientation.lower()}.mp4" + final_path = out_dir / fname + merged = await asyncio.to_thread(merge_videos, clips, str(final_path)) + if not merged: + raise HTTPException(502, "ffmpeg concat failed") + + duration = await asyncio.to_thread(probe_duration, str(final_path)) + target = target_duration_s or sdk_video.target_duration_s + trimmed = False + if target and duration and duration > target: + trimmed_path = out_dir / f"{final_path.stem}_trimmed.mp4" + ok = await asyncio.to_thread( + trim_video, str(final_path), str(trimmed_path), 0, target) + if ok: + final_path = trimmed_path + duration = target + trimmed = True + else: + logger.warning("concat: trim to %ss failed, keeping full length", target) + + url = "file://" + str(final_path.resolve()) + updates: dict = {f"{orientation.lower()}_url": url, "duration": duration} + if target is not None: + updates["target_duration_s"] = target + await crud.update_video(vid, **updates) + return { + "video_id": vid, + "output_path": str(final_path), + "url": url, + "duration": duration, + "target_duration_s": target, + "trimmed": trimmed, + "scenes_used": len(clips), + "scenes_missing": missing, + } + finally: + shutil.rmtree(tmpdir, ignore_errors=True) + + +@router.post("/{vid}/concat", response_model=ConcatResponse) +async def concat_video(vid: str, body: ConcatRequest): + """Merge scene clips (display_order) into one video file. + + Provider-neutral: clips may be file:// URLs (assistant provider) or + https:// URLs (Flow) — remote clips are downloaded first and every clip + is normalized to uniform h264/AAC before concat. + """ + return await _assemble_video( + vid, body.orientation, body.target_duration_s, + body.output_filename, tag="concat") + + +@router.post("/{vid}/finalize", response_model=FinalizeResponse) +async def finalize_video(vid: str, body: FinalizeRequest): + """Full finish: concat (+ optional trim) → music/narration mix → COMPLETED.""" + asm = await _assemble_video( + vid, body.orientation, body.target_duration_s, None, tag="final") + steps = [f"concat ({asm['scenes_used']} scenes)"] + if asm["trimmed"]: + steps.append(f"trimmed to {asm['target_duration_s']}s") + + final_path = Path(asm["output_path"]) + if body.music_path: + mixed = final_path.parent / f"{final_path.stem}_music.mp4" + ok = await asyncio.to_thread( + add_music, str(final_path), body.music_path, str(mixed), + body.music_volume) + if not ok: + raise HTTPException(502, "ffmpeg music mix failed") + final_path = mixed + steps.append("music mix") + if body.narration_path: + mixed = final_path.parent / f"{final_path.stem}_narrated.mp4" + ok = await asyncio.to_thread( + add_narration, str(final_path), body.narration_path, str(mixed)) + if not ok: + raise HTTPException(502, "ffmpeg narration mix failed") + final_path = mixed + steps.append("narration mix") + + duration = await asyncio.to_thread(probe_duration, str(final_path)) + url = "file://" + str(final_path.resolve()) + orientation = (body.orientation or "").upper() + updates: dict = {"status": "COMPLETED"} + if duration is not None: + updates["duration"] = duration + if orientation in ("VERTICAL", "HORIZONTAL"): + updates[f"{orientation.lower()}_url"] = url + else: + # keep the concat orientation's URL in sync + key = "vertical_url" if "_vertical" in asm["output_path"] else "horizontal_url" + updates[key] = url + await crud.update_video(vid, **updates) + + return FinalizeResponse( + video_id=vid, output_path=str(final_path), url=url, + duration=duration, steps=steps) diff --git a/agent/config.py b/agent/config.py index bebbcc954..9c72cfc25 100644 --- a/agent/config.py +++ b/agent/config.py @@ -52,13 +52,32 @@ # are fixed — so it is only carried for the DB column and the dashboard. DEFAULT_PAYGATE_TIER = os.environ.get("DEFAULT_PAYGATE_TIER", "PAYGATE_TIER_TWO") +# ─── Media Provider ───────────────────────────────────────── +# "flow" (default): generate via Google Flow through the Chrome extension. +# "assistant": route all generation to the AI assistant instead — each request +# is published as a row in the provider_job table and the worker waits for an +# external worker (the assistant) to claim and complete it via +# /api/provider-jobs. See agent/sdk/services/assistant_provider.py and +# agent/worker/assistant_worker.py for the full protocol. +# Default media provider for requests that don't specify one ("flow" | +# "assistant" | any registered provider name). MEDIA_PROVIDER is kept as a +# legacy alias — DEFAULT_PROVIDER wins if both are set. +DEFAULT_PROVIDER = os.environ.get( + "DEFAULT_PROVIDER", os.environ.get("MEDIA_PROVIDER", "flow") +).strip().lower() +MEDIA_PROVIDER = DEFAULT_PROVIDER # legacy alias +ASSISTANT_PROVIDER_TIMEOUT_S = int(os.environ.get("ASSISTANT_PROVIDER_TIMEOUT_S", "1800")) +ASSISTANT_PROVIDER_POLL_S = int(os.environ.get("ASSISTANT_PROVIDER_POLL_S", "15")) +ASSISTANT_MAX_CONCURRENT = int(os.environ.get("ASSISTANT_MAX_CONCURRENT", "2")) +ASSISTANT_COOLDOWN_S = float(os.environ.get("ASSISTANT_COOLDOWN_S", "0")) + # ─── Worker ────────────────────────────────────────────────── POLL_INTERVAL = int(os.environ.get("POLL_INTERVAL", "5")) VIDEO_POLL_INTERVAL = int(os.environ.get("VIDEO_POLL_INTERVAL", "10")) # polling interval for video/upscale status MAX_RETRIES = int(os.environ.get("MAX_RETRIES", "5")) VIDEO_POLL_TIMEOUT = int(os.environ.get("VIDEO_POLL_TIMEOUT", "420")) -API_COOLDOWN = int(os.environ.get("API_COOLDOWN", "10")) # seconds between API calls (anti-spam) -MAX_CONCURRENT_REQUESTS = int(os.environ.get("MAX_CONCURRENT_REQUESTS", "5")) # Google Flow max parallel requests +API_COOLDOWN = int(os.environ.get("API_COOLDOWN", "10")) # DEPRECATED: per-provider cooldown_s in provider capabilities is authoritative +MAX_CONCURRENT_REQUESTS = int(os.environ.get("MAX_CONCURRENT_REQUESTS", "5")) # DEPRECATED: per-provider max_concurrent in provider capabilities is authoritative STALE_PROCESSING_TIMEOUT = int(os.environ.get("STALE_PROCESSING_TIMEOUT", "600")) # 10 min # ─── Model Keys (loaded from models.json for easy updates) ── diff --git a/agent/db/crud.py b/agent/db/crud.py index 51f7a1d45..a9ae2b1ac 100644 --- a/agent/db/crud.py +++ b/agent/db/crud.py @@ -1,6 +1,8 @@ """Async CRUD operations with column whitelisting.""" +import asyncio import json import logging +import time import uuid from datetime import datetime, timezone from typing import Optional @@ -8,7 +10,7 @@ logger = logging.getLogger(__name__) -_VALID_TABLES = frozenset({"character", "project", "video", "scene", "request", "material"}) +_VALID_TABLES = frozenset({"character", "project", "video", "scene", "request", "material", "provider_job"}) def _validate_table(table: str) -> None: @@ -20,7 +22,7 @@ def _validate_table(table: str) -> None: "character": {"name", "slug", "entity_type", "description", "image_prompt", "voice_description", "reference_image_url", "media_id", "updated_at"}, "project": {"name", "description", "story", "thumbnail_url", "language", "status", "user_paygate_tier", "narrator_voice", "narrator_ref_audio", "material", "allow_music", "allow_voice", "updated_at"}, "video": {"title", "description", "display_order", "status", "orientation", "vertical_url", "horizontal_url", - "thumbnail_url", "duration", "resolution", "youtube_id", "privacy", "tags", "updated_at"}, + "thumbnail_url", "duration", "target_duration_s", "resolution", "youtube_id", "privacy", "tags", "updated_at"}, "scene": {"prompt", "image_prompt", "video_prompt", "character_names", "parent_scene_id", "chain_type", "vertical_image_url", "vertical_image_media_id", "vertical_image_status", "vertical_video_url", "vertical_video_media_id", "vertical_video_status", @@ -31,6 +33,9 @@ def _validate_table(table: str) -> None: "vertical_end_scene_media_id", "horizontal_end_scene_media_id", "trim_start", "trim_end", "duration", "display_order", "source", "transition_prompt", "narrator_text", "updated_at"}, "request": {"status", "request_id", "media_id", "output_url", "error_message", "retry_count", "next_retry_at", "source_media_id", "updated_at"}, + "provider_job": {"provider", "kind", "status", "prompt", "orientation", "source_url", "end_url", "extra", + "claimed_by", "claimed_at", "lease_expires_at", "progress", "progress_message", + "result", "error_message", "retry_count", "updated_at"}, } @@ -161,13 +166,14 @@ async def get_project_characters(project_id: str) -> list[dict]: # ─── Video ────────────────────────────────────────────────── -async def create_video(project_id: str, title: str, description: str = None, display_order: int = 0, orientation: str = None) -> dict: +async def create_video(project_id: str, title: str, description: str = None, display_order: int = 0, orientation: str = None, + target_duration_s: float = None) -> dict: db = await get_db() vid, now = _uuid(), _now() async with _db_lock: await db.execute( - "INSERT INTO video (id,project_id,title,description,display_order,orientation,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?)", - (vid, project_id, title, description, display_order, orientation, now, now)) + "INSERT INTO video (id,project_id,title,description,display_order,orientation,target_duration_s,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?)", + (vid, project_id, title, description, display_order, orientation, target_duration_s, now, now)) await db.commit() return await _get_with_db(db, "video", "id", vid) @@ -235,14 +241,17 @@ async def list_characters_by_media_id(media_id: str) -> list[dict]: async def create_request(req_type: str, orientation: str = None, scene_id: str = None, character_id: str = None, project_id: str = None, video_id: str = None, - source_media_id: str = None, **_kw) -> dict: + source_media_id: str = None, provider: str = None, + **_kw) -> dict: + from agent.config import DEFAULT_PROVIDER db = await get_db() rid, now = _uuid(), _now() + prov = (provider or DEFAULT_PROVIDER).strip().lower() async with _db_lock: await db.execute( - """INSERT INTO request (id,project_id,video_id,scene_id,character_id,type,orientation,source_media_id,created_at,updated_at) - VALUES (?,?,?,?,?,?,?,?,?,?)""", - (rid, project_id, video_id, scene_id, character_id, req_type, orientation, source_media_id, now, now)) + """INSERT INTO request (id,project_id,video_id,scene_id,character_id,type,orientation,source_media_id,provider,created_at,updated_at) + VALUES (?,?,?,?,?,?,?,?,?,?,?)""", + (rid, project_id, video_id, scene_id, character_id, req_type, orientation, source_media_id, prov, now, now)) await db.commit() return await _get_with_db(db, "request", "id", rid) @@ -338,3 +347,245 @@ async def list_materials() -> list[dict]: db = await get_db() cur = await db.execute("SELECT * FROM material ORDER BY created_at") return [dict(r) for r in await cur.fetchall()] + + +# --------------------------------------------------------------------------- +# Provider jobs — persistent handoff queue for external media providers/agents +# --------------------------------------------------------------------------- +# Lifecycle: QUEUED -> CLAIMED -> RUNNING -> SUCCEEDED | FAILED | CANCELLED. +# A worker claims a job with a lease (claim + heartbeat extends it). If the +# lease expires, any worker may reclaim the job — crashed workers never +# strand jobs. Only the worker holding the lease may heartbeat/progress/ +# complete/fail. + +TERMINAL_JOB_STATUSES = frozenset({"SUCCEEDED", "FAILED", "CANCELLED"}) + + +def _lease_expiry_str(ttl_s: float) -> str: + return datetime.fromtimestamp( + datetime.now(timezone.utc).timestamp() + ttl_s, + tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") + + +async def create_provider_job(provider: str, kind: str, prompt: str = "", + orientation: str = None, source_url: str = None, + start_url: str = None, + end_url: str = None, extra: dict = None, + job_id: str = None) -> dict: + """Create a QUEUED provider job. Returns the row.""" + db = await get_db() + jid = job_id or uuid.uuid4().hex[:12] + now = _now() + async with _db_lock: + await db.execute( + """INSERT INTO provider_job + (id, provider, kind, status, prompt, orientation, source_url, start_url, end_url, extra, created_at, updated_at) + VALUES (?,?,?,?,?,?,?,?,?,?,?,?)""", + (jid, provider.strip().lower(), kind, "QUEUED", prompt or "", + orientation, source_url, start_url, end_url, + json.dumps(extra or {}), now, now)) + await db.commit() + return await _get_with_db(db, "provider_job", "id", jid) + + +async def get_provider_job(job_id: str) -> Optional[dict]: + return await _get("provider_job", "id", job_id) + + +async def list_provider_jobs(provider: str = None, status: str = None, + limit: int = 100) -> list[dict]: + db = await get_db() + q, params = "SELECT * FROM provider_job WHERE 1=1", [] + if provider: + q += " AND provider=?"; params.append(provider.strip().lower()) + if status: + q += " AND status=?"; params.append(status) + q += " ORDER BY created_at DESC LIMIT ?"; params.append(limit) + cur = await db.execute(q, params) + return [dict(r) for r in await cur.fetchall()] + + +async def claim_provider_job(job_id: str, worker_id: str, + lease_ttl_s: float = 300) -> Optional[dict]: + """Claim a QUEUED job, or reclaim one whose lease expired. + + Atomic single UPDATE guarded by status/lease — returns the updated row, + or None when the job isn't claimable (already held by a live worker, + terminal, or missing). + """ + db = await get_db() + now, expiry = _now(), _lease_expiry_str(lease_ttl_s) + async with _db_lock: + cur = await db.execute( + """UPDATE provider_job + SET status='CLAIMED', claimed_by=?, claimed_at=?, lease_expires_at=?, + updated_at=?, retry_count=retry_count+1 + WHERE id=? + AND status NOT IN ('SUCCEEDED','FAILED','CANCELLED') + AND (status='QUEUED' + OR (status IN ('CLAIMED','RUNNING') + AND (lease_expires_at IS NULL OR lease_expires_at <= ?)))""", + (worker_id, now, expiry, now, job_id, now)) + await db.commit() + if cur.rowcount == 0: + return None + return await _get_with_db(db, "provider_job", "id", job_id) + + +async def heartbeat_provider_job(job_id: str, worker_id: str, + lease_ttl_s: float = 300) -> Optional[dict]: + """Extend the lease. Only the lease holder may heartbeat a live job.""" + db = await get_db() + now, expiry = _now(), _lease_expiry_str(lease_ttl_s) + async with _db_lock: + cur = await db.execute( + """UPDATE provider_job + SET lease_expires_at=?, updated_at=?, + status=CASE WHEN status='CLAIMED' THEN 'RUNNING' ELSE status END + WHERE id=? AND claimed_by=? + AND status IN ('CLAIMED','RUNNING')""", + (expiry, now, job_id, worker_id)) + await db.commit() + if cur.rowcount == 0: + return None + return await _get_with_db(db, "provider_job", "id", job_id) + + +async def update_provider_job_progress(job_id: str, worker_id: str, progress: int, + message: str = None) -> Optional[dict]: + """Report progress. Only the lease holder may do this on a live job. + + Returns the row, or None when the caller doesn't hold the lease or the + job isn't live (CLAIMED/RUNNING). + """ + db = await get_db() + now = _now() + async with _db_lock: + cur = await db.execute( + """UPDATE provider_job + SET progress=?, progress_message=?, updated_at=? + WHERE id=? AND claimed_by=? + AND status IN ('CLAIMED','RUNNING')""", + (max(0, min(100, int(progress))), message, now, + job_id, worker_id)) + await db.commit() + if cur.rowcount == 0: + return None + return await _get_with_db(db, "provider_job", "id", job_id) + + +async def complete_provider_job(job_id: str, worker_id: str, + result: dict = None) -> Optional[dict]: + """Complete a job as its lease holder. + + Idempotent: the lease holder re-completing an already-SUCCEEDED job gets + the existing row back (safe retry after a lost response). Returns None + when the caller never held the lease or the job ended in another + terminal state. + """ + db = await get_db() + now = _now() + async with _db_lock: + cur = await db.execute( + """UPDATE provider_job + SET status='SUCCEEDED', result=?, progress=100, + lease_expires_at=NULL, updated_at=? + WHERE id=? AND claimed_by=? + AND status IN ('CLAIMED','RUNNING')""", + (json.dumps(result or {}), now, job_id, worker_id)) + await db.commit() + if cur.rowcount == 0: + row = await _get_with_db(db, "provider_job", "id", job_id) + if (row and row.get("status") == "SUCCEEDED" + and row.get("claimed_by") == worker_id): + return row # idempotent retry by the holder + return None + return await _get_with_db(db, "provider_job", "id", job_id) + + +async def fail_provider_job(job_id: str, worker_id: str, + error: str) -> Optional[dict]: + """Fail a job as its lease holder. + + Idempotent for the holder re-failing an already-FAILED job. A SUCCEEDED + or CANCELLED job cannot be failed — returns None. + """ + db = await get_db() + now = _now() + async with _db_lock: + cur = await db.execute( + """UPDATE provider_job + SET status='FAILED', error_message=?, + lease_expires_at=NULL, updated_at=? + WHERE id=? AND claimed_by=? + AND status IN ('CLAIMED','RUNNING')""", + (error, now, job_id, worker_id)) + await db.commit() + if cur.rowcount == 0: + row = await _get_with_db(db, "provider_job", "id", job_id) + if (row and row.get("status") == "FAILED" + and row.get("claimed_by") == worker_id): + return row # idempotent retry by the holder + return None + return await _get_with_db(db, "provider_job", "id", job_id) + + +async def cancel_provider_job(job_id: str) -> Optional[dict]: + """Producer-side cancel. Only non-terminal jobs can be cancelled. + + Returns the row, or None when the job is missing or already terminal. + """ + db = await get_db() + now = _now() + async with _db_lock: + cur = await db.execute( + """UPDATE provider_job + SET status='CANCELLED', lease_expires_at=NULL, updated_at=? + WHERE id=? + AND status NOT IN ('SUCCEEDED','FAILED','CANCELLED')""", + (now, job_id)) + await db.commit() + if cur.rowcount == 0: + return None + return await _get_with_db(db, "provider_job", "id", job_id) + + +async def next_queued_provider_job(provider: str, worker_id: str, + lease_ttl_s: float = 300) -> Optional[dict]: + """Find the oldest claimable job for a provider and claim it. + + Claimable = QUEUED, or CLAIMED/RUNNING with an expired lease. + Returns the claimed row, or None when nothing is available. + """ + db = await get_db() + now = _now() + cur = await db.execute( + """SELECT id FROM provider_job + WHERE provider=? + AND (status='QUEUED' + OR (status IN ('CLAIMED','RUNNING') + AND (lease_expires_at IS NULL OR lease_expires_at <= ?))) + ORDER BY created_at ASC LIMIT 1""", + (provider.strip().lower(), now)) + row = await cur.fetchone() + if not row: + return None + return await claim_provider_job(row["id"], worker_id, lease_ttl_s) + + +async def wait_for_provider_job(job_id: str, timeout_s: float = 600, + poll_interval_s: float = 2.0) -> Optional[dict]: + """Block until a provider job reaches a terminal status or timeout. + + Returns the final row, or None on timeout / missing job. + """ + deadline = time.monotonic() + timeout_s + while True: + job = await get_provider_job(job_id) + if job is None: + return None + if job.get("status") in TERMINAL_JOB_STATUSES: + return job + if time.monotonic() >= deadline: + return None + await asyncio.sleep(min(poll_interval_s, max(0.1, deadline - time.monotonic()))) diff --git a/agent/db/schema.py b/agent/db/schema.py index 365ec5d89..3f696daa9 100644 --- a/agent/db/schema.py +++ b/agent/db/schema.py @@ -69,6 +69,7 @@ horizontal_url TEXT, thumbnail_url TEXT, duration REAL, + target_duration_s REAL, -- desired final length; concat/finalize trims to it resolution TEXT, orientation TEXT CHECK(orientation IN ('VERTICAL','HORIZONTAL')), youtube_id TEXT, @@ -149,6 +150,7 @@ next_retry_at TEXT, edit_prompt TEXT, -- prompt for EDIT_IMAGE requests source_media_id TEXT, -- source image media_id for EDIT_IMAGE requests + provider TEXT, -- media provider backend: flow | assistant | ... created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')) ); @@ -158,6 +160,38 @@ CREATE INDEX IF NOT EXISTS idx_request_status ON request(status); CREATE INDEX IF NOT EXISTS idx_request_scene ON request(scene_id); CREATE INDEX IF NOT EXISTS idx_video_project ON video(project_id); + +-- Persistent provider jobs: the handoff queue between the FlowKit worker and +-- external media providers/agents (assistant, HTTP workers, ...). A job is +-- created QUEUED, claimed by a worker (claim/lease), heartbeated while +-- running, then completed/failed/cancelled. Leases expire so crashed workers +-- don't strand jobs — an expired lease is reclaimable. +CREATE TABLE IF NOT EXISTS provider_job ( + id TEXT PRIMARY KEY, -- ProviderJob.job_id + provider TEXT NOT NULL, -- target backend: flow | assistant | ... + kind TEXT NOT NULL, -- image | edit_image | i2v | r2v | upscale + status TEXT NOT NULL DEFAULT 'QUEUED' + CHECK(status IN ('QUEUED','CLAIMED','RUNNING','SUCCEEDED','FAILED','CANCELLED')), + prompt TEXT NOT NULL DEFAULT '', + orientation TEXT, -- VERTICAL | HORIZONTAL + source_url TEXT, -- input image URL (edit_image) + start_url TEXT, -- start frame URL (i2v video) + end_url TEXT, + extra TEXT, -- JSON: provider-specific params + claimed_by TEXT, -- worker id holding the lease + claimed_at TEXT, + lease_expires_at TEXT, -- heartbeat deadline; expired => reclaimable + progress INTEGER NOT NULL DEFAULT 0, + progress_message TEXT, + result TEXT, -- JSON result payload (output_url, media_id, ...) + error_message TEXT, + retry_count INTEGER NOT NULL DEFAULT 0, + created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), + updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')) +); + +CREATE INDEX IF NOT EXISTS idx_provider_job_provider_status ON provider_job(provider, status); +CREATE INDEX IF NOT EXISTS idx_provider_job_lease ON provider_job(lease_expires_at); """ @@ -167,6 +201,12 @@ async def init_db(): await db.execute("PRAGMA journal_mode=WAL") await db.execute("PRAGMA foreign_keys=ON") await db.executescript(SCHEMA) + # Migration: add provider column to request table (per-request media provider) + cursor = await db.execute("PRAGMA table_info(request)") + req_columns = {row[1] for row in await cursor.fetchall()} + if "provider" not in req_columns: + await db.execute("ALTER TABLE request ADD COLUMN provider TEXT") + logger.info("Migrated: added provider column to request table") # Migration: add slug column to character table + backfill cursor = await db.execute("PRAGMA table_info(character)") columns = {row[1] for row in await cursor.fetchall()} @@ -258,6 +298,12 @@ async def init_db(): if "narrator_text" not in scene_columns: await db.execute("ALTER TABLE scene ADD COLUMN narrator_text TEXT") logger.info("Migrated: added narrator_text column to scene table") + # Migration: add start_url to provider_job table (i2v start frame) + cursor = await db.execute("PRAGMA table_info(provider_job)") + pj_columns = {row[1] for row in await cursor.fetchall()} + if "start_url" not in pj_columns: + await db.execute("ALTER TABLE provider_job ADD COLUMN start_url TEXT") + logger.info("Migrated: added start_url column to provider_job table") # Migration: add narrator fields to project table cursor = await db.execute("PRAGMA table_info(project)") project_columns = {row[1] for row in await cursor.fetchall()} @@ -294,6 +340,10 @@ async def init_db(): elif scene[1] == "COMPLETED": await db.execute("UPDATE video SET orientation = 'VERTICAL' WHERE id = ?", (vid,)) logger.info("Migrated: added orientation column to video table with backfill") + # Migration: add target_duration_s to video table + if "target_duration_s" not in video_columns: + await db.execute("ALTER TABLE video ADD COLUMN target_duration_s REAL") + logger.info("Migrated: added target_duration_s column to video table") # Migration: create material table if missing cursor = await db.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='material'") if not await cursor.fetchone(): diff --git a/agent/main.py b/agent/main.py index 7299b4614..aec72ae19 100644 --- a/agent/main.py +++ b/agent/main.py @@ -23,6 +23,7 @@ from agent.api.music import router as music_router from agent.api.models import router as models_router from agent.api.providers import router as providers_router +from agent.api.provider_jobs import router as provider_jobs_router from agent.api.active_project import router as active_project_router from agent.worker.processor import get_worker_controller from agent.services.flow_client import get_flow_client @@ -157,6 +158,7 @@ async def flow_caller_observability(request: Request, call_next): app.include_router(tts_router, prefix="/api") app.include_router(materials_router, prefix="/api") app.include_router(music_router, prefix="/api") +app.include_router(provider_jobs_router, prefix="/api") app.include_router(models_router) app.include_router(providers_router) app.include_router(active_project_router) diff --git a/agent/models/request.py b/agent/models/request.py index 80b7a4b72..fd08ba0ef 100644 --- a/agent/models/request.py +++ b/agent/models/request.py @@ -11,6 +11,7 @@ class RequestCreate(BaseModel): project_id: Optional[str] = None video_id: Optional[str] = None source_media_id: Optional[str] = None + provider: Optional[str] = None # media provider backend: flow | assistant | ... @model_validator(mode="after") def check_required_fields(self) -> "RequestCreate": @@ -46,5 +47,6 @@ class Request(BaseModel): error_message: Optional[str] = None retry_count: int = 0 source_media_id: Optional[str] = None + provider: Optional[str] = None created_at: Optional[str] = None updated_at: Optional[str] = None diff --git a/agent/models/review.py b/agent/models/review.py index 562f2bb14..f1cc80e8a 100644 --- a/agent/models/review.py +++ b/agent/models/review.py @@ -1,5 +1,5 @@ """Pydantic models for video review results.""" -from pydantic import BaseModel +from pydantic import BaseModel, Field from typing import Literal, Optional @@ -54,3 +54,87 @@ class VideoReview(BaseModel): scene_reviews: list[SceneReview] scenes_reviewed: int scenes_skipped: int # no video yet + + +class SceneScoreInput(BaseModel): + """One scene's raw reviewer answer, as Muse scores it. + + Same JSON shape a CLI reviewer returns: dimensions, errors, + usable_segments. The server applies the identical validation, severity + rules, CRITICAL caps, and overall computation as every other backend. + """ + scene_id: str + dimensions: DimensionScores + errors: list[VideoError] = Field(default_factory=list) + usable_segments: list[SegmentScore] = Field(default_factory=list) + n_frames: int = 0 + fps: float = 4.0 + + +class RegenerateAfterReviewRequest(BaseModel): + """Review a video, then enqueue REGENERATE_VIDEO requests for bad scenes. + + Regeneration is bounded: at most ``max_regenerations`` REGENERATE_VIDEO + requests are ever enqueued per scene (counted across all past runs). + """ + project_id: str + mode: str = "light" # light (4fps) | deep (8fps) + orientation: Optional[str] = None # VERTICAL | HORIZONTAL (auto if omitted) + scene_ids: Optional[list[str]] = None + max_regenerations: int = 1 + provider: Optional[str] = None # provider for the regen requests + bad_verdicts: list[str] = Field(default_factory=lambda: ["poor", "unusable"]) + # Assistant-scored review: when present, the CLI/SDK review is skipped and + # the VideoReview is computed from these scores instead. + scores: Optional[list[SceneScoreInput]] = None + + +class SceneRegenDecision(BaseModel): + scene_id: str + verdict: str + regenerated: bool + request_id: Optional[str] = None + reason: Optional[str] = None + + +class ReviewSheetsRequest(BaseModel): + """Build contact sheets for Muse review — no AI CLI involved.""" + project_id: str + mode: str = "light" # light (4fps) | deep (8fps) + orientation: Optional[str] = None # VERTICAL | HORIZONTAL (auto if omitted) + scene_ids: Optional[list[str]] = None + + +class ReviewSheetInfo(BaseModel): + scene_id: str + sheets: list[str] # absolute paths to contact sheet images + n_frames: int + fps: float + timestamped: bool + prompt: str # the rubric prompt the reviewer should answer + scene_prompt: str = "" + video_prompt: str = "" + character_names: list[str] = Field(default_factory=list) + + +class ReviewSheetsResponse(BaseModel): + video_id: str + project_id: str + mode: str + orientation: str + sheets: list[ReviewSheetInfo] + scenes_skipped: int = 0 # no fetchable video + + +class ReviewSubmitRequest(BaseModel): + """Submit Muse's scores; the server computes the review.""" + project_id: str + mode: str = "light" + orientation: Optional[str] = None + scores: list[SceneScoreInput] + + +class RegenerateAfterReviewResponse(BaseModel): + review: VideoReview + decisions: list[SceneRegenDecision] + diff --git a/agent/models/tts.py b/agent/models/tts.py index 6e2975802..0da48ea23 100644 --- a/agent/models/tts.py +++ b/agent/models/tts.py @@ -9,6 +9,11 @@ class TTSGenerateRequest(BaseModel): ref_audio: Optional[str] = Field(None, max_length=500) ref_text: Optional[str] = None speed: float = Field(1.0, ge=0.5, le=3.0) + provider: Optional[str] = Field( + None, + description="'local' (default) or a media provider name — " + "a provider job (kind=audio) is queued for an external worker", + ) class TTSGenerateResponse(BaseModel): diff --git a/agent/models/video.py b/agent/models/video.py index 31c8317f9..0f314f7d0 100644 --- a/agent/models/video.py +++ b/agent/models/video.py @@ -9,6 +9,7 @@ class VideoCreate(BaseModel): description: Optional[str] = None display_order: int = 0 orientation: Optional[str] = None + target_duration_s: Optional[float] = None class VideoUpdate(BaseModel): @@ -21,6 +22,7 @@ class VideoUpdate(BaseModel): horizontal_url: Optional[str] = None thumbnail_url: Optional[str] = None duration: Optional[float] = None + target_duration_s: Optional[float] = None resolution: Optional[str] = None youtube_id: Optional[str] = None privacy: Optional[str] = None @@ -39,6 +41,7 @@ class Video(BaseModel): horizontal_url: Optional[str] = None thumbnail_url: Optional[str] = None duration: Optional[float] = None + target_duration_s: Optional[float] = None resolution: Optional[str] = None youtube_id: Optional[str] = None privacy: str = "unlisted" diff --git a/agent/sdk/models/video.py b/agent/sdk/models/video.py index ff7be123c..b1fc6df56 100644 --- a/agent/sdk/models/video.py +++ b/agent/sdk/models/video.py @@ -27,6 +27,7 @@ class Video(DomainModel): horizontal_url: Optional[str] = None thumbnail_url: Optional[str] = None duration: Optional[float] = None + target_duration_s: Optional[float] = None resolution: Optional[str] = None youtube_id: Optional[str] = None privacy: str = "unlisted" diff --git a/agent/sdk/persistence/sqlite_repository.py b/agent/sdk/persistence/sqlite_repository.py index 368d4c834..84f0c3e75 100644 --- a/agent/sdk/persistence/sqlite_repository.py +++ b/agent/sdk/persistence/sqlite_repository.py @@ -70,6 +70,7 @@ def _row_to_video(self, row: dict[str, Any]) -> Video: horizontal_url=row.get("horizontal_url"), thumbnail_url=row.get("thumbnail_url"), duration=row.get("duration"), + target_duration_s=row.get("target_duration_s"), resolution=row.get("resolution"), youtube_id=row.get("youtube_id"), privacy=row.get("privacy", "unlisted"), @@ -302,6 +303,7 @@ async def save_video(self, video: Video) -> None: horizontal_url=video.horizontal_url, thumbnail_url=video.thumbnail_url, duration=video.duration, + target_duration_s=video.target_duration_s, resolution=video.resolution, youtube_id=video.youtube_id, privacy=video.privacy, @@ -316,6 +318,7 @@ async def create_video( description: Optional[str] = None, display_order: int = 0, orientation: Optional[str] = None, + target_duration_s: Optional[float] = None, ) -> Video: row = await crud.create_video( project_id=project_id, @@ -323,6 +326,7 @@ async def create_video( description=description, display_order=display_order, orientation=orientation, + target_duration_s=target_duration_s, ) return self._row_to_video(row) diff --git a/agent/sdk/services/assistant_provider.py b/agent/sdk/services/assistant_provider.py new file mode 100644 index 000000000..b8096d29d --- /dev/null +++ b/agent/sdk/services/assistant_provider.py @@ -0,0 +1,215 @@ +"""Assistant media provider — routes generation to the AI assistant instead of Google Flow. + +Implements the :class:`MediaProvider` interface (see ``provider_base.py``), so +``OperationService`` treats it like any other backend. The transport is the +persistent provider-job queue (``provider_job`` table + ``/api/provider-jobs`` +HTTP API): + +Producer side (this provider): + 1. ``run(job)`` inserts a QUEUED row into ``provider_job`` with the full + prompt, orientation, input URLs (``source_url`` / ``start_url`` / + ``end_url`` / ``extra["reference_urls"]``) and provider-specific params + in ``extra``. + 2. It then blocks in ``crud.wait_for_provider_job`` until the job reaches + a terminal status or ``ASSISTANT_PROVIDER_TIMEOUT_S`` elapses. + 3. The terminal row is translated into the same Flow-shaped dict the rest + of the pipeline parses (``_parsing._extract_media_id`` / + ``_extract_output_url``), so downstream code never knows which backend + produced the media. + +Worker side (the assistant, or any external agent): + 1. ``GET /api/provider-jobs/wait-next?provider=assistant&worker_id=<id>`` + long-polls for the next claimable job and claims it (lease granted). + 2. ``POST /api/provider-jobs/{id}/heartbeat`` every ~lease_ttl/3 while + working; ``POST .../progress`` optionally reports progress. + 3. ``POST /api/provider-jobs/{id}/complete`` with a result payload:: + + {"output_url": "<file:// or https:// URL of the finished media>", + "media_id": "<uuid, optional — one is minted when absent>"} + + or ``POST .../fail`` with ``{"error": "..."}``. + +A crashed worker's lease expires and the job becomes reclaimable, so jobs are +never stranded. See ``agent/worker/assistant_worker.py`` for a reference +worker implementing this protocol. +""" + +from __future__ import annotations + +import json +import logging +import uuid +from pathlib import Path +from urllib.parse import urlparse + +from agent import config +from agent.db import crud +from agent.sdk.services.provider_base import ( + KIND_AUDIO, + KIND_EDIT_IMAGE, + KIND_IMAGE, + KIND_UPSCALE, + KIND_VIDEO, + KIND_VIDEO_REFS, + MediaProvider, + ProviderCapabilities, + ProviderJob, +) + +logger = logging.getLogger(__name__) + + +def _image_result(mid: str, url: str) -> dict: + """Flow-shaped image result so _parsing._extract_media_id/_extract_output_url work.""" + return { + "data": { + "media": [ + { + "name": mid, + "image": {"generatedImage": {"mediaId": mid, "fifeUrl": url}}, + } + ] + } + } + + +def _video_result(mid: str, url: str) -> dict: + """Flow-shaped video result so _parsing helpers work.""" + return { + "data": { + "operations": [ + { + "operation": { + "name": mid, + "metadata": {"video": {"mediaId": mid, "fifeUrl": url}}, + }, + "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL", + } + ] + } + } + + +def _audio_result(url: str) -> dict: + """TTS result: the finished audio URL plus a local path when file://.""" + parsed = urlparse(url or "") + local_path = str(Path(parsed.path).resolve()) if parsed.scheme == "file" else "" + return {"data": {"url": url, "audio_path": local_path or url}} + + +class AssistantProvider(MediaProvider): + """Publishes generation jobs to the provider-job queue and awaits a worker.""" + + name = "assistant" + display_name = "Assistant (Pax)" + capabilities = ProviderCapabilities( + generate_image=True, + edit_image=True, + generate_video_i2v=True, + generate_video_r2v=True, + upscale=False, # the assistant cannot upscale video + generate_audio=True, # TTS via provider-job queue + max_concurrent=config.ASSISTANT_MAX_CONCURRENT, + cooldown_s=config.ASSISTANT_COOLDOWN_S, + ) + + def is_available(self) -> bool: + """The assistant bridge needs no credentials or Chrome — always up.""" + return True + + def __init__(self) -> None: + self.timeout_s = config.ASSISTANT_PROVIDER_TIMEOUT_S + self.poll_s = config.ASSISTANT_PROVIDER_POLL_S + + # ── MediaProvider interface ── + + async def run(self, job: ProviderJob) -> dict: + """Publish one provider job and wait for an external worker to finish it.""" + if job.kind == KIND_EDIT_IMAGE: + if not job.source_url: + return {"error": "No source image to edit — generate a scene image first"} + elif job.kind == KIND_AUDIO: + if not (job.prompt or "").strip(): + return {"error": "No text to synthesize — TTS prompt is empty"} + elif job.kind in (KIND_VIDEO, KIND_VIDEO_REFS): + prefix = "vertical" if job.orientation == "VERTICAL" else "horizontal" + if job.kind == KIND_VIDEO_REFS: + # Degrade gracefully: r2v with no refs becomes plain i2v off + # the scene image. Fail only when there is nothing to + # generate from. + if not job.reference_urls and not job.start_url: + return {"error": "No valid reference images for r2v"} + elif not job.start_url: + return {"error": f"No {prefix} image for scene"} + elif job.kind not in (KIND_IMAGE, KIND_AUDIO): + return {"error": f"AssistantProvider: unknown job kind '{job.kind}'"} + + payload_extra = dict(job.extra or {}) + payload_extra["reference_urls"] = list(job.reference_urls) + + await crud.create_provider_job( + provider=self.name, + kind=job.kind, + prompt=job.prompt, + orientation=job.orientation, + source_url=job.source_url, + start_url=job.start_url, + end_url=job.end_url, + extra=payload_extra, + job_id=job.job_id, + ) + logger.info("Assistant provider: job %s (%s) queued — waiting for worker", + job.job_id[:12], job.kind) + + final = await crud.wait_for_provider_job( + job.job_id, timeout_s=self.timeout_s, poll_interval_s=self.poll_s) + if final is None: + logger.error("Assistant provider: job %s timed out after %ds", + job.job_id[:12], self.timeout_s) + return {"error": f"Assistant provider timeout: no worker completed job " + f"{job.job_id[:12]} after {self.timeout_s}s"} + + status = final.get("status") + if status == "SUCCEEDED": + try: + result = json.loads(final.get("result") or "{}") + except (json.JSONDecodeError, TypeError): + result = {} + url = result.get("output_url", "") + mid = result.get("media_id") or str(uuid.uuid4()) + logger.info("Assistant provider: job %s completed (media_id=%s)", + job.job_id[:12], mid[:8]) + if job.kind in (KIND_VIDEO, KIND_VIDEO_REFS): + return _video_result(mid, url) + if job.kind == KIND_AUDIO: + return _audio_result(url) + return _image_result(mid, url) + if status == "CANCELLED": + return {"error": f"Assistant provider job {job.job_id[:12]} was cancelled"} + return {"error": final.get("error_message") or + f"Assistant provider job {job.job_id[:12]} failed"} + + def check(self, job: ProviderJob) -> str | None: + if job.kind == KIND_UPSCALE: + # Keep the historical message — worker/tests match on it. + return "UPSCALE_VIDEO is not supported by the assistant media provider" + return super().check(job) + + def needs_media_id_registration(self) -> bool: + # The assistant mints UUID media_ids itself (_image_result / + # _video_result) — no upload-back step needed. + return False + + async def register_existing_image( + self, url: str, *, name: str = "", project_id: str = "" + ) -> dict: + """Mint a UUID media_id for an already-existing local image.""" + parsed = urlparse(url) + local = Path(parsed.path) if parsed.scheme == "file" else Path(url) + if not local.is_file(): + return {"error": f"AssistantProvider: local image not found for '{name}': {url}"} + mid = str(uuid.uuid4()) + canonical = "file://" + str(local.resolve()) + logger.info("AssistantProvider: registered existing image '%s' → media_id=%s", + name, mid[:8]) + return {"data": {"media": [{"name": mid}], "url": canonical}} diff --git a/agent/sdk/services/flow_provider.py b/agent/sdk/services/flow_provider.py new file mode 100644 index 000000000..6a70e7f98 --- /dev/null +++ b/agent/sdk/services/flow_provider.py @@ -0,0 +1,538 @@ +"""FlowProvider — MediaProvider adapter for Google Flow (Chrome extension). + +Wraps :class:`FlowClient` and exposes the provider interface. All Flow +submit + poll logic lives here; OperationService only builds ProviderJobs. +""" + +from __future__ import annotations + +import asyncio +import base64 +import logging +import os +import ssl +from typing import Optional + +import aiohttp + +from agent import config +from agent.config import VIDEO_POLL_INTERVAL, VIDEO_POLL_TIMEOUT +from agent.db import crud +from agent.sdk.services.provider_base import ( + KIND_EDIT_IMAGE, + KIND_IMAGE, + KIND_UPSCALE, + KIND_VIDEO, + KIND_VIDEO_REFS, + MediaProvider, + ProviderCapabilities, + ProviderJob, +) +from agent.utils.paths import scene_4k_path +from agent.utils.slugify import slugify +from agent.worker._parsing import ( + _extract_operations, + _extract_uuid_from_url, + _is_error, +) + +logger = logging.getLogger(__name__) + + +def _save_raw_bytes( + operations: list[dict], scene_id: str, project_slug: str, display_order: int +) -> str | None: + """If operations contain rawBytes (inline 4K video), save to disk and return path.""" + for op in operations: + raw_b64 = op.get("rawBytes") + if not raw_b64: + continue + # Guard against extremely large payloads (>500MB base64 ≈ ~685M chars) + if len(raw_b64) > 685_000_000: + logger.warning("rawBytes too large (%d chars), skipping", len(raw_b64)) + continue + try: + video_data = base64.b64decode(raw_b64) + path = scene_4k_path(project_slug, display_order, scene_id) + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(video_data) + logger.info("Saved rawBytes 4K video: %s (%d bytes)", path, len(video_data)) + return str(path) + except Exception as e: + logger.warning("Failed to save rawBytes: %s", e) + return None + + +async def _poll_workflows( + client, + operations: list[dict], + timeout: int, +) -> dict: + """Poll workflow-mode operations (Low Priority). Flow returns MP4 binary + inline as base64 in `video.encodedVideo` — decode and save to disk, then + synthesize an OLD-schema success response with a file:// URL. + + The response shape is: + {"name": "<media_id>", "video": {"encodedVideo": "<base64 MP4>", ...}} + + Detection logic: + - "ready" = response is a dict with keys {"name","video"} where video.encodedVideo + starts with AAAAI... (MP4 ftyp header in base64) + - "still gen" = response missing video block, or encodedVideo missing/empty + """ + poll_interval = VIDEO_POLL_INTERVAL + elapsed = 0 + completed = {} # media_id → local_path + + while elapsed < timeout: + await asyncio.sleep(poll_interval) + elapsed += poll_interval + + for op in operations: + mid = op.get("_primary_media_id", "") + if not mid or mid in completed: + continue + media_resp = await client.get_media(mid) + status = media_resp.get("status") + if status != 200: + logger.debug("Workflow media %s not ready (status=%s)", mid[:8], status) + continue + + # Direct top-level (not wrapped in `data`) + payload = media_resp.get("data", media_resp) if isinstance(media_resp.get("data"), dict) and "video" in media_resp.get("data", {}) else media_resp + video_block = payload.get("video", {}) if isinstance(payload, dict) else {} + encoded = video_block.get("encodedVideo", "") if isinstance(video_block, dict) else "" + + if not encoded: + continue + try: + binary = base64.b64decode(encoded) + except Exception as e: + logger.warning("Workflow media %s: failed to decode encodedVideo: %s", mid[:8], e) + continue + # Validate MP4 magic: real video starts with `ftyp` box at bytes 4-8. + # While generating, Flow returns metadata payload (~1-2KB) — skip until real MP4. + is_mp4 = len(binary) >= 12 and binary[4:8] == b"ftyp" + if not is_mp4: + logger.debug("Workflow media %s still generating (got %d bytes, not MP4)", + mid[:8], len(binary)) + continue + out_dir = "output/_workflow_videos" + os.makedirs(out_dir, exist_ok=True) + out_path = f"{out_dir}/{mid}.mp4" + with open(out_path, "wb") as f: + f.write(binary) + completed[mid] = {"path": out_path, "size": len(binary)} + logger.info("Workflow media %s ready: saved %d bytes → %s", + mid[:8], len(binary), out_path) + + if len(completed) == len(operations): + synth_ops = [] + for op in operations: + mid = op.get("_primary_media_id", "") + wf_name = op.get("operation", {}).get("name", "") + local = completed.get(mid, {}).get("path", "") + # Use file:// so downstream sees a URL-shaped string + local_url = f"file://{os.path.abspath(local)}" if local else "" + synth_ops.append({ + "operation": { + "name": wf_name, + "metadata": {"video": {"mediaId": mid, "fifeUrl": local_url}}, + }, + "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL", + }) + logger.info("All %d workflow(s) completed after %ds", len(operations), elapsed) + return {"data": {"operations": synth_ops}} + + logger.warning("Workflow polling timed out after %ds. Done=%d/%d", + timeout, len(completed), len(operations)) + return {"error": f"Workflow polling timeout after {timeout}s"} + + +async def _poll_operations( + client, + operations: list[dict], + timeout: int = VIDEO_POLL_TIMEOUT, +) -> dict: + """Poll until all operations complete or timeout. + + Two polling paths: + - OLD schema → check_video_status(operations) + - Workflow mode (Low Priority) → poll get_media(primaryMediaId) until ready + """ + if not operations: + return {"error": "No operations to poll"} + + # Workflow-mode polling: poll media endpoint for each primaryMediaId + if all(op.get("_workflow_mode") for op in operations): + return await _poll_workflows(client, operations, timeout) + + poll_interval = VIDEO_POLL_INTERVAL + elapsed = 0 + current_ops = operations + # The batch path attaches the operation's own grumble ("Media not found.") + # to a still-pending round. It is a diagnostic, not a verdict — finished + # jobs report it too — so it is only worth quoting if we time out. + last_complaint = None + + while elapsed < timeout: + await asyncio.sleep(poll_interval) + elapsed += poll_interval + + status_result = await client.check_video_status(current_ops) + if _is_error(status_result): + logger.warning("Status poll error: %s", status_result.get("error")) + continue + + data = status_result.get("data", status_result) + ops = data.get("operations", []) + if not ops: + continue + + current_ops = ops + all_done = True + has_error = False + error_msg = "" + + for op in ops: + if op.get("complaint"): + last_complaint = op["complaint"] + status = op.get("status", "") + if status == "MEDIA_GENERATION_STATUS_SUCCESSFUL": + continue + elif status == "MEDIA_GENERATION_STATUS_FAILED": + op_name = op.get('operation', {}).get('name', '?') + # Log full operation for debugging failure reason + import json as _json + logger.error("Operation FAILED: name=%s full=%s", op_name, _json.dumps(op)[:1000]) + error_msg = f"Operation failed: {op_name}" + has_error = True + break + else: + all_done = False + + if has_error: + return {"error": error_msg} + if all_done: + logger.info("All %d operations completed after %ds", len(ops), elapsed) + return {"data": data} + + detail = f": {last_complaint}" if last_complaint else "" + return {"error": f"Polling timeout after {timeout}s{detail}"} + + +async def _upload_character_image(client, char: dict, project_id: str) -> str | None: + """Download character reference image and upload to Google Flow to get media_id.""" + ref_url = char.get("reference_image_url") + if not ref_url: + return None + + try: + try: + import certifi + ssl_ctx = ssl.create_default_context(cafile=certifi.where()) + except ImportError: + ssl_ctx = ssl.create_default_context() + async with aiohttp.ClientSession() as session: + async with session.get(ref_url, ssl=ssl_ctx) as resp: + if resp.status != 200: + logger.error("Failed to download character image: HTTP %d", resp.status) + return None + image_bytes = await resp.read() + content_type = resp.headers.get("content-type", "image/jpeg") + + if "png" in content_type: + mime = "image/png" + elif "gif" in content_type: + mime = "image/gif" + else: + mime = "image/jpeg" + + ext = mime.split("/")[-1] + file_name = f"{char.get('name', 'character')}.{ext}" + + encoded = base64.b64encode(image_bytes).decode("utf-8") + result = await client.upload_image( + encoded, mime_type=mime, project_id=project_id, file_name=file_name, + ) + + if result.get("_mediaId"): + return result["_mediaId"] + + data = result.get("data", {}) + if isinstance(data, dict): + media = data.get("media", {}) + if isinstance(media, dict) and media.get("name"): + return media["name"] + + return None + except Exception as e: + logger.exception("Failed to upload character image: %s", e) + return None + + +class FlowProvider(MediaProvider): + """Google Flow backend — direct provider via the Chrome extension.""" + + name = "flow" + display_name = "Google Flow" + capabilities = ProviderCapabilities( + generate_image=True, + edit_image=True, + generate_video_i2v=True, + generate_video_r2v=True, + upscale=True, + max_concurrent=5, + cooldown_s=10.0, + ) + + def __init__(self, client) -> None: + self._client = client + + def is_available(self) -> bool: + """Flow is available only while the Chrome extension is connected.""" + try: + return bool(self._client.connected) + except Exception: + return False + + # ── MediaProvider interface ────────────────────────────────────────── + + async def run(self, job: ProviderJob) -> dict: + if job.kind == KIND_IMAGE: + return await self._run_image(job) + if job.kind == KIND_EDIT_IMAGE: + return await self._run_edit_image(job) + if job.kind == KIND_VIDEO: + return await self._run_video(job) + if job.kind == KIND_VIDEO_REFS: + return await self._run_video_refs(job) + if job.kind == KIND_UPSCALE: + return await self._run_upscale(job) + if job.kind == KIND_AUDIO: + return {"error": "TTS/audio is not supported by the flow provider — " + "use the assistant provider or local TTS"} + return {"error": f"FlowProvider: unknown job kind '{job.kind}'"} + + def needs_media_id_registration(self) -> bool: + # Flow tracks media by UUID media_id — generated images must be + # uploaded back to obtain one. + return True + + async def register_existing_image( + self, url: str, *, name: str = "", project_id: str = "" + ) -> dict: + mid = await _upload_character_image( + self._client, {"name": name, "reference_image_url": url}, project_id + ) + if mid: + return {"data": {"media": [{"name": mid}], "url": url}} + # Fallback: Flow sometimes returns UUID-bearing URLs directly. + uuid_from_url = _extract_uuid_from_url(url) + if uuid_from_url: + logger.info("FlowProvider: extracted UUID from URL for '%s'", name) + return {"data": {"media": [{"name": uuid_from_url}], "url": url}} + return {"error": f"FlowProvider: could not register image for '{name}'"} + + # ── kind implementations ───────────────────────────────────────────── + + async def _run_image(self, job: ProviderJob) -> dict: + ex = job.extra + return await self._client.generate_images( + prompt=job.prompt, + project_id=ex.get("project_id", "0"), + aspect_ratio=ex.get("aspect", "IMAGE_ASPECT_RATIO_PORTRAIT"), + user_paygate_tier=ex.get("tier", "PAYGATE_TIER_TWO"), + character_media_ids=ex.get("character_media_ids"), + ) + + async def _run_edit_image(self, job: ProviderJob) -> dict: + ex = job.extra + if not ex.get("source_media_id"): + return {"error": "No source image to edit — generate a scene image first"} + return await self._client.edit_image( + prompt=job.prompt, + source_media_id=ex.get("source_media_id", ""), + project_id=ex.get("project_id", "0"), + aspect_ratio=ex.get("aspect", "IMAGE_ASPECT_RATIO_PORTRAIT"), + user_paygate_tier=ex.get("tier", "PAYGATE_TIER_ONE"), + character_media_ids=ex.get("character_media_ids"), + ) + + async def _run_video(self, job: ProviderJob) -> dict: + """i2v: submit + poll. Re-polls a previous submission on retry.""" + ex = job.extra + request_id = ex.get("request_id", "") + + existing_op = None + if request_id: + req_row = await crud.get_request(request_id) + existing_op = req_row.get("request_id") if req_row else None + + # A bare uuid is the operation id, and looking it up in the project + # listing is exactly what the status poll does — resubmitting instead + # would abandon a running render and pay for a second one. + if existing_op: + logger.info("Video gen already submitted (op=%s), re-polling", existing_op[:30]) + operations = [{"operation": {"name": existing_op}, "status": "MEDIA_GENERATION_STATUS_PENDING"}] + return await _poll_operations(self._client, operations) + + submit_result = await self._client.generate_video( + start_image_media_id=ex.get("start_media_id", ""), + prompt=job.prompt, + project_id=ex.get("project_id", "0"), + scene_id=ex.get("scene_id", ""), + aspect_ratio=ex.get("aspect", "VIDEO_ASPECT_RATIO_PORTRAIT"), + end_image_media_id=ex.get("end_media_id"), + user_paygate_tier=ex.get("tier", "PAYGATE_TIER_TWO"), + ) + + if _is_error(submit_result): + logger.error("[DEBUG] Video gen submit_result IS_ERROR: %s", str(submit_result)[:2000]) + return submit_result + + operations = _extract_operations(submit_result) + if not operations: + logger.error("[DEBUG] Video gen NO_OPERATIONS submit_result: %s", str(submit_result)[:2000]) + return {"error": "Video gen returned no operations"} + + op_name = operations[0].get("operation", {}).get("name", "") + if request_id: + await crud.update_request(request_id, request_id=op_name) + + status = operations[0].get("status", "") + if status == "MEDIA_GENERATION_STATUS_SUCCESSFUL": + logger.info("Video gen completed immediately") + return submit_result + if status == "MEDIA_GENERATION_STATUS_FAILED": + return {"error": "Video generation failed immediately"} + + logger.info("Video gen submitted, polling %d operations...", len(operations)) + return await _poll_operations(self._client, operations) + + async def _run_video_refs(self, job: ProviderJob) -> dict: + """r2v: submit + poll. Re-polls a previous submission on retry.""" + ex = job.extra + request_id = ex.get("request_id", "") + ref_ids = ex.get("ref_media_ids", []) + + if not ref_ids: + return {"error": "No valid reference media_ids for r2v"} + + # Check if already submitted (op_name saved from previous attempt) + existing_op = None + if request_id: + req_row = await crud.get_request(request_id) + existing_op = req_row.get("request_id") if req_row else None + + if existing_op: + logger.info("R2V already submitted (op=%s), re-polling", existing_op[:30]) + operations = [{"operation": {"name": existing_op}, "status": "MEDIA_GENERATION_STATUS_PENDING"}] + return await _poll_operations(self._client, operations) + + submit_result = await self._client.generate_video_from_references( + reference_media_ids=ref_ids, + prompt=job.prompt, + project_id=ex.get("project_id", "0"), + scene_id=ex.get("scene_id", ""), + aspect_ratio=ex.get("aspect", "VIDEO_ASPECT_RATIO_PORTRAIT"), + user_paygate_tier=ex.get("tier", "PAYGATE_TIER_TWO"), + ) + + if _is_error(submit_result): + return submit_result + + operations = _extract_operations(submit_result) + if not operations: + return {"error": "R2V returned no operations"} + + op_name = operations[0].get("operation", {}).get("name", "") + if request_id: + await crud.update_request(request_id, request_id=op_name) + + status = operations[0].get("status", "") + if status == "MEDIA_GENERATION_STATUS_SUCCESSFUL": + logger.info("R2V completed immediately") + return submit_result + if status == "MEDIA_GENERATION_STATUS_FAILED": + return {"error": "R2V failed immediately"} + + logger.info("R2V submitted with %d refs, polling %d operations...", len(ref_ids), len(operations)) + return await _poll_operations(self._client, operations) + + async def _run_upscale(self, job: ProviderJob) -> dict: + ex = job.extra + request_id = ex.get("request_id", "") + + existing_op = None + if request_id: + req_row = await crud.get_request(request_id) + existing_op = req_row.get("request_id") if req_row else None + + if existing_op: + # Already submitted — just re-poll + logger.info("Upscale already submitted (op=%s), re-polling", existing_op[:30]) + operations = [{"operation": {"name": existing_op}, "status": "MEDIA_GENERATION_STATUS_PENDING"}] + return await _poll_operations(self._client, operations, timeout=300) + + submit_result = await self._client.upscale_video( + media_id=ex.get("video_media_id", ""), + scene_id=ex.get("scene_id", ""), + aspect_ratio=ex.get("aspect", "VIDEO_ASPECT_RATIO_PORTRAIT"), + ) + + if _is_error(submit_result): + return submit_result + + operations = _extract_operations(submit_result) + if not operations: + return {"error": "Upscale returned no operations"} + + # Check for inline rawBytes (4K video data returned directly) + project_slug = ex.get("project_slug") or slugify(ex.get("project_id", "unnamed")) + display_order = ex.get("display_order", 0) + scene_id = ex.get("scene_id", "") + raw_path = _save_raw_bytes(operations, scene_id, project_slug, display_order) + if raw_path: + logger.info("Upscale returned inline 4K video, saved to %s", raw_path) + # Inject saved path into result for downstream parsing + if not operations[0].get("operation"): + operations[0]["operation"] = {} + operations[0]["operation"].setdefault("metadata", {}).setdefault("video", {})["fifeUrl"] = raw_path + operations[0]["status"] = "MEDIA_GENERATION_STATUS_SUCCESSFUL" + return {"data": {"operations": operations}} + + op_name = operations[0].get("operation", {}).get("name", "") + if request_id: + await crud.update_request(request_id, request_id=op_name) + + status = operations[0].get("status", "") + if status == "MEDIA_GENERATION_STATUS_SUCCESSFUL": + logger.info("Upscale completed immediately") + return submit_result + if status == "MEDIA_GENERATION_STATUS_FAILED": + return {"error": "Upscale failed immediately"} + + logger.info("Upscale submitted, polling %d operations...", len(operations)) + poll_result = await _poll_operations(self._client, operations, timeout=300) + + # Check poll result for rawBytes too + poll_data = poll_result.get("data", poll_result) + poll_ops = poll_data.get("operations", []) + if poll_ops: + raw_path = _save_raw_bytes(poll_ops, scene_id, project_slug, display_order) + if raw_path: + logger.info("Poll returned inline 4K video, saved to %s", raw_path) + poll_ops[0].setdefault("operation", {}).setdefault("metadata", {}).setdefault("video", {})["fifeUrl"] = raw_path + + return poll_result + + +# Re-exported for any code still importing from operations (moved here). +__all__ = [ + "FlowProvider", + "_poll_operations", + "_poll_workflows", + "_save_raw_bytes", + "_upload_character_image", +] diff --git a/agent/sdk/services/operations.py b/agent/sdk/services/operations.py index e7157cd45..57c7a1000 100644 --- a/agent/sdk/services/operations.py +++ b/agent/sdk/services/operations.py @@ -1,52 +1,35 @@ -"""SDK OperationService — executes media generation operations directly. +"""SDK OperationService — executes media generation operations via providers. -Each method receives loaded data (scene/character dicts), calls FlowClient, -parses results, updates the DB, and returns a result dict for processor +Each method receives loaded data (scene/character dicts), builds a +backend-agnostic :class:`ProviderJob`, resolves the :class:`MediaProvider` +for the request (Google Flow, an AI assistant, or any registered backend), +runs the job, updates the DB, and returns a result dict for processor status tracking. """ from __future__ import annotations -import asyncio -import base64 import json import logging -import ssl +import uuid from typing import TYPE_CHECKING, Optional - -def _build_continuation_prompt(base_prompt: str) -> str: - """Build a transformation-focused prompt for CONTINUATION scene images. - - When editing from a parent image, the default prompt just describes the - child scene statically — the edit API preserves the parent's composition. - This helper prepends transformation instructions so the AI actually - changes camera angle, location, and setup. - """ - return ( - f"Transform this image into a completely different moment. " - f"Move the camera to a new angle, position, and composition. " - f"Change the surrounding environment and visual setup. " - f"{base_prompt}" - ) - - -def _char_matches(c: dict, name_set: set) -> bool: - """Check if a character matches any name in the set by slug OR display name.""" - slug = c.get("slug") or "" - name = c.get("name", "") - return (slug and slug in name_set) or (name and name in name_set) - -import aiohttp - from agent.db import crud -from agent.config import VIDEO_POLL_INTERVAL, VIDEO_POLL_TIMEOUT -from agent.utils.paths import scene_4k_path +from agent.config import DEFAULT_PROVIDER +from agent.sdk.services.registry import ProviderRegistry +from agent.sdk.services.provider_base import ( + KIND_EDIT_IMAGE, + KIND_IMAGE, + KIND_UPSCALE, + KIND_VIDEO, + KIND_VIDEO_REFS, + MediaProvider, + ProviderJob, +) from agent.utils.slugify import slugify from agent.worker._parsing import ( _is_error, _is_uuid, - _extract_uuid_from_url, _extract_media_id, _extract_output_url, ) @@ -61,6 +44,13 @@ def _char_matches(c: dict, name_set: set) -> bool: _LANDSCAPE_ENTITY_TYPES = {"location"} +def _char_matches(c: dict, name_set: set) -> bool: + """Check if a character matches any name in the set by slug OR display name.""" + slug = c.get("slug") or "" + name = c.get("name", "") + return (slug and slug in name_set) or (name and name in name_set) + + def _reference_aspect_ratio(entity_type: str) -> str: """Pick aspect ratio based on entity type.""" if entity_type in _LANDSCAPE_ENTITY_TYPES: @@ -68,256 +58,54 @@ def _reference_aspect_ratio(entity_type: str) -> str: return "IMAGE_ASPECT_RATIO_PORTRAIT" -def _save_raw_bytes( - operations: list[dict], scene_id: str, project_slug: str, display_order: int -) -> str | None: - """If operations contain rawBytes (inline 4K video), save to disk and return path.""" - for op in operations: - raw_b64 = op.get("rawBytes") - if not raw_b64: - continue - # Guard against extremely large payloads (>500MB base64 ≈ ~685M chars) - if len(raw_b64) > 685_000_000: - logger.warning("rawBytes too large (%d chars), skipping", len(raw_b64)) - continue - try: - video_data = base64.b64decode(raw_b64) - path = scene_4k_path(project_slug, display_order, scene_id) - path.parent.mkdir(parents=True, exist_ok=True) - path.write_bytes(video_data) - logger.info("Saved rawBytes 4K video: %s (%d bytes)", path, len(video_data)) - return str(path) - except Exception as e: - logger.warning("Failed to save rawBytes: %s", e) - return None - - -def _extract_operations(result: dict) -> list[dict]: - """Extract operations list from video gen / upscale submit response. - - Supports two response schemas: - - OLD (Lite/Fast/Ultra): {"data": {"operations": [{"operation": {"name": ...}, "status": ...}]}} - - NEW (Low Priority — veo_3_1_*_low_priority, *_ultra_relaxed): - {"data": {"workflows": [{"name": "...", "metadata": {"primaryMediaId": "..."}}], - "media": [{"name": "...", ...}]}} - """ - data = result.get("data", result) - ops = data.get("operations", []) - if ops: - for op in ops: - op_name = op.get("operation", {}).get("name") - if not op_name: - logger.warning("Operation missing name: %s", op) - return ops - - # NEW schema: workflows + media → synthesize operation entries - workflows = data.get("workflows", []) - media_list = data.get("media", []) - if not workflows or not media_list: - return [] - - media_by_id = {m.get("name"): m for m in media_list if m.get("name")} - synthesized = [] - for wf in workflows: - wf_name = wf.get("name", "") - meta = wf.get("metadata", {}) - primary_media_id = meta.get("primaryMediaId", "") - if not wf_name or not primary_media_id: - continue - synthesized.append({ - "operation": { - "name": wf_name, - "metadata": {"video": {"mediaId": primary_media_id}}, - }, - "status": "MEDIA_GENERATION_STATUS_PENDING", - "_workflow_mode": True, - "_primary_media_id": primary_media_id, - }) - if synthesized: - logger.info("Detected workflow-schema response: %d workflow(s) → synthesized", len(synthesized)) - return synthesized - - -async def _poll_workflows( - client: FlowClient, - operations: list[dict], - timeout: int, -) -> dict: - """Poll workflow-mode operations (Low Priority). Flow returns MP4 binary - inline as base64 in `video.encodedVideo` — decode and save to disk, then - synthesize an OLD-schema success response with a file:// URL. - - The response shape is: - {"name": "<media_id>", "video": {"encodedVideo": "<base64 MP4>", ...}} - - Detection logic: - - "ready" = response is a dict with keys {"name","video"} where video.encodedVideo - starts with AAAAI... (MP4 ftyp header in base64) - - "still gen" = response missing video block, or encodedVideo missing/empty - """ - import base64 - import os as _os - - poll_interval = VIDEO_POLL_INTERVAL - elapsed = 0 - completed = {} # media_id → local_path - - while elapsed < timeout: - await asyncio.sleep(poll_interval) - elapsed += poll_interval - - for op in operations: - mid = op.get("_primary_media_id", "") - if not mid or mid in completed: - continue - media_resp = await client.get_media(mid) - status = media_resp.get("status") - if status != 200: - logger.debug("Workflow media %s not ready (status=%s)", mid[:8], status) - continue - - # Direct top-level (not wrapped in `data`) - payload = media_resp.get("data", media_resp) if isinstance(media_resp.get("data"), dict) and "video" in media_resp.get("data", {}) else media_resp - video_block = payload.get("video", {}) if isinstance(payload, dict) else {} - encoded = video_block.get("encodedVideo", "") if isinstance(video_block, dict) else "" - - if not encoded: - continue - try: - binary = base64.b64decode(encoded) - except Exception as e: - logger.warning("Workflow media %s: failed to decode encodedVideo: %s", mid[:8], e) - continue - # Validate MP4 magic: real video starts with `ftyp` box at bytes 4-8. - # While generating, Flow returns metadata payload (~1-2KB) — skip until real MP4. - is_mp4 = len(binary) >= 12 and binary[4:8] == b"ftyp" - if not is_mp4: - logger.debug("Workflow media %s still generating (got %d bytes, not MP4)", - mid[:8], len(binary)) - continue - out_dir = "output/_workflow_videos" - _os.makedirs(out_dir, exist_ok=True) - out_path = f"{out_dir}/{mid}.mp4" - with open(out_path, "wb") as f: - f.write(binary) - completed[mid] = {"path": out_path, "size": len(binary)} - logger.info("Workflow media %s ready: saved %d bytes → %s", - mid[:8], len(binary), out_path) - - if len(completed) == len(operations): - synth_ops = [] - for op in operations: - mid = op.get("_primary_media_id", "") - wf_name = op.get("operation", {}).get("name", "") - local = completed.get(mid, {}).get("path", "") - # Use file:// so downstream sees a URL-shaped string - local_url = f"file://{_os.path.abspath(local)}" if local else "" - synth_ops.append({ - "operation": { - "name": wf_name, - "metadata": {"video": {"mediaId": mid, "fifeUrl": local_url}}, - }, - "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL", - }) - logger.info("All %d workflow(s) completed after %ds", len(operations), elapsed) - return {"data": {"operations": synth_ops}} - - logger.warning("Workflow polling timed out after %ds. Done=%d/%d", - timeout, len(completed), len(operations)) - return {"error": f"Workflow polling timeout after {timeout}s"} - - -async def _poll_operations( - client: FlowClient, - operations: list[dict], - timeout: int = VIDEO_POLL_TIMEOUT, -) -> dict: - """Poll until all operations complete or timeout. - - Two polling paths: - - OLD schema → check_video_status(operations) - - Workflow mode (Low Priority) → poll get_media(primaryMediaId) until ready - """ - if not operations: - return {"error": "No operations to poll"} - - # Workflow-mode polling: poll media endpoint for each primaryMediaId - if all(op.get("_workflow_mode") for op in operations): - return await _poll_workflows(client, operations, timeout) - - poll_interval = VIDEO_POLL_INTERVAL - elapsed = 0 - current_ops = operations - # The batch path attaches the operation's own grumble ("Media not found.") - # to a still-pending round. It is a diagnostic, not a verdict — finished - # jobs report it too — so it is only worth quoting if we time out. - last_complaint = None - - while elapsed < timeout: - await asyncio.sleep(poll_interval) - elapsed += poll_interval - - status_result = await client.check_video_status(current_ops) - if _is_error(status_result): - logger.warning("Status poll error: %s", status_result.get("error")) - continue - - data = status_result.get("data", status_result) - ops = data.get("operations", []) - if not ops: - continue - - current_ops = ops - all_done = True - has_error = False - error_msg = "" - - for op in ops: - if op.get("complaint"): - last_complaint = op["complaint"] - status = op.get("status", "") - if status == "MEDIA_GENERATION_STATUS_SUCCESSFUL": - continue - elif status == "MEDIA_GENERATION_STATUS_FAILED": - op_name = op.get('operation', {}).get('name', '?') - # Log full operation for debugging failure reason - import json as _json - logger.error("Operation FAILED: name=%s full=%s", op_name, _json.dumps(op)[:1000]) - error_msg = f"Operation failed: {op_name}" - has_error = True - break - else: - all_done = False - - if has_error: - return {"error": error_msg} - if all_done: - logger.info("All %d operations completed after %ds", len(ops), elapsed) - return {"data": data} - - done_count = sum(1 for o in ops if o.get("status") == "MEDIA_GENERATION_STATUS_SUCCESSFUL") - logger.debug("Poll %ds/%ds: %d/%d done", elapsed, timeout, done_count, len(ops)) - - detail = f": {last_complaint}" if last_complaint else "" - return {"error": f"Polling timeout after {timeout}s{detail}"} - - class OperationService: - """Executes media generation operations using FlowClient + Repository. + """Executes media generation operations via pluggable MediaProviders. - Each method calls FlowClient directly, parses the response, updates - the database, and returns a result dict (with 'data' or 'error'). + Each method builds a backend-agnostic ProviderJob, resolves the provider + for the request (per-request override, else the DEFAULT_PROVIDER), runs + the job, updates the database, and returns a result dict (with 'data' + or 'error'). """ - def __init__(self, flow_client: FlowClient, repo: Repository): + def __init__(self, flow_client: FlowClient, repo: Repository, + providers: dict[str, MediaProvider] | None = None, + registry: ProviderRegistry | None = None): self._client = flow_client self._repo = repo + # Provider registry. "flow" wraps the injected FlowClient; + # "assistant" needs no credentials and is always available. + # Extra backends (a Sora adapter, a local SDXL worker, …) can be + # injected here and selected per request. + self._registry = registry or ProviderRegistry(flow_client, providers) + + @property + def registry(self) -> ProviderRegistry: + return self._registry + + @property + def providers(self) -> dict[str, MediaProvider]: + return self._registry.providers + + def _resolve_provider(self, name: str | None = None) -> MediaProvider: + """Resolve a provider by name, falling back to the default.""" + return self._registry.resolve(name) + + async def _run_provider_job(self, job: ProviderJob, + provider_name: str | None = None) -> dict: + """Capability-check then run a job on the resolved provider.""" + provider = self._resolve_provider(provider_name) + err = provider.check(job) + if err: + return {"error": err} + return await provider.run(job) # ------------------------------------------------------------------ # Scene image operations # ------------------------------------------------------------------ - async def generate_scene_image(self, scene: dict, orientation: str) -> dict: + async def generate_scene_image(self, scene: dict, orientation: str, + job_id: str = "", + provider: str | None = None) -> dict: """Generate a scene image with reference imageInputs.""" project = await crud.get_project(scene.get("_project_id", "0")) aspect = "IMAGE_ASPECT_RATIO_PORTRAIT" if orientation == "VERTICAL" else "IMAGE_ASPECT_RATIO_LANDSCAPE" @@ -328,8 +116,10 @@ async def generate_scene_image(self, scene: dict, orientation: str) -> dict: tier = project.get("user_paygate_tier", "PAYGATE_TIER_TWO") if project else "PAYGATE_TIER_TWO" pid = scene.get("_project_id", "0") - # Resolve character reference media_ids + # Resolve character reference media_ids (Flow) and image URLs (assistant) char_media_ids = None + ref_urls: list[str] = [] + ref_names: list[str] = [] char_names_raw = scene.get("character_names") if char_names_raw and pid: if isinstance(char_names_raw, str): @@ -350,6 +140,9 @@ async def generate_scene_image(self, scene: dict, orientation: str) -> dict: mid = c.get("media_id") if mid: valid_ids.append(mid) + ref_names.append(c.get("name", "")) + if c.get("reference_image_url"): + ref_urls.append(c["reference_image_url"]) else: missing_refs.append(c.get("slug") or c["name"]) @@ -361,13 +154,32 @@ async def generate_scene_image(self, scene: dict, orientation: str) -> dict: logger.info("Scene %s: using %d reference images", scene.get("id", "?")[:8], len(char_media_ids)) - return await self._client.generate_images( - prompt=prompt, project_id=pid, aspect_ratio=aspect, - user_paygate_tier=tier, character_media_ids=char_media_ids, + job = ProviderJob( + job_id=job_id or uuid.uuid4().hex[:12], + kind=KIND_IMAGE, + prompt=prompt, + orientation=orientation, + reference_urls=tuple(ref_urls), + extra={ + # Flow backend knobs + "project_id": pid, + "tier": tier, + "aspect": aspect, + "character_media_ids": char_media_ids, + # Assistant / future backends context + "kind": "image", + "scene_id": scene.get("id"), + "project_name": project.get("name") if project else "", + "display_order": scene.get("display_order", 0), + "reference_names": ref_names, + }, ) + return await self._run_provider_job(job, provider) async def edit_scene_image(self, scene: dict, orientation: str, - source_media_id: str | None = None) -> dict: + source_media_id: str | None = None, + job_id: str = "", + provider: str | None = None) -> dict: """Edit an existing scene image using IMAGE_INPUT_TYPE_BASE_IMAGE. Resolves character refs from scene's character_names and passes them @@ -389,16 +201,24 @@ async def edit_scene_image(self, scene: dict, orientation: str, src = parent.get(f"{orient_prefix}_image_media_id") if not src: src = scene.get(f"{orient_prefix}_image_media_id") - if not src: - return {"error": "No source image to edit — generate a scene image first"} + + # URL form of the source (for URL-based backends like the assistant). + # source_media_id is a Flow UUID — URL backends need the image URL. + src_url = None + if scene.get("parent_scene_id"): + parent = await crud.get_scene(scene["parent_scene_id"]) + src_url = (parent or {}).get(f"{orient_prefix}_image_url") + src_url = src_url or scene.get(f"{orient_prefix}_image_url") edit_prompt = scene.get("image_prompt") or scene.get("prompt", "") # CONTINUATION scenes: enrich prompt with transformation context if scene.get("parent_scene_id") and not scene.get("image_prompt"): edit_prompt = _build_continuation_prompt(edit_prompt) - # Resolve character reference media_ids for edit consistency + # Resolve character references in both forms (media_ids for Flow, + # URLs for the assistant). char_media_ids = None + ref_urls: list[str] = [] char_names_raw = scene.get("character_names") if char_names_raw and pid: if isinstance(char_names_raw, str): @@ -413,21 +233,37 @@ async def edit_scene_image(self, scene: dict, orientation: str, for c in project_chars: if _char_matches(c, char_names_set) and c.get("media_id"): valid_ids.append(c["media_id"]) + if c.get("reference_image_url"): + ref_urls.append(c["reference_image_url"]) char_media_ids = valid_ids if valid_ids else None - return await self._client.edit_image( - prompt=edit_prompt, source_media_id=src, - project_id=pid, aspect_ratio=aspect, - user_paygate_tier=tier, - character_media_ids=char_media_ids, + job = ProviderJob( + job_id=job_id or uuid.uuid4().hex[:12], + kind=KIND_EDIT_IMAGE, + prompt=edit_prompt, + orientation=orientation, + source_url=src_url, + reference_urls=tuple(ref_urls), + extra={ + "project_id": pid, + "tier": tier, + "aspect": aspect, + "source_media_id": src, + "character_media_ids": char_media_ids, + "scene_id": scene.get("id"), + "project_name": project.get("name") if project else "", + "display_order": scene.get("display_order", 0), + }, ) + return await self._run_provider_job(job, provider) # ------------------------------------------------------------------ # Video operations # ------------------------------------------------------------------ async def generate_scene_video(self, scene: dict, orientation: str, - request_id: str = "") -> dict: + request_id: str = "", + provider: str | None = None) -> dict: """Generate video from a scene image (i2v). Submits + polls.""" prefix = "vertical" if orientation == "VERTICAL" else "horizontal" image_media_id = scene.get(f"{prefix}_image_media_id") @@ -447,55 +283,30 @@ async def generate_scene_video(self, scene: dict, orientation: str, base_prompt = scene.get("video_prompt") or scene.get("prompt", "") prompt = await _build_video_prompt(base_prompt, scene, pid) - # Already submitted on a previous attempt? Re-poll it. - existing_op = None - if request_id: - req_row = await crud.get_request(request_id) - existing_op = req_row.get("request_id") if req_row else None - - # A bare uuid is the operation id, and looking it up in the project - # listing is exactly what the status poll does — resubmitting instead - # would abandon a running render and pay for a second one. - if existing_op: - logger.info("Video gen already submitted (op=%s), re-polling", existing_op[:30]) - operations = [{"operation": {"name": existing_op}, "status": "MEDIA_GENERATION_STATUS_PENDING"}] - return await _poll_operations(self._client, operations) - - submit_result = await self._client.generate_video( - start_image_media_id=image_media_id, + job = ProviderJob( + job_id=request_id or uuid.uuid4().hex[:12], + kind=KIND_VIDEO, prompt=prompt, - project_id=pid, - scene_id=scene.get("id", ""), - aspect_ratio=aspect, - end_image_media_id=end_id, - user_paygate_tier=tier, + orientation=orientation, + start_url=scene.get(f"{prefix}_image_url"), + end_url=await self._resolve_chain_end_url(scene, prefix), + extra={ + "project_id": pid, + "tier": tier, + "aspect": aspect, + "scene_id": scene.get("id", ""), + "start_media_id": image_media_id, + "end_media_id": end_id, + "request_id": request_id, + "project_name": project.get("name") if project else "", + "display_order": scene.get("display_order", 0), + }, ) - - if _is_error(submit_result): - logger.error("[DEBUG] Video gen submit_result IS_ERROR: %s", str(submit_result)[:2000]) - return submit_result - - operations = _extract_operations(submit_result) - if not operations: - logger.error("[DEBUG] Video gen NO_OPERATIONS submit_result: %s", str(submit_result)[:2000]) - return {"error": "Video gen returned no operations"} - - op_name = operations[0].get("operation", {}).get("name", "") - if request_id: - await crud.update_request(request_id, request_id=op_name) - - status = operations[0].get("status", "") - if status == "MEDIA_GENERATION_STATUS_SUCCESSFUL": - logger.info("Video gen completed immediately") - return submit_result - if status == "MEDIA_GENERATION_STATUS_FAILED": - return {"error": "Video generation failed immediately"} - - logger.info("Video gen submitted, polling %d operations...", len(operations)) - return await _poll_operations(self._client, operations) + return await self._run_provider_job(job, provider) async def generate_scene_video_refs(self, scene: dict, orientation: str, - request_id: str = "") -> dict: + request_id: str = "", + provider: str | None = None) -> dict: """Generate video from reference images (r2v). Submits + polls. R2V uses any entity images (characters, visual_assets, locations) plus @@ -537,6 +348,8 @@ async def generate_scene_video_refs(self, scene: dict, orientation: str, _R2V_MAX_REFS = 3 _R2V_ENTITY_PRIORITY = ("visual_asset", "character") ref_ids: list[str] = [] + ref_urls: list[str] = [] + ref_names_r2v: list[str] = [] seen: set[str] = set() # 1. end_scene image (highest priority for chain scenes) @@ -560,53 +373,34 @@ async def generate_scene_video_refs(self, scene: dict, orientation: str, if mid and mid not in seen: ref_ids.append(mid) seen.add(mid) + ref_names_r2v.append(c.get("name", "")) + if c.get("reference_image_url"): + ref_urls.append(c["reference_image_url"]) - if not ref_ids: - return {"error": "No valid reference media_ids for r2v"} - - # Check if already submitted (op_name saved from previous attempt) - existing_op = None - if request_id: - req_row = await crud.get_request(request_id) - existing_op = req_row.get("request_id") if req_row else None - - if existing_op: - logger.info("R2V already submitted (op=%s), re-polling", existing_op[:30]) - operations = [{"operation": {"name": existing_op}, "status": "MEDIA_GENERATION_STATUS_PENDING"}] - return await _poll_operations(self._client, operations) - - submit_result = await self._client.generate_video_from_references( - reference_media_ids=ref_ids, + job = ProviderJob( + job_id=request_id or uuid.uuid4().hex[:12], + kind=KIND_VIDEO_REFS, prompt=prompt, - project_id=pid, - scene_id=scene.get("id", ""), - aspect_ratio=aspect, - user_paygate_tier=tier, + orientation=orientation, + start_url=scene.get(f"{prefix}_image_url"), + reference_urls=tuple(ref_urls), + extra={ + "project_id": pid, + "tier": tier, + "aspect": aspect, + "scene_id": scene.get("id", ""), + "ref_media_ids": ref_ids, + "request_id": request_id, + "project_name": project.get("name") if project else "", + "display_order": scene.get("display_order", 0), + "reference_names": ref_names_r2v, + }, ) - - if _is_error(submit_result): - return submit_result - - operations = _extract_operations(submit_result) - if not operations: - return {"error": "R2V returned no operations"} - - op_name = operations[0].get("operation", {}).get("name", "") - if request_id: - await crud.update_request(request_id, request_id=op_name) - - status = operations[0].get("status", "") - if status == "MEDIA_GENERATION_STATUS_SUCCESSFUL": - logger.info("R2V completed immediately") - return submit_result - if status == "MEDIA_GENERATION_STATUS_FAILED": - return {"error": "R2V failed immediately"} - - logger.info("R2V submitted with %d refs, polling %d operations...", len(ref_ids), len(operations)) - return await _poll_operations(self._client, operations) + return await self._run_provider_job(job, provider) async def upscale_scene_video(self, scene: dict, orientation: str, - request_id: str = "") -> dict: + request_id: str = "", + provider: str | None = None) -> dict: """Upscale a completed scene video. Submits + polls. If a previous attempt already submitted (op_name saved in DB), skip @@ -618,161 +412,184 @@ async def upscale_scene_video(self, scene: dict, orientation: str, return {"error": f"No {prefix} video media_id for scene"} aspect = "VIDEO_ASPECT_RATIO_PORTRAIT" if orientation == "VERTICAL" else "VIDEO_ASPECT_RATIO_LANDSCAPE" - - # Check if already submitted (op_name saved from previous attempt) - existing_op = None - if request_id: - req_row = await crud.get_request(request_id) - existing_op = req_row.get("request_id") if req_row else None - - if existing_op: - # Already submitted — just re-poll - logger.info("Upscale already submitted (op=%s), re-polling", existing_op[:30]) - operations = [{"operation": {"name": existing_op}, "status": "MEDIA_GENERATION_STATUS_PENDING"}] - return await _poll_operations(self._client, operations, timeout=300) - - submit_result = await self._client.upscale_video( - media_id=video_media_id, - scene_id=scene.get("id", ""), - aspect_ratio=aspect, - ) - - if _is_error(submit_result): - return submit_result - - operations = _extract_operations(submit_result) - if not operations: - return {"error": "Upscale returned no operations"} - - # Check for inline rawBytes (4K video data returned directly) project = await crud.get_project(scene.get("_project_id", "0")) project_slug = slugify(project.get("name", "unnamed")) if project else slugify(scene.get("_project_id", "unnamed")) - display_order = scene.get("display_order", 0) - raw_path = _save_raw_bytes(operations, scene.get("id", ""), project_slug, display_order) - if raw_path: - logger.info("Upscale returned inline 4K video, saved to %s", raw_path) - # Inject saved path into result for downstream parsing - if not operations[0].get("operation"): - operations[0]["operation"] = {} - operations[0]["operation"].setdefault("metadata", {}).setdefault("video", {})["fifeUrl"] = raw_path - operations[0]["status"] = "MEDIA_GENERATION_STATUS_SUCCESSFUL" - return {"data": {"operations": operations}} - - op_name = operations[0].get("operation", {}).get("name", "") - if request_id: - await crud.update_request(request_id, request_id=op_name) - - status = operations[0].get("status", "") - if status == "MEDIA_GENERATION_STATUS_SUCCESSFUL": - logger.info("Upscale completed immediately") - return submit_result - if status == "MEDIA_GENERATION_STATUS_FAILED": - return {"error": "Upscale failed immediately"} - - logger.info("Upscale submitted, polling %d operations...", len(operations)) - poll_result = await _poll_operations(self._client, operations, timeout=300) - - # Check poll result for rawBytes too - poll_data = poll_result.get("data", poll_result) - poll_ops = poll_data.get("operations", []) - if poll_ops: - raw_path = _save_raw_bytes(poll_ops, scene.get("id", ""), project_slug, display_order) - if raw_path: - logger.info("Poll returned inline 4K video, saved to %s", raw_path) - poll_ops[0].setdefault("operation", {}).setdefault("metadata", {}).setdefault("video", {})["fifeUrl"] = raw_path - - return poll_result + + job = ProviderJob( + job_id=request_id or uuid.uuid4().hex[:12], + kind=KIND_UPSCALE, + prompt="", + orientation=orientation, + extra={ + "project_id": scene.get("_project_id", "0"), + "aspect": aspect, + "scene_id": scene.get("id", ""), + "video_media_id": video_media_id, + "request_id": request_id, + "project_slug": project_slug, + "display_order": scene.get("display_order", 0), + }, + ) + return await self._run_provider_job(job, provider) # ------------------------------------------------------------------ # Reference image operations # ------------------------------------------------------------------ - async def generate_reference_image(self, char: dict, project_id: str) -> dict: + async def generate_reference_image(self, char: dict, project_id: str, + job_id: str = "", + provider: str | None = None) -> dict: """Generate a reference image for a character/entity. - Handles fast-path (image exists, just upload) and normal path (generate + upload). - Updates character DB record with media_id and reference_image_url. - Returns result dict. + Handles fast-path (image exists, just register for a media id) and + normal path (generate + register). Updates character DB record with + media_id and reference_image_url. Returns result dict. """ entity_type = char.get("entity_type", "character") pid = project_id + prov = self._resolve_provider(provider) - # Fast path: image already generated, just need upload for UUID + # Fast path: image already exists — just needs a provider media id. existing_url = char.get("reference_image_url") if existing_url and not char.get("media_id"): - logger.info("%s '%s' already has image, retrying upload only (saving credits)", - entity_type, char["name"]) - upload_mid = await _upload_character_image(self._client, { - "name": char["name"], - "reference_image_url": existing_url, - }, pid) - - if upload_mid: - await crud.update_character(char["id"], media_id=upload_mid) - logger.info("%s '%s' upload retry succeeded: media_id=%s", - entity_type, char["name"], upload_mid[:30]) - return {"data": {"media": [{"name": upload_mid}]}} - - uuid_from_url = _extract_uuid_from_url(existing_url) - if uuid_from_url: - await crud.update_character(char["id"], media_id=uuid_from_url) - logger.info("%s '%s' extracted UUID from URL: media_id=%s", - entity_type, char["name"], uuid_from_url) - return {"data": {"media": [{"name": uuid_from_url}]}} - - return {"error": f"Upload retry failed for {char['name']} — image exists but cannot get UUID media_id"} - - # Normal path: generate image from scratch + logger.info("%s '%s' already has image, registering with provider '%s'", + entity_type, char["name"], prov.name) + result = await prov.register_existing_image( + existing_url, name=char.get("name", ""), project_id=pid) + if not _is_error(result): + data = result.get("data", {}) or {} + media = data.get("media") or [] + mid = media[0].get("name") if media else None + url = data.get("url", existing_url) + await crud.update_character(char["id"], media_id=mid, + reference_image_url=url) + logger.info("%s '%s' registered: media_id=%s", + entity_type, char["name"], (mid or "?")[:8]) + return result + + # Normal path: generate from scratch. prompt = char.get("image_prompt") or f"Character reference: {char['name']}. {char.get('description', '')}" - project = await crud.get_project(pid) if pid != "0" else None tier = project.get("user_paygate_tier", "PAYGATE_TIER_TWO") if project else "PAYGATE_TIER_TWO" aspect = _reference_aspect_ratio(entity_type) + orientation = "VERTICAL" if "PORTRAIT" in aspect else "HORIZONTAL" - result = await self._client.generate_images( - prompt=prompt, project_id=pid, aspect_ratio=aspect, - user_paygate_tier=tier, + job = ProviderJob( + job_id=job_id or uuid.uuid4().hex[:12], + kind=KIND_IMAGE, + prompt=prompt, + orientation=orientation, + extra={ + "kind": "reference_image", + "project_id": pid, + "tier": tier, + "aspect": aspect, + "entity_name": char["name"], + "entity_type": entity_type, + "composition": "portrait full-body, head-to-toe, front-facing, centered" + if orientation == "VERTICAL" + else "landscape establishing shot, level horizon, atmospheric", + }, ) + result = await self._run_provider_job(job, provider) if not _is_error(result): output_url = _extract_output_url(result, "GENERATE_IMAGE") - - if output_url: - direct_mid = _extract_media_id(result, "GENERATE_IMAGE") - if direct_mid and _is_uuid(direct_mid): - await crud.update_character(char["id"], media_id=direct_mid, reference_image_url=output_url) - logger.info("%s '%s' ref image ready (no upload needed, %s): media_id=%s", - entity_type, char["name"], aspect.split("_")[-1].lower(), direct_mid) + direct_mid = _extract_media_id(result, "GENERATE_IMAGE") + if direct_mid and _is_uuid(direct_mid): + await crud.update_character(char["id"], media_id=direct_mid, + reference_image_url=output_url) + logger.info("%s '%s' ref image ready (%s): media_id=%s", + entity_type, char["name"], + aspect.split("_")[-1].lower(), direct_mid) + return result + if prov.needs_media_id_registration() and output_url: + reg = await prov.register_existing_image( + output_url, name=char.get("name", ""), project_id=pid) + if not _is_error(reg): + reg_data = reg.get("data", {}) or {} + reg_media = reg_data.get("media") or [] + upload_mid = reg_media[0].get("name") if reg_media else None + await crud.update_character(char["id"], media_id=upload_mid, + reference_image_url=output_url) + logger.info("%s '%s' ref image uploaded (%s): media_id=%s", + entity_type, char["name"], + aspect.split("_")[-1].lower(), + (upload_mid or "?")[:30]) return result + logger.warning("%s '%s' upload failed, no media_id stored — will retry", + entity_type, char["name"]) + return {"error": f"Upload failed for {char['name']} — image generated but could not get UUID media_id"} + # Provider minted its own id — store whatever we got. + await crud.update_character(char["id"], media_id=direct_mid, + reference_image_url=output_url) + logger.info("%s '%s' ref image ready via %s: media_id=%s", + entity_type, char["name"], prov.name, (direct_mid or "?")[:8]) - upload_mid = await _upload_character_image(self._client, { - "name": char["name"], - "reference_image_url": output_url, - }, pid) + return result - if upload_mid: - await crud.update_character(char["id"], media_id=upload_mid, reference_image_url=output_url) - logger.info("%s '%s' ref image uploaded (%s): media_id=%s", - entity_type, char["name"], aspect.split("_")[-1].lower(), - upload_mid[:30] if upload_mid else "?") - else: - await crud.update_character(char["id"], reference_image_url=output_url) - uuid_from_url = _extract_uuid_from_url(output_url) - if uuid_from_url: - await crud.update_character(char["id"], media_id=uuid_from_url) - logger.info("%s '%s' extracted UUID from URL fallback: media_id=%s", - entity_type, char["name"], uuid_from_url) - return {"data": {"media": [{"name": uuid_from_url}]}} - logger.warning("%s '%s' upload failed, no media_id stored — will retry", - entity_type, char["name"]) - return {"error": f"Upload failed for {char['name']} — image generated but could not get UUID media_id"} + async def edit_character_image(self, char: dict, project_id: str, + source_media_id: str | None = None, + job_id: str = "", + provider: str | None = None) -> dict: + """Edit a character/location reference image. + + Resolves the provider for the request and publishes an edit_image + job; URL-based backends use the character's reference_image_url, + Flow uses the media_id. + """ + src = source_media_id or char.get("media_id") + edit_prompt = char.get("image_prompt") or char.get("description", "") + aspect = "IMAGE_ASPECT_RATIO_LANDSCAPE" if char.get("entity_type") in ("location",) else "IMAGE_ASPECT_RATIO_PORTRAIT" + orientation = "VERTICAL" if "PORTRAIT" in aspect else "HORIZONTAL" + project = await crud.get_project(project_id) if project_id != "0" else None + tier = project.get("user_paygate_tier", "PAYGATE_TIER_ONE") if project else "PAYGATE_TIER_ONE" + job = ProviderJob( + job_id=job_id or uuid.uuid4().hex[:12], + kind=KIND_EDIT_IMAGE, + prompt=edit_prompt, + orientation=orientation, + source_url=char.get("reference_image_url"), + extra={ + "project_id": project_id, + "tier": tier, + "aspect": aspect, + "source_media_id": src, + "entity_name": char.get("name"), + "entity_type": char.get("entity_type", "character"), + }, + ) + result = await self._run_provider_job(job, provider) + if not _is_error(result): + mid = _extract_media_id(result, "GENERATE_IMAGE") + url = _extract_output_url(result, "GENERATE_IMAGE") + await crud.update_character(char["id"], media_id=mid, + reference_image_url=url) + logger.info("%s '%s' ref image edited via %s: media_id=%s", + char.get("entity_type", "character"), char.get("name"), + self._resolve_provider(provider).name, (mid or "?")[:8]) return result # ------------------------------------------------------------------ # Queue-based wrappers (create request in DB for processor pickup) # ------------------------------------------------------------------ + async def _resolve_chain_end_url(self, scene: dict, prefix: str) -> str | None: + """Assistant-mode chaining: find the child scene's image URL for this scene's end frame.""" + video_id = scene.get("video_id") + if not video_id: + return None + try: + for s in await crud.list_scenes(video_id=video_id): + if s.get("parent_scene_id") == scene.get("id"): + url = s.get(f"{prefix}_image_url") + if url: + return url + except Exception as e: + logger.warning("Could not resolve chain end frame: %s", e) + return None + async def _resolve_queue_orientation(self, video_id: str, orientation: str | None) -> str: """Resolve orientation for queue methods: explicit > video table > VERTICAL.""" if orientation: @@ -783,81 +600,97 @@ async def _resolve_queue_orientation(self, video_id: str, orientation: str | Non return "VERTICAL" async def queue_scene_image(self, scene_id: str, project_id: str, - video_id: str, orientation: str | None = None) -> str: + video_id: str, orientation: str | None = None, + provider: str | None = None) -> str: """Queue a GENERATE_IMAGE request. Returns request id.""" orientation = await self._resolve_queue_orientation(video_id, orientation) row = await crud.create_request( req_type="GENERATE_IMAGE", orientation=orientation, scene_id=scene_id, project_id=project_id, video_id=video_id, + provider=provider, ) return row["id"] async def queue_edit_scene_image(self, scene_id: str, project_id: str, video_id: str, orientation: str | None = None, edit_prompt: str | None = None, - source_media_id: str | None = None) -> str: + source_media_id: str | None = None, + provider: str | None = None) -> str: """Queue an EDIT_IMAGE request. Returns request id.""" orientation = await self._resolve_queue_orientation(video_id, orientation) row = await crud.create_request( req_type="EDIT_IMAGE", orientation=orientation, scene_id=scene_id, project_id=project_id, video_id=video_id, edit_prompt=edit_prompt, source_media_id=source_media_id, + provider=provider, ) return row["id"] async def queue_scene_video(self, scene_id: str, project_id: str, - video_id: str, orientation: str | None = None) -> str: + video_id: str, orientation: str | None = None, + provider: str | None = None) -> str: """Queue a GENERATE_VIDEO request. Returns request id.""" orientation = await self._resolve_queue_orientation(video_id, orientation) row = await crud.create_request( req_type="GENERATE_VIDEO", orientation=orientation, scene_id=scene_id, project_id=project_id, video_id=video_id, + provider=provider, ) return row["id"] async def queue_scene_video_refs(self, scene_id: str, project_id: str, - video_id: str, orientation: str | None = None) -> str: + video_id: str, orientation: str | None = None, + provider: str | None = None) -> str: """Queue a GENERATE_VIDEO_REFS request. Returns request id.""" orientation = await self._resolve_queue_orientation(video_id, orientation) row = await crud.create_request( req_type="GENERATE_VIDEO_REFS", orientation=orientation, scene_id=scene_id, project_id=project_id, video_id=video_id, + provider=provider, ) return row["id"] async def queue_upscale_video(self, scene_id: str, project_id: str, - video_id: str, orientation: str | None = None) -> str: + video_id: str, orientation: str | None = None, + provider: str | None = None) -> str: """Queue an UPSCALE_VIDEO request. Returns request id.""" orientation = await self._resolve_queue_orientation(video_id, orientation) row = await crud.create_request( req_type="UPSCALE_VIDEO", orientation=orientation, scene_id=scene_id, project_id=project_id, video_id=video_id, + provider=provider, ) return row["id"] - async def queue_reference_image(self, character_id: str, project_id: str) -> str: + async def queue_reference_image(self, character_id: str, project_id: str, + provider: str | None = None) -> str: """Queue a GENERATE_CHARACTER_IMAGE request. Returns request id.""" row = await crud.create_request( req_type="GENERATE_CHARACTER_IMAGE", character_id=character_id, project_id=project_id, + provider=provider, ) return row["id"] async def queue_regenerate_scene_image(self, scene_id: str, project_id: str, - video_id: str, orientation: str | None = None) -> str: + video_id: str, orientation: str | None = None, + provider: str | None = None) -> str: """Queue a REGENERATE_IMAGE request (bypasses skip check). Returns request id.""" orientation = await self._resolve_queue_orientation(video_id, orientation) row = await crud.create_request( req_type="REGENERATE_IMAGE", orientation=orientation, scene_id=scene_id, project_id=project_id, video_id=video_id, + provider=provider, ) return row["id"] - async def queue_regenerate_character_image(self, character_id: str, project_id: str) -> str: + async def queue_regenerate_character_image(self, character_id: str, project_id: str, + provider: str | None = None) -> str: """Queue a REGENERATE_CHARACTER_IMAGE request (clears existing, regenerates). Returns request id.""" row = await crud.create_request( req_type="REGENERATE_CHARACTER_IMAGE", character_id=character_id, project_id=project_id, + provider=provider, ) return row["id"] @@ -941,56 +774,6 @@ async def _build_video_prompt(base_prompt: str, scene: dict, project_id: str | N return " ".join(parts) -async def _upload_character_image(client: FlowClient, char: dict, project_id: str) -> str | None: - """Download character reference image and upload to Google Flow to get media_id.""" - ref_url = char.get("reference_image_url") - if not ref_url: - return None - - try: - try: - import certifi - ssl_ctx = ssl.create_default_context(cafile=certifi.where()) - except ImportError: - ssl_ctx = ssl.create_default_context() - async with aiohttp.ClientSession() as session: - async with session.get(ref_url, ssl=ssl_ctx) as resp: - if resp.status != 200: - logger.error("Failed to download character image: HTTP %d", resp.status) - return None - image_bytes = await resp.read() - content_type = resp.headers.get("content-type", "image/jpeg") - - if "png" in content_type: - mime = "image/png" - elif "gif" in content_type: - mime = "image/gif" - else: - mime = "image/jpeg" - - ext = mime.split("/")[-1] - file_name = f"{char.get('name', 'character')}.{ext}" - - encoded = base64.b64encode(image_bytes).decode("utf-8") - result = await client.upload_image( - encoded, mime_type=mime, project_id=project_id, file_name=file_name, - ) - - if result.get("_mediaId"): - return result["_mediaId"] - - data = result.get("data", {}) - if isinstance(data, dict): - media = data.get("media", {}) - if isinstance(media, dict) and media.get("name"): - return media["name"] - - return None - except Exception as e: - logger.exception("Failed to upload character image: %s", e) - return None - - # ------------------------------------------------------------------ # Module-level singleton # ------------------------------------------------------------------ diff --git a/agent/sdk/services/provider_base.py b/agent/sdk/services/provider_base.py new file mode 100644 index 000000000..650654cce --- /dev/null +++ b/agent/sdk/services/provider_base.py @@ -0,0 +1,143 @@ +"""Media provider abstraction — FlowKit works with any generation backend. + +A :class:`MediaProvider` executes one :class:`ProviderJob` and returns a +result dict in the same shape the rest of the pipeline already understands:: + + {"data": {...}} on success + {"error": "..."} on failure + +Two provider flavours exist: + +* **direct** (e.g. Google Flow) — submits to the backend and waits for the + result inside the worker process. +* **delegated** (e.g. a Muse agent or any external AI agent) — the provider + publishes the job to the provider-job queue; an external worker claims it + via the HTTP API, renders, and posts the result back. + +``OperationService`` never talks to a backend directly — it builds a +:class:`ProviderJob` (backend-agnostic inputs) plus backend-specific knobs in +``job.extra``, resolves the provider for the request, and calls +``provider.run(job)``. +""" + +from __future__ import annotations + +import logging +from abc import ABC, abstractmethod +from dataclasses import dataclass, field +from typing import Optional + +logger = logging.getLogger(__name__) + +# ── Job kinds ────────────────────────────────────────────────────────────── +KIND_IMAGE = "image" # prompt (+refs) -> image (scene / reference) +KIND_EDIT_IMAGE = "edit_image" # source image + prompt -> edited image +KIND_VIDEO = "video" # start image (+end) -> video (i2v) +KIND_VIDEO_REFS = "video_refs" # reference images -> video (r2v) +KIND_UPSCALE = "upscale" # video -> upscaled video +KIND_AUDIO = "audio" # text (+voice hints) -> speech audio (TTS) + +_ALL_KINDS = (KIND_IMAGE, KIND_EDIT_IMAGE, KIND_VIDEO, KIND_VIDEO_REFS, + KIND_UPSCALE, KIND_AUDIO) + + +@dataclass(frozen=True) +class ProviderCapabilities: + """What a provider can do, plus its own throttling limits. + + Throttling is per-provider: the worker reads these instead of the old + global MAX_CONCURRENT_REQUESTS / API_COOLDOWN. + """ + + generate_image: bool = True + edit_image: bool = True + generate_video_i2v: bool = True + generate_video_r2v: bool = True + upscale: bool = False + generate_audio: bool = False + max_concurrent: int = 5 + cooldown_s: float = 0.0 + + def supports(self, kind: str) -> bool: + return { + KIND_IMAGE: self.generate_image, + KIND_EDIT_IMAGE: self.edit_image, + KIND_VIDEO: self.generate_video_i2v, + KIND_VIDEO_REFS: self.generate_video_r2v, + KIND_UPSCALE: self.upscale, + KIND_AUDIO: self.generate_audio, + }.get(kind, False) + + +@dataclass +class ProviderJob: + """One unit of generation work, described backend-agnostically. + + ``extra`` carries backend-specific knobs the generic fields cannot + express. Convention for the built-in providers: + + * flow: project_id, tier, aspect, character_media_ids, + source_media_id, start_media_id, end_media_id, + ref_media_ids, request_id, scene_id + * assistant: scene_id, project_id, project_name, display_order, + reference_names, entity_name, entity_type, composition + """ + + job_id: str + kind: str + prompt: str = "" + orientation: str = "VERTICAL" # "VERTICAL" | "HORIZONTAL" + source_url: Optional[str] = None # edit_image input + start_url: Optional[str] = None # video start frame + end_url: Optional[str] = None # video end frame (chained) + reference_urls: tuple = () # consistency references + duration_s: Optional[float] = None + extra: dict = field(default_factory=dict) + + def __post_init__(self) -> None: + if self.kind not in _ALL_KINDS: + raise ValueError(f"Unknown provider job kind: {self.kind!r}") + + +class MediaProvider(ABC): + """Abstract generation backend.""" + + name: str = "base" + display_name: str = "Base provider" + capabilities: ProviderCapabilities = ProviderCapabilities() + + @abstractmethod + async def run(self, job: ProviderJob) -> dict: + """Execute one job. Returns {"data": ...} or {"error": ...}.""" + + def is_available(self) -> bool: + """Whether this provider can currently run jobs. + + Flow needs the Chrome extension connected; the assistant is + always available (filesystem bridge, no credentials). + """ + return True + + def check(self, job: ProviderJob) -> Optional[str]: + """Return an error string if this provider cannot run the job.""" + if not self.capabilities.supports(job.kind): + return ( + f"Provider '{self.name}' does not support " + f"job kind '{job.kind}'" + ) + return None + + def needs_media_id_registration(self) -> bool: + """Whether generated outputs must be registered back to obtain a + provider media id (Flow needs this; UUID-minting providers don't).""" + return False + + async def register_existing_image( + self, url: str, *, name: str = "", project_id: str = "" + ) -> dict: + """Turn an already-existing image URL into a provider media id. + + Used by the reference-image fast path ("image exists, just needs an + id"). Providers that have no id concept may mint a UUID. + """ + raise NotImplementedError(f"{self.name} has no register_existing_image") diff --git a/agent/sdk/services/registry.py b/agent/sdk/services/registry.py new file mode 100644 index 000000000..904d02612 --- /dev/null +++ b/agent/sdk/services/registry.py @@ -0,0 +1,104 @@ +"""Standalone provider registry. + +The registry owns all registered :class:`MediaProvider` backends and is +shared between the SDK (``OperationService``) and the HTTP layer +(``/api/providers/status``), so provider discovery and health reporting do +not depend on having an ``OperationService`` instance around. + +Built-ins: + - ``flow`` — Google Flow via the Chrome extension + FlowClient. + Only available when the extension is connected. + - ``assistant`` — the local assistant (e.g. Pax/Muse) via the persistent + provider-job queue (``provider_job`` table + ``/api/provider-jobs``). + Always available, needs no Chrome. + +Extra backends (a Sora adapter, a local SDXL worker, …) can be registered +at startup and are then selectable per request through the ``provider`` +field on requests / the ``DEFAULT_PROVIDER`` config. +""" + +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING + +from agent.config import DEFAULT_PROVIDER +from agent.sdk.services.assistant_provider import AssistantProvider +from agent.sdk.services.flow_provider import FlowProvider +from agent.sdk.services.provider_base import MediaProvider + +if TYPE_CHECKING: + from agent.services.flow_client import FlowClient + +logger = logging.getLogger(__name__) + + +class ProviderRegistry: + """Owns the set of available media providers.""" + + def __init__( + self, + flow_client: "FlowClient | None" = None, + extra: dict[str, MediaProvider] | None = None, + ): + providers: dict[str, MediaProvider] = {} + if flow_client is not None: + providers["flow"] = FlowProvider(flow_client) + providers["assistant"] = AssistantProvider() + if extra: + providers.update(extra) + self._providers = providers + + @property + def providers(self) -> dict[str, MediaProvider]: + return self._providers + + def names(self) -> list[str]: + return list(self._providers) + + def get(self, name: str | None) -> MediaProvider | None: + key = (name or "").strip().lower() + return self._providers.get(key) + + def register(self, name: str, provider: MediaProvider) -> None: + """Add or replace a provider backend.""" + self._providers[name.strip().lower()] = provider + + def resolve(self, name: str | None = None) -> MediaProvider: + """Resolve a provider by name, falling back to the configured default.""" + key = (name or DEFAULT_PROVIDER).strip().lower() + provider = self._providers.get(key) + if provider is None: + logger.warning( + "Unknown provider '%s', falling back to default '%s'", + key, DEFAULT_PROVIDER, + ) + provider = self._providers.get(DEFAULT_PROVIDER) + if provider is None: + # Last resort: any provider at all. + provider = next(iter(self._providers.values())) + return provider + + def status(self) -> list[dict]: + """Serializable status for every registered provider. + + Used by ``GET /api/providers/status``. + """ + out = [] + for name, provider in self._providers.items(): + caps = provider.capabilities + out.append({ + "name": name, + "display_name": getattr(provider, "display_name", name), + "available": provider.is_available(), + "capabilities": { + "generate_image": caps.generate_image, + "edit_image": caps.edit_image, + "generate_video_i2v": caps.generate_video_i2v, + "generate_video_r2v": caps.generate_video_r2v, + "upscale": caps.upscale, + "max_concurrent": caps.max_concurrent, + "cooldown_s": caps.cooldown_s, + }, + }) + return out diff --git a/agent/services/cli_providers.py b/agent/services/cli_providers.py index 81977d0cc..20559af57 100644 --- a/agent/services/cli_providers.py +++ b/agent/services/cli_providers.py @@ -1,10 +1,15 @@ -"""What each AI CLI accepts, and which one a given role runs on. +"""What each AI reviewer accepts, and which one a given role runs on. Three CLIs back the vision work: Claude Code (`claude`), Google Antigravity (`agy`) and OpenAI Codex (`codex`). They disagree about almost everything — flag names, effort ladders, whether an unknown model slug is an error — so the differences live here rather than being re-derived at each call site. +A fourth reviewer, `muse`, is the assistant itself (Muse): no binary, no +model catalog, no effort ladder. It is an official provider option, not a +default — a role pointed at `muse` means Muse scores contact sheets by +hand via the review-sheets / review-submit endpoints (see `/fk-review-video`). + Config lives in `agent/providers.json`, hot-reloaded into `config.CLI_PROVIDERS`: {"active": "claude", @@ -31,6 +36,9 @@ "claude": "claude", "agy": "agy", "codex": "codex", + # `muse` has no binary: the reviewer IS the assistant (Muse), reading + # contact sheets through its own vision and scoring via review-submit. + "muse": None, } # Reasoning-effort ladders, as each CLI actually accepts them. agy's own help @@ -42,6 +50,7 @@ "claude": ("low", "medium", "high", "xhigh", "max"), "agy": ("low", "medium", "high"), "codex": ("low", "medium", "high", "xhigh", "max"), + "muse": (), } # agy's model slugs carry the effort in them — gemini-3.8-flash-low, @@ -55,6 +64,7 @@ "claude": False, "agy": True, "codex": False, + "muse": False, } # Whether the catalog we can list is the whole truth. agy validates --model @@ -66,6 +76,7 @@ "claude": False, "agy": True, "codex": False, + "muse": False, } # Claude Code resolves these aliases itself; full model names also work, which @@ -155,9 +166,16 @@ async def validate_role_entry(role: str, entry: dict) -> dict: raise ValueError( f"Unknown provider '{provider}' for role '{role}'. Known: {sorted(PROVIDER_BINARIES)}" ) - if not shutil.which(PROVIDER_BINARIES[provider]): + binary = PROVIDER_BINARIES[provider] + if binary is not None and not shutil.which(binary): + raise ValueError( + f"'{binary}' binary not found on PATH — install it first" + ) + # `muse` (the assistant itself) needs no binary and takes no model/effort. + if provider == "muse" and (entry.get("model") or entry.get("effort")): raise ValueError( - f"'{PROVIDER_BINARIES[provider]}' binary not found on PATH — install it first" + "The 'muse' reviewer is the assistant itself — it takes no model " + "or effort. Clear both fields." ) effort = entry.get("effort") or None @@ -282,6 +300,8 @@ async def list_models(provider: str, force: bool = False) -> list[dict]: if hit and now - hit[0] < _CATALOG_TTL_S: return list(hit[1]) + if provider == "muse": + return [] # no binary, no catalog — the assistant is the reviewer if not shutil.which(PROVIDER_BINARIES[provider]): return [] diff --git a/agent/services/post_process.py b/agent/services/post_process.py index a8287c036..2efade3c8 100644 --- a/agent/services/post_process.py +++ b/agent/services/post_process.py @@ -17,6 +17,46 @@ def _clamp_float(value: float, name: str, lo: float = _FLOAT_MIN, hi: float = _F return value +def probe_duration(path: str) -> float | None: + """Return media duration in seconds via ffprobe, or None on failure.""" + try: + probe = subprocess.run( + ["ffprobe", "-v", "quiet", "-show_entries", "format=duration", + "-of", "csv=p=0", str(path)], + capture_output=True, text=True, timeout=30, + ) + return float(probe.stdout.strip()) + except (ValueError, AttributeError, subprocess.SubprocessError, OSError): + logger.error("probe_duration failed for %s", path) + return None + + +def normalize_clip(input_path: str, output_path: str, size: str | None = None, + fps: int = 30) -> bool: + """Re-encode one clip to uniform h264/yuv420p + AAC so concat -c copy is safe. + + Clips from different providers (Flow vs assistant) may differ in codec, + pixel format, or timebase; normalizing first avoids concat failures. + """ + cmd = ["ffmpeg", "-y", "-i", str(input_path), + "-c:v", "libx264", "-pix_fmt", "yuv420p", "-r", str(int(fps)), + "-c:a", "aac", "-b:a", "128k", "-ar", "48000", "-ac", "2", + "-movflags", "+faststart"] + if size: + cmd += ["-vf", f"scale={size}:force_original_aspect_ratio=decrease," + f"pad={size}:(ow-iw)/2:(oh-ih)/2"] + cmd.append(str(output_path)) + try: + result = subprocess.run(cmd, capture_output=True, text=True, timeout=300) + except (subprocess.SubprocessError, OSError) as e: + logger.error("Normalize failed for %s: %s", input_path, e) + return False + if result.returncode != 0: + logger.error("Normalize failed for %s: %s", input_path, result.stderr[-300:]) + return False + return True + + def trim_video(input_path: str, output_path: str, start: float, end: float) -> bool: """Trim video to [start, end] seconds.""" if not Path(input_path).exists(): diff --git a/agent/services/video_reviewer.py b/agent/services/video_reviewer.py index 7afaf6fdc..5529e0c55 100644 --- a/agent/services/video_reviewer.py +++ b/agent/services/video_reviewer.py @@ -1,4 +1,4 @@ -"""Video review engine — frame extraction + Claude Vision analysis. +"""Video review engine — frame extraction + AI vision analysis. Two analysis backends: 1. CLI subprocess (claude/agy/codex, default) — no API key needed, uses contact sheets @@ -14,6 +14,7 @@ import subprocess import tempfile from pathlib import Path +from urllib.parse import urlparse import ssl @@ -140,6 +141,24 @@ async def _download_video(url: str, dest: Path) -> None: f.write(chunk) +def _local_media_path(url: str) -> Path | None: + """Return the local file for file:// URLs or plain paths, else None. + + Provider-neutral: clips produced by the assistant provider (or any local + backend) are already on disk — no download needed. + """ + if not url: + return None + parsed = urlparse(url) + if parsed.scheme == "file": + p = Path(parsed.path) + return p if p.is_file() else None + if not parsed.scheme: + p = Path(url) + return p if p.is_file() else None + return None + + async def _download_via_get_media(media_id: str, dest: Path) -> None: """Re-fetch a clip through the media record when its stored url has expired. @@ -645,7 +664,19 @@ async def _analyze_cli( `role` is passed in by a multi-scene review so every scene runs on the same backend — see `review_video`. + + The `muse` reviewer (Muse, the assistant itself) has no CLI to shell out to: + pointing the role at it and calling this endpoint is a configuration + mistake, not a review — build sheets via `review-sheets` and submit scores + via `review-submit` instead (see `/fk-review-video`). """ + if (role or {}).get("provider") == "muse": + raise RuntimeError( + "video_review role is 'muse' (Muse, the assistant itself): the server " + "cannot invoke it. Use POST /api/videos/<VID>/review-sheets to " + "build contact sheets, score them by hand, then POST " + "/api/videos/<VID>/review-submit." + ) if timestamped is None: timestamped = _has_drawtext() n_sheets = len(contact_sheets) @@ -743,6 +774,41 @@ async def _analyze_sdk( # ─── Public API ─────────────────────────────────────────────── +async def _fetch_scene_video( + scene: dict, orient_prefix: str, tmp_path: Path, +): + """Resolve a scene's clip to a local path (download if remote). + + Provider-neutral: file:// URLs and local paths are used directly; + http(s) URLs are downloaded, with the Flow get_media RPC as a fallback + when the extension is connected. + """ + video_url = scene.get(f"{orient_prefix}_video_url") + if not video_url: + raise ValueError(f"No video URL found for scene {scene['id']}") + + local = _local_media_path(video_url) + if local: + logger.info("Reviewing local video for scene %s: %s", scene["id"], local) + return local + video_path = tmp_path / "scene.mp4" + logger.info("Downloading video for scene %s from %s", scene["id"], video_url[:80]) + try: + await _download_video(video_url, video_path) + except (_URLExpiredError, Exception) as e: + # URL expired or download failed — fall back to get_media API. + # That is a Flow-only mechanism; skip it for other providers. + media_id = scene.get(f"{orient_prefix}_video_media_id") + from agent.services.flow_client import get_flow_client + if not media_id or not get_flow_client().connected: + raise ValueError( + f"Cannot fetch video for scene {scene['id']}: {e}") + logger.info("URL download failed for scene %s (%s), fetching via get_media %s", + scene["id"], type(e).__name__, media_id[:12]) + await _download_via_get_media(media_id, video_path) + return video_path + + async def review_scene_video( scene: dict, characters: list, @@ -751,34 +817,17 @@ async def review_scene_video( project_id: str = None, role: dict | None = None, ) -> SceneReview: - """Review a single scene's video via frame extraction + Claude Vision. + """Review a single scene's video via frame extraction + AI vision. `role` pins the provider/model/effort. `review_video` resolves it once and passes it down; a single-scene call resolves it here. """ fps = REVIEW_FPS_DEEP if mode == "deep" else REVIEW_FPS_LIGHT - orient_prefix = "vertical" if orientation.upper() == "VERTICAL" else "horizontal" - video_url = scene.get(f"{orient_prefix}_video_url") - - if not video_url: - raise ValueError(f"No video URL found for scene {scene['id']} ({orientation})") with tempfile.TemporaryDirectory() as tmp: tmp_path = Path(tmp) - video_path = tmp_path / "scene.mp4" - - logger.info("Downloading video for scene %s from %s", scene["id"], video_url[:80]) - try: - await _download_video(video_url, video_path) - except (_URLExpiredError, Exception) as e: - # URL expired or download failed — fall back to get_media API - media_id = scene.get(f"{orient_prefix}_video_media_id") - if not media_id: - raise ValueError(f"No media_id to refresh URL for scene {scene['id']}") - logger.info("URL download failed for scene %s (%s), fetching via get_media %s", - scene["id"], type(e).__name__, media_id[:12]) - await _download_via_get_media(media_id, video_path) + video_path = await _fetch_scene_video(scene, orient_prefix, tmp_path) if ANTHROPIC_API_KEY: # SDK path: individual frames @@ -808,6 +857,63 @@ async def review_scene_video( timestamped=timestamped, role=role, ) + return score_review_answer(scene["id"], result, n_frames, fps) + + +async def prepare_review_sheets( + scene: dict, + characters: list, + mode: str, + orientation: str, + persist_dir: Path, +) -> dict: + """Build contact sheets for a scene WITHOUT calling any reviewer. + + Sheets are written under ``persist_dir`` (survives the call) so an + external reviewer — e.g. Muse scoring by hand — can read them later. + Returns sheet paths, frame metadata, and the rubric prompt the reviewer + should answer. + + Raises ValueError when the scene has no fetchable video. + """ + fps = REVIEW_FPS_DEEP if mode == "deep" else REVIEW_FPS_LIGHT + orient_prefix = "vertical" if orientation.upper() == "VERTICAL" else "horizontal" + + scene_dir = Path(persist_dir) / scene["id"] + scene_dir.mkdir(parents=True, exist_ok=True) + + with tempfile.TemporaryDirectory() as tmp: + tmp_path = Path(tmp) + video_path = await _fetch_scene_video(scene, orient_prefix, tmp_path) + contact_sheets, n_frames, timestamped = await asyncio.get_event_loop().run_in_executor( + None, _create_contact_sheets, str(video_path), fps, str(scene_dir) + ) + if not contact_sheets or not all(s.exists() for s in contact_sheets): + raise RuntimeError(f"Contact sheets not created for scene {scene['id']}") + prompt = _build_prompt(n_frames, fps, len(contact_sheets), scene) + return { + "scene_id": scene["id"], + "sheets": [str(s) for s in contact_sheets], + "n_frames": n_frames, + "fps": fps, + "timestamped": timestamped, + "prompt": prompt, + "scene_prompt": scene.get("prompt") or "", + "video_prompt": scene.get("video_prompt") or "", + "character_names": _parse_character_names(scene) or [c.get("name") for c in (characters or []) if c.get("name")], + } + + +def score_review_answer( + scene_id: str, result: dict, n_frames: int, fps: float, +) -> SceneReview: + """Turn a raw reviewer answer (dimensions/errors/usable_segments) into a SceneReview. + + Shared by every reviewer backend — CLI, SDK, or Muse scoring contact + sheets by hand. Applies the same repairs, severity rules, CRITICAL caps, + and overall computation. + """ + errors = [] # Parse structured errors with severity. # # The three fields are NOT equal, so they are not treated equally. Only @@ -912,11 +1018,11 @@ async def review_scene_video( logger.warning( "Scene %s: review answer needed repair — %d error field(s) defaulted, " "%d usable segment(s) unreadable", - scene["id"], repaired_fields, dropped_segments, + scene_id, repaired_fields, dropped_segments, ) return SceneReview( - scene_id=scene["id"], + scene_id=scene_id, overall_score=overall, verdict=_verdict(overall), dimensions=dims, diff --git a/agent/worker/_parsing.py b/agent/worker/_parsing.py index d74071c73..c8bd76234 100644 --- a/agent/worker/_parsing.py +++ b/agent/worker/_parsing.py @@ -109,3 +109,49 @@ def _extract_output_url(result: dict, req_type: str) -> str: return "" # URL will be set by _save_raw_bytes in operations.py return data.get("videoUri", data.get("imageUri", "")) + + +def _extract_operations(result: dict) -> list[dict]: + """Extract operations list from video gen / upscale submit response. + + Supports two response schemas: + - OLD (Lite/Fast/Ultra): {"data": {"operations": [{"operation": {"name": ...}, "status": ...}]}} + - NEW (Low Priority — veo_3_1_*_low_priority, *_ultra_relaxed): + {"data": {"workflows": [{"name": "...", "metadata": {"primaryMediaId": "..."}}], + "media": [{"name": "...", ...}]}} + """ + data = result.get("data", result) + ops = data.get("operations", []) + if ops: + for op in ops: + op_name = op.get("operation", {}).get("name") + if not op_name: + logger.warning("Operation missing name: %s", op) + return ops + + # NEW schema: workflows + media → synthesize operation entries + workflows = data.get("workflows", []) + media_list = data.get("media", []) + if not workflows or not media_list: + return [] + + media_by_id = {m.get("name"): m for m in media_list if m.get("name")} + synthesized = [] + for wf in workflows: + wf_name = wf.get("name", "") + meta = wf.get("metadata", {}) + primary_media_id = meta.get("primaryMediaId", "") + if not wf_name or not primary_media_id: + continue + synthesized.append({ + "operation": { + "name": wf_name, + "metadata": {"video": {"mediaId": primary_media_id}}, + }, + "status": "MEDIA_GENERATION_STATUS_PENDING", + "_workflow_mode": True, + "_primary_media_id": primary_media_id, + }) + if synthesized: + logger.info("Detected workflow-schema response: %d workflow(s) → synthesized", len(synthesized)) + return synthesized diff --git a/agent/worker/assistant_worker.py b/agent/worker/assistant_worker.py new file mode 100644 index 000000000..641470774 --- /dev/null +++ b/agent/worker/assistant_worker.py @@ -0,0 +1,235 @@ +#!/usr/bin/env python3 +"""Reference worker for the FlowKit provider-job queue. + +This script implements the *worker side* of the provider-job protocol against +the FlowKit HTTP API (``/api/provider-jobs``). It is the counterpart to +``AssistantProvider.run()`` (the producer side), which inserts QUEUED rows and +blocks until a worker finishes them. + +Protocol (equivalent curl shown for agents that prefer raw HTTP): + + # 1. Long-poll for the next claimable job (claims it atomically, lease granted) + GET /api/provider-jobs/wait-next?provider=assistant&worker_id=w1&timeout_s=60 + # -> 200 + job row, or 204 when nothing arrives before the timeout + + # 2. While working, extend the lease (every ~lease_ttl/3; default ttl 300s) + POST /api/provider-jobs/{id}/heartbeat {"worker_id": "w1", "lease_ttl_s": 300} + # Only the lease holder may heartbeat / progress / complete / fail. + # complete/fail are idempotent: repeating them on an already-terminal + # job returns the existing row; a stranger's attempt gets 409. + + # 3. Optionally report progress + POST /api/provider-jobs/{id}/progress {"worker_id": "w1", "progress": 50, "message": "rendering"} + + # 4. Finish + POST /api/provider-jobs/{id}/complete {"worker_id": "w1", "result": {"output_url": "...", "media_id": "<uuid>"}} + # or + POST /api/provider-jobs/{id}/fail {"worker_id": "w1", "error": "..."} + +The job row carries everything needed to generate:: + + {"id": ..., "kind": "image|edit_image|i2v|r2v|upscale", + "prompt": ..., "orientation": "VERTICAL|HORIZONTAL", + "source_url": ..., "end_url": ..., + "extra": {"reference_urls": [...], "aspect": ..., ...}} + +``complete`` expects ``result.output_url`` — a ``file://`` or ``https://`` URL +of the finished media — and an optional ``result.media_id`` (a UUID is minted +when absent). + +To build a real worker, replace :func:`process_job` with actual generation +(image/video model calls, uploads, ...). The protocol loop, leasing, and +heartbeat plumbing below are reusable as-is via :class:`ProviderJobClient`. + +Usage: + python -m agent.worker.assistant_worker --provider assistant --worker-id pax-1 + python -m agent.worker.assistant_worker --once # process a single job then exit +""" + +from __future__ import annotations + +import argparse +import asyncio +import logging +import sys + +import aiohttp + +logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") +logger = logging.getLogger("assistant_worker") + + +class ProviderJobClient: + """Thin async client for the /api/provider-jobs worker endpoints.""" + + def __init__(self, api_base: str, worker_id: str, lease_ttl_s: float = 300): + self.api_base = api_base.rstrip("/") + self.worker_id = worker_id + self.lease_ttl_s = lease_ttl_s + self._session: aiohttp.ClientSession | None = None + + async def __aenter__(self): + self._session = aiohttp.ClientSession() + return self + + async def __aexit__(self, *exc): + if self._session: + await self._session.close() + self._session = None + + def _url(self, path: str) -> str: + return f"{self.api_base}/provider-jobs{path}" + + async def wait_next(self, provider: str, timeout_s: float = 60) -> dict | None: + """Long-poll for the next claimable job; returns the claimed row or None.""" + assert self._session is not None + params = {"provider": provider, "worker_id": self.worker_id, + "lease_ttl_s": self.lease_ttl_s, "timeout_s": timeout_s} + async with self._session.get(self._url("/wait-next"), params=params) as resp: + if resp.status == 204: + return None + resp.raise_for_status() + return await resp.json() + + async def heartbeat(self, job_id: str) -> dict: + assert self._session is not None + async with self._session.post( + self._url(f"/{job_id}/heartbeat"), + json={"worker_id": self.worker_id, "lease_ttl_s": self.lease_ttl_s}) as resp: + resp.raise_for_status() + return await resp.json() + + async def progress(self, job_id: str, pct: int, message: str | None = None) -> None: + assert self._session is not None + async with self._session.post( + self._url(f"/{job_id}/progress"), + json={"worker_id": self.worker_id, + "progress": pct, "message": message}) as resp: + resp.raise_for_status() + + async def complete(self, job_id: str, output_url: str, + media_id: str | None = None) -> dict: + assert self._session is not None + result = {"output_url": output_url} + if media_id: + result["media_id"] = media_id + async with self._session.post( + self._url(f"/{job_id}/complete"), + json={"worker_id": self.worker_id, + "result": result}) as resp: + resp.raise_for_status() + return await resp.json() + + async def fail(self, job_id: str, error: str) -> dict: + assert self._session is not None + async with self._session.post( + self._url(f"/{job_id}/fail"), + json={"worker_id": self.worker_id, + "error": error}) as resp: + resp.raise_for_status() + return await resp.json() + + +# --------------------------------------------------------------------------- +# Generation hook — replace this with real media generation. +# --------------------------------------------------------------------------- + +async def process_job(job: dict, client: ProviderJobClient) -> dict: + """Generate the media for *job*. + + Return ``{"output_url": ..., "media_id": ...}`` (media_id optional). + Raise on failure — the caller reports it via ``/fail``. + + The default implementation is a stub: subclass or monkeypatch this + function with a real image/video backend. + """ + raise NotImplementedError( + "process_job is a stub — implement generation for job kind " + f"'{job.get('kind')}' (prompt: {job.get('prompt', '')[:80]!r}) and return " + '{"output_url": ..., "media_id": ...}, or complete the job via the ' + "HTTP API from your own agent loop.") + + +# --------------------------------------------------------------------------- +# Worker loop +# --------------------------------------------------------------------------- + +async def _heartbeat_loop(client: ProviderJobClient, job_id: str, + stop: asyncio.Event) -> None: + """Extend the lease until the job is done.""" + interval = max(5.0, client.lease_ttl_s / 3) + while not stop.is_set(): + try: + await asyncio.wait_for(stop.wait(), timeout=interval) + except asyncio.TimeoutError: + pass + if stop.is_set(): + break + try: + await client.heartbeat(job_id) + logger.debug("heartbeat ok for %s", job_id[:12]) + except Exception as e: + logger.warning("heartbeat failed for %s: %s", job_id[:12], e) + + +async def _handle_one(client: ProviderJobClient, job: dict) -> None: + job_id = job["id"] + logger.info("claimed job %s kind=%s prompt=%r", + job_id[:12], job.get("kind"), job.get("prompt", "")[:80]) + stop = asyncio.Event() + hb = asyncio.ensure_future(_heartbeat_loop(client, job_id, stop)) + try: + result = await process_job(job, client) + await client.complete(job_id, result["output_url"], result.get("media_id")) + logger.info("job %s completed: %s", job_id[:12], result.get("output_url", "")[:80]) + except Exception as e: + logger.exception("job %s failed", job_id[:12]) + try: + await client.fail(job_id, f"{type(e).__name__}: {e}") + except Exception: + logger.warning("could not report failure for %s", job_id[:12]) + finally: + stop.set() + await hb + + +async def run_worker(api_base: str, provider: str, worker_id: str, + lease_ttl_s: float, once: bool = False) -> None: + async with ProviderJobClient(api_base, worker_id, lease_ttl_s) as client: + logger.info("worker %s listening for provider=%s at %s", + worker_id, provider, api_base) + while True: + job = await client.wait_next(provider, timeout_s=60) + if job is None: + if once: + logger.info("no job available, exiting (--once)") + return + continue + await _handle_one(client, job) + if once: + return + + +def main(argv: list[str] | None = None) -> int: + p = argparse.ArgumentParser(description="Reference worker for FlowKit provider jobs") + p.add_argument("--api", default="http://localhost:8000/api", + help="FlowKit API base (default: http://localhost:8000/api)") + p.add_argument("--provider", default="assistant", + help="provider queue to consume (default: assistant)") + p.add_argument("--worker-id", default="worker-1", + help="unique id for this worker (used for lease ownership)") + p.add_argument("--lease-ttl", type=float, default=300, + help="lease seconds per heartbeat (default: 300)") + p.add_argument("--once", action="store_true", + help="process a single job (or none) then exit") + args = p.parse_args(argv) + try: + asyncio.run(run_worker(args.api, args.provider, args.worker_id, + args.lease_ttl, args.once)) + except KeyboardInterrupt: + logger.info("interrupted, exiting") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/agent/worker/processor.py b/agent/worker/processor.py index c736410aa..94164bf15 100644 --- a/agent/worker/processor.py +++ b/agent/worker/processor.py @@ -14,7 +14,7 @@ from agent.db import crud from agent.services.flow_client import get_flow_client from agent.services.event_bus import event_bus -from agent.config import POLL_INTERVAL, MAX_RETRIES, API_COOLDOWN, MAX_CONCURRENT_REQUESTS +from agent.config import POLL_INTERVAL, MAX_RETRIES from agent.worker._parsing import _is_error from agent.sdk.services.result_handler import parse_result, apply_scene_result, apply_character_result @@ -53,13 +53,35 @@ def release(self): self._semaphore.release() +def _request_provider_name(req: dict) -> str: + """Provider backend for a request row (persisted per request).""" + from agent.config import DEFAULT_PROVIDER + return ((req.get("provider") or DEFAULT_PROVIDER) or "").strip().lower() or "flow" + + +def _get_registry(): + """Shared provider registry (via the SDK singleton when initialized).""" + try: + from agent.sdk.services.operations import get_operations + return get_operations().registry + except RuntimeError: + # SDK not initialized (e.g. unit tests) — build a standalone one. + from agent.sdk.services.registry import ProviderRegistry + from agent.services.flow_client import get_flow_client + return ProviderRegistry(get_flow_client()) + + class WorkerController: """Controls the background worker loop with rate limiting and graceful shutdown.""" def __init__(self): self._shutdown = asyncio.Event() self._active_ids: set[str] = set() - self._rate_limiter = APIRateLimiter(MAX_CONCURRENT_REQUESTS, API_COOLDOWN) + self._active_provider: dict[str, str] = {} # rid -> provider name + # Per-provider rate limiters, built lazily from provider capabilities + # (Flow: 5 concurrent + 10s cooldown; assistant: 2 concurrent, no + # cooldown). Replaces the old single global limiter. + self._limiters: dict[str, APIRateLimiter] = {} self._deferred: dict[str, float] = {} # rid -> defer_until timestamp self._retry_after: dict[str, float] = {} # rid -> retry_after timestamp @@ -68,6 +90,19 @@ def active_count(self) -> int: """Number of currently active requests.""" return len(self._active_ids) + def _limiter_for(self, provider_name: str, max_concurrent: int, + cooldown_s: float) -> APIRateLimiter: + limiter = self._limiters.get(provider_name) + if limiter is None: + limiter = APIRateLimiter(max_concurrent, cooldown_s) + self._limiters[provider_name] = limiter + logger.info("Rate limiter for provider '%s': max_concurrent=%d cooldown=%.1fs", + provider_name, max_concurrent, cooldown_s) + return limiter + + def _active_for_provider(self, provider_name: str) -> int: + return sum(1 for p in self._active_provider.values() if p == provider_name) + async def start(self): """Start the worker loop.""" await self._cleanup_stale_processing() @@ -99,38 +134,37 @@ async def _cleanup_stale_processing(self): logger.warning("Could not clean up stale requests: %s", e) async def _run_loop(self): - client = get_flow_client() + registry = _get_registry() while not self._shutdown.is_set(): try: - if not client.connected: - await asyncio.sleep(POLL_INTERVAL) - continue - now = time.time() - slots_available = MAX_CONCURRENT_REQUESTS - len(self._active_ids) - if slots_available <= 0: + + # Fetch a generous window of actionable requests; per-request + # provider gating below decides what actually runs. + fetch_limit = 0 + for name in registry.names(): + caps = registry.get(name).capabilities + fetch_limit += max(0, caps.max_concurrent - self._active_for_provider(name)) + if fetch_limit <= 0: await asyncio.sleep(POLL_INTERVAL) continue pending = await crud.list_actionable_requests( - exclude_ids=self._active_ids, limit=slots_available + exclude_ids=self._active_ids, limit=fetch_limit ) pending_count = len(pending) await event_bus.emit("worker_tick", { "active": len(self._active_ids), - "slots": slots_available, "pending": pending_count, }) if pending: - logger.info("Worker: %d actionable, %d active, %d slots", - len(pending), len(self._active_ids), slots_available) + logger.info("Worker: %d actionable, %d active", + len(pending), len(self._active_ids)) for req in pending: - if slots_available <= 0: - break rid = req["id"] # Skip in-flight @@ -146,8 +180,22 @@ async def _run_loop(self): if rid in self._retry_after and self._retry_after[rid] > now: continue + # Provider-aware gate: resolve the backend for THIS + # request. A backend that is unavailable (e.g. Flow with + # no Chrome extension connected) leaves its requests + # PENDING while other providers keep working. + pname = _request_provider_name(req) + provider = registry.resolve(pname) + if not provider.is_available(): + logger.debug("Request %s deferred: provider '%s' unavailable", + rid[:8], provider.name) + continue + caps = provider.capabilities + if self._active_for_provider(provider.name) >= caps.max_concurrent: + continue + self._active_ids.add(rid) - slots_available -= 1 + self._active_provider[rid] = provider.name asyncio.create_task(self._run_one(req)) # Prune stale deferred/retry entries for requests no longer pending @@ -162,14 +210,20 @@ async def _run_loop(self): async def _run_one(self, req: dict): rid = req["id"] + pname = _request_provider_name(req) + registry = _get_registry() + provider = registry.resolve(pname) + caps = provider.capabilities + limiter = self._limiter_for(provider.name, caps.max_concurrent, caps.cooldown_s) try: - await self._rate_limiter.acquire() + await limiter.acquire() try: await _process_one(req, self._deferred, self._retry_after) finally: - self._rate_limiter.release() + limiter.release() finally: self._active_ids.discard(rid) + self._active_provider.pop(rid, None) async def _prerequisites_met(req: dict, orientation: str) -> bool: @@ -295,6 +349,9 @@ async def _dispatch(req: dict, orientation: str) -> dict: ops = get_operations() req_type, rid = req["type"], req["id"] pid = req.get("project_id", "0") + # Per-request provider selection: persisted on the request row, falling + # back to DEFAULT_PROVIDER when unset (handled by the registry). + provider = req.get("provider") # Scene-based operations if req_type in ("GENERATE_IMAGE", "REGENERATE_IMAGE", "EDIT_IMAGE", @@ -305,15 +362,15 @@ async def _dispatch(req: dict, orientation: str) -> dict: scene["_project_id"] = pid if req_type in ("GENERATE_IMAGE", "REGENERATE_IMAGE"): - return await ops.generate_scene_image(scene, orientation) + return await ops.generate_scene_image(scene, orientation, job_id=rid, provider=provider) if req_type == "EDIT_IMAGE": - return await ops.edit_scene_image(scene, orientation, source_media_id=req.get("source_media_id")) + return await ops.edit_scene_image(scene, orientation, source_media_id=req.get("source_media_id"), job_id=rid, provider=provider) if req_type in ("GENERATE_VIDEO", "REGENERATE_VIDEO"): - return await ops.generate_scene_video(scene, orientation, request_id=rid) + return await ops.generate_scene_video(scene, orientation, request_id=rid, provider=provider) if req_type == "GENERATE_VIDEO_REFS": - return await ops.generate_scene_video_refs(scene, orientation, request_id=rid) + return await ops.generate_scene_video_refs(scene, orientation, request_id=rid, provider=provider) if req_type == "UPSCALE_VIDEO": - return await ops.upscale_scene_video(scene, orientation, request_id=rid) + return await ops.upscale_scene_video(scene, orientation, request_id=rid, provider=provider) # Character operations if req_type in ("GENERATE_CHARACTER_IMAGE", "REGENERATE_CHARACTER_IMAGE", "EDIT_CHARACTER_IMAGE"): @@ -325,21 +382,11 @@ async def _dispatch(req: dict, orientation: str) -> dict: await crud.update_character(char["id"], media_id=None, reference_image_url=None) char["media_id"] = None char["reference_image_url"] = None - return await ops.generate_reference_image(char, pid) + return await ops.generate_reference_image(char, pid, job_id=rid, provider=provider) if req_type == "EDIT_CHARACTER_IMAGE": - src = req.get("source_media_id") or char.get("media_id") - if not src: - return {"error": "No source image to edit — generate a reference image first"} - edit_prompt = char.get("image_prompt") or char.get("description", "") - project = await crud.get_project(pid) if pid != "0" else None - tier = project.get("user_paygate_tier", "PAYGATE_TIER_ONE") if project else "PAYGATE_TIER_ONE" - aspect = "IMAGE_ASPECT_RATIO_LANDSCAPE" if char.get("entity_type") in ("location",) else "IMAGE_ASPECT_RATIO_PORTRAIT" - return await ops._client.edit_image( - prompt=edit_prompt, source_media_id=src, - project_id=pid, aspect_ratio=aspect, - user_paygate_tier=tier, - ) - return await ops.generate_reference_image(char, pid) + return await ops.edit_character_image( + char, pid, source_media_id=req.get("source_media_id"), job_id=rid, provider=provider) + return await ops.generate_reference_image(char, pid, job_id=rid, provider=provider) return {"error": f"Unknown request type: {req_type}"} diff --git a/dashboard/src/pages/SettingsPage.tsx b/dashboard/src/pages/SettingsPage.tsx index 8022b70d5..4b9ba026f 100644 --- a/dashboard/src/pages/SettingsPage.tsx +++ b/dashboard/src/pages/SettingsPage.tsx @@ -194,7 +194,7 @@ export default function SettingsPage() { {Object.entries(providers).map(([name, info]) => ( <div key={name} className="flex items-center gap-3 text-[11px]"> <span className="w-1.5 h-1.5 rounded-full flex-shrink-0" style={{ background: info.installed ? 'var(--green)' : 'var(--red)' }} /> - <span style={{ width: 90 }}>{info.binary}</span> + <span style={{ width: 90 }}>{info.binary ?? name}</span> <span style={{ color: 'var(--muted)', width: 100 }}> {info.installed ? t('settings.providers.installed') : t('settings.providers.missing')} </span> @@ -252,7 +252,7 @@ export default function SettingsPage() { > {Object.entries(providers).map(([name, p]) => ( <option key={name} value={name} disabled={!p.installed}> - {p.installed ? p.binary : `${p.binary} · ${t('settings.notInstalled')}`} + {p.installed ? (p.binary ?? name) : `${p.binary} · ${t('settings.notInstalled')}`} </option> ))} </select> diff --git a/setup.py b/setup.py index 948994dbe..15ea35074 100644 --- a/setup.py +++ b/setup.py @@ -106,7 +106,7 @@ def generate_claude(skills): 7. **Cascade on regen** — regenerating an image auto-clears downstream video + upscale. 8. **REGENERATE vs GENERATE** — `GENERATE_*` skips if already COMPLETED. `REGENERATE_*` always runs (clears + regenerates). 9. **Image Material required** — every project needs a `material` field (e.g. `realistic`, `3d_pixar`, `anime`). List available: `GET /api/materials`. -10. **Server handles throttling** — worker enforces max 5 concurrent requests + 10s cooldown. Submit ALL requests via `/batch`; do NOT manually stagger or loop. +10. **Server handles throttling (per provider)** — each media provider declares its own limits (Flow: max 5 concurrent + 10s cooldown; assistant: max 2 concurrent, no cooldown). Submit ALL requests via `/batch`; do NOT manually stagger or loop. Check effective limits: `GET /api/providers/status`. 11. **Video prompts use sub-clip timing** — structure 8s video as time segments: `0-3s: [action]. 3-6s: [action]. 6-8s: [action].` 12. **Character dialogue in sub-clips** — embed speech in quotes: `Luna says "Goodnight."` Max 10-15 words per character per 2-3s segment. 13. **Scenes are mutable** — use `PATCH /api/scenes/{sid}` to update `prompt`, `video_prompt`, `narrator_text`, `character_names` after creation. Don't delete and recreate — patch instead. @@ -175,7 +175,10 @@ def _agents_md_body(skills, title): f"Before ANY workflow:\n" f"```bash\n" f"curl -s http://127.0.0.1:8100/health\n" - f"# Must return: {{\"extension_connected\": true}}\n" + f"# Flow mode must return: {{\"extension_connected\": true}}\n" + f"# Assistant mode (MEDIA_PROVIDER=assistant or provider=assistant per request):\n" + f"# extension_connected may be false — no Chrome extension needed.\n" + f"# Check provider status instead: GET /api/providers/status\n" f"```\n\n" f"{_CRITICAL_RULES}\n" f"{_PIPELINE_OVERVIEW}\n" diff --git a/skills/README.md b/skills/README.md index bd9bf2f1e..257a4df24 100644 --- a/skills/README.md +++ b/skills/README.md @@ -25,6 +25,7 @@ Workflow skills for AI agents and humans. Each skill is a step-by-step recipe. | Skill | File | Description | |-------|------|-------------| | `fk-camera-guide` | [fk-camera-guide.md](fk-camera-guide.md) | Camera angles, movements, lighting, DOF for cinematic video prompts | +| `fk-provider` | [fk-provider.md](fk-provider.md) | Media providers: choose the generation backend, run the assistant worker, troubleshoot provider jobs | ## Utilities diff --git a/skills/fk-change-provider.md b/skills/fk-change-provider.md index 9c48e7580..359223f47 100644 --- a/skills/fk-change-provider.md +++ b/skills/fk-change-provider.md @@ -1,15 +1,20 @@ -# fk-change-provider — View & Switch the AI CLI for a Role +# fk-change-provider — View & Switch the Reviewer for a Role -View or change which AI CLI (`claude`, `agy`, `codex`) — and which model and +View or change which reviewer (`muse`, `claude`, `agy`, `codex`) — and which model and reasoning effort — runs each AI role. One role exists today: `video_review`, the vision analysis behind `/fk-review-video`. +- `muse` = the assistant itself (Muse): no CLI, no model, no effort. The + review flow becomes contact sheets → hand scoring → submit (see + `/fk-review-video` step 3a). Official provider, opt-in per role. +- `claude` / `agy` / `codex` = AI CLIs the server shells out to. + Usage: - `/fk-change-provider` — show current status - `/fk-change-provider list` — show current status -- `/fk-change-provider set <claude|agy|codex>` — switch the provider -- `/fk-change-provider set <provider> --model <id>` — switch provider and model -- `/fk-change-provider set <provider> --effort <level>` — switch provider and effort +- `/fk-change-provider set <muse|claude|agy|codex>` — switch the provider +- `/fk-change-provider set <provider> --model <id>` — switch provider and model (CLIs only) +- `/fk-change-provider set <provider> --effort <level>` — switch provider and effort (CLIs only) (for `agy`, model and effort are mutually exclusive — see Step 2) The dashboard has the same controls under **Settings**. @@ -39,11 +44,12 @@ Then the providers: | Provider | Binary | Installed | Tested | Efforts | |----------|--------|-----------|--------|---------| +| muse | — (the assistant) | Always | n/a | — | | claude | `claude` | Yes | Yes | low, medium, high, xhigh, max | | agy | `agy` | Yes | Yes | low, medium, high | | codex | `codex` | Yes | No | low, medium, high, xhigh, max | -- `Installed` reflects whether the binary is found on PATH. +- `Installed` reflects whether the binary is found on PATH (`muse` needs none). - `Tested` reflects the live `<binary> --version` probe (populated because of `?live=true`); `null` means not yet probed. diff --git a/skills/fk-doctor.md b/skills/fk-doctor.md index 54da6a3bb..3caa30011 100644 --- a/skills/fk-doctor.md +++ b/skills/fk-doctor.md @@ -5,6 +5,7 @@ Diagnose any FlowKit error and prescribe a fix. Knows the full error taxonomy ac **TRIGGER (auto-invoke) when:** - Any `/api/requests/*` response has `status=FAILED` or `error_message` is set - A request has been `PROCESSING` for > 10 minutes with no progress +- A provider job is stuck `QUEUED` (no worker), `CLAIMED` past its lease, or `FAILED` — or any `/api/provider-jobs/*` call returns 409 - `GET /health` returns `extension_connected: false` - User reports any error string containing: `UNSAFE_GENERATION`, `QUOTA`, `not found`, `CAPTCHA`, `UNUSUAL_ACTIVITY`, `NO_AT_TOKEN`, `NO_FLOW_PROJECT`, `UNSUPPORTED_ON_BATCH_API`, `NO_FLOW_TAB`, `FLOW_TAB_DISCARDED`, `NO_INJECTION_RESULT`, `extension_switched`, `Failed to fetch`, `MODEL_ACCESS_DENIED`, `PAYGATE_TIER_TWO`, `invalidTags`, `quotaExceeded`, `invalid_grant` - User asks "why did X fail", "what's wrong with the pipeline", "why is this stuck", "tại sao X lỗi", "lỗi gì vậy" @@ -45,9 +46,16 @@ curl -s "http://127.0.0.1:8100/api/requests?status=FAILED&limit=20" # Stuck in PROCESSING > 10 min curl -s "http://127.0.0.1:8100/api/requests?status=PROCESSING" + +# Provider jobs (assistant / external workers) +curl -s "http://127.0.0.1:8100/api/provider-jobs?limit=20" ``` Bucket the failures by `error_message` prefix, print a table, and for each bucket give the fix from the taxonomy. +For requests with a `provider` other than `flow`, also read the linked +provider job (`provider_job_id` on the request row): a `QUEUED` job with no +worker means `assistant_worker.py` isn't running; a `FAILED` job carries the +worker's `error_message`. ## Mode 2: Single request (`/fk-doctor <RID>`) @@ -61,6 +69,8 @@ Read: - `retry_count` — will it retry? (MAX_RETRIES=5) - `type` — GENERATE_IMAGE / GENERATE_VIDEO / UPSCALE_VIDEO / GENERATE_CHARACTER_IMAGE - Linked scene_id / character_id for re-upload context +- `provider` + `provider_job_id` — for non-flow providers, read the provider + job row (`status`, `claimed_by`, `error_message`) before anything else Cross-reference `error_message` against the taxonomy below. Print: **Diagnosis / Cause / Auto-handling / Manual fix**. @@ -209,6 +219,12 @@ Review runs outside the worker — no retry policy applies, the call just raises Providers, models and efforts come from `agent/providers.json`; see `/fk-change-provider`. +No review CLI installed (e.g. the Muse runtime)? Use Muse review instead — +`POST /api/videos/<VID>/review-sheets`, score the sheets by hand, then +`POST .../review-submit`. See `/fk-review-video`. A `review` call that fails +with "command not found" / non-zero exit before producing JSON almost always +means the CLI binary is missing, not that the video is bad. + | Error | Cause | Fix | |---|---|---| | `Frame extraction failed: ... No such filter: 'drawtext'` | ffmpeg built without libfreetype. Should no longer happen — the filter is probed and skipped — so seeing it means the probe was bypassed | `ffmpeg -filters \| grep drawtext`. Absent is fine; sheets just lose their burned-in timestamps | @@ -232,6 +248,23 @@ Decision order — stop at first match: 3. **`captcha` / `recaptcha`** → PENDING if retry_count < 10; else FAILED. 4. **Default** → increment `retry_count`; if < `MAX_RETRIES` (5), schedule retry at `now + min(2^retry * 10, 300)`s. Else FAILED. +### H. Provider-job errors (assistant / external workers) + +Provider jobs live outside the worker retry policy above — the queue is +`POST /api/provider-jobs`, the worker is `agent/worker/assistant_worker.py`. +Check the job row first: `GET /api/provider-jobs?provider=assistant&limit=20`. + +| Symptom | Cause | Fix | +|---|---|---| +| Job stuck `QUEUED` | No worker running | Start `assistant_worker.py` (see `/fk-provider`) | +| Job stuck `CLAIMED`/`RUNNING`, `lease_expires_at` in the past | Worker died without heartbeating | Wait for expiry — another worker reclaims it automatically | +| Job `FAILED`, `error_message` set | The worker reported a failure | Read `error_message`; fix the worker-side cause, then resubmit | +| `409` on `/heartbeat`, `/progress`, `/complete`, `/fail` | Not the lease holder — `claimed_by` differs, or the job already left `CLAIMED`/`RUNNING` | Use the `worker_id` that claimed it; if the lease expired, re-claim | +| Request `PROCESSING` forever but no provider job exists | Job creation failed server-side | Check server logs around the request; the `provider_job_id` column on the request row | +| `400 Unknown provider '<name>'` | Typo, or the provider isn't registered | Names come from `GET /api/providers/status` | +| `400 provider 'flow' does not support audio` | TTS routed to flow | Use `assistant` or `local` for `/api/tts/generate` | +| `Cannot fetch video for scene ...` in review | Remote URL dead and no Flow fallback (not connected, or non-Flow media) | Re-check the URL; for Flow media connect the extension, for local files verify the path exists | + ## Output format Always end with a prescription block: diff --git a/skills/fk-gen-chain-videos.md b/skills/fk-gen-chain-videos.md index e0e58b882..0c4f4d55e 100644 --- a/skills/fk-gen-chain-videos.md +++ b/skills/fk-gen-chain-videos.md @@ -2,6 +2,16 @@ Generate videos with automatic scene chaining (start+end frame transitions). Usage: `/gen-chain-videos <project_id> <video_id>` +## Provider (optional) + +Usage: `/fk-gen-chain-videos <project_id> <video_id> [--provider <name>]` + +Pass `"provider": "<name>"` on each item in the `/api/requests/batch` +payload (`flow` | `assistant`; default is the server `DEFAULT_PROVIDER`). +The assistant provider queues a provider job — make sure a worker is running +(see `/fk-provider`). Chained start/end frames are passed as `start_url` / +`end_url` on the provider job, so chaining works on any provider. + This creates smooth transitions between scenes in a chain by using the **NEXT scene's image as the endImage** of the current scene's video, so the last frame of scene N matches the first frame of scene N+1 → seamless concat. ## Before you start: chaining is not on the new Flow API diff --git a/skills/fk-gen-images.md b/skills/fk-gen-images.md index f12e083ea..e3901c65d 100644 --- a/skills/fk-gen-images.md +++ b/skills/fk-gen-images.md @@ -2,6 +2,16 @@ Generate scene images for all scenes in a video. Usage: `/fk-gen-images <project_id> <video_id>` +## Provider (optional) + +Usage: `/fk-gen-images <project_id> <video_id> [--provider <name>]` + +Pass `"provider": "<name>"` on each item in the `/api/requests/batch` +payload (`flow` | `assistant`; default is the server `DEFAULT_PROVIDER`). +The assistant provider queues a provider job — make sure a worker is running +(see `/fk-provider`). Assistant image output lands as `file://` URLs, which +never expire. + If not provided, ask or list projects/videos. ## Step 0: Detect orientation diff --git a/skills/fk-gen-narrator.md b/skills/fk-gen-narrator.md index 4e49f55d2..8272d0866 100644 --- a/skills/fk-gen-narrator.md +++ b/skills/fk-gen-narrator.md @@ -188,6 +188,15 @@ The `ref_text` is the **exact transcript** of what's spoken in `ref_audio`. - If template was created via `/fk-gen-tts-template`: `ref_text` = the standard base transcript used during creation (stored in `templates.json`) - If template is a user-provided WAV: transcribe it first using whisper, then use that transcript as `ref_text` for all scenes +### Provider (optional) + +Usage: `/fk-gen-narrator <video_id> [--provider <name>] [--force] [--language vi] [--speed 1.1]` + +Add `"provider": "<name>"` to the `/api/tts/generate` payload to route TTS +through a provider job (`assistant`) instead of the local OmniVoice engine — +the worker's provider must support audio (`generate_audio` capability). Omit +it for local TTS. `flow` cannot do audio and is rejected with 400. + ### Key rules: - `ref_audio` = the voice template WAV file (voice timbre source) - `ref_text` = exact transcript of `ref_audio` (phoneme alignment) diff --git a/skills/fk-gen-refs.md b/skills/fk-gen-refs.md index 45c30949b..435682603 100644 --- a/skills/fk-gen-refs.md +++ b/skills/fk-gen-refs.md @@ -2,6 +2,15 @@ Generate reference images for all entities in a project. Usage: `/fk-gen-refs <project_id>` +## Provider (optional) + +Usage: `/fk-gen-refs <project_id> [--provider <name>]` + +Pass `"provider": "<name>"` on each item in the `/api/requests/batch` +payload (`flow` | `assistant`; default is the server `DEFAULT_PROVIDER`). +The assistant provider queues a provider job — make sure a worker is running +(see `/fk-provider`). + If no project_id provided, use `GET /api/active-project` or list projects via `GET /api/projects`. ## Step 1: Check health diff --git a/skills/fk-gen-tts-template.md b/skills/fk-gen-tts-template.md index 8b101a47e..9c2b2544a 100644 --- a/skills/fk-gen-tts-template.md +++ b/skills/fk-gen-tts-template.md @@ -4,6 +4,13 @@ Create a reusable voice template for consistent narration across all scenes. **IMPORTANT:** Always create a voice template BEFORE narrating scenes. Without a template, each scene generates with a slightly different voice. With a template, voice cloning ensures 100% consistency. +## Provider (optional) + +`/api/tts/generate` accepts `"provider"`: omit it (or `"local"`) for the +bundled TTS engine, or `"assistant"` to dispatch a provider job (the worker's +provider must support audio). `flow` is rejected with 400 — it has no audio +capability. See `/fk-provider`. + ## Prerequisites - GLA server running: `curl http://127.0.0.1:8100/health` diff --git a/skills/fk-gen-videos.md b/skills/fk-gen-videos.md index 200c6a4f1..70bab8eb9 100644 --- a/skills/fk-gen-videos.md +++ b/skills/fk-gen-videos.md @@ -2,6 +2,16 @@ Generate videos for all scenes in a video. Usage: `/fk-gen-videos <project_id> <video_id>` +## Provider (optional) + +Usage: `/fk-gen-videos <project_id> <video_id> [--provider <name>]` + +Pass `"provider": "<name>"` on each item in the `/api/requests/batch` +payload (`flow` | `assistant`; default is the server `DEFAULT_PROVIDER`). +The assistant provider queues a provider job — make sure a worker is running +(see `/fk-provider`). Assistant image output lands as `file://` URLs, which +never expire. + ## Step 0: Detect orientation ```bash diff --git a/skills/fk-provider.md b/skills/fk-provider.md new file mode 100644 index 000000000..d9d177a0d --- /dev/null +++ b/skills/fk-provider.md @@ -0,0 +1,121 @@ +# fk-provider — Media providers: choose the generation backend + +FlowKit is provider-neutral. A **media provider** is the backend that renders +media: `flow` (Google Flow via the Chrome extension), `assistant` (Muse or any +HTTP-capable external worker), or any future registered provider. + +Every generation request, thumbnail, and TTS call accepts an optional +`provider`. Omit it and the server default (`DEFAULT_PROVIDER`, usually +`flow`) is used. + +## Check status + +```bash +curl -s http://127.0.0.1:8100/api/providers/status | python3 -m json.tool +# {"default": "flow", "providers": {"flow": {"available": true, ...}, +# "assistant": {"available": true, ...}}} +``` + +`flow.available` is true only while the Chrome extension is connected. +`assistant.available` is true when the provider is registered — it needs no +Chrome, but it needs a **worker** (below) to actually do the work. + +## Per-request provider + +Add `"provider"` to any item in `/api/requests` or `/api/requests/batch`: + +```bash +curl -X POST http://127.0.0.1:8100/api/requests/batch \ + -H "Content-Type: application/json" \ + -d '{"requests": [ + {"type": "GENERATE_VIDEO", "scene_id": "<SID>", "project_id": "<PID>", + "video_id": "<VID>", "orientation": "VERTICAL", "provider": "assistant"} + ]}' +``` + +Generation skills (`/fk-gen-images`, `/fk-gen-videos`, `/fk-gen-refs`, +`/fk-gen-chain-videos`, `/fk-thumbnail`) accept `[--provider <name>]` and pass +it through the same way. + +Thumbnail: `POST /api/projects/<PID>/generate-thumbnail` +`{"prompt": "...", "provider": "assistant"}`. + +TTS: `POST /api/tts/generate` `{"text": "...", "provider": "assistant"}`. +(`"provider": "local"` or omitted = the bundled TTS engine. `flow` cannot do +audio — it is rejected with 400.) + +## Capabilities differ per provider + +- `flow`: image, edit_image, i2v (image-to-video), r2v, upscale. **No audio.** +- `assistant`: image, edit_image, i2v, r2v, **audio (TTS)**. No upscale. + +Asking a provider for a kind it doesn't support returns 400 with a message +naming the right backend to use instead. + +## The assistant provider needs a worker + +When a request uses `provider: assistant`, the server creates a **provider +job** (`POST /api/provider-jobs`) and waits for an external worker to claim +and complete it. No worker = the request sits in PROCESSING until the job +times out. + +Run the reference worker (it shells out to whatever CLI you configure — +see the top of `agent/worker/assistant_worker.py`): + +```bash +cd ~/workspace/flowkit +.venv/bin/python agent/worker/assistant_worker.py \ + --api http://127.0.0.1:8100 --provider assistant --worker-id w1 +``` + +Worker protocol (full spec in the module docstring): + +1. `GET /api/provider-jobs/wait-next?provider=assistant&worker_id=w1&timeout_s=60` + — long-polls and atomically claims the next job (lease granted). +2. `POST /api/provider-jobs/{id}/heartbeat` `{"worker_id": "w1"}` + — every ~lease/3 while working (default lease 300s). +3. `POST /api/provider-jobs/{id}/progress` `{"worker_id": "w1", "progress": 50}` + — optional. +4. `POST /api/provider-jobs/{id}/complete` + `{"worker_id": "w1", "result": {"output_url": "file:///...", "media_id": "<uuid>"}}` + — or `/fail` `{"worker_id": "w1", "error": "..."}`. + +Only the lease holder may heartbeat/progress/complete/fail; strangers get +409. complete/fail are idempotent for the holder (safe to retry after a lost +response). `output_url` should be `file://` or `https://` — the server copies +it into the project output dir. + +## Provider jobs: inspect and troubleshoot + +```bash +# list recent jobs for a provider +curl -s "http://127.0.0.1:8100/api/provider-jobs?provider=assistant&limit=20" | python3 -m json.tool +# wait for one job to finish (server-side long poll) +curl -s "http://127.0.0.1:8100/api/provider-jobs/<JOB_ID>/wait?timeout_s=600" +``` + +| Symptom | Meaning | Fix | +|---|---|---| +| Job stuck `QUEUED` | no worker running | start `assistant_worker.py` | +| Job stuck `CLAIMED`/`RUNNING`, no heartbeat | worker died | wait for lease expiry (~5 min), another worker reclaims it | +| `409` on complete/fail | not the lease holder, or job already terminal | check `claimed_by` on the job row | +| Request `PROCESSING` forever, job `FAILED` | worker reported an error | read `error_message` on the job row | +| `400 unknown provider` | typo or unregistered name | use a name from `/api/providers/status` | +| `400 provider 'flow' does not support audio` | TTS via flow | use `assistant` or `local` | + +## Local URLs never expire + +Assistant-provider output is stored as `file://` URLs on the server. Unlike +Flow's signed GCS URLs, these never expire — **skip `/fk-refresh-urls`** +entirely for assistant-generated media. (The skill itself no-ops when it +finds only local URLs.) + +## Adding a new provider + +1. Subclass `MediaProvider` in `agent/sdk/services/` (see + `assistant_provider.py` for the DB-backed reference). +2. Declare `name` and `capabilities` (which kinds it supports). +3. Register it in the provider registry (`agent/sdk/services/registry.py` + docstring) and add the name to `config`. +4. If it needs an external worker, speak the provider-job protocol above — + `assistant_worker.py` is the reference implementation. diff --git a/skills/fk-refresh-urls.md b/skills/fk-refresh-urls.md index 9689d56e0..b4afdef54 100644 --- a/skills/fk-refresh-urls.md +++ b/skills/fk-refresh-urls.md @@ -10,6 +10,27 @@ Usage: `/fk-refresh-urls <video_id> [--project-id <PID>]` ## Pre-flight +### Step 0: Skip when all URLs are local (provider no-op) + +Assistant-provider media is stored as `file://` URLs, which never expire — +refreshing them is a no-op. Check first: + +```bash +curl -s "http://127.0.0.1:8100/api/scenes?video_id=${VID}" | python3 -c " +import sys, json +scenes = json.load(sys.stdin) +urls = [v for s in scenes for k, v in s.items() + if k.endswith('_url') and v] +remote = [u for u in urls if u.startswith('http')] +print(f'{len(urls)} urls, {len(remote)} remote') +" +# If remote == 0: STOP. Nothing to refresh — all media is local. +``` + +Only continue below when remote URLs exist (Flow's signed GCS URLs expire +after hours/days). + + ```bash curl -s http://127.0.0.1:8100/api/flow/status # Must show: {"connected": true, "transport": "batch"} diff --git a/skills/fk-review-video.md b/skills/fk-review-video.md index c7d89339b..9ac3234ff 100644 --- a/skills/fk-review-video.md +++ b/skills/fk-review-video.md @@ -1,27 +1,37 @@ -Review AI-generated scene videos for quality using Claude Vision. +Review AI-generated scene videos for quality. -Usage: `/fk-review-video <video_id> [--mode light|deep]` +Usage: `/fk-review-video <video_id> [--mode light|deep] [--by cli|muse]` -Default mode: `light`. Orientation auto-detected from project `meta.json`. +Default mode: `light`. Default reviewer: `cli` (whatever the `video_review` +role points at in `agent/providers.json`). + +## Reviewer backends + +- **`cli`** (default): `POST /api/videos/<VID>/review` shells out to the + configured `video_review` role provider. Needs the CLI binary on PATH. +- **`muse`** (official provider): the server builds contact sheets + (`POST /api/videos/<VID>/review-sheets`), Muse reads them with vision and + scores each scene, then submits (`POST /api/videos/<VID>/review-submit`). + Works everywhere — no CLI, no API key. Select it with + `/fk-change-provider set muse`. ## Prerequisites -- `ANTHROPIC_API_KEY` env var set - `ffmpeg` + `ffprobe` installed - Scenes must have completed videos (`${ori}_video_status = COMPLETED`) +- (`cli` only) the review CLI installed; (`muse`) nothing extra ## Step 1: Pre-check ```bash -# Verify server + extension connected +# Verify server is up (extension NOT required for review) curl -s http://127.0.0.1:8100/health -# Must return: {"extension_connected": true} # Verify video exists curl -s http://127.0.0.1:8100/api/videos/<VID> ``` -**ABORT** if extension not connected or video not found. +**ABORT** if the server is down or the video is not found. ## Step 2: Check scenes have completed videos @@ -33,7 +43,48 @@ For each scene, verify `${ori}_video_status = COMPLETED` (orientation auto-detec **ABORT** if any scene is missing a completed video — tell user to run `/fk-gen-videos` first. -## Step 3: Run review via API +## Step 3a: Muse review (`--by muse`) + +Build the contact sheets — no AI CLI involved: + +```bash +curl -s -X POST "http://127.0.0.1:8100/api/videos/<VID>/review-sheets" \ + -H "Content-Type: application/json" \ + -d '{"project_id": "<PID>", "mode": "light"}' | python3 -m json.tool +# → {sheets: [{scene_id, sheets: ["/abs/path/sheet_1.jpg", ...], +# n_frames, fps, prompt (rubric), scene_prompt, ...}]} +``` + +Sheets persist under `<output>/<slug>/review/sheets/<scene_id>/`. **Read each +sheet image with vision** and score the scene against the rubric in `prompt`: +6 dimensions (0.0–10.0), errors with severity (CRITICAL/HIGH/MINOR) + +time_range + description, usable_segments. Be strict on CRITICAL errors +(character morph, breed swap, role reversal, brand logo, wrong count) — +any CRITICAL caps character_consistency at 3.0 and the verdict below +acceptable. + +Submit the scores — the server applies the same validation, severity rules, +and caps as the CLI backend: + +```bash +curl -s -X POST "http://127.0.0.1:8100/api/videos/<VID>/review-submit" \ + -H "Content-Type: application/json" \ + -d '{"project_id": "<PID>", "mode": "light", "scores": [ + {"scene_id": "<SID>", "n_frames": 32, "fps": 4.0, + "dimensions": {"character_consistency": 8.0, "prompt_adherence": 7.5, + "motion_quality": 7.0, "visual_fidelity": 8.0, + "temporal_coherence": 7.5, "composition": 8.0}, + "errors": [{"severity": "MINOR", "time_range": "5s-6s", + "description": "background signage garbles"}], + "usable_segments": [{"time_range": "0s-8s", "score": 8.0}]} + ]}' | python3 -m json.tool +``` + +To auto-regenerate bad scenes from Muse scores (bounded by +`max_regenerations` per scene), pass the same `scores` array to +`POST /api/videos/<VID>/review-regenerate`. + +## Step 3b: CLI review (default, `--by cli`) ```bash curl -X POST "http://127.0.0.1:8100/api/videos/<VID>/review?project_id=<PID>&mode=light&orientation=${ORI}" @@ -43,13 +94,8 @@ curl -X POST "http://127.0.0.1:8100/api/videos/<VID>/review?project_id=<PID>&mod - `mode`: `light` (default) or `deep` - `orientation`: auto-detected from meta.json (`${ORI}`) -The API will extract frames from each scene video, send them to Claude Vision, and return per-scene quality scores. - -**Poll until complete:** -```bash -curl -s http://127.0.0.1:8100/api/requests/<RID> -# Wait for status: "COMPLETED" -``` +The API extracts frames from each scene video, sends them to the configured +review CLI, and returns per-scene quality scores. ## Step 4: Interpret results diff --git a/skills/fk-thumbnail.md b/skills/fk-thumbnail.md index f213f2ac7..e05f5068f 100644 --- a/skills/fk-thumbnail.md +++ b/skills/fk-thumbnail.md @@ -1,6 +1,14 @@ Generate 4 YouTube-optimized thumbnail variants for a project video. -Usage: `/fk-thumbnail [project_id]` +Usage: `/fk-thumbnail [project_id] [--provider <name>]` +## Provider (optional) + +Usage: `/fk-thumbnail [project_id] [--provider <name>]` + +Pass `"provider"` in the `generate-thumbnail` payload (`flow` | `assistant`; +default is the server `DEFAULT_PROVIDER`). The assistant provider queues a +provider job — make sure a worker is running (see `/fk-provider`). Flow +thumbnail generation needs the Chrome extension; assistant needs none. ## Step 1: Load project context @@ -113,7 +121,8 @@ for i in 1 2 3 4; do "prompt": "<variant_prompt_with_text_embedded>", "character_names": ["<main_char1>", "<main_char2>"], "aspect_ratio": "LANDSCAPE", - "output_filename": "thumbnail_v'$i'.png" + "output_filename": "thumbnail_v'$i'.png", + "provider": "assistant" // or "flow"; omit for server default }' sleep 8 done diff --git a/tests/conftest.py b/tests/conftest.py index b464523bb..90e1b9956 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -146,3 +146,21 @@ def sample_character_row(sample_uuid): "created_at": "2026-04-01T00:00:00", "updated_at": "2026-04-01T00:00:00", } + + +@pytest.fixture +async def test_db(tmp_path, monkeypatch): + """Point the FlowKit SQLite DB at a temp file and initialize the schema. + + Resets the cached schema connection so each test gets a fresh database. + NOTE: agent.db.schema binds DB_PATH at import time + (``from agent.config import DB_PATH``), so patch the binding in the + schema module, not the attribute on agent.config. + """ + from agent.db import schema + monkeypatch.setattr(schema, "DB_PATH", tmp_path / "test.db") + schema._db_connection = None + await schema.init_db() + yield tmp_path / "test.db" + await schema.close_db() + schema._db_connection = None diff --git a/tests/unit/test_assistant_provider.py b/tests/unit/test_assistant_provider.py new file mode 100644 index 000000000..9634f8410 --- /dev/null +++ b/tests/unit/test_assistant_provider.py @@ -0,0 +1,173 @@ +"""Tests for the assistant media provider (provider-job queue transport). + +pytest-asyncio runs in AUTO mode (see pytest.ini), so these are native +async tests — no manual event-loop juggling. +""" +import asyncio +import json + +import pytest + +from agent.db import crud +from agent.sdk.services import assistant_provider as ap +from agent.sdk.services.provider_base import ( + KIND_EDIT_IMAGE, + KIND_IMAGE, + KIND_UPSCALE, + KIND_VIDEO, + ProviderJob, +) +from agent.sdk.services.result_handler import parse_result +from agent.worker._parsing import _is_uuid + +SAMPLE_UUID = "550e8400-e29b-41d4-a716-446655440000" + + +@pytest.fixture +def provider(): + prov = ap.AssistantProvider() + prov.timeout_s = 30 + prov.poll_s = 0.05 + return prov + + +def _image_job(job_id="jobimg123456", **kw): + args = dict(job_id=job_id, kind=KIND_IMAGE, prompt="a cat", + orientation="VERTICAL") + args.update(kw) + return ProviderJob(**args) + + +async def _fake_worker(job_id, result=None, fail=None, delay=0.2): + """Simulate an external worker: wait for the row, claim, finish.""" + for _ in range(200): + if await crud.get_provider_job(job_id): + break + await asyncio.sleep(0.05) + claimed = await crud.claim_provider_job(job_id, "w1", lease_ttl_s=60) + assert claimed is not None + await asyncio.sleep(delay) + if fail: + await crud.fail_provider_job(job_id, "w1", fail) + else: + await crud.complete_provider_job(job_id, "w1", result or {}) + + +async def test_run_queues_job_and_returns_worker_result(test_db, provider): + job_id = "jobimg123456" + task = asyncio.ensure_future(_fake_worker( + job_id, result={"output_url": "file:///tmp/out.png", "media_id": SAMPLE_UUID})) + + result = await provider.run(_image_job(job_id)) + await task + + assert not result.get("error"), result + gen = parse_result(result, "GENERATE_IMAGE") + assert gen.success + assert gen.media_id == SAMPLE_UUID + assert gen.url == "file:///tmp/out.png" + + row = await crud.get_provider_job(job_id) + assert row["status"] == "SUCCEEDED" + assert row["provider"] == "assistant" + assert row["kind"] == KIND_IMAGE + assert json.loads(row["extra"])["reference_urls"] == [] + + +async def test_run_mints_media_id_when_worker_omits_it(test_db, provider): + job_id = "jobimgmint01" + task = asyncio.ensure_future(_fake_worker( + job_id, result={"output_url": "file:///tmp/out.png"})) + + result = await provider.run(_image_job(job_id)) + await task + + gen = parse_result(result, "GENERATE_IMAGE") + assert gen.success and _is_uuid(gen.media_id) + + +async def test_run_video_result_shape(test_db, provider): + job_id = "jobvid123456" + task = asyncio.ensure_future(_fake_worker( + job_id, result={"output_url": "file:///tmp/out.mp4", "media_id": SAMPLE_UUID})) + job = ProviderJob(job_id=job_id, kind=KIND_VIDEO, prompt="cat walks", + orientation="HORIZONTAL", start_url="file:///tmp/start.png") + + result = await provider.run(job) + await task + + gen = parse_result(result, "GENERATE_VIDEO") + assert gen.success + assert gen.media_id == SAMPLE_UUID + assert gen.url.endswith(".mp4") + + +async def test_run_propagates_worker_failure(test_db, provider): + job_id = "jobfail12345" + task = asyncio.ensure_future(_fake_worker(job_id, fail="boom")) + result = await provider.run(_image_job(job_id)) + await task + assert result.get("error") == "boom" + + +async def test_run_timeout_when_no_worker(test_db, provider): + provider.timeout_s = 1 + provider.poll_s = 0.05 + result = await provider.run(_image_job("jobtimeout1")) + assert "error" in result + assert "timeout" in result["error"].lower() + # the queued row is left behind for a later worker + row = await crud.get_provider_job("jobtimeout1") + assert row["status"] == "QUEUED" + + +async def test_run_validates_before_queuing(test_db, provider): + # edit with no source: validation error, nothing queued + job = ProviderJob(job_id="jobedit00001", kind=KIND_EDIT_IMAGE, + prompt="make it rain", orientation="VERTICAL") + result = await provider.run(job) + assert "error" in result and "No source image" in result["error"] + assert await crud.get_provider_job("jobedit00001") is None + + # upscale is rejected by check() + assert provider.check(ProviderJob(job_id="x", kind=KIND_UPSCALE)) is not None + + # unknown kind (dataclass rejects it at construction; mutate to reach the branch) + weird = ProviderJob(job_id="jobunk000001", kind=KIND_IMAGE) + weird.kind = "teleport" + result = await provider.run(weird) + assert "error" in result + + +async def test_run_video_requires_start_image(test_db, provider): + job = ProviderJob(job_id="jobvidnoimg0", kind=KIND_VIDEO, + prompt="x", orientation="VERTICAL") + result = await provider.run(job) + assert "error" in result and "No vertical image" in result["error"] + assert await crud.get_provider_job("jobvidnoimg0") is None + + +async def test_run_cancelled_job_reports_cancelled(test_db, provider): + job_id = "jobcancel0001" + + async def canceller(): + for _ in range(200): + if await crud.get_provider_job(job_id): + break + await asyncio.sleep(0.05) + await crud.cancel_provider_job(job_id) + + task = asyncio.ensure_future(canceller()) + result = await provider.run(_image_job(job_id)) + await task + assert "cancelled" in result["error"].lower() + + +async def test_register_existing_image_mints_uuid(test_db, provider, tmp_path): + img = tmp_path / "pic.png" + img.write_bytes(b"\x89PNG fake") + result = await provider.register_existing_image(f"file://{img}", name="pic") + assert not result.get("error") + mid = result["data"]["media"][0]["name"] + assert _is_uuid(mid) + assert result["data"]["url"].startswith("file://") diff --git a/tests/unit/test_cli_providers.py b/tests/unit/test_cli_providers.py index 0a046e1b0..a6f02f1e4 100644 --- a/tests/unit/test_cli_providers.py +++ b/tests/unit/test_cli_providers.py @@ -867,6 +867,39 @@ async def test_an_empty_catalog_does_not_block_the_write(self, fake_binaries): # --------------------------------------------------------------------------- +class TestMuseReviewer: + """`muse` — the assistant itself — is a first-class reviewer with no binary.""" + + @pytest.mark.asyncio + async def test_muse_needs_no_binary_on_path(self, monkeypatch): + monkeypatch.setattr(cli_providers.shutil, "which", lambda b: None) + entry = await cli_providers.validate_role_entry( + "video_review", {"provider": "muse"}) + assert entry["provider"] == "muse" + + @pytest.mark.asyncio + async def test_muse_rejects_model_and_effort(self): + with pytest.raises(ValueError, match="takes no model"): + await cli_providers.validate_role_entry( + "video_review", {"provider": "muse", "model": "sonnet"}) + with pytest.raises(ValueError, match="takes no model"): + await cli_providers.validate_role_entry( + "video_review", {"provider": "muse", "effort": "high"}) + + @pytest.mark.asyncio + async def test_muse_catalog_is_empty(self): + assert await cli_providers.list_models("muse") == [] + + def test_muse_is_a_known_provider(self): + assert cli_providers.PROVIDER_BINARIES["muse"] is None + + @pytest.mark.asyncio + async def test_analyze_cli_refuses_muse_with_directions(self): + with pytest.raises(RuntimeError, match="review-sheets"): + await _analyze_cli( + [], 10, 4.0, {}, role={"provider": "muse"}) + + # agent/services/cli_providers.py :: model catalogs # --------------------------------------------------------------------------- diff --git a/tests/unit/test_muse_review.py b/tests/unit/test_muse_review.py new file mode 100644 index 000000000..797dbd2a4 --- /dev/null +++ b/tests/unit/test_muse_review.py @@ -0,0 +1,167 @@ +"""Tests for Muse review: contact sheets -> hand scoring -> submit. + +pytest-asyncio runs in AUTO mode (see pytest.ini). +""" +import subprocess +from pathlib import Path + +import pytest +from fastapi import FastAPI +from fastapi.testclient import TestClient + +from agent.api import reviews as reviews_api +from agent.db import crud +from agent.services.video_reviewer import ( + prepare_review_sheets, + score_review_answer, +) + + +@pytest.fixture +def reviews_client(test_db): + app = FastAPI() + app.include_router(reviews_api.router, prefix="/api") + return TestClient(app, raise_server_exceptions=False) + + +@pytest.fixture +def scene_with_clip(test_db, tmp_path): + """A project/video/scene whose vertical_video_url points at a real clip.""" + async def _make(): + clip = tmp_path / "clip.mp4" + subprocess.run( + ["ffmpeg", "-y", "-v", "error", + "-f", "lavfi", "-i", "testsrc=duration=2:size=320x568:rate=10", + "-pix_fmt", "yuv420p", str(clip)], + check=True) + proj = await crud.create_project(name="Review Sheets") + video = await crud.create_video(project_id=proj["id"], title="V", + orientation="VERTICAL") + scene = await crud.create_scene(video_id=video["id"], display_order=0, + prompt="a cat walks in the rain") + scene = await crud.update_scene( + scene["id"], + vertical_video_url=f"file://{clip}", + vertical_image_media_id="11111111-2222-3333-4444-555555555555") + return proj, video, scene, clip + return _make + + +async def test_prepare_review_sheets_builds_persisted_sheets( + scene_with_clip, tmp_path): + proj, video, scene, clip = await scene_with_clip() + out = tmp_path / "sheets" + + info = await prepare_review_sheets(scene, [], "light", "VERTICAL", out) + + assert info["scene_id"] == scene["id"] + assert info["n_frames"] > 0 + assert info["fps"] == 4.0 + assert info["sheets"], "expected at least one contact sheet" + for s in info["sheets"]: + assert Path(s).exists(), f"sheet must persist on disk: {s}" + assert str(out) in s + assert "SCORING DIMENSIONS" in info["prompt"] + assert "a cat walks in the rain" in info["prompt"] + + +async def test_prepare_review_sheets_no_video_raises(test_db): + proj = await crud.create_project(name="No Clip") + video = await crud.create_video(project_id=proj["id"], title="V", + orientation="VERTICAL") + scene = await crud.create_scene(video_id=video["id"], display_order=0, + prompt="x") + with pytest.raises(ValueError): + await prepare_review_sheets(scene, [], "light", "VERTICAL", Path("/tmp/x")) + + +def test_score_review_answer_applies_critical_cap(): + sr = score_review_answer( + "s1", + {"dimensions": {"character_consistency": 9.0, "prompt_adherence": 8.0, + "motion_quality": 8.0, "visual_fidelity": 8.0, + "temporal_coherence": 8.0, "composition": 8.0}, + "errors": [{"severity": "CRITICAL", "time_range": "3s-5s", + "description": "character morphs, extra limb"}], + "usable_segments": [{"time_range": "0s-2s", "score": 8.0}]}, + n_frames=32, fps=4.0, + ) + assert sr.scene_id == "s1" + assert sr.has_critical_errors is True + assert sr.dimensions.character_consistency == 3.0 # capped + assert sr.overall_score <= 5.9 # forced below acceptable + assert sr.verdict in ("poor", "unusable") + assert sr.frames_analyzed == 32 + + +def test_score_review_answer_rejects_missing_dimensions(): + with pytest.raises(RuntimeError): + score_review_answer("s1", {"dimensions": {}, "errors": []}, + n_frames=8, fps=4.0) + + +def test_score_review_answer_rejects_bad_severity(): + with pytest.raises(RuntimeError): + score_review_answer( + "s1", + {"dimensions": {"character_consistency": 5.0, "prompt_adherence": 5.0, + "motion_quality": 5.0, "visual_fidelity": 5.0, + "temporal_coherence": 5.0, "composition": 5.0}, + "errors": [{"severity": "MEH", "time_range": "1s-2s", + "description": "x"}]}, + n_frames=8, fps=4.0) + + +async def test_review_sheets_then_submit_end_to_end( + reviews_client, scene_with_clip): + proj, video, scene, clip = await scene_with_clip() + + r = reviews_client.post( + f"/api/videos/{video['id']}/review-sheets", + json={"project_id": proj["id"], "mode": "light"}) + assert r.status_code == 200, r.text + body = r.json() + assert len(body["sheets"]) == 1 + sheet = body["sheets"][0] + assert sheet["scene_id"] == scene["id"] + assert Path(sheet["sheets"][0]).exists() + + # Muse scores the sheets by hand and submits. + r = reviews_client.post( + f"/api/videos/{video['id']}/review-submit", + json={"project_id": proj["id"], "mode": "light", "scores": [{ + "scene_id": scene["id"], + "dimensions": {"character_consistency": 4.0, "prompt_adherence": 7.0, + "motion_quality": 6.0, "visual_fidelity": 7.0, + "temporal_coherence": 6.0, "composition": 7.0}, + "errors": [{"severity": "HIGH", "time_range": "1s-2s", + "description": "camera drifts left suddenly"}], + "usable_segments": [{"time_range": "0s-1s", "score": 7.0}], + "n_frames": sheet["n_frames"], "fps": sheet["fps"], + }]}) + assert r.status_code == 200, r.text + review = r.json() + assert review["scenes_reviewed"] == 1 + sr = review["scene_reviews"][0] + assert sr["has_critical_errors"] is False + assert sr["overall_score"] > 0 + + # review-regenerate with Muse scores enqueues a bounded regen. + r = reviews_client.post( + f"/api/videos/{video['id']}/review-regenerate", + json={"project_id": proj["id"], "mode": "light", + "max_regenerations": 1, "bad_verdicts": ["poor", "unusable"], + "scores": [{ + "scene_id": scene["id"], + "dimensions": {"character_consistency": 2.0, + "prompt_adherence": 2.0, "motion_quality": 2.0, + "visual_fidelity": 2.0, "temporal_coherence": 2.0, + "composition": 2.0}, + "errors": [], "usable_segments": [], + "n_frames": 8, "fps": 4.0, + }]}) + assert r.status_code == 200, r.text + decisions = r.json()["decisions"] + assert len(decisions) == 1 + assert decisions[0]["regenerated"] is True + assert decisions[0]["request_id"] diff --git a/tests/unit/test_operations.py b/tests/unit/test_operations.py index c0b85e2da..a24f72f96 100644 --- a/tests/unit/test_operations.py +++ b/tests/unit/test_operations.py @@ -178,13 +178,16 @@ async def test_a_submitted_operation_is_repolled_not_resubmitted( mock_client.generate_video = AsyncMock() polled = {"data": {"operations": [{"status": "MEDIA_GENERATION_STATUS_SUCCESSFUL"}]}} - with patch("agent.sdk.services.operations.crud") as mock_crud, \ + # Retry logic now lives in FlowProvider — patch its crud/_poll_operations. + # generate_scene_video itself still reads the project tier via operations.crud. + with patch("agent.sdk.services.operations.crud") as ops_crud, \ + patch("agent.sdk.services.flow_provider.crud") as flow_crud, \ patch("agent.sdk.services.operations._build_video_prompt", new=AsyncMock(return_value="p")), \ - patch("agent.sdk.services.operations._poll_operations", + patch("agent.sdk.services.flow_provider._poll_operations", new=AsyncMock(return_value=polled)) as mock_poll: - mock_crud.get_project = AsyncMock(return_value={"user_paygate_tier": "PAYGATE_TIER_ONE"}) - mock_crud.get_request = AsyncMock(return_value={"request_id": SAMPLE_UUID_2}) + ops_crud.get_project = AsyncMock(return_value={"user_paygate_tier": "PAYGATE_TIER_ONE"}) + flow_crud.get_request = AsyncMock(return_value={"request_id": SAMPLE_UUID_2}) result = await service.generate_scene_video( base_scene, "VERTICAL", request_id="req-1") @@ -199,14 +202,15 @@ async def test_no_prior_operation_still_submits(self, service, base_scene, mock_ mock_client.generate_video = AsyncMock( return_value={"data": {"operations": [{"operation": {"name": "op-new"}}]}}) - with patch("agent.sdk.services.operations.crud") as mock_crud, \ + with patch("agent.sdk.services.operations.crud") as ops_crud, \ + patch("agent.sdk.services.flow_provider.crud") as flow_crud, \ patch("agent.sdk.services.operations._build_video_prompt", new=AsyncMock(return_value="p")), \ - patch("agent.sdk.services.operations._poll_operations", + patch("agent.sdk.services.flow_provider._poll_operations", new=AsyncMock(return_value={"data": {}})): - mock_crud.get_project = AsyncMock(return_value={"user_paygate_tier": "PAYGATE_TIER_ONE"}) - mock_crud.get_request = AsyncMock(return_value=None) - mock_crud.update_request = AsyncMock() + ops_crud.get_project = AsyncMock(return_value={"user_paygate_tier": "PAYGATE_TIER_ONE"}) + flow_crud.get_request = AsyncMock(return_value=None) + flow_crud.update_request = AsyncMock() await service.generate_scene_video(base_scene, "VERTICAL", request_id="req-1") @@ -257,6 +261,7 @@ async def test_returns_error_when_no_source_image(self, service, base_scene): with patch("agent.sdk.services.operations.crud") as mock_crud: mock_crud.get_project = AsyncMock(return_value=project) + mock_crud.get_project_characters = AsyncMock(return_value=[]) result = await service.edit_scene_image(base_scene, "VERTICAL", source_media_id=None) @@ -296,11 +301,20 @@ def char_has_url_no_media(self): @pytest.mark.asyncio async def test_normal_path_generates_and_uploads(self, service, char_no_media, mock_client): - """Normal path: calls generate_images, extracts URL, uploads to get media_id.""" + """Normal path: calls generate_images; non-UUID media id triggers upload to get one.""" project = {"user_paygate_tier": "PAYGATE_TIER_TWO"} + # No UUID anywhere (media name is CAMS-format, URL has no UUID) → + # must upload to obtain a UUID media id. + fife_url = "https://lh3.googleusercontent.com/image/CAMS_non_uuid_media?sqp=params" + mock_client.generate_images = AsyncMock(return_value={ + "data": {"media": [{ + "name": "CAMS_non_uuid_media", + "image": {"generatedImage": {"mediaId": "CAMS_non_uuid_media", "fifeUrl": fife_url}}, + }]} + }) with patch("agent.sdk.services.operations.crud") as mock_crud, \ - patch("agent.sdk.services.operations._upload_character_image", + patch("agent.sdk.services.flow_provider._upload_character_image", new_callable=AsyncMock) as mock_upload: mock_crud.get_project = AsyncMock(return_value=project) mock_crud.update_character = AsyncMock() @@ -312,12 +326,35 @@ async def test_normal_path_generates_and_uploads(self, service, char_no_media, m call_kwargs = mock_client.generate_images.call_args.kwargs assert call_kwargs["aspect_ratio"] == "IMAGE_ASPECT_RATIO_PORTRAIT" assert call_kwargs["prompt"] == char_no_media["image_prompt"] + mock_upload.assert_awaited_once() + mock_crud.update_character.assert_called_once_with( + CHAR_ID, media_id=SAMPLE_UUID_2, reference_image_url=fife_url) + assert "data" in result + + @pytest.mark.asyncio + async def test_normal_path_skips_upload_when_uuid_returned(self, service, char_no_media, mock_client): + """Normal path: Flow returns a UUID media id directly → no upload needed.""" + project = {"user_paygate_tier": "PAYGATE_TIER_TWO"} + + with patch("agent.sdk.services.operations.crud") as mock_crud, \ + patch("agent.sdk.services.flow_provider._upload_character_image", + new_callable=AsyncMock) as mock_upload: + mock_crud.get_project = AsyncMock(return_value=project) + mock_crud.update_character = AsyncMock() + + result = await service.generate_reference_image(char_no_media, PROJECT_ID) + + # mock_client.generate_images returns media name=SAMPLE_UUID (a UUID) + mock_client.generate_images.assert_called_once() + mock_upload.assert_not_awaited() + assert "data" in result @pytest.mark.asyncio async def test_fast_path_upload_only_when_url_exists(self, service, char_has_url_no_media, mock_client): """Fast path: skips generate_images when URL exists but media_id is missing.""" + url = char_has_url_no_media["reference_image_url"] with patch("agent.sdk.services.operations.crud") as mock_crud, \ - patch("agent.sdk.services.operations._upload_character_image", + patch("agent.sdk.services.flow_provider._upload_character_image", new_callable=AsyncMock) as mock_upload: mock_crud.update_character = AsyncMock() mock_upload.return_value = SAMPLE_UUID_2 @@ -326,14 +363,16 @@ async def test_fast_path_upload_only_when_url_exists(self, service, char_has_url # generate_images must NOT be called on fast path mock_client.generate_images.assert_not_called() - mock_crud.update_character.assert_called_once_with(CHAR_ID, media_id=SAMPLE_UUID_2) + mock_crud.update_character.assert_called_once_with( + CHAR_ID, media_id=SAMPLE_UUID_2, reference_image_url=url) assert "data" in result @pytest.mark.asyncio async def test_fast_path_falls_back_to_uuid_from_url(self, service, char_has_url_no_media): """Fast path: when upload fails, extracts UUID directly from the image URL.""" + url = char_has_url_no_media["reference_image_url"] with patch("agent.sdk.services.operations.crud") as mock_crud, \ - patch("agent.sdk.services.operations._upload_character_image", + patch("agent.sdk.services.flow_provider._upload_character_image", new_callable=AsyncMock) as mock_upload: mock_crud.update_character = AsyncMock() mock_upload.return_value = None # upload fails @@ -341,7 +380,8 @@ async def test_fast_path_falls_back_to_uuid_from_url(self, service, char_has_url result = await service.generate_reference_image(char_has_url_no_media, PROJECT_ID) # Should extract UUID from URL: SAMPLE_UUID is embedded in the URL - mock_crud.update_character.assert_called_once_with(CHAR_ID, media_id=SAMPLE_UUID) + mock_crud.update_character.assert_called_once_with( + CHAR_ID, media_id=SAMPLE_UUID, reference_image_url=url) assert "data" in result @@ -362,6 +402,7 @@ async def test_queue_scene_image_creates_generate_image_request(self, service): mock_crud.create_request.assert_called_once_with( req_type="GENERATE_IMAGE", orientation="VERTICAL", scene_id=SCENE_ID, project_id=PROJECT_ID, video_id=VIDEO_ID, + provider=None, ) @pytest.mark.asyncio @@ -376,6 +417,7 @@ async def test_queue_scene_video_creates_generate_video_request(self, service): mock_crud.create_request.assert_called_once_with( req_type="GENERATE_VIDEO", orientation="VERTICAL", scene_id=SCENE_ID, project_id=PROJECT_ID, video_id=VIDEO_ID, + provider=None, ) @pytest.mark.asyncio @@ -390,6 +432,7 @@ async def test_queue_upscale_video_creates_upscale_video_request(self, service): mock_crud.create_request.assert_called_once_with( req_type="UPSCALE_VIDEO", orientation="VERTICAL", scene_id=SCENE_ID, project_id=PROJECT_ID, video_id=VIDEO_ID, + provider=None, ) @pytest.mark.asyncio @@ -404,6 +447,7 @@ async def test_generate_character_image_delegates_to_queue_reference_image(self, mock_crud.create_request.assert_called_once_with( req_type="GENERATE_CHARACTER_IMAGE", character_id=CHAR_ID, project_id=PROJECT_ID, + provider=None, ) diff --git a/tests/unit/test_provider_aware_projects.py b/tests/unit/test_provider_aware_projects.py new file mode 100644 index 000000000..b7a16af12 --- /dev/null +++ b/tests/unit/test_provider_aware_projects.py @@ -0,0 +1,104 @@ +"""Tests for provider-aware project creation and refresh-urls no-op. + +pytest-asyncio runs in AUTO mode (see pytest.ini). +""" +import uuid +from unittest.mock import MagicMock + +import pytest +from fastapi import FastAPI +from fastapi.testclient import TestClient + +from agent.api import projects as projects_api +from agent.api import flow as flow_api +from agent.db import crud + + +@pytest.fixture +def projects_client(test_db, monkeypatch): + app = FastAPI() + app.include_router(projects_api.router, prefix="/api") + return TestClient(app, raise_server_exceptions=False) + + +@pytest.fixture +def flow_client(test_db, monkeypatch): + app = FastAPI() + app.include_router(flow_api.router, prefix="/api") + return TestClient(app, raise_server_exceptions=False) + + +def _disconnected_client(monkeypatch, target_module): + """Patch get_flow_client in target_module to return a disconnected client.""" + client = MagicMock() + client.connected = False + # flow_project_id validates UUID format like the real client + client.flow_project_id = lambda req: ( + req if req and __import__("re").match( + r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", + req, __import__("re").I) else None) + monkeypatch.setattr(target_module, "get_flow_client", lambda: client) + return client + + +async def test_create_project_without_extension_local_only( + projects_client, test_db, monkeypatch): + _disconnected_client(monkeypatch, projects_api) + + r = projects_client.post("/api/projects", json={"name": "Local Only"}) + assert r.status_code == 200, r.text + body = r.json() + # minted UUID, not a Flow project + uuid.UUID(body["id"]) + assert body["name"] == "Local Only" + + row = await crud.get_project(body["id"]) + assert row is not None + + +async def test_create_project_with_explicit_flow_id_no_extension( + projects_client, test_db, monkeypatch): + _disconnected_client(monkeypatch, projects_api) + fid = str(uuid.uuid4()) + + r = projects_client.post("/api/projects", + json={"name": "Reuse", "flow_project_id": fid}) + assert r.status_code == 200, r.text + assert r.json()["id"] == fid + + +async def test_refresh_urls_noop_for_local_media(flow_client, test_db, + monkeypatch, tmp_path): + _disconnected_client(monkeypatch, flow_api) + + proj = await crud.create_project(name="Local Media") + video = await crud.create_video(project_id=proj["id"], title="V", + orientation="VERTICAL") + scene = await crud.create_scene(video_id=video["id"], display_order=0, + prompt="x") + clip = tmp_path / "c.mp4" + clip.write_bytes(b"fake") + await crud.update_scene(scene["id"], vertical_video_url=f"file://{clip}") + + # No extension connected AND all URLs local -> no-op, not 503. + r = flow_client.post(f"/api/flow/refresh-urls/{proj['id']}") + assert r.status_code == 200, r.text + body = r.json() + assert body["refreshed"] == 0 + assert "nothing to refresh" in body["skipped"] + + +async def test_refresh_urls_still_needs_extension_for_remote( + flow_client, test_db, monkeypatch): + _disconnected_client(monkeypatch, flow_api) + + proj = await crud.create_project(name="Remote Media") + video = await crud.create_video(project_id=proj["id"], title="V", + orientation="VERTICAL") + scene = await crud.create_scene(video_id=video["id"], display_order=0, + prompt="x") + await crud.update_scene( + scene["id"], vertical_video_url="https://example.com/clip.mp4") + + r = flow_client.post(f"/api/flow/refresh-urls/{proj['id']}") + assert r.status_code == 503 # extension required for remote URLs diff --git a/tests/unit/test_provider_jobs.py b/tests/unit/test_provider_jobs.py new file mode 100644 index 000000000..4f19d34b9 --- /dev/null +++ b/tests/unit/test_provider_jobs.py @@ -0,0 +1,314 @@ +"""Tests for the provider-job queue: CRUD lease semantics + HTTP API. + +pytest-asyncio runs in AUTO mode (see pytest.ini). +""" +import asyncio +import json + +import pytest +from fastapi import FastAPI +from fastapi.testclient import TestClient + +from agent.api.provider_jobs import router as provider_jobs_router +from agent.db import crud + + +@pytest.fixture +def api_client(test_db): + app = FastAPI() + app.include_router(provider_jobs_router, prefix="/api") + return TestClient(app) + + +async def _mk(provider="assistant", kind="image", job_id=None, **kw): + return await crud.create_provider_job(provider=provider, kind=kind, + prompt="p", job_id=job_id, **kw) + + +# --------------------------------------------------------------------------- +# CRUD: lifecycle + leasing +# --------------------------------------------------------------------------- + +async def test_create_and_get(test_db): + row = await _mk(job_id="j1") + assert row["status"] == "QUEUED" + assert row["provider"] == "assistant" + assert json.loads(row["extra"]) == {} + got = await crud.get_provider_job("j1") + assert got["id"] == "j1" + + +async def test_list_filters(test_db): + await _mk(job_id="a1", provider="assistant") + await _mk(job_id="a2", provider="assistant") + await _mk(job_id="f1", provider="flow") + rows = await crud.list_provider_jobs(provider="assistant") + assert {r["id"] for r in rows} == {"a1", "a2"} + rows = await crud.list_provider_jobs(status="QUEUED", limit=10) + assert len(rows) == 3 + + +async def test_claim_happy_path(test_db): + await _mk(job_id="j1") + row = await crud.claim_provider_job("j1", "w1", lease_ttl_s=300) + assert row["status"] == "CLAIMED" + assert row["claimed_by"] == "w1" + assert row["lease_expires_at"] is not None + + +async def test_claim_conflict_when_lease_valid(test_db): + await _mk(job_id="j1") + assert await crud.claim_provider_job("j1", "w1", lease_ttl_s=300) + # second worker cannot steal a live lease + assert await crud.claim_provider_job("j1", "w2", lease_ttl_s=300) is None + + +async def test_claim_reclaims_expired_lease(test_db): + await _mk(job_id="j1") + assert await crud.claim_provider_job("j1", "w1", lease_ttl_s=-1) # already expired + row = await crud.claim_provider_job("j1", "w2", lease_ttl_s=300) + assert row is not None and row["claimed_by"] == "w2" + + +async def test_claim_rejects_terminal(test_db): + await _mk(job_id="j1") + await crud.claim_provider_job("j1", "w1") + await crud.complete_provider_job("j1", "w1", {"output_url": "x"}) + assert await crud.claim_provider_job("j1", "w1") is None + assert await crud.get_provider_job("missing") is None or True + assert await crud.claim_provider_job("missing", "w1") is None + + +async def test_heartbeat_extends_and_rejects_stranger(test_db): + await _mk(job_id="j1") + await crud.claim_provider_job("j1", "w1", lease_ttl_s=60) + before = (await crud.get_provider_job("j1"))["lease_expires_at"] + await asyncio.sleep(0.05) + row = await crud.heartbeat_provider_job("j1", "w1", lease_ttl_s=600) + assert row is not None + assert row["lease_expires_at"] > before + assert row["status"] == "RUNNING" # CLAIMED -> RUNNING on first heartbeat + # a different worker cannot heartbeat + assert await crud.heartbeat_provider_job("j1", "w2") is None + + +async def test_progress_complete_fail_cancel(test_db): + await _mk(job_id="j1") + await crud.claim_provider_job("j1", "w1") + row = await crud.update_provider_job_progress("j1", "w1", 42, "halfway") + assert row["progress"] == 42 and row["progress_message"] == "halfway" + row = await crud.complete_provider_job("j1", "w1", {"output_url": "file:///o.png"}) + assert row["status"] == "SUCCEEDED" and row["progress"] == 100 + assert json.loads(row["result"])["output_url"] == "file:///o.png" + + await _mk(job_id="j2") + await crud.claim_provider_job("j2", "w1") + row = await crud.fail_provider_job("j2", "w1", "boom") + assert row["status"] == "FAILED" and row["error_message"] == "boom" + + await _mk(job_id="j3") + row = await crud.cancel_provider_job("j3") + assert row["status"] == "CANCELLED" + + +async def test_ownership_enforced(test_db): + """Only the lease holder may touch a live job; terminal rules hold.""" + await _mk(job_id="j1") + # stranger progress/complete/fail on a QUEUED job -> None + assert await crud.update_provider_job_progress("j1", "w9", 10) is None + assert await crud.complete_provider_job("j1", "w9", {}) is None + assert await crud.fail_provider_job("j1", "w9", "x") is None + + await crud.claim_provider_job("j1", "w1") + # wrong worker still rejected + assert await crud.update_provider_job_progress("j1", "w2", 10) is None + assert await crud.complete_provider_job("j1", "w2", {}) is None + assert await crud.fail_provider_job("j1", "w2", "x") is None + + # holder completes; stranger fail afterwards is rejected + row = await crud.complete_provider_job("j1", "w1", {"output_url": "o"}) + assert row["status"] == "SUCCEEDED" + assert await crud.fail_provider_job("j1", "w1", "late") is None + assert await crud.fail_provider_job("j1", "w2", "late") is None + + # idempotent re-complete returns the row + row2 = await crud.complete_provider_job("j1", "w1", {"output_url": "o"}) + assert row2["status"] == "SUCCEEDED" + assert json.loads(row2["result"])["output_url"] == "o" + + # cancel on terminal job rejected + assert await crud.cancel_provider_job("j1") is None + + +async def test_fail_idempotent_and_cancel_guards(test_db): + await _mk(job_id="j2") + await crud.claim_provider_job("j2", "w1") + row = await crud.fail_provider_job("j2", "w1", "boom") + assert row["status"] == "FAILED" + # idempotent re-fail returns the row + row2 = await crud.fail_provider_job("j2", "w1", "boom") + assert row2["status"] == "FAILED" and row2["error_message"] == "boom" + # a SUCCEEDED job cannot be failed + await _mk(job_id="j3") + await crud.claim_provider_job("j3", "w1") + await crud.complete_provider_job("j3", "w1", {}) + assert await crud.fail_provider_job("j3", "w1", "x") is None + # cancel a live job works, twice does not + await _mk(job_id="j4") + await crud.claim_provider_job("j4", "w1") + assert (await crud.cancel_provider_job("j4"))["status"] == "CANCELLED" + assert await crud.cancel_provider_job("j4") is None + + +async def test_wait_for_job_returns_on_completion(test_db): + await _mk(job_id="j1") + await crud.claim_provider_job("j1", "w1") + + async def finisher(): + await asyncio.sleep(0.2) + await crud.complete_provider_job("j1", "w1", {"output_url": "x"}) + + task = asyncio.ensure_future(finisher()) + row = await crud.wait_for_provider_job("j1", timeout_s=10, poll_interval_s=0.05) + await task + assert row["status"] == "SUCCEEDED" + + +async def test_wait_for_job_timeout(test_db): + await _mk(job_id="j1") + assert await crud.wait_for_provider_job("j1", timeout_s=0.3, poll_interval_s=0.05) is None + assert await crud.wait_for_provider_job("missing", timeout_s=1) is None + + +async def test_next_queued_claims_oldest(test_db): + await _mk(job_id="old") + await asyncio.sleep(0.02) + await _mk(job_id="new") + row = await crud.next_queued_provider_job("assistant", "w1") + assert row["id"] == "old" and row["claimed_by"] == "w1" + # second call gets the next one + row = await crud.next_queued_provider_job("assistant", "w1") + assert row["id"] == "new" + assert await crud.next_queued_provider_job("assistant", "w1") is None + assert await crud.next_queued_provider_job("flow", "w1") is None + + +# --------------------------------------------------------------------------- +# HTTP API +# --------------------------------------------------------------------------- + +def test_api_create_get_wait_cycle(api_client): + r = api_client.post("/api/provider-jobs", json={ + "provider": "assistant", "kind": "image", "prompt": "a cat", + "orientation": "VERTICAL", "extra": {"a": 1}}) + assert r.status_code == 200, r.text + job = r.json() + job_id = job["id"] + assert job["status"] == "QUEUED" + assert job["extra"] == {"a": 1} # JSON columns parsed + + r = api_client.get(f"/api/provider-jobs/{job_id}") + assert r.status_code == 200 and r.json()["prompt"] == "a cat" + + r = api_client.get("/api/provider-jobs", params={"provider": "assistant"}) + assert any(j["id"] == job_id for j in r.json()) + + # claim + heartbeat + progress + complete + r = api_client.post(f"/api/provider-jobs/{job_id}/claim", + json={"worker_id": "w1", "lease_ttl_s": 300}) + assert r.status_code == 200 and r.json()["claimed_by"] == "w1" + + r = api_client.post(f"/api/provider-jobs/{job_id}/heartbeat", + json={"worker_id": "w1"}) + assert r.status_code == 200 and r.json()["status"] == "RUNNING" + + r = api_client.post(f"/api/provider-jobs/{job_id}/progress", + json={"worker_id": "w1", "progress": 50, "message": "half"}) + assert r.status_code == 200 and r.json()["progress"] == 50 + + # stranger progress is rejected + r = api_client.post(f"/api/provider-jobs/{job_id}/progress", + json={"worker_id": "w2", "progress": 60}) + assert r.status_code == 409 + + r = api_client.post(f"/api/provider-jobs/{job_id}/complete", + json={"worker_id": "w1", + "result": {"output_url": "file:///o.png"}}) + assert r.status_code == 200 + assert r.json()["status"] == "SUCCEEDED" + assert r.json()["result"]["output_url"] == "file:///o.png" + + # idempotent re-complete returns the row + r = api_client.post(f"/api/provider-jobs/{job_id}/complete", + json={"worker_id": "w1", + "result": {"output_url": "file:///o.png"}}) + assert r.status_code == 200 and r.json()["status"] == "SUCCEEDED" + + # a stranger's complete on the terminal job is still rejected + r = api_client.post(f"/api/provider-jobs/{job_id}/complete", + json={"worker_id": "w2", + "result": {"output_url": "file:///evil.png"}}) + assert r.status_code == 409 + + # wait returns immediately for terminal jobs + r = api_client.get(f"/api/provider-jobs/{job_id}/wait", params={"timeout_s": 5}) + assert r.status_code == 200 and r.json()["status"] == "SUCCEEDED" + + +def test_api_wait_next_long_poll(api_client): + import threading, time + created = {} + + def producer(): + time.sleep(0.5) + r = api_client.post("/api/provider-jobs", json={ + "provider": "assistant", "kind": "image", "prompt": "late job"}) + created["id"] = r.json()["id"] + + t = threading.Thread(target=producer) + t.start() + r = api_client.get("/api/provider-jobs/wait-next", + params={"provider": "assistant", "worker_id": "w9", + "timeout_s": 10}) + t.join() + assert r.status_code == 200, r.text + assert r.json()["id"] == created["id"] + assert r.json()["claimed_by"] == "w9" + + +def test_api_wait_next_timeout_returns_204(api_client): + r = api_client.get("/api/provider-jobs/wait-next", + params={"provider": "nobody", "worker_id": "w1", + "timeout_s": 1}) + assert r.status_code == 204 + + +def test_api_errors(api_client): + assert api_client.get("/api/provider-jobs/missing").status_code == 404 + assert api_client.get("/api/provider-jobs/missing/wait").status_code == 404 + r = api_client.post("/api/provider-jobs/missing/claim", + json={"worker_id": "w1"}) + assert r.status_code == 409 + # heartbeat by non-holder + r = api_client.post("/api/provider-jobs", json={ + "provider": "assistant", "kind": "image", "prompt": "x"}) + jid = r.json()["id"] + api_client.post(f"/api/provider-jobs/{jid}/claim", json={"worker_id": "w1"}) + r = api_client.post(f"/api/provider-jobs/{jid}/heartbeat", + json={"worker_id": "w2"}) + assert r.status_code == 409 + # fail by non-holder rejected; fail by holder works + r = api_client.post(f"/api/provider-jobs/{jid}/fail", + json={"worker_id": "w2", "error": "bad"}) + assert r.status_code == 409 + r = api_client.post(f"/api/provider-jobs/{jid}/fail", + json={"worker_id": "w1", "error": "bad"}) + assert r.json()["status"] == "FAILED" + # cancel on a terminal job is rejected + r = api_client.post(f"/api/provider-jobs/{jid}/cancel") + assert r.status_code == 409 + r = api_client.post("/api/provider-jobs", json={ + "provider": "assistant", "kind": "image", "prompt": "y"}) + jid2 = r.json()["id"] + r = api_client.post(f"/api/provider-jobs/{jid2}/cancel") + assert r.json()["status"] == "CANCELLED" diff --git a/tests/unit/test_review_regenerate.py b/tests/unit/test_review_regenerate.py new file mode 100644 index 000000000..71513adb8 --- /dev/null +++ b/tests/unit/test_review_regenerate.py @@ -0,0 +1,153 @@ +"""Tests for review provider-neutrality and bounded auto-regeneration. + +pytest-asyncio runs in AUTO mode (see pytest.ini). +""" +from pathlib import Path + +import pytest +from fastapi import FastAPI +from fastapi.testclient import TestClient + +from agent.api import reviews as reviews_api +from agent.db import crud +from agent.models.review import ( + DimensionScores, + SceneReview, + VideoReview, +) +from agent.services.video_reviewer import _local_media_path + + +@pytest.fixture +def reviews_client(test_db, monkeypatch): + app = FastAPI() + app.include_router(reviews_api.router, prefix="/api") + return TestClient(app, raise_server_exceptions=False) + + +def _dims(): + return DimensionScores(character_consistency=1, prompt_adherence=1, + motion_quality=1, visual_fidelity=1, + temporal_coherence=1, composition=1) + + +def _scene_review(sid, verdict, critical=False): + return SceneReview(scene_id=sid, overall_score=1.0, verdict=verdict, + dimensions=_dims(), errors=[], usable_segments=[], + fix_guide="", frames_analyzed=4, fps_used=4.0, + has_critical_errors=critical) + + +def _video_review(vid, scene_reviews): + return VideoReview(video_id=vid, project_id="p", mode="light", + orientation="VERTICAL", overall_score=1.0, + verdict="poor", scene_reviews=scene_reviews, + scenes_reviewed=len(scene_reviews), scenes_skipped=0) + + +async def _mk_scene(test_db, tmp_path, vid, order, image_media_id="img-mid"): + scene = await crud.create_scene(video_id=vid, display_order=order, + prompt=f"scene {order}") + clip = tmp_path / f"rev_{order}.mp4" + clip.write_bytes(b"fake") + await crud.update_scene(scene["id"], vertical_video_url=f"file://{clip}", + vertical_image_media_id=image_media_id) + return scene + + +async def test_local_media_path_file_url(tmp_path): + f = tmp_path / "clip.mp4" + f.write_bytes(b"x") + assert _local_media_path(f"file://{f}") == f + assert _local_media_path(str(f)) == f + assert _local_media_path("https://example.com/a.mp4") is None + assert _local_media_path("") is None + assert _local_media_path(None) is None + assert _local_media_path(f"file://{tmp_path}/missing.mp4") is None + + +async def test_review_regenerate_enqueues_bad_scenes(reviews_client, test_db, + tmp_path, monkeypatch): + proj = await crud.create_project(name="Rev Test") + video = await crud.create_video(project_id=proj["id"], title="V", + orientation="VERTICAL") + s_bad = await _mk_scene(test_db, tmp_path, video["id"], 0) + s_good = await _mk_scene(test_db, tmp_path, video["id"], 1) + + async def fake_review(*a, **k): + return _video_review(video["id"], + [_scene_review(s_bad["id"], "poor"), + _scene_review(s_good["id"], "good")]) + + monkeypatch.setattr(reviews_api, "review_video", fake_review) + + r = reviews_client.post( + f"/api/videos/{video['id']}/review-regenerate", + json={"project_id": proj["id"], "max_regenerations": 1}) + assert r.status_code == 200, r.text + body = r.json() + decisions = {d["scene_id"]: d for d in body["decisions"]} + assert decisions[s_bad["id"]]["regenerated"] is True + assert decisions[s_bad["id"]]["request_id"] + assert decisions[s_good["id"]]["regenerated"] is False + + reqs = await crud.list_requests(scene_id=s_bad["id"]) + assert any(x["type"] == "REGENERATE_VIDEO" for x in reqs) + + +async def test_review_regenerate_bound_reached(reviews_client, test_db, + tmp_path, monkeypatch): + proj = await crud.create_project(name="Rev Bound") + video = await crud.create_video(project_id=proj["id"], title="V", + orientation="VERTICAL") + s_bad = await _mk_scene(test_db, tmp_path, video["id"], 0) + + async def fake_review(*a, **k): + return _video_review(video["id"], [_scene_review(s_bad["id"], "unusable")]) + + monkeypatch.setattr(reviews_api, "review_video", fake_review) + + body_json = {"project_id": proj["id"], "max_regenerations": 1} + r1 = reviews_client.post(f"/api/videos/{video['id']}/review-regenerate", + json=body_json) + assert r1.json()["decisions"][0]["regenerated"] is True + + # Second run: bound reached, no new request. + r2 = reviews_client.post(f"/api/videos/{video['id']}/review-regenerate", + json=body_json) + assert r2.status_code == 200 + d = r2.json()["decisions"][0] + assert d["regenerated"] is False + assert "bound reached" in d["reason"] + + reqs = await crud.list_requests(scene_id=s_bad["id"]) + assert sum(1 for x in reqs if x["type"] == "REGENERATE_VIDEO") == 1 + + +async def test_review_regenerate_no_image_skips(reviews_client, test_db, + tmp_path, monkeypatch): + proj = await crud.create_project(name="Rev NoImg") + video = await crud.create_video(project_id=proj["id"], title="V", + orientation="VERTICAL") + scene = await crud.create_scene(video_id=video["id"], display_order=0, + prompt="x") + # no vertical_image_media_id set + + async def fake_review(*a, **k): + return _video_review(video["id"], [_scene_review(scene["id"], "poor")]) + + monkeypatch.setattr(reviews_api, "review_video", fake_review) + + r = reviews_client.post( + f"/api/videos/{video['id']}/review-regenerate", + json={"project_id": proj["id"]}) + assert r.status_code == 200, r.text + d = r.json()["decisions"][0] + assert d["regenerated"] is False + assert "no scene image" in d["reason"] + + +async def test_review_regenerate_404(reviews_client, test_db): + r = reviews_client.post("/api/videos/nope/review-regenerate", + json={"project_id": "x"}) + assert r.status_code == 404 diff --git a/tests/unit/test_video_assemble.py b/tests/unit/test_video_assemble.py new file mode 100644 index 000000000..60246a6e4 --- /dev/null +++ b/tests/unit/test_video_assemble.py @@ -0,0 +1,307 @@ +"""Tests for Phase 3: concat/finalize endpoints, target_duration_s, +thumbnail/TTS provider routing. + +pytest-asyncio runs in AUTO mode (see pytest.ini). +""" +import subprocess +from pathlib import Path + +import pytest +from fastapi import FastAPI +from fastapi.testclient import TestClient + +from agent.api import projects as projects_api +from agent.api import tts as tts_api +from agent.api.videos import router as videos_router +from agent.db import crud +from agent.sdk.services.provider_base import ( + KIND_AUDIO, + KIND_IMAGE, + MediaProvider, + ProviderCapabilities, +) + + +@pytest.fixture +def videos_client(test_db): + app = FastAPI() + app.include_router(videos_router, prefix="/api") + return TestClient(app, raise_server_exceptions=False) + + +def _make_clip(path: Path, duration: float = 1.0, size: str = "320x240") -> None: + path.parent.mkdir(parents=True, exist_ok=True) + subprocess.run( + ["ffmpeg", "-y", "-f", "lavfi", "-i", f"color=c=red:s={size}:d={duration}:r=30", + "-f", "lavfi", "-i", f"sine=frequency=440:duration={duration}", + "-c:v", "libx264", "-pix_fmt", "yuv420p", "-c:a", "aac", + "-shortest", str(path)], + capture_output=True, check=True, timeout=60) + + +async def _mk_video_with_clips(tmp_path, n_scenes=3, orientation="VERTICAL", + target_duration_s=None, clip_duration=1.0): + proj = await crud.create_project(name="Assemble Test") + video = await crud.create_video( + project_id=proj["id"], title="Ep 1", orientation=orientation, + target_duration_s=target_duration_s) + key = f"{orientation.lower()}_video_url" + for i in range(n_scenes): + scene = await crud.create_scene( + video_id=video["id"], display_order=i, prompt=f"scene {i}") + clip = tmp_path / f"scene_{i}.mp4" + _make_clip(clip, duration=clip_duration) + await crud.update_scene(scene["id"], **{key: f"file://{clip}"}) + return proj, video + + +# --------------------------------------------------------------------------- +# target_duration_s persistence +# --------------------------------------------------------------------------- + +async def test_target_duration_s_roundtrip(test_db): + proj = await crud.create_project(name="P") + v = await crud.create_video(project_id=proj["id"], title="V", + target_duration_s=60.0) + assert v["target_duration_s"] == 60.0 + v2 = await crud.update_video(v["id"], target_duration_s=30.0) + assert v2["target_duration_s"] == 30.0 + assert (await crud.get_video(v["id"]))["target_duration_s"] == 30.0 + + +# --------------------------------------------------------------------------- +# concat / finalize +# --------------------------------------------------------------------------- + +async def test_concat_merges_and_trims(videos_client, test_db, tmp_path): + _, video = await _mk_video_with_clips( + tmp_path, n_scenes=3, target_duration_s=2.5) + + r = videos_client.post(f"/api/videos/{video['id']}/concat", + json={"orientation": "VERTICAL"}) + assert r.status_code == 200, r.text + body = r.json() + assert body["scenes_used"] == 3 + assert body["scenes_missing"] == [] + assert body["trimmed"] is True # 3s of clips trimmed to 2.5s target + assert abs(body["duration"] - 2.5) < 0.3 + assert Path(body["output_path"]).is_file() + + row = await crud.get_video(video["id"]) + assert row["vertical_url"].startswith("file://") + assert abs(row["duration"] - 2.5) < 0.3 + assert row["target_duration_s"] == 2.5 + + +async def test_concat_no_target_keeps_full_length(videos_client, test_db, tmp_path): + _, video = await _mk_video_with_clips(tmp_path, n_scenes=2) + + r = videos_client.post(f"/api/videos/{video['id']}/concat", json={}) + assert r.status_code == 200, r.text + body = r.json() + assert body["trimmed"] is False + assert abs(body["duration"] - 2.0) < 0.3 + + +async def test_concat_request_target_overrides_stored(videos_client, test_db, tmp_path): + _, video = await _mk_video_with_clips( + tmp_path, n_scenes=3, target_duration_s=99.0) + + r = videos_client.post(f"/api/videos/{video['id']}/concat", + json={"target_duration_s": 1.5}) + assert r.status_code == 200, r.text + body = r.json() + assert body["trimmed"] is True + assert abs(body["duration"] - 1.5) < 0.3 + row = await crud.get_video(video["id"]) + assert row["target_duration_s"] == 1.5 + + +async def test_concat_missing_scenes_400(videos_client, test_db): + proj = await crud.create_project(name="P3") + video = await crud.create_video(project_id=proj["id"], title="V3", + orientation="VERTICAL") + await crud.create_scene(video_id=video["id"], display_order=0, prompt="x") + r = videos_client.post(f"/api/videos/{video['id']}/concat", json={}) + assert r.status_code == 400 + + +async def test_finalize_marks_completed(videos_client, test_db, tmp_path): + _, video = await _mk_video_with_clips(tmp_path, n_scenes=2) + + r = videos_client.post(f"/api/videos/{video['id']}/finalize", + json={"orientation": "VERTICAL", + "target_duration_s": 1.5}) + assert r.status_code == 200, r.text + body = r.json() + assert body["status"] == "COMPLETED" + assert "concat (2 scenes)" in body["steps"] + assert Path(body["output_path"]).is_file() + + row = await crud.get_video(video["id"]) + assert row["status"] == "COMPLETED" + + +async def test_finalize_404(videos_client, test_db): + r = videos_client.post("/api/videos/nope/finalize", json={}) + assert r.status_code == 404 + + +# --------------------------------------------------------------------------- +# thumbnail via provider +# --------------------------------------------------------------------------- + +class _FakeThumbProvider(MediaProvider): + name = "assistant" + capabilities = ProviderCapabilities() + + def __init__(self, image_url: str): + self.jobs = [] + self.image_url = image_url + + async def run(self, job): + self.jobs.append(job) + mid = "550e8400-e29b-41d4-a716-446655440000" + return {"data": {"media": [{"name": mid, + "image": {"generatedImage": { + "mediaId": mid, + "fifeUrl": self.image_url}}}]}} + + +@pytest.fixture +def projects_client(test_db, tmp_path, monkeypatch): + src = tmp_path / "thumb_src.png" + src.write_bytes(b"\x89PNG fake") + fake = _FakeThumbProvider(image_url=f"file://{src}") + + class FakeRegistry: + def get(self, name): + return fake if name == "assistant" else None + + def names(self): + return ["assistant"] + + class FakeOps: + registry = FakeRegistry() + + monkeypatch.setattr("agent.sdk.services.operations.get_operations", lambda: FakeOps()) + + app = FastAPI() + app.include_router(projects_api.router, prefix="/api") + client = TestClient(app, raise_server_exceptions=False) + client.fake_provider = fake + return client + + +async def test_thumbnail_via_provider(projects_client, test_db): + proj = await crud.create_project(name="Thumb Proj") + + r = projects_client.post( + f"/api/projects/{proj['id']}/generate-thumbnail", + json={"prompt": "epic thumbnail", "provider": "assistant"}) + assert r.status_code == 200, r.text + body = r.json() + assert body["success"] is True + assert Path(body["output_path"]).is_file() + + job = projects_client.fake_provider.jobs[0] + assert job.kind == KIND_IMAGE + assert job.orientation == "HORIZONTAL" # LANDSCAPE default + assert "epic thumbnail" in job.prompt + + +async def test_thumbnail_unknown_provider_400(projects_client, test_db): + proj = await crud.create_project(name="P") + r = projects_client.post( + f"/api/projects/{proj['id']}/generate-thumbnail", + json={"prompt": "x", "provider": "nope"}) + assert r.status_code == 400 + + +# --------------------------------------------------------------------------- +# TTS via provider +# --------------------------------------------------------------------------- + +class _FakeTTSProvider(MediaProvider): + name = "assistant" + capabilities = ProviderCapabilities(generate_audio=True) + + def __init__(self): + self.jobs = [] + + async def run(self, job): + self.jobs.append(job) + return {"data": {"url": "file:///tmp/fake_tts.wav", + "audio_path": "/tmp/fake_tts.wav"}} + + def check(self, job): + if job.kind == KIND_AUDIO: + return None + return super().check(job) + + +@pytest.fixture +def tts_client(test_db, monkeypatch): + fake = _FakeTTSProvider() + + class FakeRegistry: + def get(self, name): + return fake if name == "assistant" else None + + def names(self): + return ["assistant"] + + class FakeOps: + registry = FakeRegistry() + + monkeypatch.setattr("agent.sdk.services.operations.get_operations", lambda: FakeOps()) + + app = FastAPI() + app.include_router(tts_api.router, prefix="/api") + client = TestClient(app, raise_server_exceptions=False) + client.fake_provider = fake + return client + + +async def test_tts_via_provider(tts_client, test_db): + r = tts_client.post("/api/tts/generate", + json={"text": "hello world", "provider": "assistant"}) + assert r.status_code == 200, r.text + body = r.json() + assert body["audio_path"] == "/tmp/fake_tts.wav" + job = tts_client.fake_provider.jobs[0] + assert job.kind == KIND_AUDIO + assert job.prompt == "hello world" + + +async def test_tts_unknown_provider_400(tts_client, test_db): + r = tts_client.post("/api/tts/generate", + json={"text": "hi", "provider": "nope"}) + assert r.status_code == 400 + + +async def test_tts_flow_provider_rejected(tts_client, test_db, monkeypatch): + """A provider without audio capability is rejected with 400.""" + from agent.sdk.services.provider_base import MediaProvider as MP + + class Flowish(MP): + name = "flow" + capabilities = ProviderCapabilities() # generate_audio=False + + async def run(self, job): + raise AssertionError("must not run") + + class FakeRegistry: + def get(self, name): + return Flowish() if name == "flow" else None + + def names(self): + return ["flow"] + + class FakeOps: + registry = FakeRegistry() + + monkeypatch.setattr("agent.sdk.services.operations.get_operations", lambda: FakeOps()) + r = tts_client.post("/api/tts/generate", + json={"text": "hi", "provider": "flow"}) + assert r.status_code == 400 From e77688b872341e1abfa908d9940a365b82c21c2f Mon Sep 17 00:00:00 2001 From: crisng95 <crisng95@users.noreply.github.com> Date: Tue, 29 Sep 2026 04:38:16 +0000 Subject: [PATCH 39/68] docs: add AI Agent Support table above Showcase in README --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 2f5b02393..ec490a1ed 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,19 @@ Standalone system to generate AI videos via Google Flow. Uses a Chrome extension as a browser bridge: it mints reCAPTCHA and runs Flow's batchexecute RPCs inside a signed-in `flow.google.com` tab, which is the only place they can be signed. +## AI Agent Support + +FlowKit's 36 skills (`skills/fk-*.md`) are plain Markdown recipes any AI coding +agent can read and follow. Review providers are swappable at runtime +(`agent/providers.json`, or `/fk-change-provider`) — no restart needed. + +| Agent | Skills | Video review provider | +|-------|--------|----------------------| +| **Muse** | Native — reads `skills/fk-*.md` directly, vision on files and contact sheets (`muse.read`) | `muse` — official opt-in provider: no CLI, no model, no API key; scores sheets by hand via `review-sheets` → `review-submit` | +| **Claude Code** | Auto-loaded via `CLAUDE.md`, native `/fk-*` slash commands | `claude` — default `video_review` role | +| **Codex CLI** | Reads `skills/fk-<name>.md` via `AGENTS.md` | `codex` — OpenAI Codex CLI | +| **agy** (Google Antigravity) | Reads skill files manually | `agy` — Antigravity CLI | + ## Showcase All outputs below were generated end-to-end by this system — from story concept to final YouTube-ready video with thumbnails, narration, and branding. From 6bc431f2b61452edf8521f40d698188d1319f9fb Mon Sep 17 00:00:00 2001 From: crisng95 <crisng95@users.noreply.github.com> Date: Tue, 29 Sep 2026 04:42:07 +0000 Subject: [PATCH 40/68] feat: agent self-review works for Muse, Codex, and agy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'muse' review provider now means 'the agent itself' — whichever agent runs the skills scores contact sheets by hand with its own vision via review-sheets -> review-submit. Docs, skills, and README updated; provider key stays 'muse' for backward compatibility. --- README.md | 9 +++++---- agent/api/reviews.py | 13 +++++++------ agent/models/review.py | 6 +++--- agent/services/cli_providers.py | 11 ++++++----- agent/services/video_reviewer.py | 18 +++++++++--------- skills/fk-change-provider.md | 5 +++-- skills/fk-doctor.md | 2 +- skills/fk-review-video.md | 9 ++++++--- tests/unit/test_muse_review.py | 6 +++--- 9 files changed, 43 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index ec490a1ed..d9e1f2aa1 100644 --- a/README.md +++ b/README.md @@ -48,10 +48,10 @@ agent can read and follow. Review providers are swappable at runtime | Agent | Skills | Video review provider | |-------|--------|----------------------| -| **Muse** | Native — reads `skills/fk-*.md` directly, vision on files and contact sheets (`muse.read`) | `muse` — official opt-in provider: no CLI, no model, no API key; scores sheets by hand via `review-sheets` → `review-submit` | +| **Muse** | Native — reads `skills/fk-*.md` directly, vision on files and contact sheets (`muse.read`) | `muse` (= the agent itself) — official opt-in self-review: no CLI, no model, no API key; score sheets by hand via `review-sheets` → `review-submit` | | **Claude Code** | Auto-loaded via `CLAUDE.md`, native `/fk-*` slash commands | `claude` — default `video_review` role | -| **Codex CLI** | Reads `skills/fk-<name>.md` via `AGENTS.md` | `codex` — OpenAI Codex CLI | -| **agy** (Google Antigravity) | Reads skill files manually | `agy` — Antigravity CLI | +| **Codex CLI** | Reads `skills/fk-<name>.md` via `AGENTS.md`; vision on contact sheets for self-review | `codex` — OpenAI Codex CLI, or `muse` (= the agent itself) for hand scoring | +| **agy** (Google Antigravity) | Reads skill files manually; vision on contact sheets for self-review | `agy` — Antigravity CLI, or `muse` (= the agent itself) for hand scoring | ## Showcase @@ -659,7 +659,8 @@ Muse is a first-class FlowKit agent, not just another skill reader: Muse reads `skills/fk-*.md` and calls its own tools directly, including vision on files (`muse.read` for contact sheets and images). - **`muse` is an official video-review provider** — no CLI, no model, no API - key. It scores review contact sheets by hand through + key. The key means "the agent itself": Muse, Codex, or agy scores review + contact sheets by hand with its own vision through `POST .../review-sheets` → vision → `POST .../review-submit` (see `/fk-review-video --by muse`). Opt in per role with `/fk-change-provider set muse`; the default role stays on `claude`. diff --git a/agent/api/reviews.py b/agent/api/reviews.py index 2165586b6..bd5449ae3 100644 --- a/agent/api/reviews.py +++ b/agent/api/reviews.py @@ -85,7 +85,7 @@ async def review_and_regenerate_endpoint(vid: str, body: RegenerateAfterReviewRe per scene. The worker queue picks the new requests up; regeneration goes through the same provider path as the original generation. - When ``body.scores`` is provided (Muse-scored review), the + When ``body.scores`` is provided (agent-scored review), the CLI/SDK review is skipped and the VideoReview is computed from those scores instead. """ @@ -122,7 +122,7 @@ def _review_from_scores( vid: str, project_id: str, mode: str, orientation: str, scores: list[SceneScoreInput], ) -> VideoReview: - """Compute a VideoReview from Muse-submitted scores. + """Compute a VideoReview from agent-submitted scores. Same validation, severity rules, CRITICAL caps, and overall computation as every other reviewer backend. @@ -255,12 +255,13 @@ async def _detect_orientation(video_id: str) -> str: @router.post("/{vid}/review-sheets", response_model=ReviewSheetsResponse) async def review_sheets_endpoint(vid: str, body: ReviewSheetsRequest): - """Build contact sheets for Muse review — no AI CLI needed. + """Build contact sheets for agent self-review — no AI CLI needed. Extracts frames and tiles them into contact sheets persisted under the project's ``review/sheets/`` dir, then returns the sheet paths plus the - rubric prompt the reviewer should answer. Muse reads the sheets, scores - each scene, and submits via ``POST .../review-submit``. + rubric prompt the reviewer should answer. The agent (Muse, Codex, or + agy) reads the sheets with its own vision, scores each scene, and + submits via ``POST .../review-submit``. """ if body.mode not in ("light", "deep"): raise HTTPException(400, "mode must be 'light' or 'deep'") @@ -306,7 +307,7 @@ async def review_sheets_endpoint(vid: str, body: ReviewSheetsRequest): @router.post("/{vid}/review-submit", response_model=VideoReview) async def review_submit_endpoint(vid: str, body: ReviewSubmitRequest): - """Submit Muse's per-scene scores; the server computes the review. + """Submit the agent\u2019s per-scene hand scores; the server computes the review. Accepts the same JSON shape a CLI reviewer returns (dimensions, errors, usable_segments) and applies identical validation, severity rules, diff --git a/agent/models/review.py b/agent/models/review.py index f1cc80e8a..ad526d440 100644 --- a/agent/models/review.py +++ b/agent/models/review.py @@ -57,7 +57,7 @@ class VideoReview(BaseModel): class SceneScoreInput(BaseModel): - """One scene's raw reviewer answer, as Muse scores it. + """One scene's raw reviewer answer, as the agent scores it by hand. Same JSON shape a CLI reviewer returns: dimensions, errors, usable_segments. The server applies the identical validation, severity @@ -98,7 +98,7 @@ class SceneRegenDecision(BaseModel): class ReviewSheetsRequest(BaseModel): - """Build contact sheets for Muse review — no AI CLI involved.""" + """Build contact sheets for agent self-review — no AI CLI involved.""" project_id: str mode: str = "light" # light (4fps) | deep (8fps) orientation: Optional[str] = None # VERTICAL | HORIZONTAL (auto if omitted) @@ -127,7 +127,7 @@ class ReviewSheetsResponse(BaseModel): class ReviewSubmitRequest(BaseModel): - """Submit Muse's scores; the server computes the review.""" + """Submit the agent\u2019s hand scores; the server computes the review.""" project_id: str mode: str = "light" orientation: Optional[str] = None diff --git a/agent/services/cli_providers.py b/agent/services/cli_providers.py index 20559af57..6115988b6 100644 --- a/agent/services/cli_providers.py +++ b/agent/services/cli_providers.py @@ -5,10 +5,11 @@ flag names, effort ladders, whether an unknown model slug is an error — so the differences live here rather than being re-derived at each call site. -A fourth reviewer, `muse`, is the assistant itself (Muse): no binary, no +A fourth reviewer, `muse`, is the agent itself (Muse, Codex, or agy — whichever agent is running these skills): no binary, no model catalog, no effort ladder. It is an official provider option, not a -default — a role pointed at `muse` means Muse scores contact sheets by +default — a role pointed at `muse` means the agent scores contact sheets by hand via the review-sheets / review-submit endpoints (see `/fk-review-video`). +The provider key is `muse` for historical reasons; it means "me, the agent". Config lives in `agent/providers.json`, hot-reloaded into `config.CLI_PROVIDERS`: @@ -36,7 +37,7 @@ "claude": "claude", "agy": "agy", "codex": "codex", - # `muse` has no binary: the reviewer IS the assistant (Muse), reading + # `muse` has no binary: the reviewer IS the agent itself, reading # contact sheets through its own vision and scoring via review-submit. "muse": None, } @@ -171,10 +172,10 @@ async def validate_role_entry(role: str, entry: dict) -> dict: raise ValueError( f"'{binary}' binary not found on PATH — install it first" ) - # `muse` (the assistant itself) needs no binary and takes no model/effort. + # `muse` (the agent itself) needs no binary and takes no model/effort. if provider == "muse" and (entry.get("model") or entry.get("effort")): raise ValueError( - "The 'muse' reviewer is the assistant itself — it takes no model " + "The 'muse' reviewer is the agent itself — it takes no model " "or effort. Clear both fields." ) diff --git a/agent/services/video_reviewer.py b/agent/services/video_reviewer.py index 5529e0c55..0fe22d213 100644 --- a/agent/services/video_reviewer.py +++ b/agent/services/video_reviewer.py @@ -665,14 +665,14 @@ async def _analyze_cli( `role` is passed in by a multi-scene review so every scene runs on the same backend — see `review_video`. - The `muse` reviewer (Muse, the assistant itself) has no CLI to shell out to: + The `muse` reviewer (the agent itself) has no CLI to shell out to: pointing the role at it and calling this endpoint is a configuration mistake, not a review — build sheets via `review-sheets` and submit scores via `review-submit` instead (see `/fk-review-video`). """ if (role or {}).get("provider") == "muse": raise RuntimeError( - "video_review role is 'muse' (Muse, the assistant itself): the server " + "video_review role is 'muse' (the agent itself): the server " "cannot invoke it. Use POST /api/videos/<VID>/review-sheets to " "build contact sheets, score them by hand, then POST " "/api/videos/<VID>/review-submit." @@ -869,10 +869,10 @@ async def prepare_review_sheets( ) -> dict: """Build contact sheets for a scene WITHOUT calling any reviewer. - Sheets are written under ``persist_dir`` (survives the call) so an - external reviewer — e.g. Muse scoring by hand — can read them later. - Returns sheet paths, frame metadata, and the rubric prompt the reviewer - should answer. + Sheets are written under ``persist_dir`` (survives the call) so the + agent itself — Muse, Codex, or agy — can read them later and score by + hand. Returns sheet paths, frame metadata, and the rubric prompt the + reviewer should answer. Raises ValueError when the scene has no fetchable video. """ @@ -909,9 +909,9 @@ def score_review_answer( ) -> SceneReview: """Turn a raw reviewer answer (dimensions/errors/usable_segments) into a SceneReview. - Shared by every reviewer backend — CLI, SDK, or Muse scoring contact - sheets by hand. Applies the same repairs, severity rules, CRITICAL caps, - and overall computation. + Shared by every reviewer backend — CLI, SDK, or the agent itself + scoring contact sheets by hand. Applies the same repairs, severity rules, + CRITICAL caps, and overall computation. """ errors = [] # Parse structured errors with severity. diff --git a/skills/fk-change-provider.md b/skills/fk-change-provider.md index 359223f47..afa2d431e 100644 --- a/skills/fk-change-provider.md +++ b/skills/fk-change-provider.md @@ -4,8 +4,9 @@ View or change which reviewer (`muse`, `claude`, `agy`, `codex`) — and which m reasoning effort — runs each AI role. One role exists today: `video_review`, the vision analysis behind `/fk-review-video`. -- `muse` = the assistant itself (Muse): no CLI, no model, no effort. The - review flow becomes contact sheets → hand scoring → submit (see +- `muse` = the agent itself (Muse, Codex, or agy — whoever runs the + skills): no CLI, no model, no effort. The review flow becomes contact + sheets → hand scoring with your own vision → submit (see `/fk-review-video` step 3a). Official provider, opt-in per role. - `claude` / `agy` / `codex` = AI CLIs the server shells out to. diff --git a/skills/fk-doctor.md b/skills/fk-doctor.md index 3caa30011..7e8c69ece 100644 --- a/skills/fk-doctor.md +++ b/skills/fk-doctor.md @@ -219,7 +219,7 @@ Review runs outside the worker — no retry policy applies, the call just raises Providers, models and efforts come from `agent/providers.json`; see `/fk-change-provider`. -No review CLI installed (e.g. the Muse runtime)? Use Muse review instead — +No review CLI installed? Score the sheets yourself instead — `POST /api/videos/<VID>/review-sheets`, score the sheets by hand, then `POST .../review-submit`. See `/fk-review-video`. A `review` call that fails with "command not found" / non-zero exit before producing JSON almost always diff --git a/skills/fk-review-video.md b/skills/fk-review-video.md index 9ac3234ff..20cc6e1ea 100644 --- a/skills/fk-review-video.md +++ b/skills/fk-review-video.md @@ -43,9 +43,12 @@ For each scene, verify `${ori}_video_status = COMPLETED` (orientation auto-detec **ABORT** if any scene is missing a completed video — tell user to run `/fk-gen-videos` first. -## Step 3a: Muse review (`--by muse`) +## Step 3a: Self review (`--by muse`) -Build the contact sheets — no AI CLI involved: +You — the agent running this skill (Muse, Codex, or agy) — score the sheets +by hand with your own vision. The provider key is `muse` for historical +reasons; it means "me, the agent". Build the contact sheets — no AI CLI +involved: ```bash curl -s -X POST "http://127.0.0.1:8100/api/videos/<VID>/review-sheets" \ @@ -80,7 +83,7 @@ curl -s -X POST "http://127.0.0.1:8100/api/videos/<VID>/review-submit" \ ]}' | python3 -m json.tool ``` -To auto-regenerate bad scenes from Muse scores (bounded by +To auto-regenerate bad scenes from your hand scores (bounded by `max_regenerations` per scene), pass the same `scores` array to `POST /api/videos/<VID>/review-regenerate`. diff --git a/tests/unit/test_muse_review.py b/tests/unit/test_muse_review.py index 797dbd2a4..8868f39d7 100644 --- a/tests/unit/test_muse_review.py +++ b/tests/unit/test_muse_review.py @@ -1,4 +1,4 @@ -"""Tests for Muse review: contact sheets -> hand scoring -> submit. +"""Tests for agent self-review (`muse` provider): contact sheets -> hand scoring -> submit. pytest-asyncio runs in AUTO mode (see pytest.ini). """ @@ -126,7 +126,7 @@ async def test_review_sheets_then_submit_end_to_end( assert sheet["scene_id"] == scene["id"] assert Path(sheet["sheets"][0]).exists() - # Muse scores the sheets by hand and submits. + # The agent scores the sheets by hand and submits. r = reviews_client.post( f"/api/videos/{video['id']}/review-submit", json={"project_id": proj["id"], "mode": "light", "scores": [{ @@ -146,7 +146,7 @@ async def test_review_sheets_then_submit_end_to_end( assert sr["has_critical_errors"] is False assert sr["overall_score"] > 0 - # review-regenerate with Muse scores enqueues a bounded regen. + # review-regenerate with hand scores enqueues a bounded regen. r = reviews_client.post( f"/api/videos/{video['id']}/review-regenerate", json={"project_id": proj["id"], "mode": "light", From 0d6714dc90f0464bd859b6b2341bd86fdfd866ab Mon Sep 17 00:00:00 2001 From: crisng95 <crisng95@users.noreply.github.com> Date: Tue, 29 Sep 2026 04:48:13 +0000 Subject: [PATCH 41/68] docs: centered AI agent icon row under AI Agent Support table --- README.md | 10 ++++++++++ docs/agents/agy.svg | 1 + docs/agents/claude.svg | 1 + docs/agents/codex.svg | 1 + docs/agents/muse.svg | 1 + 5 files changed, 14 insertions(+) create mode 100644 docs/agents/agy.svg create mode 100644 docs/agents/claude.svg create mode 100644 docs/agents/codex.svg create mode 100644 docs/agents/muse.svg diff --git a/README.md b/README.md index d9e1f2aa1..42e7aee05 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,16 @@ agent can read and follow. Review providers are swappable at runtime | **Codex CLI** | Reads `skills/fk-<name>.md` via `AGENTS.md`; vision on contact sheets for self-review | `codex` — OpenAI Codex CLI, or `muse` (= the agent itself) for hand scoring | | **agy** (Google Antigravity) | Reads skill files manually; vision on contact sheets for self-review | `agy` — Antigravity CLI, or `muse` (= the agent itself) for hand scoring | +<p align="center"> + <img src="docs/agents/muse.svg" height="56" alt="Muse" title="Muse" /> +      + <img src="docs/agents/claude.svg" height="56" alt="Claude Code" title="Claude Code" /> +      + <img src="docs/agents/codex.svg" height="56" alt="Codex" title="Codex" /> +      + <img src="docs/agents/agy.svg" height="56" alt="Antigravity" title="Antigravity (agy)" /> +</p> + ## Showcase All outputs below were generated end-to-end by this system — from story concept to final YouTube-ready video with thumbnails, narration, and branding. diff --git a/docs/agents/agy.svg b/docs/agents/agy.svg new file mode 100644 index 000000000..5e2ccf1e1 --- /dev/null +++ b/docs/agents/agy.svg @@ -0,0 +1 @@ +<svg fill="#4285F4" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Google \ No newline at end of file diff --git a/docs/agents/claude.svg b/docs/agents/claude.svg new file mode 100644 index 000000000..88dc7450b --- /dev/null +++ b/docs/agents/claude.svg @@ -0,0 +1 @@ +Anthropic \ No newline at end of file diff --git a/docs/agents/codex.svg b/docs/agents/codex.svg new file mode 100644 index 000000000..e2db371a4 --- /dev/null +++ b/docs/agents/codex.svg @@ -0,0 +1 @@ +Codex diff --git a/docs/agents/muse.svg b/docs/agents/muse.svg new file mode 100644 index 000000000..385fb0a1b --- /dev/null +++ b/docs/agents/muse.svg @@ -0,0 +1 @@ +Meta \ No newline at end of file From 7837949647af467d0b3f804380e1c577e0e5354d Mon Sep 17 00:00:00 2001 From: crisng95 Date: Tue, 29 Sep 2026 04:50:24 +0000 Subject: [PATCH 42/68] docs: use official brand colors for agent icons (Claude coral, multicolor Google G) --- docs/agents/agy.svg | 2 +- docs/agents/claude.svg | 2 +- docs/agents/codex.svg | 2 +- docs/agents/muse.svg | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/agents/agy.svg b/docs/agents/agy.svg index 5e2ccf1e1..c3f5edd05 100644 --- a/docs/agents/agy.svg +++ b/docs/agents/agy.svg @@ -1 +1 @@ -Google \ No newline at end of file +Antigravity diff --git a/docs/agents/claude.svg b/docs/agents/claude.svg index 88dc7450b..be14cbc82 100644 --- a/docs/agents/claude.svg +++ b/docs/agents/claude.svg @@ -1 +1 @@ -Anthropic \ No newline at end of file +Claude Code diff --git a/docs/agents/codex.svg b/docs/agents/codex.svg index e2db371a4..e90fd7ffc 100644 --- a/docs/agents/codex.svg +++ b/docs/agents/codex.svg @@ -1 +1 @@ -Codex +Codex diff --git a/docs/agents/muse.svg b/docs/agents/muse.svg index 385fb0a1b..d894dd6ea 100644 --- a/docs/agents/muse.svg +++ b/docs/agents/muse.svg @@ -1 +1 @@ -Meta \ No newline at end of file +Muse From 72e5f933413f34e8294d7459549b5fdb56b9e153 Mon Sep 17 00:00:00 2001 From: crisng95 Date: Tue, 29 Sep 2026 04:52:03 +0000 Subject: [PATCH 43/68] docs: move agent icon row above the intro paragraph --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 42e7aee05..a92394dcf 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,16 @@ Standalone system to generate AI videos via Google Flow. Uses a Chrome extension ## AI Agent Support +

+ Muse +      + Claude Code +      + Codex +      + Antigravity +

+ FlowKit's 36 skills (`skills/fk-*.md`) are plain Markdown recipes any AI coding agent can read and follow. Review providers are swappable at runtime (`agent/providers.json`, or `/fk-change-provider`) — no restart needed. @@ -53,16 +63,6 @@ agent can read and follow. Review providers are swappable at runtime | **Codex CLI** | Reads `skills/fk-.md` via `AGENTS.md`; vision on contact sheets for self-review | `codex` — OpenAI Codex CLI, or `muse` (= the agent itself) for hand scoring | | **agy** (Google Antigravity) | Reads skill files manually; vision on contact sheets for self-review | `agy` — Antigravity CLI, or `muse` (= the agent itself) for hand scoring | -

- Muse -      - Claude Code -      - Codex -      - Antigravity -

- ## Showcase All outputs below were generated end-to-end by this system — from story concept to final YouTube-ready video with thumbnails, narration, and branding. From 4257e1e7ff332f6da8a3182511f24bbe358ce766 Mon Sep 17 00:00:00 2001 From: crisng95 Date: Tue, 29 Sep 2026 04:52:56 +0000 Subject: [PATCH 44/68] docs: single composite agent icon strip (white pill, official brand colors) --- README.md | 2 +- docs/agents/agy.svg | 1 - docs/agents/claude.svg | 1 - docs/agents/codex.svg | 1 - docs/agents/muse.svg | 1 - docs/agents/row.svg | 1 + 6 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 docs/agents/agy.svg delete mode 100644 docs/agents/claude.svg delete mode 100644 docs/agents/codex.svg delete mode 100644 docs/agents/muse.svg create mode 100644 docs/agents/row.svg diff --git a/README.md b/README.md index a92394dcf..1ff2f2e16 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- FLOW KIT + Muse, Claude Code, Codex, Antigravity

diff --git a/docs/agents/agy.svg b/docs/agents/agy.svg deleted file mode 100644 index c3f5edd05..000000000 --- a/docs/agents/agy.svg +++ /dev/null @@ -1 +0,0 @@ -Antigravity diff --git a/docs/agents/claude.svg b/docs/agents/claude.svg deleted file mode 100644 index be14cbc82..000000000 --- a/docs/agents/claude.svg +++ /dev/null @@ -1 +0,0 @@ -Claude Code diff --git a/docs/agents/codex.svg b/docs/agents/codex.svg deleted file mode 100644 index e90fd7ffc..000000000 --- a/docs/agents/codex.svg +++ /dev/null @@ -1 +0,0 @@ -Codex diff --git a/docs/agents/muse.svg b/docs/agents/muse.svg deleted file mode 100644 index d894dd6ea..000000000 --- a/docs/agents/muse.svg +++ /dev/null @@ -1 +0,0 @@ -Muse diff --git a/docs/agents/row.svg b/docs/agents/row.svg new file mode 100644 index 000000000..46f6e08bd --- /dev/null +++ b/docs/agents/row.svg @@ -0,0 +1 @@ +AI agents From 7d385a1791032dc704ca20a6504b2b4c9ebef295 Mon Sep 17 00:00:00 2001 From: crisng95 Date: Tue, 29 Sep 2026 04:54:52 +0000 Subject: [PATCH 45/68] docs: restore individual agent icons (correct brand colors, white tiles) --- docs/agents/agy.svg | 1 + docs/agents/claude.svg | 1 + docs/agents/codex.svg | 1 + docs/agents/muse.svg | 1 + 4 files changed, 4 insertions(+) create mode 100644 docs/agents/agy.svg create mode 100644 docs/agents/claude.svg create mode 100644 docs/agents/codex.svg create mode 100644 docs/agents/muse.svg diff --git a/docs/agents/agy.svg b/docs/agents/agy.svg new file mode 100644 index 000000000..c3f5edd05 --- /dev/null +++ b/docs/agents/agy.svg @@ -0,0 +1 @@ +Antigravity diff --git a/docs/agents/claude.svg b/docs/agents/claude.svg new file mode 100644 index 000000000..be14cbc82 --- /dev/null +++ b/docs/agents/claude.svg @@ -0,0 +1 @@ +Claude Code diff --git a/docs/agents/codex.svg b/docs/agents/codex.svg new file mode 100644 index 000000000..e90fd7ffc --- /dev/null +++ b/docs/agents/codex.svg @@ -0,0 +1 @@ +Codex diff --git a/docs/agents/muse.svg b/docs/agents/muse.svg new file mode 100644 index 000000000..d894dd6ea --- /dev/null +++ b/docs/agents/muse.svg @@ -0,0 +1 @@ +Muse From de3187337fbfd311a2b5d8c8c50c64dc68c058db Mon Sep 17 00:00:00 2001 From: crisng95 Date: Tue, 29 Sep 2026 04:55:52 +0000 Subject: [PATCH 46/68] docs: agent icons via fresh v2 URLs (white tiles, official brand colors) --- README.md | 12 ++++-------- docs/agents/row.svg | 1 - docs/agents/v2/agy.svg | 1 + docs/agents/v2/claude.svg | 1 + docs/agents/v2/codex.svg | 1 + docs/agents/v2/muse.svg | 1 + 6 files changed, 8 insertions(+), 9 deletions(-) delete mode 100644 docs/agents/row.svg create mode 100644 docs/agents/v2/agy.svg create mode 100644 docs/agents/v2/claude.svg create mode 100644 docs/agents/v2/codex.svg create mode 100644 docs/agents/v2/muse.svg diff --git a/README.md b/README.md index 1ff2f2e16..1b4bd5af5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,3 @@ -

- Muse, Claude Code, Codex, Antigravity -

-

License: MIT Python 3.10+ @@ -43,13 +39,13 @@ Standalone system to generate AI videos via Google Flow. Uses a Chrome extension ## AI Agent Support

- Muse + Muse      - Claude Code + Claude Code      - Codex + Codex      - Antigravity + Antigravity

FlowKit's 36 skills (`skills/fk-*.md`) are plain Markdown recipes any AI coding diff --git a/docs/agents/row.svg b/docs/agents/row.svg deleted file mode 100644 index 46f6e08bd..000000000 --- a/docs/agents/row.svg +++ /dev/null @@ -1 +0,0 @@ -AI agents diff --git a/docs/agents/v2/agy.svg b/docs/agents/v2/agy.svg new file mode 100644 index 000000000..c3f5edd05 --- /dev/null +++ b/docs/agents/v2/agy.svg @@ -0,0 +1 @@ +Antigravity diff --git a/docs/agents/v2/claude.svg b/docs/agents/v2/claude.svg new file mode 100644 index 000000000..be14cbc82 --- /dev/null +++ b/docs/agents/v2/claude.svg @@ -0,0 +1 @@ +Claude Code diff --git a/docs/agents/v2/codex.svg b/docs/agents/v2/codex.svg new file mode 100644 index 000000000..e90fd7ffc --- /dev/null +++ b/docs/agents/v2/codex.svg @@ -0,0 +1 @@ +Codex diff --git a/docs/agents/v2/muse.svg b/docs/agents/v2/muse.svg new file mode 100644 index 000000000..d894dd6ea --- /dev/null +++ b/docs/agents/v2/muse.svg @@ -0,0 +1 @@ +Muse From d59257edf154ebba372745878bee220a9c77a017 Mon Sep 17 00:00:00 2001 From: Khanh Date: Tue, 29 Sep 2026 19:44:19 +0700 Subject: [PATCH 47/68] fix: resolve file:// URLs correctly on Windows The pipeline stores local media as "file://" + str(path). On Windows that is file://C:\...\x.mp4, which urlparse splits into netloc="C:\..." and an empty path, so every Path(parsed.path) caller decided the clip was missing and fell through to an HTTP download that then failed. Add agent.utils.paths.file_url_to_path (netloc+path via url2pathname, so both as_uri() and the naive form work) and use it in video_reviewer, api/videos, api/projects and assistant_provider. Make the two test_cli_providers assertions spell /tmp the way the host OS does. Windows: 12 failed -> 0 failed (445 passed). --- agent/api/projects.py | 5 ++- agent/api/videos.py | 7 ++-- agent/sdk/services/assistant_provider.py | 10 +++-- agent/services/video_reviewer.py | 10 +++-- agent/utils/paths.py | 21 +++++++++++ tests/unit/test_cli_providers.py | 5 ++- tests/unit/test_file_url_paths.py | 48 ++++++++++++++++++++++++ 7 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 tests/unit/test_file_url_paths.py diff --git a/agent/api/projects.py b/agent/api/projects.py index 9a6f33c36..f1000c823 100644 --- a/agent/api/projects.py +++ b/agent/api/projects.py @@ -10,6 +10,7 @@ from fastapi import APIRouter, HTTPException from pydantic import BaseModel +from agent.utils.paths import file_url_to_path from agent.config import BASE_DIR from agent.models.project import Project, ProjectCreate, ProjectUpdate from agent.models.character import Character @@ -467,8 +468,8 @@ async def generate_thumbnail(pid: str, body: ThumbnailRequest): except aiohttp.ClientError as e: raise HTTPException(502, f"Failed to download image: {e}") from e elif gen_result.url.startswith("file://"): - src = Path(urlparse(gen_result.url).path) - if not src.is_file(): + src = file_url_to_path(gen_result.url) + if src is None or not src.is_file(): raise HTTPException(502, f"Provider returned missing file: {gen_result.url}") shutil.copy2(src, output_path) diff --git a/agent/api/videos.py b/agent/api/videos.py index bfc5be79a..2a5e56273 100644 --- a/agent/api/videos.py +++ b/agent/api/videos.py @@ -10,6 +10,7 @@ from fastapi import APIRouter, HTTPException from pydantic import BaseModel, Field +from agent.utils.paths import file_url_to_path from agent.config import OUTPUT_DIR from agent.db import crud from agent.models.video import Video, VideoCreate, VideoUpdate @@ -131,10 +132,10 @@ def _resolve_media_local(url: str, tmpdir: Path) -> Optional[str]: """Resolve a media URL to a local file path (downloading http(s) when needed).""" if not url: return None + local = file_url_to_path(url) + if local is not None: + return str(local) if local.is_file() else None parsed = urlparse(url) - if parsed.scheme == "file": - p = Path(parsed.path) - return str(p) if p.is_file() else None if parsed.scheme in ("http", "https"): dest = tmpdir / f"dl_{abs(hash(url)) % 10**8}{Path(parsed.path).suffix or '.mp4'}" try: diff --git a/agent/sdk/services/assistant_provider.py b/agent/sdk/services/assistant_provider.py index b8096d29d..199eb7ff3 100644 --- a/agent/sdk/services/assistant_provider.py +++ b/agent/sdk/services/assistant_provider.py @@ -44,6 +44,7 @@ from agent import config from agent.db import crud +from agent.utils.paths import file_url_to_path from agent.sdk.services.provider_base import ( KIND_AUDIO, KIND_EDIT_IMAGE, @@ -92,8 +93,8 @@ def _video_result(mid: str, url: str) -> dict: def _audio_result(url: str) -> dict: """TTS result: the finished audio URL plus a local path when file://.""" - parsed = urlparse(url or "") - local_path = str(Path(parsed.path).resolve()) if parsed.scheme == "file" else "" + local = file_url_to_path(url or "") + local_path = str(local.resolve()) if local is not None else "" return {"data": {"url": url, "audio_path": local_path or url}} @@ -204,8 +205,9 @@ async def register_existing_image( self, url: str, *, name: str = "", project_id: str = "" ) -> dict: """Mint a UUID media_id for an already-existing local image.""" - parsed = urlparse(url) - local = Path(parsed.path) if parsed.scheme == "file" else Path(url) + local = file_url_to_path(url) + if local is None: + local = Path(url) if not local.is_file(): return {"error": f"AssistantProvider: local image not found for '{name}': {url}"} mid = str(uuid.uuid4()) diff --git a/agent/services/video_reviewer.py b/agent/services/video_reviewer.py index 0fe22d213..0318c2ee7 100644 --- a/agent/services/video_reviewer.py +++ b/agent/services/video_reviewer.py @@ -38,6 +38,7 @@ PROVIDER_BINARIES, resolve_role, ) +from agent.utils.paths import file_url_to_path logger = logging.getLogger(__name__) @@ -149,11 +150,12 @@ def _local_media_path(url: str) -> Path | None: """ if not url: return None - parsed = urlparse(url) - if parsed.scheme == "file": - p = Path(parsed.path) + p = file_url_to_path(url) + if p is not None: return p if p.is_file() else None - if not parsed.scheme: + parsed = urlparse(url) + # A Windows drive letter ("C:") parses as a scheme; it is still a path. + if not parsed.scheme or len(parsed.scheme) == 1: p = Path(url) return p if p.is_file() else None return None diff --git a/agent/utils/paths.py b/agent/utils/paths.py index fae79d7bc..a41909ae6 100644 --- a/agent/utils/paths.py +++ b/agent/utils/paths.py @@ -1,9 +1,30 @@ """Centralized path resolver for project output directories and scene files.""" from pathlib import Path +from urllib.parse import urlparse +from urllib.request import url2pathname from agent.config import OUTPUT_DIR +def file_url_to_path(url: str | None) -> "Path | None": + """Turn a ``file://`` URL into a local ``Path``; ``None`` for anything else. + + Accepts both the RFC 8089 form ``Path.as_uri()`` produces + (``file:///C:/x/y.png``, percent-encoded) and the naive + ``"file://" + str(path)`` form the pipeline stores. The latter is fine on + POSIX (``file:///tmp/y.png``) but on Windows ``urlparse`` files + ``C:\\x\\y.png`` under *netloc* with an empty *path*, so reading only + ``parsed.path`` made every local clip look missing. + """ + if not url: + return None + parsed = urlparse(url) + if parsed.scheme != "file": + return None + raw = (parsed.netloc or "") + parsed.path + return Path(url2pathname(raw)) + + def project_dir(project_slug: str) -> Path: """Return the output directory for a given project slug.""" return OUTPUT_DIR / project_slug diff --git a/tests/unit/test_cli_providers.py b/tests/unit/test_cli_providers.py index a6f02f1e4..a1e848989 100644 --- a/tests/unit/test_cli_providers.py +++ b/tests/unit/test_cli_providers.py @@ -415,7 +415,8 @@ async def test_claude_agy_providers_include_read_the_images_at(self, provider, r assert "BASE_PROMPT" in captured["prompt"] # The sheets live outside the server cwd, so the directory holding them # is named to the CLI rather than left to be discovered. - assert captured["add_dirs"] == ("/tmp",) + # str(Path) so the expectation is spelled the way the OS spells it. + assert captured["add_dirs"] == (str(Path("/tmp")),) assert result == {"dimensions": {}, "errors": [], "usable_segments": []} @pytest.mark.asyncio @@ -473,7 +474,7 @@ async def test_single_sheet_wrapper_wording_matches_original_singular_form(self) new=AsyncMock(side_effect=capture_runner(captured))): await _analyze_cli(contact_sheets, 9, 4.0, {}, timestamped=True) - assert captured["prompt"].startswith("Read the image at /tmp/sheet_00.jpg.") + assert captured["prompt"].startswith(f"Read the image at {contact_sheets[0]}.") assert "Read the images at:" not in captured["prompt"] assert "sequential contact sheets" not in captured["prompt"] assert "It is a contact sheet of 9 video frames at 4.0fps with timestamps." in captured["prompt"] diff --git a/tests/unit/test_file_url_paths.py b/tests/unit/test_file_url_paths.py new file mode 100644 index 000000000..0a5d446f1 --- /dev/null +++ b/tests/unit/test_file_url_paths.py @@ -0,0 +1,48 @@ +"""file:// URL <-> local path conversion must work on every OS. + +The pipeline stores local media as ``"file://" + str(path)``. On POSIX that +yields ``file:///tmp/x.mp4`` which ``urlparse().path`` reads back fine. On +Windows it yields ``file://C:\\Temp\\x.mp4`` — ``urlparse`` puts ``C:\\Temp\\x.mp4`` +in *netloc* and leaves ``path`` empty, so every ``Path(parsed.path)`` caller +concluded the file did not exist and fell through to an HTTP download. +""" +import sys +from pathlib import Path + +import pytest + +from agent.utils.paths import file_url_to_path + + +def test_naive_file_url_from_str_path_roundtrips(tmp_path): + f = tmp_path / "clip.mp4" + f.write_bytes(b"x") + assert file_url_to_path(f"file://{f}") == f + + +def test_rfc8089_file_url_from_as_uri_roundtrips(tmp_path): + f = tmp_path / "x y.png" # space -> %20 in as_uri() + f.write_bytes(b"x") + assert file_url_to_path(f.as_uri()) == f + + +def test_posix_style_file_url_is_accepted(): + p = file_url_to_path("file:///tmp/out.png") + assert p == Path("/tmp/out.png") + + +def test_non_file_urls_and_empty_return_none(): + assert file_url_to_path("https://example.com/a.mp4") is None + assert file_url_to_path("") is None + assert file_url_to_path(None) is None + + +def test_plain_path_is_not_a_file_url(tmp_path): + # Callers that accept bare paths handle that branch themselves. + assert file_url_to_path(str(tmp_path / "a.mp4")) is None + + +@pytest.mark.skipif(sys.platform != "win32", reason="Windows drive-letter form") +def test_windows_backslash_form_keeps_drive_letter(): + p = file_url_to_path(r"file://C:\Windows\Temp\x.png") + assert p == Path(r"C:\Windows\Temp\x.png") From 5e5dec2a2b27b719b72541f4cb712f57e5ccbeda Mon Sep 17 00:00:00 2001 From: Khanh Date: Tue, 29 Sep 2026 21:11:49 +0700 Subject: [PATCH 48/68] fix(tts): save OmniVoice output as 2-D tensor, honour TTS_DEVICE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OmniVoice.generate() returns list[numpy.ndarray] (1-D). torchaudio.save needs (channels, samples), so every TTS call failed at the last step with 'Expected 2D Tensor, got 1D' after the model had generated fine. Wrap the item via a shared _to_wav_tensor helper in both inline scripts. Also pass config.TTS_DEVICE through to device_map instead of hardcoding cpu — TTS_DEVICE already existed in config but was never used. On an RTX 3060 a template takes ~23s including model load vs minutes on CPU. --- agent/services/tts.py | 28 ++++++--- tests/unit/test_tts_scripts.py | 100 +++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 tests/unit/test_tts_scripts.py diff --git a/agent/services/tts.py b/agent/services/tts.py index 14a729856..23b3bf574 100644 --- a/agent/services/tts.py +++ b/agent/services/tts.py @@ -7,21 +7,32 @@ from pathlib import Path from typing import Optional -from agent.config import TTS_MODEL, TTS_SAMPLE_RATE +from agent.config import TTS_DEVICE, TTS_MODEL, TTS_SAMPLE_RATE logger = logging.getLogger(__name__) # Default to python3.10 (has torch/torchaudio/omnivoice); override with TTS_PYTHON_BIN if needed PYTHON_BIN = os.environ.get("TTS_PYTHON_BIN", "python3.10") +# Shared by both inline scripts. OmniVoice.generate() returns a list of 1-D +# numpy arrays; torchaudio.save wants a 2-D (channels, samples) tensor, so +# the raw item cannot be handed over as-is ("Expected 2D Tensor, got 1D"). +_TO_WAV_TENSOR = """ +def _to_wav_tensor(item): + w = item if isinstance(item, torch.Tensor) else torch.as_tensor(item) + w = w.detach().cpu().float() + return w.unsqueeze(0) if w.ndim == 1 else w +""" + # Inline script template for TTS generation via subprocess _TTS_SCRIPT = """ import sys, json, torch, torchaudio args = json.loads(sys.argv[1]) from omnivoice import OmniVoice - -model = OmniVoice.from_pretrained(args["model"], device_map="cpu", dtype=torch.float32) +""" + _TO_WAV_TENSOR + """ +model = OmniVoice.from_pretrained( + args["model"], device_map=args.get("device", "cpu"), dtype=torch.float32) kwargs = {"text": args["text"]} if args.get("ref_audio") and args.get("ref_text"): @@ -33,7 +44,7 @@ kwargs["speed"] = args["speed"] audio = model.generate(**kwargs) -torchaudio.save(args["output"], audio[0], args["sample_rate"]) +torchaudio.save(args["output"], _to_wav_tensor(audio[0]), args["sample_rate"]) print(json.dumps({"ok": True, "path": args["output"]})) """ @@ -44,8 +55,9 @@ args = json.loads(sys.argv[1]) from omnivoice import OmniVoice - -model = OmniVoice.from_pretrained(args["model"], device_map="cpu", dtype=torch.float32) +""" + _TO_WAV_TENSOR + """ +model = OmniVoice.from_pretrained( + args["model"], device_map=args.get("device", "cpu"), dtype=torch.float32) results = [] for item in args["items"]: @@ -61,7 +73,7 @@ audio = model.generate(**kwargs) Path(item["output"]).parent.mkdir(parents=True, exist_ok=True) - torchaudio.save(item["output"], audio[0], args["sample_rate"]) + torchaudio.save(item["output"], _to_wav_tensor(audio[0]), args["sample_rate"]) info = torchaudio.info(item["output"]) duration = info.num_frames / info.sample_rate @@ -90,6 +102,7 @@ async def generate_speech( "output": output_path, "sample_rate": TTS_SAMPLE_RATE, "speed": speed, + "device": TTS_DEVICE, } if instruct: args["instruct"] = instruct @@ -166,6 +179,7 @@ async def generate_video_narration( "sample_rate": TTS_SAMPLE_RATE, "speed": speed, "items": items, + "device": TTS_DEVICE, } if instruct: args["instruct"] = instruct diff --git a/tests/unit/test_tts_scripts.py b/tests/unit/test_tts_scripts.py new file mode 100644 index 000000000..f378d37ec --- /dev/null +++ b/tests/unit/test_tts_scripts.py @@ -0,0 +1,100 @@ +"""The inline TTS scripts must save what OmniVoice.generate() actually returns. + +OmniVoice >= 0.2 returns ``list[numpy.ndarray]`` (1-D float32 per item). +``torchaudio.save`` wants a 2-D ``(channels, samples)`` tensor, so handing it +``audio[0]`` raw fails with ``Expected 2D Tensor, got 1D`` — every TTS call +died at the very last step, after the model had generated fine. + +These tests exec the script templates against a fake ``omnivoice`` module so +they run without torch/omnivoice installed in the agent venv. +""" +import json +import sys +import types + +import pytest + +np = pytest.importorskip("numpy") + +from agent.services import tts as tts_mod # noqa: E402 + + +class _FakeTorchaudio: + saved = [] + + class info: # noqa: N801 — mimics torchaudio.info(path) + def __init__(self, path): + self.num_frames = 24000 + self.sample_rate = 24000 + + @classmethod + def save(cls, path, tensor, sample_rate): + if getattr(tensor, "ndim", None) != 2: + raise ValueError(f"Expected 2D Tensor, got {tensor.ndim}D.") + cls.saved.append((path, tuple(tensor.shape), sample_rate)) + + +class _FakeOmniVoice: + kwargs_seen = {} + + @classmethod + def from_pretrained(cls, model, **kwargs): + cls.kwargs_seen = kwargs + return cls() + + def generate(self, **kwargs): + return [np.zeros(2400, dtype=np.float32)] + + +@pytest.fixture +def fake_modules(monkeypatch): + torch = pytest.importorskip("torch") + _FakeTorchaudio.saved = [] + monkeypatch.setitem(sys.modules, "torchaudio", _FakeTorchaudio) + ov = types.ModuleType("omnivoice") + ov.OmniVoice = _FakeOmniVoice + monkeypatch.setitem(sys.modules, "omnivoice", ov) + return torch + + +def _run(script: str, args: dict, capsys): + sys.argv = ["tts", json.dumps(args)] + exec(compile(script, "", "exec"), {"__name__": "__main__"}) + return json.loads(capsys.readouterr().out.strip().splitlines()[-1]) + + +def test_single_script_saves_1d_numpy_output_as_2d(fake_modules, tmp_path, capsys): + out = tmp_path / "a.wav" + result = _run(tts_mod._TTS_SCRIPT, { + "model": "m", "text": "xin chào", "output": str(out), "sample_rate": 24000, + }, capsys) + assert result["ok"] is True + assert _FakeTorchaudio.saved == [(str(out), (1, 2400), 24000)] + + +def test_batch_script_saves_1d_numpy_output_as_2d(fake_modules, tmp_path, capsys): + out = tmp_path / "s" / "b.wav" + results = _run(tts_mod._TTS_BATCH_SCRIPT, { + "model": "m", "sample_rate": 24000, + "items": [{"id": "s1", "text": "xin chào", "output": str(out)}], + }, capsys) + assert results == [{"id": "s1", "ok": True, "path": str(out), "duration": 1.0}] + assert _FakeTorchaudio.saved == [(str(out), (1, 2400), 24000)] + + +def test_scripts_honour_device_arg(fake_modules, tmp_path, capsys): + _run(tts_mod._TTS_SCRIPT, { + "model": "m", "text": "x", "output": str(tmp_path / "a.wav"), + "sample_rate": 24000, "device": "cuda", + }, capsys) + assert _FakeOmniVoice.kwargs_seen["device_map"] == "cuda" + + +def test_generate_speech_passes_configured_device(monkeypatch, tmp_path): + captured = {} + monkeypatch.setattr(tts_mod, "TTS_DEVICE", "cuda") + monkeypatch.setattr(tts_mod, "_run_tts_subprocess", + lambda args: captured.update(args) or {"ok": True}) + import asyncio + asyncio.run(tts_mod.generate_speech("hi", str(tmp_path / "o.wav"))) + assert captured["device"] == "cuda" From 328df2a6b7c548b855cf3c8de7f4057af387d7f6 Mon Sep 17 00:00:00 2001 From: Khanh Date: Wed, 30 Sep 2026 12:55:34 +0700 Subject: [PATCH 49/68] feat: per-project video_model_family so the worker can use Omni Flash The queue path (GENERATE_VIDEO -> FlowProvider._run_video) was hardwired to Veo. Omni Flash was reachable only through the ad-hoc /api/flow/generate-video endpoint, which does not persist results to the scene, so choosing Omni meant leaving the pipeline (no review, no concat, no retry-repoll). Add project.video_model_family ('veo' | 'omni_flash', default veo, with schema migration), thread it through ProjectCreate/ProjectUpdate, the SDK model/repository, and into job.extra. _run_video dispatches on it: omni_flash -> generate_omni_flash_first_frame_video / _first_last_video, which return the same batch-operation shape, so polling and the already-submitted guard are shared. Defaults come from OMNI_FLASH_DURATION_S / OMNI_FLASH_RESOLUTION. --- agent/api/projects.py | 1 + agent/config.py | 4 + agent/db/crud.py | 8 +- agent/db/schema.py | 4 + agent/models/project.py | 10 +- agent/sdk/models/project.py | 1 + agent/sdk/persistence/sqlite_repository.py | 4 + agent/sdk/services/flow_provider.py | 43 +++++++-- agent/sdk/services/operations.py | 2 + tests/unit/test_video_model_family.py | 101 +++++++++++++++++++++ 10 files changed, 164 insertions(+), 14 deletions(-) create mode 100644 tests/unit/test_video_model_family.py diff --git a/agent/api/projects.py b/agent/api/projects.py index f1000c823..69fe112b6 100644 --- a/agent/api/projects.py +++ b/agent/api/projects.py @@ -213,6 +213,7 @@ async def create(body: ProjectCreate): material=material_id, allow_music=create_data.get("allow_music", False), allow_voice=create_data.get("allow_voice", False), + video_model_family=create_data.get("video_model_family", "veo"), ) # Step 3: Create reference entities (characters, locations, assets) with profiles diff --git a/agent/config.py b/agent/config.py index 9c72cfc25..d5875ddd3 100644 --- a/agent/config.py +++ b/agent/config.py @@ -76,6 +76,10 @@ VIDEO_POLL_INTERVAL = int(os.environ.get("VIDEO_POLL_INTERVAL", "10")) # polling interval for video/upscale status MAX_RETRIES = int(os.environ.get("MAX_RETRIES", "5")) VIDEO_POLL_TIMEOUT = int(os.environ.get("VIDEO_POLL_TIMEOUT", "420")) +# Omni Flash defaults used by the worker when a project's video_model_family +# is "omni_flash". Duration must be 4/6/8/10; resolution 360p or 720p. +OMNI_FLASH_DURATION_S = int(os.environ.get("OMNI_FLASH_DURATION_S", "8")) +OMNI_FLASH_RESOLUTION = os.environ.get("OMNI_FLASH_RESOLUTION", "720p") API_COOLDOWN = int(os.environ.get("API_COOLDOWN", "10")) # DEPRECATED: per-provider cooldown_s in provider capabilities is authoritative MAX_CONCURRENT_REQUESTS = int(os.environ.get("MAX_CONCURRENT_REQUESTS", "5")) # DEPRECATED: per-provider max_concurrent in provider capabilities is authoritative STALE_PROCESSING_TIMEOUT = int(os.environ.get("STALE_PROCESSING_TIMEOUT", "600")) # 10 min diff --git a/agent/db/crud.py b/agent/db/crud.py index a9ae2b1ac..00184fc8a 100644 --- a/agent/db/crud.py +++ b/agent/db/crud.py @@ -20,7 +20,7 @@ def _validate_table(table: str) -> None: # Column whitelists per table — prevents SQL injection via kwargs keys _COLUMNS = { "character": {"name", "slug", "entity_type", "description", "image_prompt", "voice_description", "reference_image_url", "media_id", "updated_at"}, - "project": {"name", "description", "story", "thumbnail_url", "language", "status", "user_paygate_tier", "narrator_voice", "narrator_ref_audio", "material", "allow_music", "allow_voice", "updated_at"}, + "project": {"name", "description", "story", "thumbnail_url", "language", "status", "user_paygate_tier", "narrator_voice", "narrator_ref_audio", "material", "allow_music", "allow_voice", "video_model_family", "updated_at"}, "video": {"title", "description", "display_order", "status", "orientation", "vertical_url", "horizontal_url", "thumbnail_url", "duration", "target_duration_s", "resolution", "youtube_id", "privacy", "tags", "updated_at"}, "scene": {"prompt", "image_prompt", "video_prompt", "character_names", "parent_scene_id", "chain_type", @@ -116,13 +116,13 @@ async def list_characters() -> list[dict]: # ─── Project ──────────────────────────────────────────────── -async def create_project(name: str, description: str = None, story: str = None, language: str = "en", user_paygate_tier: str = "PAYGATE_TIER_ONE", id: str = None, material: str = None, allow_music: bool = False, allow_voice: bool = False) -> dict: +async def create_project(name: str, description: str = None, story: str = None, language: str = "en", user_paygate_tier: str = "PAYGATE_TIER_ONE", id: str = None, material: str = None, allow_music: bool = False, allow_voice: bool = False, video_model_family: str = "veo") -> dict: db = await get_db() pid, now = id or _uuid(), _now() async with _db_lock: await db.execute( - "INSERT INTO project (id,name,description,story,language,user_paygate_tier,material,allow_music,allow_voice,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?)", - (pid, name, description, story, language, user_paygate_tier, material, int(allow_music), int(allow_voice), now, now)) + "INSERT INTO project (id,name,description,story,language,user_paygate_tier,material,allow_music,allow_voice,video_model_family,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", + (pid, name, description, story, language, user_paygate_tier, material, int(allow_music), int(allow_voice), video_model_family or "veo", now, now)) await db.commit() return await _get_with_db(db, "project", "id", pid) diff --git a/agent/db/schema.py b/agent/db/schema.py index 3f696daa9..eeef28d3e 100644 --- a/agent/db/schema.py +++ b/agent/db/schema.py @@ -38,6 +38,7 @@ material TEXT DEFAULT 'realistic', allow_music INTEGER NOT NULL DEFAULT 0, allow_voice INTEGER NOT NULL DEFAULT 0, + video_model_family TEXT NOT NULL DEFAULT 'veo', created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')) ); @@ -322,6 +323,9 @@ async def init_db(): if "allow_voice" not in project_columns: await db.execute("ALTER TABLE project ADD COLUMN allow_voice INTEGER NOT NULL DEFAULT 0") logger.info("Migrated: added allow_voice column to project table") + if "video_model_family" not in project_columns: + await db.execute("ALTER TABLE project ADD COLUMN video_model_family TEXT NOT NULL DEFAULT 'veo'") + logger.info("Migrated: added video_model_family column to project table") # Migration: add orientation to video table + backfill from scene data cursor = await db.execute("PRAGMA table_info(video)") video_columns = {row[1] for row in await cursor.fetchall()} diff --git a/agent/models/project.py b/agent/models/project.py index fdc6489fd..38a34fd7d 100644 --- a/agent/models/project.py +++ b/agent/models/project.py @@ -1,7 +1,12 @@ from pydantic import BaseModel, Field, model_validator -from typing import Optional +from typing import Literal, Optional from agent.models.enums import ProjectStatus, PaygateTier, EntityType +# Which Flow video family the worker uses for this project's scenes. +# veo -> Veo 3.1 i2v (1080p). r2v / first+last are unported on batch. +# omni_flash -> Omni Flash (720p, 4/6/8/10s); all frame/ref modes are ported. +VideoModelFamily = Literal["veo", "omni_flash"] + class CharacterInput(BaseModel): """Reference entity stub provided at project creation time.""" @@ -25,6 +30,7 @@ class ProjectCreate(BaseModel): style: Optional[str] = None # deprecated: use material instead; "3D"→"3d_pixar", "photorealistic"→"realistic" allow_music: bool = False # when True, skip "no background music" suffix in video prompts allow_voice: bool = False # when True, keep character dialogue in video audio (suppress only music/narration) + video_model_family: VideoModelFamily = "veo" characters: Optional[list[CharacterInput]] = None @model_validator(mode="before") @@ -52,6 +58,7 @@ class ProjectUpdate(BaseModel): material: Optional[str] = None allow_music: Optional[bool] = None allow_voice: Optional[bool] = None + video_model_family: Optional[VideoModelFamily] = None class Project(BaseModel): @@ -66,6 +73,7 @@ class Project(BaseModel): material: Optional[str] = None allow_music: bool = False allow_voice: bool = False + video_model_family: str = "veo" narrator_voice: Optional[str] = None narrator_ref_audio: Optional[str] = None created_at: Optional[str] = None diff --git a/agent/sdk/models/project.py b/agent/sdk/models/project.py index 003f2ea9f..ec44238c5 100644 --- a/agent/sdk/models/project.py +++ b/agent/sdk/models/project.py @@ -29,6 +29,7 @@ class Project(DomainModel): material: Optional[str] = None allow_music: bool = False allow_voice: bool = False + video_model_family: str = "veo" narrator_voice: Optional[str] = None narrator_ref_audio: Optional[str] = None created_at: Optional[str] = None diff --git a/agent/sdk/persistence/sqlite_repository.py b/agent/sdk/persistence/sqlite_repository.py index 84f0c3e75..7662a7f83 100644 --- a/agent/sdk/persistence/sqlite_repository.py +++ b/agent/sdk/persistence/sqlite_repository.py @@ -34,6 +34,7 @@ def _row_to_project(self, row: dict[str, Any]) -> Project: material=row.get("material"), allow_music=bool(row.get("allow_music", 0)), allow_voice=bool(row.get("allow_voice", 0)), + video_model_family=row.get("video_model_family") or "veo", narrator_voice=row.get("narrator_voice"), narrator_ref_audio=row.get("narrator_ref_audio"), created_at=row.get("created_at"), @@ -192,6 +193,7 @@ async def save_project(self, project: Project) -> None: user_paygate_tier=project.user_paygate_tier, allow_music=int(project.allow_music), allow_voice=int(project.allow_voice), + video_model_family=project.video_model_family, ) async def create_project( @@ -206,6 +208,7 @@ async def create_project( material: Optional[str] = None, allow_music: bool = False, allow_voice: bool = False, + video_model_family: str = "veo", ) -> Project: row = await crud.create_project( name=name, @@ -217,6 +220,7 @@ async def create_project( material=material, allow_music=allow_music, allow_voice=allow_voice, + video_model_family=video_model_family, ) return self._row_to_project(row) diff --git a/agent/sdk/services/flow_provider.py b/agent/sdk/services/flow_provider.py index 6a70e7f98..09318fad4 100644 --- a/agent/sdk/services/flow_provider.py +++ b/agent/sdk/services/flow_provider.py @@ -18,6 +18,10 @@ from agent import config from agent.config import VIDEO_POLL_INTERVAL, VIDEO_POLL_TIMEOUT from agent.db import crud +from agent.services.omni_flash import ( + generate_omni_flash_first_frame_video, + generate_omni_flash_first_last_video, +) from agent.sdk.services.provider_base import ( KIND_EDIT_IMAGE, KIND_IMAGE, @@ -377,15 +381,36 @@ async def _run_video(self, job: ProviderJob) -> dict: operations = [{"operation": {"name": existing_op}, "status": "MEDIA_GENERATION_STATUS_PENDING"}] return await _poll_operations(self._client, operations) - submit_result = await self._client.generate_video( - start_image_media_id=ex.get("start_media_id", ""), - prompt=job.prompt, - project_id=ex.get("project_id", "0"), - scene_id=ex.get("scene_id", ""), - aspect_ratio=ex.get("aspect", "VIDEO_ASPECT_RATIO_PORTRAIT"), - end_image_media_id=ex.get("end_media_id"), - user_paygate_tier=ex.get("tier", "PAYGATE_TIER_TWO"), - ) + # The project's video_model_family picks the Flow family. Omni Flash + # returns the same batch-operation shape as Veo, so polling and the + # retry-repoll guard above are shared. + if ex.get("model_family") == "omni_flash": + common = dict( + start_image_media_id=ex.get("start_media_id", ""), + prompt=job.prompt, + project_id=ex.get("project_id", "0"), + scene_id=ex.get("scene_id", ""), + duration_s=int(ex.get("duration_s") or config.OMNI_FLASH_DURATION_S), + resolution=ex.get("resolution") or config.OMNI_FLASH_RESOLUTION, + aspect_ratio=ex.get("aspect", "VIDEO_ASPECT_RATIO_PORTRAIT"), + user_paygate_tier=ex.get("tier", "PAYGATE_TIER_TWO"), + ) + end_id = ex.get("end_media_id") + if end_id: + submit_result = await generate_omni_flash_first_last_video( + end_image_media_id=end_id, **common) + else: + submit_result = await generate_omni_flash_first_frame_video(**common) + else: + submit_result = await self._client.generate_video( + start_image_media_id=ex.get("start_media_id", ""), + prompt=job.prompt, + project_id=ex.get("project_id", "0"), + scene_id=ex.get("scene_id", ""), + aspect_ratio=ex.get("aspect", "VIDEO_ASPECT_RATIO_PORTRAIT"), + end_image_media_id=ex.get("end_media_id"), + user_paygate_tier=ex.get("tier", "PAYGATE_TIER_TWO"), + ) if _is_error(submit_result): logger.error("[DEBUG] Video gen submit_result IS_ERROR: %s", str(submit_result)[:2000]) diff --git a/agent/sdk/services/operations.py b/agent/sdk/services/operations.py index 57c7a1000..eb20e10f5 100644 --- a/agent/sdk/services/operations.py +++ b/agent/sdk/services/operations.py @@ -275,6 +275,7 @@ async def generate_scene_video(self, scene: dict, orientation: str, tier = project.get("user_paygate_tier", "PAYGATE_TIER_TWO") if project else "PAYGATE_TIER_TWO" pid = scene.get("_project_id", "0") end_id = scene.get(f"{prefix}_end_scene_media_id") + model_family = (project.get("video_model_family") if project else None) or "veo" # Chain scenes with end_image: prefer transition_prompt (describes motion between frames) if end_id and scene.get("transition_prompt"): @@ -298,6 +299,7 @@ async def generate_scene_video(self, scene: dict, orientation: str, "start_media_id": image_media_id, "end_media_id": end_id, "request_id": request_id, + "model_family": model_family, "project_name": project.get("name") if project else "", "display_order": scene.get("display_order", 0), }, diff --git a/tests/unit/test_video_model_family.py b/tests/unit/test_video_model_family.py new file mode 100644 index 000000000..9d63a991c --- /dev/null +++ b/tests/unit/test_video_model_family.py @@ -0,0 +1,101 @@ +"""The worker must honour a project's video_model_family. + +Before this, the queue path (GENERATE_VIDEO -> FlowProvider._run_video) was +hardwired to Veo; Omni Flash existed only on the ad-hoc /api/flow/generate-video +endpoint, which does not write results back to the scene. A project that +chooses Omni Flash (720p, cheaper, and the only family with r2v / first+last +on the batch transport) must get it through the normal pipeline so review, +concat and retry-repoll keep working unchanged. +""" +from unittest.mock import AsyncMock, patch + +import pytest + +from agent.sdk.services.flow_provider import FlowProvider +from agent.sdk.services.provider_base import KIND_VIDEO, ProviderJob + + +def _job(**extra): + base = {"project_id": "p1", "tier": "PAYGATE_TIER_TWO", "aspect": "VIDEO_ASPECT_RATIO_LANDSCAPE", + "scene_id": "s1", "start_media_id": "img-1", "end_media_id": None, "request_id": ""} + base.update(extra) + return ProviderJob(job_id="j", kind=KIND_VIDEO, prompt="walk", orientation="HORIZONTAL", extra=base) + + +@pytest.mark.asyncio +async def test_omni_flash_family_routes_to_omni_first_frame(): + client = AsyncMock() + client.generate_video = AsyncMock() + submitted = {"data": {"operations": [{"operation": {"name": "op-omni"}, + "status": "MEDIA_GENERATION_STATUS_PENDING"}]}} + with patch("agent.sdk.services.flow_provider.generate_omni_flash_first_frame_video", + new=AsyncMock(return_value=submitted)) as omni, \ + patch("agent.sdk.services.flow_provider._poll_operations", + new=AsyncMock(return_value={"data": {"ok": 1}})) as poll: + result = await FlowProvider(client)._run_video(_job(model_family="omni_flash")) + + client.generate_video.assert_not_called() + kw = omni.await_args.kwargs + assert kw["start_image_media_id"] == "img-1" + assert kw["aspect_ratio"] == "VIDEO_ASPECT_RATIO_LANDSCAPE" + assert kw["duration_s"] == 8 and kw["resolution"] == "720p" + assert poll.await_args.args[1][0]["operation"]["name"] == "op-omni" + assert result == {"data": {"ok": 1}} + + +@pytest.mark.asyncio +async def test_omni_flash_with_end_frame_uses_first_last(): + client = AsyncMock() + submitted = {"data": {"operations": [{"operation": {"name": "op-fl"}, + "status": "MEDIA_GENERATION_STATUS_PENDING"}]}} + with patch("agent.sdk.services.flow_provider.generate_omni_flash_first_last_video", + new=AsyncMock(return_value=submitted)) as fl, \ + patch("agent.sdk.services.flow_provider._poll_operations", + new=AsyncMock(return_value={"data": {}})): + await FlowProvider(client)._run_video(_job(model_family="omni_flash", end_media_id="img-2")) + assert fl.await_args.kwargs["end_image_media_id"] == "img-2" + + +@pytest.mark.asyncio +async def test_default_family_is_still_veo(): + client = AsyncMock() + client.generate_video = AsyncMock( + return_value={"data": {"operations": [{"operation": {"name": "op-veo"}}]}}) + with patch("agent.sdk.services.flow_provider._poll_operations", + new=AsyncMock(return_value={"data": {}})): + await FlowProvider(client)._run_video(_job()) + client.generate_video.assert_called_once() + + +@pytest.mark.asyncio +async def test_generate_scene_video_passes_project_family(): + """operations.generate_scene_video reads the project's family into job.extra.""" + from agent.sdk.services.operations import OperationService + + captured = {} + + async def fake_run(self, job, provider=None): + captured.update(job.extra) + return {"data": {}} + + scene = {"id": "s1", "_project_id": "p1", "horizontal_image_media_id": "img-1", + "horizontal_image_url": "file:///x.png", "video_prompt": "walk", "display_order": 1} + with patch("agent.sdk.services.operations.crud") as crud, \ + patch("agent.sdk.services.operations._build_video_prompt", new=AsyncMock(return_value="p")), \ + patch.object(OperationService, "_run_provider_job", fake_run), \ + patch.object(OperationService, "_resolve_chain_end_url", new=AsyncMock(return_value=None)): + crud.get_project = AsyncMock(return_value={"user_paygate_tier": "PAYGATE_TIER_TWO", + "video_model_family": "omni_flash"}) + await OperationService.__new__(OperationService).generate_scene_video(scene, "HORIZONTAL") + assert captured["model_family"] == "omni_flash" + + +@pytest.mark.asyncio +async def test_project_update_persists_video_model_family(test_db): + """crud._update whitelists columns; the new one must be allowed or PATCH is a silent no-op.""" + from agent.db import crud + + p = await crud.create_project("x") + assert p["video_model_family"] == "veo" + row = await crud._update("project", "id", p["id"], video_model_family="omni_flash") + assert row["video_model_family"] == "omni_flash" From 0b790bcb7b3ab56816dd64a43543c6ead0e99a37 Mon Sep 17 00:00:00 2001 From: Khanh Date: Wed, 30 Sep 2026 14:32:46 +0700 Subject: [PATCH 50/68] feat: FLOW_MAX_CONCURRENT / FLOW_COOLDOWN_S env for provider pacing Each generate mints a reCAPTCHA in the Flow tab. A worker firing ~30 of them 10s apart from a background tab degrades the session score until Flow returns PUBLIC_ERROR_UNUSUAL_ACTIVITY on every call, while the same account still generates fine by hand. Expose the provider's max_concurrent and cooldown_s via env so operators can slow down without editing code; defaults unchanged. --- agent/config.py | 5 +++++ agent/sdk/services/flow_provider.py | 4 ++-- tests/unit/test_video_model_family.py | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/agent/config.py b/agent/config.py index d5875ddd3..e020edc81 100644 --- a/agent/config.py +++ b/agent/config.py @@ -80,6 +80,11 @@ # is "omni_flash". Duration must be 4/6/8/10; resolution 360p or 720p. OMNI_FLASH_DURATION_S = int(os.environ.get("OMNI_FLASH_DURATION_S", "8")) OMNI_FLASH_RESOLUTION = os.environ.get("OMNI_FLASH_RESOLUTION", "720p") +# Flow provider pacing. Every generate mints a reCAPTCHA inside the Flow tab; +# firing them back-to-back from a background tab degrades the session score +# until Google answers PUBLIC_ERROR_UNUSUAL_ACTIVITY. Slow down when that hits. +FLOW_MAX_CONCURRENT = int(os.environ.get("FLOW_MAX_CONCURRENT", "5")) +FLOW_COOLDOWN_S = float(os.environ.get("FLOW_COOLDOWN_S", "10")) API_COOLDOWN = int(os.environ.get("API_COOLDOWN", "10")) # DEPRECATED: per-provider cooldown_s in provider capabilities is authoritative MAX_CONCURRENT_REQUESTS = int(os.environ.get("MAX_CONCURRENT_REQUESTS", "5")) # DEPRECATED: per-provider max_concurrent in provider capabilities is authoritative STALE_PROCESSING_TIMEOUT = int(os.environ.get("STALE_PROCESSING_TIMEOUT", "600")) # 10 min diff --git a/agent/sdk/services/flow_provider.py b/agent/sdk/services/flow_provider.py index 09318fad4..243efae93 100644 --- a/agent/sdk/services/flow_provider.py +++ b/agent/sdk/services/flow_provider.py @@ -286,8 +286,8 @@ class FlowProvider(MediaProvider): generate_video_i2v=True, generate_video_r2v=True, upscale=True, - max_concurrent=5, - cooldown_s=10.0, + max_concurrent=config.FLOW_MAX_CONCURRENT, + cooldown_s=config.FLOW_COOLDOWN_S, ) def __init__(self, client) -> None: diff --git a/tests/unit/test_video_model_family.py b/tests/unit/test_video_model_family.py index 9d63a991c..9c3942781 100644 --- a/tests/unit/test_video_model_family.py +++ b/tests/unit/test_video_model_family.py @@ -99,3 +99,21 @@ async def test_project_update_persists_video_model_family(test_db): assert p["video_model_family"] == "veo" row = await crud._update("project", "id", p["id"], video_model_family="omni_flash") assert row["video_model_family"] == "omni_flash" + + +def test_flow_provider_rate_limits_come_from_env(monkeypatch): + """A session that fires generates every 10s trips Flow's UNUSUAL_ACTIVITY guard; + operators must be able to slow the worker without editing code.""" + import importlib + from agent import config + monkeypatch.setenv("FLOW_MAX_CONCURRENT", "1") + monkeypatch.setenv("FLOW_COOLDOWN_S", "45") + importlib.reload(config) + import agent.sdk.services.flow_provider as fp + importlib.reload(fp) + try: + assert fp.FlowProvider.capabilities.max_concurrent == 1 + assert fp.FlowProvider.capabilities.cooldown_s == 45.0 + finally: + monkeypatch.delenv("FLOW_MAX_CONCURRENT"); monkeypatch.delenv("FLOW_COOLDOWN_S") + importlib.reload(config); importlib.reload(fp) From 5008187e0946e86c272e3a3be61e2ad514235224 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 30 Sep 2026 16:07:03 +0000 Subject: [PATCH 51/68] Add muse2api media provider (muse.ai via an OpenAI-compatible gateway) Flow Kit -> Muse2APIProvider -> muse2api -> muse.ai. A new `muse2api` MediaProvider renders scene/reference images and i2v video through a muse2api gateway (https://github.com/crisng95/muse2api): - agent/services/muse2api_client.py: async HTTP client for /v1/images/generations, /v1/videos (+ task polling) and /v1/media, Bearer auth, OpenAI error bodies surfaced as "muse2api ". Input frames are sent inline as data URLs so the gateway can run on another host. - agent/sdk/services/muse2api_provider.py: translates ProviderJobs, downloads results into output/_shared/muse2api/ as file:// URLs with minted UUID media_ids (Flow-shaped results, pipeline unchanged). Chained end frames and r2v fail loudly unless MUSE2API_ALLOW_DEGRADED=1; edit/upscale/audio are not offered. - Registered in ProviderRegistry; available once MUSE2API_URL is set. - Config, README, fk-provider/fk-doctor and generation skills updated. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01MfvQsdxJhWw15u6Zm51YJM --- README.md | 27 +++ agent/config.py | 20 ++- agent/sdk/services/muse2api_provider.py | 195 +++++++++++++++++++++ agent/sdk/services/registry.py | 4 + agent/services/muse2api_client.py | 221 ++++++++++++++++++++++++ skills/fk-doctor.md | 22 ++- skills/fk-gen-chain-videos.md | 6 +- skills/fk-gen-images.md | 2 +- skills/fk-gen-refs.md | 2 +- skills/fk-gen-videos.md | 2 +- skills/fk-provider.md | 38 +++- skills/fk-thumbnail.md | 4 +- tests/unit/test_muse2api_provider.py | 200 +++++++++++++++++++++ 13 files changed, 733 insertions(+), 10 deletions(-) create mode 100644 agent/sdk/services/muse2api_provider.py create mode 100644 agent/services/muse2api_client.py create mode 100644 tests/unit/test_muse2api_provider.py diff --git a/README.md b/README.md index 1b4bd5af5..6d0bfb16f 100644 --- a/README.md +++ b/README.md @@ -270,6 +270,14 @@ You can also pass `flow_project_id` per project on `POST /api/projects`. | `MEDIA_PROVIDER` | `flow` | `flow` (Google Flow via extension) or `assistant` (route all generation to the AI assistant). | | `ASSISTANT_PROVIDER_TIMEOUT_S` | `1800` | How long a request waits for a worker to complete its provider job before failing. | | `ASSISTANT_PROVIDER_POLL_S` | `15` | How often to poll the provider-job row while waiting for completion. | +| `MUSE2API_URL` | — | Base URL of a [muse2api](https://github.com/crisng95/muse2api) gateway. Setting it makes the `muse2api` provider available. | +| `MUSE2API_KEY` | — | The gateway's `MUSE2API_API_KEY` (sent as `Authorization: Bearer`). | +| `MUSE2API_IMAGE_MODEL` / `MUSE2API_VIDEO_MODEL` | `muse-image` / `muse-video` | Model ids sent to the gateway. | +| `MUSE2API_VIDEO_SECONDS` | `8` | Clip length requested for i2v. | +| `MUSE2API_TIMEOUT_S` | `1800` | Max wait for one image call or video task (covers the gateway's own account failover). | +| `MUSE2API_POLL_S` | `5` | Video task poll interval. | +| `MUSE2API_MAX_CONCURRENT` / `MUSE2API_COOLDOWN_S` | `2` / `0` | Worker throttling for this provider. | +| `MUSE2API_ALLOW_DEGRADED` | `0` | `1` renders chained scenes and r2v as plain i2v (muse.ai takes a first frame only). | ### Assistant Media Provider (`MEDIA_PROVIDER=assistant`) @@ -299,6 +307,25 @@ See `agent/worker/assistant_worker.py` for a reference worker implementing the worker side of the protocol. Video upscale is not supported on this provider and fails loudly. +### Muse Media Provider (`provider: muse2api`) + +Renders through a [muse2api](https://github.com/crisng95/muse2api) gateway, which +exposes the muse.ai web app as an OpenAI-compatible API: + +``` +Flow Kit worker ──> Muse2APIProvider ──HTTP──> muse2api ──> muse.ai +``` + +The gateway owns the muse.ai accounts, pooling and failover; Flow Kit calls +`POST /v1/images/generations` for images and `POST /v1/videos` + +`GET /v1/videos/{id}` for i2v, sends input frames inline as data URLs (so the +gateway may run on another host), and downloads every result into +`output/_shared/muse2api/` as a `file://` URL with a minted UUID `media_id`. Set +`MUSE2API_URL` and `MUSE2API_KEY`, then pass `"provider": "muse2api"` per request +or set `DEFAULT_PROVIDER=muse2api`. Supports image and i2v; no edit, upscale or +TTS, and no end frame or r2v unless `MUSE2API_ALLOW_DEGRADED=1`. Troubleshooting +lives in `/fk-provider`. + ### Post-production (provider-neutral) Concat, finalize, and review work on clips from any provider — each clip is diff --git a/agent/config.py b/agent/config.py index 9c72cfc25..5ec2ac3f6 100644 --- a/agent/config.py +++ b/agent/config.py @@ -60,7 +60,7 @@ # /api/provider-jobs. See agent/sdk/services/assistant_provider.py and # agent/worker/assistant_worker.py for the full protocol. # Default media provider for requests that don't specify one ("flow" | -# "assistant" | any registered provider name). MEDIA_PROVIDER is kept as a +# "assistant" | "muse2api" | any registered provider name). MEDIA_PROVIDER is kept as a # legacy alias — DEFAULT_PROVIDER wins if both are set. DEFAULT_PROVIDER = os.environ.get( "DEFAULT_PROVIDER", os.environ.get("MEDIA_PROVIDER", "flow") @@ -71,6 +71,24 @@ ASSISTANT_MAX_CONCURRENT = int(os.environ.get("ASSISTANT_MAX_CONCURRENT", "2")) ASSISTANT_COOLDOWN_S = float(os.environ.get("ASSISTANT_COOLDOWN_S", "0")) +# "muse2api": render through a muse2api gateway (https://github.com/crisng95/muse2api), +# which fronts the muse.ai web app with an OpenAI-compatible API. The provider +# is registered always and becomes available once MUSE2API_URL is set; the key +# is the gateway's own MUSE2API_API_KEY. See agent/sdk/services/muse2api_provider.py. +MUSE2API_URL = os.environ.get("MUSE2API_URL", "").strip().rstrip("/") +MUSE2API_KEY = os.environ.get("MUSE2API_KEY", "") +MUSE2API_IMAGE_MODEL = os.environ.get("MUSE2API_IMAGE_MODEL", "muse-image") +MUSE2API_VIDEO_MODEL = os.environ.get("MUSE2API_VIDEO_MODEL", "muse-video") +MUSE2API_VIDEO_SECONDS = int(os.environ.get("MUSE2API_VIDEO_SECONDS", "8")) +# Covers the gateway's own failover (up to 3 accounts x its 240s/600s timeouts). +MUSE2API_TIMEOUT_S = float(os.environ.get("MUSE2API_TIMEOUT_S", "1800")) +MUSE2API_POLL_S = float(os.environ.get("MUSE2API_POLL_S", "5")) +MUSE2API_MAX_CONCURRENT = int(os.environ.get("MUSE2API_MAX_CONCURRENT", "2")) +MUSE2API_COOLDOWN_S = float(os.environ.get("MUSE2API_COOLDOWN_S", "0")) +# muse.ai takes a first frame only. With this on, chained scenes drop the end +# frame and r2v renders as i2v; off, both fail loudly (same rule as Flow). +MUSE2API_ALLOW_DEGRADED = os.environ.get("MUSE2API_ALLOW_DEGRADED", "0") == "1" + # ─── Worker ────────────────────────────────────────────────── POLL_INTERVAL = int(os.environ.get("POLL_INTERVAL", "5")) VIDEO_POLL_INTERVAL = int(os.environ.get("VIDEO_POLL_INTERVAL", "10")) # polling interval for video/upscale status diff --git a/agent/sdk/services/muse2api_provider.py b/agent/sdk/services/muse2api_provider.py new file mode 100644 index 000000000..28af6c531 --- /dev/null +++ b/agent/sdk/services/muse2api_provider.py @@ -0,0 +1,195 @@ +"""Muse2APIProvider — MediaProvider adapter for a muse2api gateway. + + Flow Kit worker ──> Muse2APIProvider ──HTTP──> muse2api ──> muse.ai + +muse2api (https://github.com/crisng95/muse2api) wraps the muse.ai web app in +an OpenAI-compatible API and owns everything upstream: the account pool, +failover, cooldowns and the browser driver. This provider only translates a +:class:`ProviderJob` into gateway calls and the answer back into the +Flow-shaped result dict the rest of the pipeline parses, so scenes rendered +here look exactly like Flow or assistant output downstream. + +Finished media is downloaded into ``output/_shared/muse2api/`` and recorded as +a ``file://`` URL. Gateway media links are only as durable as the gateway's +data dir (and only reachable where the gateway is), and ``file://`` URLs +never expire, so ``/fk-refresh-urls`` has nothing to do for them. + +What muse.ai can and cannot do shapes the capabilities: + +* image — text-to-image. Reference images are not an input the + gateway accepts, so entity refs are dropped (logged). +* video (i2v) — first frame + prompt. +* chained video — no end-frame input: fails unless MUSE2API_ALLOW_DEGRADED=1, + which drops the end frame and renders plain i2v. +* video_refs — only with MUSE2API_ALLOW_DEGRADED=1, as i2v off the scene + image (or the first reference). +* edit_image, upscale, audio — not offered (``/v1/images/edits`` is 501). +""" + +from __future__ import annotations + +import asyncio +import logging +import uuid +from pathlib import Path +from urllib.parse import unquote, urlparse + +from agent import config +from agent.sdk.services.assistant_provider import _image_result, _video_result +from agent.sdk.services.provider_base import ( + KIND_IMAGE, + KIND_VIDEO, + KIND_VIDEO_REFS, + MediaProvider, + ProviderCapabilities, + ProviderJob, +) +from agent.services.muse2api_client import Muse2APIClient, Muse2APIError, to_data_url + +logger = logging.getLogger(__name__) + +_ASPECT = {"VERTICAL": "9:16", "HORIZONTAL": "16:9"} +_VIDEO_EXT = {"video/mp4": "mp4", "video/webm": "webm", "video/quicktime": "mov"} + + +def _image_ext(data: bytes) -> str: + if data[:8] == b"\x89PNG\r\n\x1a\n": + return "png" + if data[:3] == b"\xff\xd8\xff": + return "jpg" + if data[:4] == b"RIFF" and data[8:12] == b"WEBP": + return "webp" + return "png" + + +class Muse2APIProvider(MediaProvider): + """Renders media through a muse2api gateway over HTTP.""" + + name = "muse2api" + display_name = "Muse (muse2api gateway)" + + def __init__(self, client: Muse2APIClient | None = None) -> None: + self.client = client or Muse2APIClient( + config.MUSE2API_URL, config.MUSE2API_KEY, + timeout_s=config.MUSE2API_TIMEOUT_S, poll_s=config.MUSE2API_POLL_S, + ) + self.allow_degraded = config.MUSE2API_ALLOW_DEGRADED + self.output_dir = config.SHARED_OUTPUT_DIR / "muse2api" + # Per instance, because r2v is only on offer when degrading is allowed. + self.capabilities = ProviderCapabilities( + generate_image=True, + edit_image=False, + generate_video_i2v=True, + generate_video_r2v=self.allow_degraded, + upscale=False, + generate_audio=False, + max_concurrent=config.MUSE2API_MAX_CONCURRENT, + cooldown_s=config.MUSE2API_COOLDOWN_S, + ) + + def is_available(self) -> bool: + """Available once MUSE2API_URL is set. Gateway health (accounts, driver) + is the gateway's business: a request it cannot serve fails with its + own error code and is retried by the worker like any other failure.""" + return self.client.configured + + def check(self, job: ProviderJob) -> str | None: + if not self.client.configured: + return "muse2api provider is not configured — set MUSE2API_URL" + if job.kind == KIND_VIDEO_REFS and not self.allow_degraded: + return ("muse2api has no reference-to-video input — set " + "MUSE2API_ALLOW_DEGRADED=1 to render it as i2v off the scene image") + return super().check(job) + + # ── MediaProvider interface ── + + async def run(self, job: ProviderJob) -> dict: + try: + if job.kind == KIND_IMAGE: + return await self._run_image(job) + if job.kind in (KIND_VIDEO, KIND_VIDEO_REFS): + return await self._run_video(job) + except Muse2APIError as e: + logger.error("muse2api: job %s (%s) failed: %s", job.job_id[:12], job.kind, e) + return {"error": str(e)} + except (OSError, ValueError) as e: + # Unreadable input image, full disk, bad base64 … + logger.error("muse2api: job %s (%s) failed: %s", job.job_id[:12], job.kind, e) + return {"error": f"muse2api: {e}"} + return {"error": f"muse2api provider does not support job kind '{job.kind}'"} + + async def _run_image(self, job: ProviderJob) -> dict: + prompt = job.prompt + composition = (job.extra or {}).get("composition") + if composition: + prompt = f"{prompt}\n\nComposition: {composition}" + if job.reference_urls: + logger.info("muse2api: job %s — %d reference image(s) dropped, the " + "gateway takes no image refs", job.job_id[:12], len(job.reference_urls)) + data = await self.client.generate_image( + prompt, model=config.MUSE2API_IMAGE_MODEL, size=_ASPECT.get(job.orientation)) + url = await self._save(job.job_id, data, _image_ext(data)) + mid = str(uuid.uuid4()) + logger.info("muse2api: image %s ready (media_id=%s)", job.job_id[:12], mid[:8]) + return _image_result(mid, url) + + async def _run_video(self, job: ProviderJob) -> dict: + prefix = "vertical" if job.orientation == "VERTICAL" else "horizontal" + start = job.start_url + if job.kind == KIND_VIDEO_REFS: + start = start or (job.reference_urls[0] if job.reference_urls else None) + if not start: + return {"error": "No valid reference images for r2v"} + logger.warning("muse2api: job %s — r2v degraded to i2v", job.job_id[:12]) + if not start: + return {"error": f"No {prefix} image for scene"} + if job.end_url: + if not self.allow_degraded: + return {"error": "muse2api has no end-frame input for chained video — " + "set MUSE2API_ALLOW_DEGRADED=1 to render plain i2v"} + logger.warning("muse2api: job %s — end frame dropped, rendering plain i2v", + job.job_id[:12]) + + image = await to_data_url(start) + seconds = int(job.duration_s) if job.duration_s else config.MUSE2API_VIDEO_SECONDS + task = await self.client.create_video( + job.prompt, model=config.MUSE2API_VIDEO_MODEL, + size=_ASPECT.get(job.orientation), seconds=seconds, image=image) + task_id = task.get("id") + if not task_id: + return {"error": "muse2api: video task created without an id"} + logger.info("muse2api: video %s submitted as %s", job.job_id[:12], task_id) + + result = await self.client.wait_video(task_id) + data = await self.client.download(result["url"]) + ext = _VIDEO_EXT.get((result.get("mime") or "").split(";")[0], "mp4") + url = await self._save(job.job_id, data, ext) + mid = str(uuid.uuid4()) + logger.info("muse2api: video %s ready (media_id=%s)", job.job_id[:12], mid[:8]) + return _video_result(mid, url) + + async def _save(self, job_id: str, data: bytes, ext: str) -> str: + path = self.output_dir / f"{job_id}.{ext}" + + def _write() -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(data) + + await asyncio.to_thread(_write) + return "file://" + str(path.resolve()) + + async def register_existing_image( + self, url: str, *, name: str = "", project_id: str = "" + ) -> dict: + """Mint a UUID for an image we already have — the gateway has no ids.""" + parsed = urlparse(url or "") + if parsed.scheme in ("http", "https"): + canonical = url + else: + local = Path(unquote(parsed.path)) if parsed.scheme == "file" else Path(url) + if not local.is_file(): + return {"error": f"muse2api: local image not found for '{name}': {url}"} + canonical = "file://" + str(local.resolve()) + mid = str(uuid.uuid4()) + logger.info("muse2api: registered existing image '%s' → media_id=%s", name, mid[:8]) + return {"data": {"media": [{"name": mid}], "url": canonical}} diff --git a/agent/sdk/services/registry.py b/agent/sdk/services/registry.py index 904d02612..ee942cb72 100644 --- a/agent/sdk/services/registry.py +++ b/agent/sdk/services/registry.py @@ -11,6 +11,8 @@ - ``assistant`` — the local assistant (e.g. Pax/Muse) via the persistent provider-job queue (``provider_job`` table + ``/api/provider-jobs``). Always available, needs no Chrome. + - ``muse2api`` — a muse2api gateway (muse.ai behind an OpenAI-compatible + API) over HTTP. Available once ``MUSE2API_URL`` is set. Extra backends (a Sora adapter, a local SDXL worker, …) can be registered at startup and are then selectable per request through the ``provider`` @@ -25,6 +27,7 @@ from agent.config import DEFAULT_PROVIDER from agent.sdk.services.assistant_provider import AssistantProvider from agent.sdk.services.flow_provider import FlowProvider +from agent.sdk.services.muse2api_provider import Muse2APIProvider from agent.sdk.services.provider_base import MediaProvider if TYPE_CHECKING: @@ -45,6 +48,7 @@ def __init__( if flow_client is not None: providers["flow"] = FlowProvider(flow_client) providers["assistant"] = AssistantProvider() + providers["muse2api"] = Muse2APIProvider() if extra: providers.update(extra) self._providers = providers diff --git a/agent/services/muse2api_client.py b/agent/services/muse2api_client.py new file mode 100644 index 000000000..ac43697c1 --- /dev/null +++ b/agent/services/muse2api_client.py @@ -0,0 +1,221 @@ +"""HTTP client for a muse2api gateway (https://github.com/crisng95/muse2api). + +muse2api exposes the muse.ai web app as an OpenAI-compatible API. Flow Kit +only needs the media half of it: + + POST /v1/images/generations prompt -> image(s) (synchronous) + POST /v1/videos prompt (+first frame) -> task + GET /v1/videos/{task_id} task status; result.url when succeeded + GET /v1/media/{name} download generated media (public) + GET /readyz driver health + available accounts + +Every ``/v1/*`` call carries ``Authorization: Bearer ``. Errors +come back as an OpenAI error body (``{"error": {"message", "type", "code"}}``) +and are raised here as :class:`Muse2APIError` carrying that code, so the +provider can report ``no_account_available`` / ``upstream_quota_exhausted`` +and the rest verbatim instead of a bare HTTP status. + +Input images are always sent inline as data URLs. Flow Kit's own media lives +at ``file://`` paths (or signed URLs only this machine can reach), and the +gateway may run on another host, so letting it fetch URLs itself would break +as soon as the two are split. +""" + +from __future__ import annotations + +import asyncio +import base64 +import logging +import mimetypes +import time +from pathlib import Path +from urllib.parse import unquote, urlparse + +import httpx + +logger = logging.getLogger(__name__) + +TERMINAL_OK = "succeeded" +TERMINAL_FAILED = ("failed", "cancelled") + + +class Muse2APIError(Exception): + """A muse2api call failed. ``code`` is the gateway's error code when known.""" + + def __init__(self, message: str, *, status: int | None = None, code: str = "") -> None: + super().__init__(message) + self.message = message + self.status = status + self.code = code + + def __str__(self) -> str: + prefix = f"muse2api {self.code}" if self.code else "muse2api" + if self.status: + prefix += f" (HTTP {self.status})" + return f"{prefix}: {self.message}" + + +def _error_from_response(resp: httpx.Response) -> Muse2APIError: + try: + body = resp.json() + except ValueError: + body = None + err = body.get("error") if isinstance(body, dict) else None + if isinstance(err, dict): + return Muse2APIError(err.get("message") or resp.reason_phrase, + status=resp.status_code, code=err.get("code") or "") + return Muse2APIError(resp.text[:300] or resp.reason_phrase, status=resp.status_code) + + +async def to_data_url(ref: str, *, timeout: float = 60.0) -> str: + """Turn a file:// path, local path, http(s) URL or data URL into a data URL.""" + ref = (ref or "").strip() + if not ref: + raise ValueError("empty image reference") + if ref.startswith("data:"): + return ref + parsed = urlparse(ref) + if parsed.scheme in ("http", "https"): + async with httpx.AsyncClient(timeout=timeout, follow_redirects=True) as client: + resp = await client.get(ref) + resp.raise_for_status() + data = resp.content + mime = resp.headers.get("content-type", "").split(";")[0].strip() + mime = mime or mimetypes.guess_type(parsed.path)[0] or "image/png" + else: + path = Path(unquote(parsed.path)) if parsed.scheme == "file" else Path(ref) + if not path.is_file(): + raise FileNotFoundError(f"image not found: {ref}") + data = await asyncio.to_thread(path.read_bytes) + mime = mimetypes.guess_type(path.name)[0] or "image/png" + return f"data:{mime};base64,{base64.b64encode(data).decode()}" + + +class Muse2APIClient: + """Thin async client for the muse2api media endpoints.""" + + def __init__(self, base_url: str, api_key: str = "", *, + timeout_s: float = 1800.0, poll_s: float = 5.0, + transport: httpx.AsyncBaseTransport | None = None) -> None: + self.base_url = (base_url or "").rstrip("/") + self.api_key = api_key + self.timeout_s = timeout_s + self.poll_s = poll_s + self._transport = transport # tests inject httpx.MockTransport here + + @property + def configured(self) -> bool: + return bool(self.base_url) + + def _headers(self) -> dict: + return {"Authorization": f"Bearer {self.api_key}"} if self.api_key else {} + + def _url(self, path: str) -> str: + return path if path.startswith(("http://", "https://")) else f"{self.base_url}{path}" + + async def _request(self, method: str, path: str, *, timeout: float = 60.0, + **kwargs) -> dict: + try: + async with httpx.AsyncClient(timeout=timeout, transport=self._transport) as client: + resp = await client.request(method, self._url(path), + headers=self._headers(), **kwargs) + except httpx.TimeoutException as e: + raise Muse2APIError(f"{method} {path} timed out after {timeout:.0f}s", + code="timeout") from e + except httpx.HTTPError as e: + raise Muse2APIError(f"{method} {path} failed: {e}", + code="connection_error") from e + if resp.status_code >= 400: + raise _error_from_response(resp) + try: + return resp.json() + except ValueError as e: + raise Muse2APIError(f"{method} {path} returned non-JSON", + status=resp.status_code) from e + + # ── Health ── + + async def readyz(self) -> dict: + return await self._request("GET", "/readyz", timeout=10.0) + + # ── Images ── + + async def generate_image(self, prompt: str, *, model: str, size: str | None) -> bytes: + """Generate one image and return its bytes (b64_json: no second download).""" + body = {"prompt": prompt, "model": model, "n": 1, "response_format": "b64_json"} + if size: + body["size"] = size + data = await self._request("POST", "/v1/images/generations", + json=body, timeout=self.timeout_s) + items = data.get("data") or [] + if not items: + raise Muse2APIError("image generation returned no data", code="empty_result") + item = items[0] + if item.get("b64_json"): + return base64.b64decode(item["b64_json"]) + if item.get("url"): + return await self.download(item["url"]) + raise Muse2APIError("image generation returned neither b64_json nor url", + code="empty_result") + + # ── Videos ── + + async def create_video(self, prompt: str, *, model: str, size: str | None, + seconds: int | None, image: str | None) -> dict: + body: dict = {"prompt": prompt, "model": model} + if size: + body["size"] = size + if seconds: + body["seconds"] = seconds + if image: + body["image"] = image + return await self._request("POST", "/v1/videos", json=body, timeout=120.0) + + async def get_video(self, task_id: str) -> dict: + return await self._request("GET", f"/v1/videos/{task_id}", timeout=30.0) + + async def wait_video(self, task_id: str) -> dict: + """Poll a video task until it finishes. Returns the task's ``result``.""" + deadline = time.monotonic() + self.timeout_s + transient = 0 + while True: + try: + task = await self.get_video(task_id) + transient = 0 + except Muse2APIError as e: + # A blip on the poll is not a failed render; a 404 is (the + # gateway restarted and lost the task, or the id is wrong). + if e.status == 404 or transient >= 3: + raise + transient += 1 + logger.warning("muse2api: poll %s failed (%s), retrying", task_id, e) + task = {} + status = (task.get("status") or "").lower() + if status == TERMINAL_OK: + result = task.get("result") or {} + if not result.get("url"): + raise Muse2APIError(f"video task {task_id} succeeded without a url", + code="empty_result") + return result + if status in TERMINAL_FAILED: + raise Muse2APIError(task.get("error") or f"video task {task_id} {status}", + code=f"task_{status}") + if time.monotonic() >= deadline: + raise Muse2APIError(f"video task {task_id} still '{status or '?'}' after " + f"{self.timeout_s:.0f}s", code="timeout") + await asyncio.sleep(self.poll_s) + + # ── Media ── + + async def download(self, url: str) -> bytes: + """Fetch generated media. ``/v1/media`` is public, but a key never hurts.""" + try: + async with httpx.AsyncClient(timeout=300.0, follow_redirects=True, + transport=self._transport) as client: + resp = await client.get(self._url(url), headers=self._headers()) + except httpx.HTTPError as e: + raise Muse2APIError(f"download {url} failed: {e}", + code="connection_error") from e + if resp.status_code >= 400: + raise _error_from_response(resp) + return resp.content diff --git a/skills/fk-doctor.md b/skills/fk-doctor.md index 7e8c69ece..56ebbff14 100644 --- a/skills/fk-doctor.md +++ b/skills/fk-doctor.md @@ -52,7 +52,7 @@ curl -s "http://127.0.0.1:8100/api/provider-jobs?limit=20" ``` Bucket the failures by `error_message` prefix, print a table, and for each bucket give the fix from the taxonomy. -For requests with a `provider` other than `flow`, also read the linked +For requests with a `provider` other than `flow` or `muse2api`, also read the linked provider job (`provider_job_id` on the request row): a `QUEUED` job with no worker means `assistant_worker.py` isn't running; a `FAILED` job carries the worker's `error_message`. @@ -265,6 +265,26 @@ Check the job row first: `GET /api/provider-jobs?provider=assistant&limit=20`. | `400 provider 'flow' does not support audio` | TTS routed to flow | Use `assistant` or `local` for `/api/tts/generate` | | `Cannot fetch video for scene ...` in review | Remote URL dead and no Flow fallback (not connected, or non-Flow media) | Re-check the URL; for Flow media connect the extension, for local files verify the path exists | +### I. muse2api gateway errors (`provider: muse2api`) + +No provider job is involved — the worker calls the gateway directly, so the +request's `error_message` is the whole story. It reads +`muse2api (HTTP ): `, where `` is the gateway's +own OpenAI error code. Check the gateway with `curl -s $MUSE2API_URL/readyz`. + +| Error | Cause | Fix | +|---|---|---| +| Requests stay `PENDING`, `muse2api.available: false` in `/api/providers/status` | `MUSE2API_URL` unset | Set `MUSE2API_URL` (+ `MUSE2API_KEY`) and restart the server | +| `muse2api connection_error` | Gateway down or wrong URL | Start muse2api; verify `MUSE2API_URL` | +| `muse2api invalid_api_key (HTTP 401)` | Key mismatch | `MUSE2API_KEY` must equal the gateway's `MUSE2API_API_KEY` | +| `muse2api no_account_available (HTTP 503)` | No usable muse.ai account (`readyz` shows `accounts.available: 0`) | Import/renew accounts via the gateway's `/admin/accounts` | +| `muse2api upstream_auth_failed` | The muse.ai session expired | Re-export cookies and update the account on the gateway | +| `muse2api upstream_quota_exhausted (HTTP 429)` | Account out of quota | Wait out the cooldown or add accounts | +| `muse2api upstream_refused` / `task_failed` | muse.ai answered but produced nothing usable (often a content refusal) | Rephrase the prompt; the worker retries it as usual | +| `muse2api timeout` | Image call or video task exceeded `MUSE2API_TIMEOUT_S` | Check the gateway logs; raise the env var if renders are just slow | +| `muse2api has no end-frame input for chained video` | Chained scene on muse2api | `MUSE2API_ALLOW_DEGRADED=1` (plain i2v), or render that scene on `flow` | +| `... does not support job kind 'edit_image'` / `'upscale'` | Not offered by muse.ai | Use `flow` for edits and upscale | + ## Output format Always end with a prescription block: diff --git a/skills/fk-gen-chain-videos.md b/skills/fk-gen-chain-videos.md index 0c4f4d55e..f4447141f 100644 --- a/skills/fk-gen-chain-videos.md +++ b/skills/fk-gen-chain-videos.md @@ -7,10 +7,12 @@ Usage: `/gen-chain-videos ` Usage: `/fk-gen-chain-videos [--provider ]` Pass `"provider": ""` on each item in the `/api/requests/batch` -payload (`flow` | `assistant`; default is the server `DEFAULT_PROVIDER`). +payload (`flow` | `assistant` | `muse2api`; default is the server `DEFAULT_PROVIDER`). The assistant provider queues a provider job — make sure a worker is running (see `/fk-provider`). Chained start/end frames are passed as `start_url` / -`end_url` on the provider job, so chaining works on any provider. +`end_url` on the provider job, so chaining works on any provider that takes an +end frame. `muse2api` does not: chained scenes fail there unless +`MUSE2API_ALLOW_DEGRADED=1`, which renders them as plain i2v. This creates smooth transitions between scenes in a chain by using the **NEXT scene's image as the endImage** of the current scene's video, so the last frame of scene N matches the first frame of scene N+1 → seamless concat. diff --git a/skills/fk-gen-images.md b/skills/fk-gen-images.md index e3901c65d..fbbcc3fb5 100644 --- a/skills/fk-gen-images.md +++ b/skills/fk-gen-images.md @@ -7,7 +7,7 @@ Usage: `/fk-gen-images ` Usage: `/fk-gen-images [--provider ]` Pass `"provider": ""` on each item in the `/api/requests/batch` -payload (`flow` | `assistant`; default is the server `DEFAULT_PROVIDER`). +payload (`flow` | `assistant` | `muse2api`; default is the server `DEFAULT_PROVIDER`). The assistant provider queues a provider job — make sure a worker is running (see `/fk-provider`). Assistant image output lands as `file://` URLs, which never expire. diff --git a/skills/fk-gen-refs.md b/skills/fk-gen-refs.md index 435682603..d3407437f 100644 --- a/skills/fk-gen-refs.md +++ b/skills/fk-gen-refs.md @@ -7,7 +7,7 @@ Usage: `/fk-gen-refs ` Usage: `/fk-gen-refs [--provider ]` Pass `"provider": ""` on each item in the `/api/requests/batch` -payload (`flow` | `assistant`; default is the server `DEFAULT_PROVIDER`). +payload (`flow` | `assistant` | `muse2api`; default is the server `DEFAULT_PROVIDER`). The assistant provider queues a provider job — make sure a worker is running (see `/fk-provider`). diff --git a/skills/fk-gen-videos.md b/skills/fk-gen-videos.md index 70bab8eb9..b0e62124a 100644 --- a/skills/fk-gen-videos.md +++ b/skills/fk-gen-videos.md @@ -7,7 +7,7 @@ Usage: `/fk-gen-videos ` Usage: `/fk-gen-videos [--provider ]` Pass `"provider": ""` on each item in the `/api/requests/batch` -payload (`flow` | `assistant`; default is the server `DEFAULT_PROVIDER`). +payload (`flow` | `assistant` | `muse2api`; default is the server `DEFAULT_PROVIDER`). The assistant provider queues a provider job — make sure a worker is running (see `/fk-provider`). Assistant image output lands as `file://` URLs, which never expire. diff --git a/skills/fk-provider.md b/skills/fk-provider.md index d9d177a0d..c51e54044 100644 --- a/skills/fk-provider.md +++ b/skills/fk-provider.md @@ -2,7 +2,9 @@ FlowKit is provider-neutral. A **media provider** is the backend that renders media: `flow` (Google Flow via the Chrome extension), `assistant` (Muse or any -HTTP-capable external worker), or any future registered provider. +HTTP-capable external worker), `muse2api` (muse.ai through a +[muse2api](https://github.com/crisng95/muse2api) gateway), or any future +registered provider. Every generation request, thumbnail, and TTS call accepts an optional `provider`. Omit it and the server default (`DEFAULT_PROVIDER`, usually @@ -48,10 +50,44 @@ audio — it is rejected with 400.) - `flow`: image, edit_image, i2v (image-to-video), r2v, upscale. **No audio.** - `assistant`: image, edit_image, i2v, r2v, **audio (TTS)**. No upscale. +- `muse2api`: image, i2v. No edit_image, upscale or audio. No end frame and no + r2v unless `MUSE2API_ALLOW_DEGRADED=1` (then both render as plain i2v). + Entity reference images are not sent — muse.ai takes none. Asking a provider for a kind it doesn't support returns 400 with a message naming the right backend to use instead. +## The muse2api provider needs a gateway + +`muse2api` calls a running [muse2api](https://github.com/crisng95/muse2api) +service over HTTP — Flow Kit → `Muse2APIProvider` → muse2api → muse.ai. The +gateway owns the muse.ai accounts, failover and cooldowns; Flow Kit only needs +its URL and key: + +```bash +# muse2api side (its own repo): python -m muse2api → http://127.0.0.1:18610 +export MUSE2API_URL=http://127.0.0.1:18610 +export MUSE2API_KEY= # data/api_key if auto-generated +# optional: DEFAULT_PROVIDER=muse2api to make it the default backend +``` + +`muse2api.available` is true once `MUSE2API_URL` is set. Check the gateway +itself with `curl -s $MUSE2API_URL/readyz` — `accounts.available: 0` means +every request will fail `no_account_available` (import an account on the +gateway via its `/admin/accounts`). + +Output is downloaded into `output/_shared/muse2api/` and stored as `file://` +URLs, so like the assistant it never needs `/fk-refresh-urls`. + +| Error (request `error_message`) | Meaning | Fix | +|---|---|---| +| `muse2api provider is not configured` | `MUSE2API_URL` unset | set it and restart the server | +| `muse2api connection_error` | gateway not reachable | start muse2api / fix the URL | +| `muse2api invalid_api_key (HTTP 401)` | wrong key | use the gateway's `MUSE2API_API_KEY` | +| `muse2api no_account_available (HTTP 503)` | no usable muse.ai account | add/renew accounts on the gateway | +| `muse2api upstream_quota_exhausted (HTTP 429)` | account out of quota | wait for cooldown or add accounts | +| `muse2api has no end-frame input` | chained scene | `MUSE2API_ALLOW_DEGRADED=1`, or use `flow` | + ## The assistant provider needs a worker When a request uses `provider: assistant`, the server creates a **provider diff --git a/skills/fk-thumbnail.md b/skills/fk-thumbnail.md index e05f5068f..3243e0b88 100644 --- a/skills/fk-thumbnail.md +++ b/skills/fk-thumbnail.md @@ -5,8 +5,8 @@ Usage: `/fk-thumbnail [project_id] [--provider ]` Usage: `/fk-thumbnail [project_id] [--provider ]` -Pass `"provider"` in the `generate-thumbnail` payload (`flow` | `assistant`; -default is the server `DEFAULT_PROVIDER`). The assistant provider queues a +Pass `"provider"` in the `generate-thumbnail` payload (`flow` | `assistant` | +`muse2api`; default is the server `DEFAULT_PROVIDER`). The assistant provider queues a provider job — make sure a worker is running (see `/fk-provider`). Flow thumbnail generation needs the Chrome extension; assistant needs none. diff --git a/tests/unit/test_muse2api_provider.py b/tests/unit/test_muse2api_provider.py new file mode 100644 index 000000000..2dc9cff05 --- /dev/null +++ b/tests/unit/test_muse2api_provider.py @@ -0,0 +1,200 @@ +"""Tests for the muse2api media provider (HTTP gateway to muse.ai). + +The gateway is faked with httpx.MockTransport, so these run offline and pin +the wire contract: paths, bearer auth, the payload fields, task polling, and +the OpenAI error body. +""" +import base64 +import json + +import httpx +import pytest + +from agent.sdk.services import muse2api_provider as mp +from agent.sdk.services.provider_base import ( + KIND_EDIT_IMAGE, + KIND_IMAGE, + KIND_UPSCALE, + KIND_VIDEO, + KIND_VIDEO_REFS, + ProviderJob, +) +from agent.sdk.services.registry import ProviderRegistry +from agent.sdk.services.result_handler import parse_result +from agent.services.muse2api_client import Muse2APIClient +from agent.worker._parsing import _is_uuid + +PNG = b"\x89PNG\r\n\x1a\n" + b"\x00" * 16 +MP4 = b"\x00\x00\x00\x18ftypmp42" + b"\x00" * 8 +BASE = "http://muse.test" + + +class FakeGateway: + """Minimal muse2api: images, video tasks that finish after N polls, media.""" + + def __init__(self, polls_until_done=2, video_status="succeeded", key="k"): + self.polls_until_done = polls_until_done + self.video_status = video_status + self.key = key + self.calls: list[tuple[str, str, dict | None]] = [] + self._polls = 0 + + def __call__(self, request: httpx.Request) -> httpx.Response: + body = json.loads(request.content) if request.content else None + self.calls.append((request.method, request.url.path, body)) + path = request.url.path + if path.startswith("/v1/media/"): + return httpx.Response(200, content=MP4, headers={"content-type": "video/mp4"}) + if request.headers.get("authorization") != f"Bearer {self.key}": + return httpx.Response(401, json={"error": { + "message": "invalid or missing API key", "type": "authentication_error", + "code": "invalid_api_key"}}) + if path == "/v1/images/generations": + return httpx.Response(200, json={"created": 1, "data": [ + {"b64_json": base64.b64encode(PNG).decode(), "revised_prompt": None}]}) + if path == "/v1/videos" and request.method == "POST": + return httpx.Response(200, json={"id": "task_1", "status": "queued"}) + if path == "/v1/videos/task_1": + self._polls += 1 + if self._polls < self.polls_until_done: + return httpx.Response(200, json={"id": "task_1", "status": "running"}) + if self.video_status != "succeeded": + return httpx.Response(200, json={"id": "task_1", "status": self.video_status, + "error": "upstream refused", "result": None}) + return httpx.Response(200, json={"id": "task_1", "status": "succeeded", "result": { + "url": f"{BASE}/v1/media/vid_abc.mp4", "mime": "video/mp4"}}) + return httpx.Response(404, json={"error": {"message": "nope", "code": "not_found"}}) + + +@pytest.fixture +def gateway(): + return FakeGateway() + + +@pytest.fixture +def provider(tmp_path, gateway, monkeypatch): + monkeypatch.setattr(mp.config, "MUSE2API_ALLOW_DEGRADED", False) + client = Muse2APIClient(BASE, "k", timeout_s=5, poll_s=0.01, + transport=httpx.MockTransport(gateway)) + prov = mp.Muse2APIProvider(client) + prov.output_dir = tmp_path / "muse2api" + return prov + + +@pytest.fixture +def start_image(tmp_path): + p = tmp_path / "start.png" + p.write_bytes(PNG) + return "file://" + str(p) + + +async def test_image_is_saved_locally_with_minted_uuid(provider, gateway): + job = ProviderJob(job_id="img1", kind=KIND_IMAGE, prompt="a fox", + orientation="HORIZONTAL", reference_urls=("file:///x.png",), + extra={"composition": "wide establishing shot"}) + result = await provider.run(job) + + gen = parse_result(result, "GENERATE_IMAGE") + assert gen.success, result + assert _is_uuid(gen.media_id) + assert gen.url.startswith("file://") and gen.url.endswith("/muse2api/img1.png") + assert (provider.output_dir / "img1.png").read_bytes() == PNG + + method, path, body = gateway.calls[0] + assert (method, path) == ("POST", "/v1/images/generations") + assert body["size"] == "16:9" + assert body["model"] == "muse-image" + assert body["response_format"] == "b64_json" + assert "wide establishing shot" in body["prompt"] + + +async def test_video_sends_first_frame_inline_and_polls(provider, gateway, start_image): + job = ProviderJob(job_id="vid1", kind=KIND_VIDEO, prompt="fox runs", + orientation="VERTICAL", start_url=start_image) + result = await provider.run(job) + + gen = parse_result(result, "GENERATE_VIDEO") + assert gen.success, result + assert _is_uuid(gen.media_id) + assert (provider.output_dir / "vid1.mp4").read_bytes() == MP4 + + create = next(c for c in gateway.calls if c[:2] == ("POST", "/v1/videos")) + body = create[2] + assert body["size"] == "9:16" + assert body["seconds"] == 8 + assert body["image"] == "data:image/png;base64," + base64.b64encode(PNG).decode() + polls = [c for c in gateway.calls if c[1] == "/v1/videos/task_1"] + assert len(polls) == 2 + + +async def test_failed_video_task_surfaces_gateway_error(tmp_path, start_image): + gw = FakeGateway(polls_until_done=1, video_status="failed") + client = Muse2APIClient(BASE, "k", timeout_s=5, poll_s=0.01, + transport=httpx.MockTransport(gw)) + prov = mp.Muse2APIProvider(client) + prov.output_dir = tmp_path + result = await prov.run(ProviderJob(job_id="v", kind=KIND_VIDEO, prompt="p", + start_url=start_image)) + assert "upstream refused" in result["error"] + + +async def test_openai_error_body_is_reported(tmp_path): + client = Muse2APIClient(BASE, "wrong", transport=httpx.MockTransport(FakeGateway())) + prov = mp.Muse2APIProvider(client) + prov.output_dir = tmp_path + result = await prov.run(ProviderJob(job_id="i", kind=KIND_IMAGE, prompt="p")) + assert result["error"] == "muse2api invalid_api_key (HTTP 401): invalid or missing API key" + + +async def test_chained_video_fails_loudly_unless_degraded(provider, gateway, start_image): + job = ProviderJob(job_id="c", kind=KIND_VIDEO, prompt="p", + start_url=start_image, end_url=start_image) + result = await provider.run(job) + assert "end-frame" in result["error"] + assert gateway.calls == [] + + provider.allow_degraded = True + result = await provider.run(job) + assert parse_result(result, "GENERATE_VIDEO").success + + +async def test_video_without_start_frame_errors(provider): + result = await provider.run(ProviderJob(job_id="n", kind=KIND_VIDEO, prompt="p")) + assert result == {"error": "No vertical image for scene"} + + +def test_capabilities_and_checks(provider, monkeypatch): + assert provider.check(ProviderJob(job_id="a", kind=KIND_IMAGE)) is None + assert provider.check(ProviderJob(job_id="a", kind=KIND_VIDEO)) is None + for kind in (KIND_EDIT_IMAGE, KIND_UPSCALE): + assert "does not support" in provider.check(ProviderJob(job_id="a", kind=kind)) + assert "MUSE2API_ALLOW_DEGRADED" in provider.check( + ProviderJob(job_id="a", kind=KIND_VIDEO_REFS)) + + monkeypatch.setattr(mp.config, "MUSE2API_ALLOW_DEGRADED", True) + degraded = mp.Muse2APIProvider(provider.client) + assert degraded.capabilities.generate_video_r2v + assert degraded.check(ProviderJob(job_id="a", kind=KIND_VIDEO_REFS)) is None + + +def test_unconfigured_provider_is_unavailable(): + prov = mp.Muse2APIProvider(Muse2APIClient("")) + assert not prov.is_available() + assert "MUSE2API_URL" in prov.check(ProviderJob(job_id="a", kind=KIND_IMAGE)) + + +async def test_register_existing_image_mints_uuid(provider, start_image): + result = await provider.register_existing_image(start_image, name="Fox") + mid = result["data"]["media"][0]["name"] + assert _is_uuid(mid) + assert result["data"]["url"] == start_image + + missing = await provider.register_existing_image("file:///nope.png", name="Fox") + assert "not found" in missing["error"] + + +def test_registry_includes_muse2api(): + registry = ProviderRegistry(flow_client=None) + assert isinstance(registry.get("muse2api"), mp.Muse2APIProvider) + names = [p["name"] for p in registry.status()] + assert "muse2api" in names From 204c7b3597ec404524f690506d193786677b0266 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 30 Sep 2026 16:14:52 +0000 Subject: [PATCH 52/68] docs: muse2api needs its own service started from its repo Spell out that the muse2api gateway is a separate service Flow Kit does not ship or start: clone crisng95/muse2api, configure the browser driver, start it, import a muse.ai account, verify /readyz, then point Flow Kit at it with MUSE2API_URL / MUSE2API_KEY. Adds a pointer from Quick Start and the env-var table. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01MfvQsdxJhWw15u6Zm51YJM --- README.md | 101 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 6d0bfb16f..1fdec7d4a 100644 --- a/README.md +++ b/README.md @@ -260,6 +260,13 @@ token. Step 3 is not optional: Flow's project-creation endpoint went with the migration, so without a pinned project every request fails `NO_FLOW_PROJECT`. You can also pass `flow_project_id` per project on `POST /api/projects`. +**Using the Muse provider (`muse2api`)?** It needs a second service: the +[muse2api](https://github.com/crisng95/muse2api) gateway, cloned from its own +repo and started separately (default `http://127.0.0.1:18610`), with +`MUSE2API_URL` / `MUSE2API_KEY` exported before step 4. The Flow tab and +extension are not needed for muse2api requests. Full setup: +[Muse Media Provider](#muse-media-provider-provider-muse2api). + ### Configuration | Env var | Default | What it does | @@ -270,7 +277,7 @@ You can also pass `flow_project_id` per project on `POST /api/projects`. | `MEDIA_PROVIDER` | `flow` | `flow` (Google Flow via extension) or `assistant` (route all generation to the AI assistant). | | `ASSISTANT_PROVIDER_TIMEOUT_S` | `1800` | How long a request waits for a worker to complete its provider job before failing. | | `ASSISTANT_PROVIDER_POLL_S` | `15` | How often to poll the provider-job row while waiting for completion. | -| `MUSE2API_URL` | — | Base URL of a [muse2api](https://github.com/crisng95/muse2api) gateway. Setting it makes the `muse2api` provider available. | +| `MUSE2API_URL` | — | Base URL of a running [muse2api](https://github.com/crisng95/muse2api) gateway — a separate service you start from its own repo (see [Muse Media Provider](#muse-media-provider-provider-muse2api)). Setting it makes the `muse2api` provider available. | | `MUSE2API_KEY` | — | The gateway's `MUSE2API_API_KEY` (sent as `Authorization: Bearer`). | | `MUSE2API_IMAGE_MODEL` / `MUSE2API_VIDEO_MODEL` | `muse-image` / `muse-video` | Model ids sent to the gateway. | | `MUSE2API_VIDEO_SECONDS` | `8` | Clip length requested for i2v. | @@ -313,18 +320,94 @@ Renders through a [muse2api](https://github.com/crisng95/muse2api) gateway, whic exposes the muse.ai web app as an OpenAI-compatible API: ``` -Flow Kit worker ──> Muse2APIProvider ──HTTP──> muse2api ──> muse.ai +Flow Kit worker ──> Muse2APIProvider ──HTTP──> muse2api service ──> muse.ai + (this repo, :8100) (separate repo, :18610) +``` + +> **muse2api is a separate service — Flow Kit does not ship or start it.** +> Flow Kit only contains the client (`agent/services/muse2api_client.py`) and +> the provider adapter. Before using `provider: muse2api` you must clone the +> [muse2api repo](https://github.com/crisng95/muse2api), start its server, and +> keep it running alongside the Flow Kit server. With no gateway running, every +> muse2api request fails with `muse2api connection_error`. + +#### 1. Start the muse2api service (from its own repo) + +```bash +git clone https://github.com/crisng95/muse2api.git +cd muse2api +python3 -m venv .venv && source .venv/bin/activate # Python 3.10+ +pip install -e . +cp .env.example .env +``` + +Edit `.env`: + +| Variable | Set to | Why | +|----------|--------|-----| +| `MUSE2API_DRIVER` | `browser` | The default `mock` returns fake media — fine for a dry run, useless for real renders. | +| `MUSE2API_CHROMIUM_PATH` | path to Chromium/Chrome (or leave empty to auto-detect) | The browser driver drives muse.ai through Chromium. | +| `MUSE2API_API_KEY` | any secret | Flow Kit sends it as `MUSE2API_KEY`. Left empty, one is generated into `data/api_key`. | +| `MUSE2API_HOST` | `0.0.0.0` only if Flow Kit runs on another machine | Default `127.0.0.1` accepts local connections only. | + +Start it and leave it running (its own terminal, tmux, or a service manager): + +```bash +python -m muse2api # → http://127.0.0.1:18610 +# or, from the same folder: docker compose up -d --build (binds 0.0.0.0:18610) +``` + +Import at least one logged-in muse.ai account — the gateway renders nothing +without one. Export the cookies `hatch_sess`, `hatch_gw`, `hatch_vml` and +`hatch_native_auth_device` from a browser signed in to muse.ai: + +```bash +KEY=$(cat data/api_key) # or your MUSE2API_API_KEY +curl http://127.0.0.1:18610/admin/accounts \ + -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ + -d '{"label":"acc1","cookies":{"hatch_sess":"...","hatch_gw":"...","hatch_vml":"...","hatch_native_auth_device":"..."}}' + +curl -s http://127.0.0.1:18610/readyz +# {"ready": true, "driver": {...}, "accounts": {"available": 1, ...}} +``` + +`ready: false` or `accounts.available: 0` means Flow Kit requests will fail with +`no_account_available` — fix the gateway first. Account management, renewal and +the rest of the gateway's options are documented in the muse2api README. + +#### 2. Point Flow Kit at it + +Set these before starting the Flow Kit server (they are read once at startup — +restart after changing them): + +```bash +export MUSE2API_URL=http://127.0.0.1:18610 # where the gateway listens +export MUSE2API_KEY= +export DEFAULT_PROVIDER=muse2api # optional: make it the default ``` -The gateway owns the muse.ai accounts, pooling and failover; Flow Kit calls -`POST /v1/images/generations` for images and `POST /v1/videos` + +Check that Flow Kit sees it: + +```bash +curl -s http://127.0.0.1:8100/api/providers/status # muse2api → "available": true +``` + +`available: true` only means `MUSE2API_URL` is set — Flow Kit does not probe the +gateway. Use `/readyz` above to confirm the service itself is up. + +#### 3. Use it + +Pass `"provider": "muse2api"` on any request (or rely on `DEFAULT_PROVIDER`). +Flow Kit calls `POST /v1/images/generations` for images and `POST /v1/videos` + `GET /v1/videos/{id}` for i2v, sends input frames inline as data URLs (so the gateway may run on another host), and downloads every result into -`output/_shared/muse2api/` as a `file://` URL with a minted UUID `media_id`. Set -`MUSE2API_URL` and `MUSE2API_KEY`, then pass `"provider": "muse2api"` per request -or set `DEFAULT_PROVIDER=muse2api`. Supports image and i2v; no edit, upscale or -TTS, and no end frame or r2v unless `MUSE2API_ALLOW_DEGRADED=1`. Troubleshooting -lives in `/fk-provider`. +`output/_shared/muse2api/` as a `file://` URL with a minted UUID `media_id` — +so `/fk-refresh-urls` is never needed for it. + +Supports image and i2v; no edit, upscale or TTS, and no end frame or r2v unless +`MUSE2API_ALLOW_DEGRADED=1`. Entity reference images are not sent (muse.ai takes +none), so character consistency across scenes is weaker than on Flow. +Troubleshooting lives in `/fk-provider` and `/fk-doctor`. ### Post-production (provider-neutral) From be9e211db56333a7ac274c293bdff85a705ffdb1 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 30 Sep 2026 16:34:19 +0000 Subject: [PATCH 53/68] fix(db): serialize get_db()'s lazy connect (flaky "database table is locked") Two coroutines hitting get_db() before the connection existed both saw None and both connected; the second overwrote the global, so the first ran its PRAGMAs (including wal_checkpoint) on the second's connection while a statement was open on it. That failed intermittently with "sqlite3.OperationalError: database table is locked" in test_assistant_provider on CI (Python 3.10, also on main in run #33) and leaked a connection whose worker thread can keep the interpreter alive. Connect under a per-event-loop init lock (separate from _db_lock, which crud holds while calling get_db), set up a local, and publish it only when ready. Adds a regression test counting connect() calls under concurrent first callers; it fails without this change. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01MfvQsdxJhWw15u6Zm51YJM --- agent/db/schema.py | 44 +++++++++++++++++++++++++------- tests/unit/test_db_connection.py | 35 +++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 tests/unit/test_db_connection.py diff --git a/agent/db/schema.py b/agent/db/schema.py index 3f696daa9..68e3981bf 100644 --- a/agent/db/schema.py +++ b/agent/db/schema.py @@ -8,6 +8,11 @@ _db_connection: aiosqlite.Connection | None = None _db_lock = asyncio.Lock() +# Guards get_db()'s lazy connect. Separate from _db_lock because crud calls +# get_db() while holding that one. Rebuilt per event loop: a lock that has +# been waited on is bound to its loop, and pytest runs each test in a new one. +_db_init_lock: asyncio.Lock | None = None +_db_init_loop: asyncio.AbstractEventLoop | None = None SCHEMA = """ CREATE TABLE IF NOT EXISTS character ( @@ -356,17 +361,38 @@ async def init_db(): logger.info("Database initialized at %s", DB_PATH) +def _get_db_init_lock() -> asyncio.Lock: + global _db_init_lock, _db_init_loop + loop = asyncio.get_running_loop() + if _db_init_lock is None or _db_init_loop is not loop: + _db_init_lock = asyncio.Lock() + _db_init_loop = loop + return _db_init_lock + + async def get_db() -> aiosqlite.Connection: - """Return the shared database connection, creating it if needed.""" + """Return the shared database connection, creating it if needed. + + The first two callers used to race here: both saw None, both connected, + the second overwrote the global, and the first then ran its PRAGMAs on + the second's connection while a statement was open on it — failing with + "database table is locked" and leaking a connection (whose worker thread + keeps the interpreter alive). Connect under a lock, set up a local, and + publish it only once it is ready. + """ global _db_connection - if _db_connection is None: - _db_connection = await aiosqlite.connect(str(DB_PATH)) - _db_connection.row_factory = aiosqlite.Row - await _db_connection.execute("PRAGMA journal_mode=WAL") - await _db_connection.execute("PRAGMA foreign_keys=ON") - # Force WAL checkpoint so this connection sees all committed writes - # from previous processes (e.g. after hot-reload) - await _db_connection.execute("PRAGMA wal_checkpoint(PASSIVE)") + if _db_connection is not None: + return _db_connection + async with _get_db_init_lock(): + if _db_connection is None: + conn = await aiosqlite.connect(str(DB_PATH)) + conn.row_factory = aiosqlite.Row + await conn.execute("PRAGMA journal_mode=WAL") + await conn.execute("PRAGMA foreign_keys=ON") + # Force WAL checkpoint so this connection sees all committed writes + # from previous processes (e.g. after hot-reload) + await conn.execute("PRAGMA wal_checkpoint(PASSIVE)") + _db_connection = conn return _db_connection diff --git a/tests/unit/test_db_connection.py b/tests/unit/test_db_connection.py new file mode 100644 index 000000000..3cea2a539 --- /dev/null +++ b/tests/unit/test_db_connection.py @@ -0,0 +1,35 @@ +"""get_db() must open exactly one connection however many callers race it. + +Two racing first callers used to each open a connection, leak one, and run +PRAGMAs on the other mid-statement ("database table is locked" in +test_assistant_provider on CI). +""" +import asyncio + +from agent.db import schema + + +async def test_concurrent_first_calls_open_one_connection(test_db, monkeypatch): + await schema.close_db() + assert schema._db_connection is None + + real_connect = schema.aiosqlite.connect + opened = [] + + def counting_connect(*args, **kwargs): + conn = real_connect(*args, **kwargs) + opened.append(conn) + return conn + + monkeypatch.setattr(schema.aiosqlite, "connect", counting_connect) + + conns = await asyncio.gather(*(schema.get_db() for _ in range(8))) + + try: + assert len(opened) == 1 + assert all(c is conns[0] for c in conns) + finally: + # Close any extras so a failure here doesn't leak worker threads. + for conn in opened: + if conn is not schema._db_connection: + await conn.close() From cb1fd333ba08d3bff7bf71e238f4bde803f456f1 Mon Sep 17 00:00:00 2001 From: Khanh Date: Fri, 2 Oct 2026 12:06:53 +0700 Subject: [PATCH 54/68] fix(tts): fade and pad the OmniVoice tail so narration does not end mid-vowel OmniVoice returns audio that stops at the last voiced sample: zero release tail, final vowel clipped. Any pipeline that trims video to narrator length then cuts exactly where the voice is still ringing, which reads as an abrupt scene change. Fade the last 60 ms and append 0.4 s of silence inside the save path so every wav ends cleanly and downstream trims get a breath. --- agent/services/tts.py | 26 +++++++++++++++++++----- tests/unit/test_tts_scripts.py | 37 ++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/agent/services/tts.py b/agent/services/tts.py index 23b3bf574..5d8fcbea3 100644 --- a/agent/services/tts.py +++ b/agent/services/tts.py @@ -17,11 +17,27 @@ # Shared by both inline scripts. OmniVoice.generate() returns a list of 1-D # numpy arrays; torchaudio.save wants a 2-D (channels, samples) tensor, so # the raw item cannot be handed over as-is ("Expected 2D Tensor, got 1D"). -_TO_WAV_TENSOR = """ -def _to_wav_tensor(item): +# +# OmniVoice also stops at the very last voiced sample: no release tail, so the +# final vowel is clipped and a cut placed at wav end lands mid-sound. Fade the +# last TAIL_FADE_S down and append TAIL_PAD_S of silence so narration ends +# cleanly and downstream "trim to narrator length" leaves a natural breath. +TAIL_FADE_S = 0.06 +TAIL_PAD_S = 0.4 +_TO_WAV_TENSOR = f""" +TAIL_FADE_S = {TAIL_FADE_S} +TAIL_PAD_S = {TAIL_PAD_S} +def _to_wav_tensor(item, sample_rate): w = item if isinstance(item, torch.Tensor) else torch.as_tensor(item) w = w.detach().cpu().float() - return w.unsqueeze(0) if w.ndim == 1 else w + w = w.unsqueeze(0) if w.ndim == 1 else w + n = w.shape[1] + fade = min(int(TAIL_FADE_S * sample_rate), n) + if fade > 0: + w = w.clone() + w[:, n - fade:] *= torch.linspace(1.0, 0.0, fade) + pad = torch.zeros(w.shape[0], int(TAIL_PAD_S * sample_rate)) + return torch.cat([w, pad], dim=1) """ # Inline script template for TTS generation via subprocess @@ -44,7 +60,7 @@ def _to_wav_tensor(item): kwargs["speed"] = args["speed"] audio = model.generate(**kwargs) -torchaudio.save(args["output"], _to_wav_tensor(audio[0]), args["sample_rate"]) +torchaudio.save(args["output"], _to_wav_tensor(audio[0], args["sample_rate"]), args["sample_rate"]) print(json.dumps({"ok": True, "path": args["output"]})) """ @@ -73,7 +89,7 @@ def _to_wav_tensor(item): audio = model.generate(**kwargs) Path(item["output"]).parent.mkdir(parents=True, exist_ok=True) - torchaudio.save(item["output"], _to_wav_tensor(audio[0]), args["sample_rate"]) + torchaudio.save(item["output"], _to_wav_tensor(audio[0], args["sample_rate"]), args["sample_rate"]) info = torchaudio.info(item["output"]) duration = info.num_frames / info.sample_rate diff --git a/tests/unit/test_tts_scripts.py b/tests/unit/test_tts_scripts.py index f378d37ec..fac639c3a 100644 --- a/tests/unit/test_tts_scripts.py +++ b/tests/unit/test_tts_scripts.py @@ -69,7 +69,7 @@ def test_single_script_saves_1d_numpy_output_as_2d(fake_modules, tmp_path, capsy "model": "m", "text": "xin chào", "output": str(out), "sample_rate": 24000, }, capsys) assert result["ok"] is True - assert _FakeTorchaudio.saved == [(str(out), (1, 2400), 24000)] + assert _FakeTorchaudio.saved == [(str(out), (1, 2400 + int(tts_mod.TAIL_PAD_S * 24000)), 24000)] def test_batch_script_saves_1d_numpy_output_as_2d(fake_modules, tmp_path, capsys): @@ -79,7 +79,7 @@ def test_batch_script_saves_1d_numpy_output_as_2d(fake_modules, tmp_path, capsys "items": [{"id": "s1", "text": "xin chào", "output": str(out)}], }, capsys) assert results == [{"id": "s1", "ok": True, "path": str(out), "duration": 1.0}] - assert _FakeTorchaudio.saved == [(str(out), (1, 2400), 24000)] + assert _FakeTorchaudio.saved == [(str(out), (1, 2400 + int(tts_mod.TAIL_PAD_S * 24000)), 24000)] def test_scripts_honour_device_arg(fake_modules, tmp_path, capsys): @@ -98,3 +98,36 @@ def test_generate_speech_passes_configured_device(monkeypatch, tmp_path): import asyncio asyncio.run(tts_mod.generate_speech("hi", str(tmp_path / "o.wav"))) assert captured["device"] == "cuda" + + +class _FakeOmniVoiceHot(_FakeOmniVoice): + """Returns audio that is still loud at the very last sample — OmniVoice + stops exactly where the voice stops, so the final vowel gets clipped.""" + + def generate(self, **kwargs): + return [np.full(2400, 0.5, dtype=np.float32)] + + +def test_saved_wav_has_silent_tail_and_fade(fake_modules, tmp_path, capsys, monkeypatch): + torch = fake_modules + captured = {} + + def save(path, tensor, sample_rate): + captured["t"] = tensor + captured["sr"] = sample_rate + monkeypatch.setattr(_FakeTorchaudio, "save", staticmethod(save)) + ov = types.ModuleType("omnivoice"); ov.OmniVoice = _FakeOmniVoiceHot + monkeypatch.setitem(sys.modules, "omnivoice", ov) + + _run(tts_mod._TTS_SCRIPT, {"model": "m", "text": "hi", "output": str(tmp_path / "o.wav"), + "sample_rate": 24000, "ref_audio": None, "ref_text": None, + "instruct": None, "language": "vi"}, capsys) + t = captured["t"] + sr = captured["sr"] + assert t.shape[0] == 1 + assert t.shape[1] >= 2400 + int(0.3 * sr), "no silence appended after the voice" + assert float(t[0, -1].abs()) < 1e-6, "tail is not silent" + # the original last voiced sample must have been faded down, not hard-cut + assert float(t[0, 2399].abs()) < 0.05, "no fade-out before the pad" + # voice body (before the 60ms fade window) untouched + assert abs(float(t[0, 500]) - 0.5) < 1e-6 From 2f2c5d84281f712452f661c6c25fba49b0f4f3b1 Mon Sep 17 00:00:00 2001 From: Khanh Date: Fri, 2 Oct 2026 12:28:59 +0700 Subject: [PATCH 55/68] feat: honour scene.duration for Omni Flash clip length MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A scene whose narration runs 7.6s cannot breathe inside an 8s clip; the only post fix is a frozen last frame, which reads as a glitch. Pass scene.duration into job.extra and round it UP to the next supported Omni Flash step (4/6/8/10) in the provider — rounding down would clip the voice. Veo ignores the field. Defaults unchanged. --- agent/sdk/services/flow_provider.py | 18 ++++++++++++- agent/sdk/services/operations.py | 4 +++ tests/unit/test_video_model_family.py | 38 +++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/agent/sdk/services/flow_provider.py b/agent/sdk/services/flow_provider.py index 243efae93..60cc25db0 100644 --- a/agent/sdk/services/flow_provider.py +++ b/agent/sdk/services/flow_provider.py @@ -19,9 +19,25 @@ from agent.config import VIDEO_POLL_INTERVAL, VIDEO_POLL_TIMEOUT from agent.db import crud from agent.services.omni_flash import ( + OMNI_FLASH_VALID_DURATIONS, generate_omni_flash_first_frame_video, generate_omni_flash_first_last_video, ) + + +def _omni_duration(requested) -> int: + """Round a requested clip length up to the next Omni Flash step (4/6/8/10s). + + Rounding *down* would clip narration; anything past the max is capped. + None/0 falls back to OMNI_FLASH_DURATION_S. + """ + if not requested: + return int(config.OMNI_FLASH_DURATION_S) + want = float(requested) + for step in OMNI_FLASH_VALID_DURATIONS: + if step >= want - 1e-6: + return step + return OMNI_FLASH_VALID_DURATIONS[-1] from agent.sdk.services.provider_base import ( KIND_EDIT_IMAGE, KIND_IMAGE, @@ -390,7 +406,7 @@ async def _run_video(self, job: ProviderJob) -> dict: prompt=job.prompt, project_id=ex.get("project_id", "0"), scene_id=ex.get("scene_id", ""), - duration_s=int(ex.get("duration_s") or config.OMNI_FLASH_DURATION_S), + duration_s=_omni_duration(ex.get("duration_s")), resolution=ex.get("resolution") or config.OMNI_FLASH_RESOLUTION, aspect_ratio=ex.get("aspect", "VIDEO_ASPECT_RATIO_PORTRAIT"), user_paygate_tier=ex.get("tier", "PAYGATE_TIER_TWO"), diff --git a/agent/sdk/services/operations.py b/agent/sdk/services/operations.py index eb20e10f5..435b337ca 100644 --- a/agent/sdk/services/operations.py +++ b/agent/sdk/services/operations.py @@ -300,6 +300,10 @@ async def generate_scene_video(self, scene: dict, orientation: str, "end_media_id": end_id, "request_id": request_id, "model_family": model_family, + # Per-scene clip length (seconds). Omni Flash honours it (rounded + # up to 4/6/8/10); Veo ignores it. Lets a scene whose narration + # outruns the default be rendered longer instead of padded in post. + "duration_s": scene.get("duration"), "project_name": project.get("name") if project else "", "display_order": scene.get("display_order", 0), }, diff --git a/tests/unit/test_video_model_family.py b/tests/unit/test_video_model_family.py index 9c3942781..01f83f5b7 100644 --- a/tests/unit/test_video_model_family.py +++ b/tests/unit/test_video_model_family.py @@ -117,3 +117,41 @@ def test_flow_provider_rate_limits_come_from_env(monkeypatch): finally: monkeypatch.delenv("FLOW_MAX_CONCURRENT"); monkeypatch.delenv("FLOW_COOLDOWN_S") importlib.reload(config); importlib.reload(fp) + + +@pytest.mark.asyncio +async def test_generate_scene_video_passes_scene_duration_for_omni(): + """scene.duration (seconds) must reach the Omni Flash call so a scene whose + narration outruns the 8s default can be rendered at 10s instead of being + padded with a frozen last frame in post.""" + from agent.sdk.services.operations import OperationService + + captured = {} + + async def fake_run(self, job, provider=None): + captured.update(job.extra) + return {"data": {}} + + scene = {"id": "s1", "_project_id": "p1", "horizontal_image_media_id": "img-1", + "horizontal_image_url": "file:///x.png", "video_prompt": "walk", "display_order": 1, + "duration": 10} + with patch("agent.sdk.services.operations.crud") as crud, \ + patch("agent.sdk.services.operations._build_video_prompt", new=AsyncMock(return_value="p")), \ + patch.object(OperationService, "_run_provider_job", fake_run), \ + patch.object(OperationService, "_resolve_chain_end_url", new=AsyncMock(return_value=None)): + crud.get_project = AsyncMock(return_value={"user_paygate_tier": "PAYGATE_TIER_TWO", + "video_model_family": "omni_flash"}) + await OperationService.__new__(OperationService).generate_scene_video(scene, "HORIZONTAL") + assert captured["duration_s"] == 10 + + +@pytest.mark.asyncio +async def test_omni_flash_rounds_duration_up_to_supported_step(): + """Omni Flash only accepts 4/6/8/10s; a 8.8s request must become 10, never 8.""" + client = AsyncMock() + submitted = {"data": {"operations": [{"operation": {"name": "op"}, "status": "MEDIA_GENERATION_STATUS_PENDING"}]}} + with patch("agent.sdk.services.flow_provider.generate_omni_flash_first_frame_video", + new=AsyncMock(return_value=submitted)) as omni, \ + patch("agent.sdk.services.flow_provider._poll_operations", new=AsyncMock(return_value={"data": {}})): + await FlowProvider(client)._run_video(_job(model_family="omni_flash", duration_s=8.8)) + assert omni.await_args.kwargs["duration_s"] == 10 From 3604ad30f4e5e58d1b2cb85d33fbd1d3d571e661 Mon Sep 17 00:00:00 2001 From: TIENLV Date: Mon, 5 Oct 2026 21:28:46 +0700 Subject: [PATCH 56/68] feat: add flowkit agent, extension scripts, and testing utilities --- agent/api/flow.py | 50 + agent/main.py | 206 + agent/models.json | 10 +- agent/services/flow_batch.py | 65 +- agent/services/flow_client.py | 42 +- agent/worker/processor.py | 2 +- dashboard/package-lock.json | 33 +- docs/hong_nhat_novel.txt | 11305 +++++++++++++++++++++++++ extension/background.js | 263 +- extension/content.js | 92 +- extension/injected.js | 208 +- requirements.txt | 2 + scratch/captured_netlog.jsonl | 321 + scratch/check_chars.py | 7 + scratch/check_db.py | 18 + scratch/check_hijack.py | 4 + scratch/check_netlog.py | 8 + scratch/check_new_media.py | 18 + scratch/check_recent_assets.py | 32 + scratch/check_requests.py | 8 + scratch/compare_stream_chat.py | 30 + scratch/inspect_28_31.py | 14 + scratch/inspect_as29s.py | 13 + scratch/inspect_assets.py | 14 + scratch/inspect_c31.py | 22 + scratch/inspect_dump.py | 36 + scratch/inspect_items.py | 16 + scratch/inspect_new_asset.py | 18 + scratch/inspect_video.py | 18 + scratch/inspect_video_op.py | 16 + scratch/inspect_zzl.py | 10 + scratch/list_captures.py | 16 + scratch/orig_background.js | 1010 +++ scratch/parse_dump.py | 13 + scratch/parse_envelopes.py | 17 + scratch/parse_media.py | 17 + scratch/parse_netlog.py | 26 + scratch/patch_scene_0.py | 38 + scratch/pause_requests.py | 6 + scratch/poll_media.py | 39 + scratch/print_c31.py | 9 + scratch/project_media_dump.txt | 8 + scratch/run_eval.py | 17 + scratch/run_regen_scene_0_image.py | 36 + scratch/stream_chat_response.txt | 8 + scratch/submit_prompt.py | 22 + scratch/test_gen_image.py | 17 + scratch/test_gn0bre.py | 9 + scratch/test_parse.py | 16 + scratch/test_project_media.py | 22 + scratch/test_prompt_api.py | 38 + scratch/test_safe_prompt.py | 44 + scratch/test_stream_chat.py | 36 + scratch/test_stream_chat_intent.py | 27 + scratch/test_submit_ui.py | 21 + scratch/test_vn_prompt.py | 17 + scratch/update_scene_0_db.py | 52 + scratch/view_recent_captures.py | 9 + scripts/cancel_video_requests.py | 14 + scripts/check_3_ops.py | 13 + scripts/check_op.py | 9 + scripts/create_hong_nhat_entities.py | 72 + scripts/create_hong_nhat_scenes.py | 75 + scripts/created_entities.json | 9 + scripts/created_scenes.json | 252 + scripts/created_video.json | 19 + scripts/debug_op_lookup.py | 31 + scripts/inspect_flow_cache.py | 9 + scripts/inspect_processing.py | 10 + scripts/inspect_video_progress.py | 19 + scripts/populate_entities_via_api.py | 83 + scripts/search_db_ids.py | 17 + scripts/test_video_gen.py | 54 + scripts/update_scene1_video.py | 14 + scripts/upgrade_scene_1.py | 41 + tests/unit/test_flow_batch_golden.py | 7 +- tests/unit/test_video_reviewer.py | 13 +- 77 files changed, 15080 insertions(+), 172 deletions(-) create mode 100644 docs/hong_nhat_novel.txt create mode 100644 scratch/captured_netlog.jsonl create mode 100644 scratch/check_chars.py create mode 100644 scratch/check_db.py create mode 100644 scratch/check_hijack.py create mode 100644 scratch/check_netlog.py create mode 100644 scratch/check_new_media.py create mode 100644 scratch/check_recent_assets.py create mode 100644 scratch/check_requests.py create mode 100644 scratch/compare_stream_chat.py create mode 100644 scratch/inspect_28_31.py create mode 100644 scratch/inspect_as29s.py create mode 100644 scratch/inspect_assets.py create mode 100644 scratch/inspect_c31.py create mode 100644 scratch/inspect_dump.py create mode 100644 scratch/inspect_items.py create mode 100644 scratch/inspect_new_asset.py create mode 100644 scratch/inspect_video.py create mode 100644 scratch/inspect_video_op.py create mode 100644 scratch/inspect_zzl.py create mode 100644 scratch/list_captures.py create mode 100644 scratch/orig_background.js create mode 100644 scratch/parse_dump.py create mode 100644 scratch/parse_envelopes.py create mode 100644 scratch/parse_media.py create mode 100644 scratch/parse_netlog.py create mode 100644 scratch/patch_scene_0.py create mode 100644 scratch/pause_requests.py create mode 100644 scratch/poll_media.py create mode 100644 scratch/print_c31.py create mode 100644 scratch/project_media_dump.txt create mode 100644 scratch/run_eval.py create mode 100644 scratch/run_regen_scene_0_image.py create mode 100644 scratch/stream_chat_response.txt create mode 100644 scratch/submit_prompt.py create mode 100644 scratch/test_gen_image.py create mode 100644 scratch/test_gn0bre.py create mode 100644 scratch/test_parse.py create mode 100644 scratch/test_project_media.py create mode 100644 scratch/test_prompt_api.py create mode 100644 scratch/test_safe_prompt.py create mode 100644 scratch/test_stream_chat.py create mode 100644 scratch/test_stream_chat_intent.py create mode 100644 scratch/test_submit_ui.py create mode 100644 scratch/test_vn_prompt.py create mode 100644 scratch/update_scene_0_db.py create mode 100644 scratch/view_recent_captures.py create mode 100644 scripts/cancel_video_requests.py create mode 100644 scripts/check_3_ops.py create mode 100644 scripts/check_op.py create mode 100644 scripts/create_hong_nhat_entities.py create mode 100644 scripts/create_hong_nhat_scenes.py create mode 100644 scripts/created_entities.json create mode 100644 scripts/created_scenes.json create mode 100644 scripts/created_video.json create mode 100644 scripts/debug_op_lookup.py create mode 100644 scripts/inspect_flow_cache.py create mode 100644 scripts/inspect_processing.py create mode 100644 scripts/inspect_video_progress.py create mode 100644 scripts/populate_entities_via_api.py create mode 100644 scripts/search_db_ids.py create mode 100644 scripts/test_video_gen.py create mode 100644 scripts/update_scene1_video.py create mode 100644 scripts/upgrade_scene_1.py diff --git a/agent/api/flow.py b/agent/api/flow.py index 2a55935bb..ddeaae71f 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -470,3 +470,53 @@ async def upload_image(body: UploadImageRequest): raise HTTPException(_safe_status_code(result.get("status")), result.get("error", result.get("data"))) media_id = result.get("_mediaId") return {"media_id": media_id, "raw": result.get("data", result)} + + +@router.get("/debug-cache") +async def debug_cache(): + client = get_flow_client() + return { + "operation_media": client._operation_media, + "operation_projects": client._operation_projects, + "operation_polls": client._operation_polls, + } + + +@router.get("/debug-listing/{operation_id}") +async def debug_listing(operation_id: str, project_id: str = "594758cc-11f5-4f92-8b3c-1213686591f4"): + import agent.services.flow_batch as fb + client = get_flow_client() + if not client.connected: + raise HTTPException(503, "Extension not connected") + result = await client.batch_rpc( + fb.RPC_PROJECT_MEDIA, fb.project_media_request(project_id), + match=operation_id, timeout=30, + ) + raw = result.get("data") or "" + mid = fb.find_media_id_in_text(raw, operation_id) + return { + "operation_id": operation_id, + "matched_media_id": mid, + "raw_preview": raw[:1000], + } + + +@router.get("/debug-project-media") +async def debug_project_media(project_id: str = "594758cc-11f5-4f92-8b3c-1213686591f4"): + import re + import agent.services.flow_batch as fb + client = get_flow_client() + if not client.connected: + raise HTTPException(503, "Extension not connected") + result = await client.batch_rpc( + fb.RPC_PROJECT_MEDIA, fb.project_media_request(project_id), + match=None, timeout=60, + ) + raw = result.get("data") or "" + uuids = list(set(re.findall(r'[0-9a-fA-F-]{36}', raw))) + return { + "raw_length": len(raw), + "found_uuids_count": len(uuids), + "uuids": uuids, + "sample": raw[:2000] + } diff --git a/agent/main.py b/agent/main.py index 32bf03b3e..367df053e 100644 --- a/agent/main.py +++ b/agent/main.py @@ -166,6 +166,190 @@ async def ext_callback(request: Request): return {"ok": False, "reason": "no matching pending request"} +@app.post("/api/ext/reload") +async def ext_reload(): + """Trigger extension to reload its background service worker.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + for ws in list(client._extensions.keys()): + try: + await ws.send(json.dumps({"id": "reload-1", "method": "reload_extension"})) + except Exception: + pass + return {"ok": True} + + +@app.post("/api/ext/reload-flow-tab") +async def ext_reload_flow_tab(): + """Trigger extension to reload open Flow tabs.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + return await client._send("reload_flow_tab", {}) + + +@app.get("/api/ext/tabs") +async def ext_tabs(): + """List open Flow tabs from the extension.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + return await client._send("list_tabs", {}) + + +@app.get("/api/ext/debug-tab") +async def ext_debug_tab(): + """Inspect candidate Flow tab status.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + return await client._send("debug_tab", {}) + + +@app.get("/api/ext/test-captcha") +async def ext_test_captcha(action: str = "IMAGE_GENERATION"): + """Test reCAPTCHA minting via extension.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + return await client._send("solve_captcha", {"captchaAction": action}) + + +@app.get("/api/ext/test-project-media") +async def ext_test_project_media(): + """Test listing media from active Flow project.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + from agent.services import flow_batch as fb + pid = "594758cc-11f5-4f92-8b3c-1213686591f4" + freq = fb.project_media_request(pid) + res = await client.batch_rpc(fb.RPC_PROJECT_MEDIA, freq) + raw = res.get("data", "") + with open("scratch/project_media_dump.txt", "w", encoding="utf-8") as f: + f.write(raw) + images = fb.read_images(raw) if raw else [] + return { + "status": res.get("status"), + "error": res.get("error"), + "data_len": len(raw), + "images": [{"media_id": img.media_id, "url": img.url} for img in images[:10]], + } + + +@app.get("/api/ext/media-url") +async def ext_media_url(media_id: str): + """Fetch signed media URLs for a media_id.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + from agent.services import flow_batch as fb + freq = fb.media_request(media_id) + res = await client.batch_rpc(fb.RPC_MEDIA, freq) + raw = res.get("data", "") + urls = None + if raw: + try: + payload = fb.first_payload(raw, fb.RPC_MEDIA) + urls = fb.read_media_urls(payload, media_id) + except Exception as e: + logger.warning("Failed to parse media urls for %s: %s", media_id, e) + return { + "status": res.get("status"), + "error": res.get("error"), + "raw": raw, + "urls": {"video": urls.video, "image": urls.image} if urls else None, + } + + +@app.post("/api/ext/stream-chat") +async def ext_stream_chat(request: Request): + """Trigger image generation via FlowCreationAgentService/StreamChat.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + data = await request.json() + prompt = data.get("prompt") + if not prompt: + from fastapi import HTTPException + raise HTTPException(400, "prompt is required") + project_id = data.get("project_id") + res = await client.stream_chat(prompt, project_id=project_id) + return res + + +@app.post("/api/ext/submit-ui-prompt") +async def ext_submit_ui_prompt(request: Request): + """Type prompt into Flow web UI ProseMirror editor and click create button.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + data = await request.json() + prompt = data.get("prompt") + if not prompt: + from fastapi import HTTPException + raise HTTPException(400, "prompt is required") + return await client._send("submit_ui_prompt", {"prompt": prompt}) + + +@app.post("/api/ext/eval-tab") +async def ext_eval_tab(request: Request): + """Execute javascript in the active Flow tab's MAIN world and return result.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + data = await request.json() + return await client._send("eval_tab", {"code": data.get("code", "")}) + + +@app.get("/api/ext/find-actions") +async def ext_find_actions(): + """Find reCAPTCHA action names in Flow web scripts.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + return await client._send("find_actions", {}) + + +@app.post("/api/ext/netlog") +async def ext_netlog(request: Request): + """Capture raw batchexecute requests from Flow UI.""" + data = await request.json() + import pathlib + p = pathlib.Path("scratch/captured_netlog.jsonl") + p.parent.mkdir(parents=True, exist_ok=True) + with open(p, "a", encoding="utf-8") as f: + f.write(json.dumps(data) + "\n") + logger.info("Captured netlog: url=%s status=%s body_len=%d", + data.get("url"), data.get("statusCode"), len(data.get("body") or "")) + return {"ok": True} + + +@app.get("/api/ext/netlog") +async def ext_get_netlog(): + """Retrieve captured raw batchexecute requests.""" + import pathlib + p = pathlib.Path("scratch/captured_netlog.jsonl") + if not p.exists(): + return {"captures": []} + lines = [json.loads(line) for line in p.read_text(encoding="utf-8").splitlines() if line.strip()] + return {"captures": lines} + + + + @app.get("/health") async def health(): client = get_flow_client() @@ -229,6 +413,28 @@ async def dashboard_ws(websocket: WebSocket): event_bus.unsubscribe(q) +@app.post("/api/test-direct") +async def test_direct(request: Request): + from agent.services import flow_batch as fb + client = get_flow_client() + data = await request.json() + pid = data.get("project_id", "594758cc-11f5-4f92-8b3c-1213686591f4") + prompt = data.get("prompt") + ref_ids = data.get("ref_media_ids") + freq = fb.image_request( + prompt, pid, count=1, + aspect="IMAGE_ASPECT_RATIO_LANDSCAPE", + ref_media_ids=ref_ids, + ) + try: + res = await client._batch_payload(fb.RPC_GEN_IMAGE, freq, fb.CAPTCHA_IMAGE) + imgs = fb.read_images(res) + return {"ok": True, "count": len(imgs), "images": [img.__dict__ for img in imgs]} + except Exception as e: + logger.exception("test_direct failed: %s", e) + return {"ok": False, "error": str(e)} + + if __name__ == "__main__": import os import uvicorn diff --git a/agent/models.json b/agent/models.json index 7830223ec..67b9c1e4a 100644 --- a/agent/models.json +++ b/agent/models.json @@ -2,12 +2,12 @@ "video_models": { "PAYGATE_TIER_TWO": { "frame_2_video": { - "VIDEO_ASPECT_RATIO_LANDSCAPE": "veo_3_1_i2v_lite_low_priority", - "VIDEO_ASPECT_RATIO_PORTRAIT": "veo_3_1_i2v_lite_low_priority" + "VIDEO_ASPECT_RATIO_LANDSCAPE": "veo_3_1_i2v_lite", + "VIDEO_ASPECT_RATIO_PORTRAIT": "veo_3_1_i2v_lite" }, "start_end_frame_2_video": { - "VIDEO_ASPECT_RATIO_LANDSCAPE": "veo_3_1_i2v_lite_low_priority", - "VIDEO_ASPECT_RATIO_PORTRAIT": "veo_3_1_i2v_lite_low_priority" + "VIDEO_ASPECT_RATIO_LANDSCAPE": "veo_3_1_i2v_lite", + "VIDEO_ASPECT_RATIO_PORTRAIT": "veo_3_1_i2v_lite" }, "reference_frame_2_video": { "VIDEO_ASPECT_RATIO_LANDSCAPE": "veo_3_1_r2v_fast_landscape_ultra_relaxed", @@ -66,6 +66,6 @@ "veo_3_1_i2v_lite", "veo_3_1_i2v_s_fast_ultra" ], - "default": "veo_3_1_i2v_lite_low_priority" + "default": "veo_3_1_i2v_lite" } } diff --git a/agent/services/flow_batch.py b/agent/services/flow_batch.py index e2f41c00e..1c24e81f7 100644 --- a/agent/services/flow_batch.py +++ b/agent/services/flow_batch.py @@ -47,6 +47,7 @@ CAPTCHA_IMAGE = "IMAGE_GENERATION" CAPTCHA_VIDEO = "VIDEO_GENERATION" +CAPTCHA_CHAT = "CHAT_GENERATION" #: The extension substitutes a freshly minted reCAPTCHA token for this marker. #: It has to be a placeholder rather than a real token because the mint has to @@ -99,7 +100,7 @@ #: [tier][quality][aspect] and carried `…_portrait` / `…_fl` / `…_relaxed` #: variants; those are gone — aspect is its own slot now, and the suffixed #: names are rejected. -VIDEO_MODEL = "veo_3_1_i2v_lite_low_priority" +VIDEO_MODEL = "veo_3_1_i2v_lite" VIDEO_MODELS = { "veo_3_1_i2v_lite_low_priority", "veo_3_1_i2v_lite", @@ -334,9 +335,9 @@ def _client_uuid() -> str: return str(uuid.uuid4()).upper() -def _context(project_id: str) -> list: +def _context(project_id: str, asset_id: Optional[str] = None) -> list: """The surface/project/captcha envelope every generate call repeats.""" - return [None, SURFACE_ID, None, None, None, project_id, None, None, None, None, + return [None, SURFACE_ID, None, None, asset_id, project_id, None, None, None, None, [CAPTCHA_SLOT, 1]] @@ -357,7 +358,8 @@ def image_request(prompt: str, project_id: str, count: int = 1, prompts: Optional[list[str]] = None, model: str = IMAGE_MODEL, ref_media_ids: Optional[list[str]] = None, - base_media_id: Optional[str] = None) -> str: + base_media_id: Optional[str] = None, + asset_id: Optional[str] = None) -> str: """One request item per variant, exactly as the REST payload did it. There is no "how many" field: Flow returns one image per item in the list, @@ -371,6 +373,7 @@ def image_request(prompt: str, project_id: str, count: int = 1, resolved_model = resolve_image_model(model) base = seed if seed is not None else random.randint(1, 10**9) items = [] + target_asset = asset_id or base_media_id for index in range(count): text = prompts[index] if prompts and index < len(prompts) else prompt image_inputs = [] @@ -380,12 +383,26 @@ def image_request(prompt: str, project_id: str, count: int = 1, _reference(mid) for mid in (ref_media_ids or []) if mid != base_media_id ) items.append([None, None, image_inputs or None, base + index * 9973, ratio, - resolved_model, None, _context(project_id), [[[text]]], - None, None, None, _client_uuid(), _client_uuid()]) - return build_envelope(RPC_GEN_IMAGE, [None, items, 1, _context(project_id), + resolved_model, None, _context(project_id, target_asset), [[[text]]], + None, None, None, None, _client_uuid()]) + return build_envelope(RPC_GEN_IMAGE, [None, items, 1, _context(project_id, target_asset), [_client_uuid()]]) +STREAM_CHAT_PATH = "/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat" + + +def stream_chat_request(prompt: str, project_id: str, client_uuid: str | None = None) -> str: + """Build the f.req payload for FlowCreationAgentService/StreamChat.""" + cid = client_uuid or str(uuid.uuid4()) + inner = [ + cid, + [[[[prompt]]]], + [f"projects/{project_id}", None, [CAPTCHA_SLOT, 1], None, None, 9], + ] + return json.dumps([None, json.dumps(inner, separators=(",", ":"), ensure_ascii=False)], separators=(",", ":"), ensure_ascii=False) + + def image_upscale_request(media_id: str, resolution: str = "2K") -> str: """Build the current FlowService.UpsampleImage request (RPC SPrCad).""" key = str(resolution).strip().upper() @@ -666,14 +683,23 @@ def find_media_id(payload: Any, operation_id: str) -> Optional[str]: """Look an operation up in the project listing and take its media id. Entries look like - ``[opId, null, null, [title, created, null, null, mediaId, clientUuid, done], projectId]``. + ``[assetId, folderId, null, [title, [sec, nanos], isVideo, null, mediaId, opId, done], projectId]``. """ + op_lower = operation_id.lower() for node in _walk_lists(payload): - if len(node) < 4 or node[0] != operation_id: + if not isinstance(node, list) or len(node) < 4: continue detail = node[3] - if isinstance(detail, list) and len(detail) > 4 and isinstance(detail[4], str): - return detail[4] + if not isinstance(detail, list) or len(detail) <= 4: + continue + # 1. Match assetId directly + if isinstance(node[0], str) and node[0].lower() == op_lower: + if isinstance(detail[4], str): + return detail[4] + # 2. Match opId in detail[5] + if len(detail) > 5 and isinstance(detail[5], str) and detail[5].lower() == op_lower: + if isinstance(detail[4], str): + return detail[4] return None @@ -684,17 +710,16 @@ def find_media_id(payload: Any, operation_id: str) -> Optional[str]: def find_media_id_in_text(text: str, operation_id: str) -> Optional[str]: - """Same lookup as :func:`find_media_id`, but on an unparsed listing. - - The project listing has no page size that shrinks it and grows with every - generation, so it will outrun whatever response cap is in place — and a - truncated tail cannot be JSON-decoded even though the entry we want is - sitting in it intact. Scanning the text finds it anyway. - """ - start = text.find(operation_id) + """Same lookup as :func:`find_media_id`, but case-insensitive on unparsed listing.""" + lower_text = text.lower() + lower_op = operation_id.lower() + start = lower_text.find(lower_op) if start == -1: return None - match = _MEDIA_SLOT.search(text, start, start + 800) + # Search within window of match + window_start = max(0, start - 400) + window_end = min(len(text), start + 800) + match = _MEDIA_SLOT.search(text, window_start, window_end) return match.group(1) if match else None diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index 92c1b003f..ed304d1c4 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -487,6 +487,7 @@ async def _send(self, method: str, params: dict, timeout: float = 300) -> dict: async def batch_rpc(self, rpcid: str, freq: str, captcha_action: str | None = None, match: str | None = None, + custom_path: str | None = None, timeout: float = 300) -> dict: """Run one batchexecute RPC in the Flow page. Returns the raw body. @@ -500,8 +501,22 @@ async def batch_rpc(self, rpcid: str, freq: str, params["captchaAction"] = captcha_action if match: params["match"] = match + if custom_path: + params["customPath"] = custom_path return await self._send("batch_rpc", params, timeout=timeout) + async def stream_chat(self, prompt: str, project_id: str | None = None, timeout: float = 120) -> dict: + """Submit a prompt via FlowCreationAgentService/StreamChat.""" + pid = self._batch_project_id(project_id) + freq = fb.stream_chat_request(prompt, pid) + return await self.batch_rpc( + "StreamChat", + freq, + captcha_action="CHAT_GENERATION", + custom_path=fb.STREAM_CHAT_PATH, + timeout=timeout, + ) + async def _batch_payload(self, rpcid: str, freq: str, captcha_action: str | None = None, timeout: float = 300): @@ -549,11 +564,9 @@ def _remember_operation(self, operation_id: str, project_id: str): return if len(self._operation_projects) > 512: self._operation_projects.clear() - self._operation_media.clear() - self._operation_polls.clear() self._operation_projects[operation_id] = project_id - # ─── High-level API Methods ────────────────────────────── + # ─── High-Level Batch Methods ──────────────────────────────── def flow_project_id(self, requested: str | None = None) -> str | None: """The Flow project to attach a new Flow Kit project to, if any. @@ -573,14 +586,14 @@ async def create_project(self, project_title: str, tool_name: str = "PINHOLE") - logger.info("Reusing pinned Flow project %s for '%s'", pid[:12], project_title) return {"status": 200, "data": {"projectId": pid}} - async def generate_images(self, prompt: str, project_id: str, - aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT", - user_paygate_tier: str = "PAYGATE_TIER_TWO", - character_media_ids: list[str] = None, - image_model: str = None, - count: int = 1, - seed: int | None = None, - base_media_id: str | None = None) -> dict: + async def generate_images(self, prompt: str, project_id: str = None, + character_media_ids: list[str] = None, + aspect_ratio: str = "IMAGE_ASPECT_RATIO_PORTRAIT", + user_paygate_tier: str = "PAYGATE_TIER_TWO", + image_model: str = None, + count: int = 1, + seed: int | None = None, + base_media_id: str | None = None) -> dict: """Generate image(s). ``character_media_ids`` are attached as reference images, which is what @@ -837,9 +850,14 @@ async def _poll_batch_operation(self, operation_id: str) -> dict: media_id, complaint = await self._find_operation_media(operation_id) if not media_id: return _as_pending_operation(operation_id, error=complaint) + logger.info("Matched media_id=%s for op=%s", media_id, operation_id) self._operation_media[operation_id] = media_id - urls = await self._batch_media_urls(media_id) + try: + urls = await self._batch_media_urls(media_id) + except Exception: + self._operation_media.pop(operation_id, None) + raise if not urls.video: # The id landed but the clip is still being written; downloading # now would save the poster still instead of the video. diff --git a/agent/worker/processor.py b/agent/worker/processor.py index daff27e16..474a63a57 100644 --- a/agent/worker/processor.py +++ b/agent/worker/processor.py @@ -459,7 +459,7 @@ async def _handle_failure(rid: str, req: dict, result: dict, retry_after: dict = return # reCAPTCHA errors: retry up to 10 times — deferred dict in main loop handles delay - if "captcha" in error_lower or "recaptcha" in error_lower: + if "captcha" in error_lower or "recaptcha" in error_lower or "unusual_activity" in error_lower: retry = req.get("retry_count", 0) + 1 if retry < 10: await crud.update_request(rid, status="PENDING", retry_count=retry, error_message=str(error_msg)) diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index 3bceb38a9..1354717c0 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -66,6 +66,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -648,6 +649,17 @@ "integrity": "sha512-VYJy0uhFm9zTJ1TxBaW/pA8bjbOM/OttaNMwZ1RHG4JKyRG7DhSdiqD1ipQoAyoD22olUtxbP78W9xY3Wd11bg==", "license": "BSD-3-Clause" }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz", + "integrity": "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", @@ -3818,6 +3830,7 @@ "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -3826,8 +3839,9 @@ "version": "19.2.14", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", - "dev": true, + "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -3836,8 +3850,9 @@ "version": "19.2.3", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, + "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -3893,6 +3908,7 @@ "integrity": "sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.58.0", "@typescript-eslint/types": "8.58.0", @@ -4188,6 +4204,7 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4432,6 +4449,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", @@ -4839,7 +4857,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/debounce-fn": { @@ -5155,6 +5173,7 @@ "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -5919,6 +5938,7 @@ "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.0.tgz", "integrity": "sha512-jhunvfHWxd7J5EFfSgH4xsYJzSe/lfqbUCxiyyeaQasUsXeEHXtzVid+7EOGByc5JnFa23SSFL3Y2RV/z1T+eQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=16.9.0" } @@ -7605,6 +7625,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -7614,6 +7635,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -8511,8 +8533,9 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8704,6 +8727,7 @@ "integrity": "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", @@ -8874,6 +8898,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/docs/hong_nhat_novel.txt b/docs/hong_nhat_novel.txt new file mode 100644 index 000000000..2dbab1b64 --- /dev/null +++ b/docs/hong_nhat_novel.txt @@ -0,0 +1,11305 @@ +HỒNG NHẬT THĂNG LONG + +Definitive Edition V13.1 — Final Prose & Copyedit Pass + +ARC 1: 44 NGÀY TRƯỚC HỒNG NHẬT + +Chương 1: Ngày Trở Về + +Ở tầng hầm B3 Mễ Trì, mặt bê tông phơi nắng đã vượt 68°C; ngay trong bóng râm, mỗi hơi thở vẫn làm phổi đau rát. Lê Quốc Tiến nằm giữa những vết nứt khô, máu từ bụng thấm xuống nền. Túi nước rách, xác người và những mảnh nhựa cong vì nhiệt vây quanh hắn; mùi bê tông, máu và da cháy đặc lại trong không khí không lưu thông. + +Qua khe trần vỡ, mặt trời đỏ sẫm treo trên những khối nhà từng sáng đèn, bình thản như thể Hà Nội chưa bao giờ có tên người sống trong đó. + +Ngày 22 tháng 6 năm 2028, thế giới bắt đầu kết thúc. Nhân loại gọi ngày đó là **Hồng Nhật**. + +Ban đầu, nó chỉ là một hiện tượng thiên văn kỳ lạ. Mặt trời đổi màu, nhiệt độ tăng vọt, mạng xã hội ngập trong video quay bầu trời đỏ rực. Người ta tranh luận, chế ảnh, livestream, chờ chuyên gia lên tiếng. Vài ngày sau, mọi lời giải thích bắt đầu mất tác dụng. Điều hòa chạy hết công suất nhưng phòng vẫn nóng như lò hấp. Đường nhựa mềm ra dưới bánh xe. Hồ nước bốc mùi tanh. Cây cối chết khô từng mảng. Những khu dân cư đông đúc biến thành những khối bê tông giữ nhiệt khổng lồ. + +Tiến đã sống trong cái lò nung ấy suốt ba năm. + +Hắn từng đào bới trong đống đổ nát ở La Phù để tìm lương khô. Từng vượt qua khu Láng khi sông Tô Lịch chỉ còn một dòng bùn đen đặc quánh. Từng đứng bên bờ Hồ Tây đã cạn một nửa, nhìn thấy dưới đáy hồ những khối kim loại khổng lồ không thuộc về bất kỳ công trình nào của con người. Hắn cũng từng tin rằng chỉ cần mình đủ tỉnh táo, đủ tàn nhẫn, đủ hiểu cách vận hành điện, nước, máy phát, kho lạnh và hệ thống an ninh, hắn sẽ sống lâu hơn phần lớn những người khác. + +Hắn đã đúng. Nhưng sống lâu hơn không có nghĩa là sống sót đến cuối cùng. Tiếng bước chân vang lên từ cuối hành lang tầng hầm. Một người đàn ông đi qua những xác chết, đôi giày dính đầy bụi đỏ và máu khô. Khi hắn dừng lại trước mặt Tiến, bóng hắn che khuất phần ánh sáng đỏ rọi xuống từ khe trần. Tiến nhận ra khuôn mặt đó. + +Trong phương án Tiến đã sống, Kha xuất hiện ở La Phù từ những ngày đầu hỗn loạn. Tiến không chứng kiến mệnh lệnh đầu tiên tại kho phía đông; hắn chỉ thấy cánh cổng bị khóa, những thi thể nằm ngoài sân và các đoàn xe của Kha chở phần lương thực còn khô rời đi. Về sau, những sổ ghi chắp vá quy cho quyết định ấy hơn một trăm mạng người, còn lời đồn ngoài sổ nói con số lớn hơn nhiều. Kha cũng là kẻ truy sát Tiến gần một năm. + +Ký ức của một người bị săn không phải hồ sơ trung lập. Nhưng có một điều Tiến không thể đổ cho lời đồn: hắn đã nhìn thấy Kha đi qua người chết mà không ngoái lại. Người đàn ông cúi xuống, ánh mắt bình thản đến mức lòng thương hại trong đó còn đáng sợ hơn căm ghét. + +“Lê Quốc Tiến,” gã nói, giọng khàn đặc vì mất nước. “Mày vốn không nên sống lâu đến thế.” + +Tiến muốn cười, nhưng máu trào lên cổ họng, chỉ bật ra một tiếng khục khặc yếu ớt. Cái chết không phải điều khiến hắn day dứt nhất. Đến tận giây phút này, hắn vẫn không biết mẹ ở quê còn sống hay đã chết. + +Sau Hồng Nhật chưa đầy hai tuần, thông tin liên lạc giữa Hà Nội và các tỉnh gần như tê liệt. Từ ngày đó, Tiến không còn gọi được về Thanh Hóa. Hắn không biết mẹ có kịp tích nước không, thuốc huyết áp còn đủ không, căn nhà mái ngói ở quê có chống nổi những đợt nóng kéo dài như thiêu đốt hay không. + +Có những nỗi đau không cần nhìn thấy xác mới trở thành ám ảnh. Người đàn ông rút dao. Lưỡi dao phản chiếu ánh sáng đỏ thẫm từ bầu trời, rồi đâm xuống. Phập. Bóng tối nuốt chửng tất cả. Tiến mở mắt trong tiếng máy lạnh chạy đều đều. + +Hắn nằm bất động vài giây, toàn thân căng cứng như một con thú vừa thoát khỏi bẫy. Không có mùi máu. Không có mùi xác chết. Không có cái nóng làm phổi đau rát. Thứ chạm vào da hắn lúc này là luồng khí lạnh quen thuộc từ chiếc điều hòa cũ treo trên tường. + +Tiến bật dậy khỏi giường. + +Căn phòng trước mắt khiến hắn sững người. Chiếc tủ gỗ đặt sát tường, bàn làm việc gắn ba màn hình lớn, chồng hóa đơn tiền điện chưa thanh toán, cốc cà phê hòa tan uống dở từ tối qua, tất cả vẫn vẹn nguyên như cũ. Ngoài cửa sổ, tiếng xe máy, tiếng còi ô tô và tiếng rao bánh mì dưới ngõ vọng lên từng đợt, tạo thành thứ âm thanh hỗn độn mà hắn từng tưởng mình sẽ không bao giờ được nghe lại. + +Hắn với lấy điện thoại trên bàn. + +**09/05/2028.** + +**07 giờ 13 phút.** + +Đèn báo trên bộ lưu điện dưới bàn chớp đỏ đúng một lần. Điều hòa khựng chưa đầy một giây rồi chạy tiếp. Trong tai Tiến có một tiếng ù trầm, giống rung động truyền qua bê tông hơn là âm thanh. + +Hắn nhìn hàng số trên màn hình, hơi thở nghẹn lại trong lồng ngực. Ký ức cuối cùng của hắn là ngày 29 tháng 9 năm 2031, khi hắn trút hơi thở cuối cùng trong tầng hầm tối tăm tại Mễ Trì. Vậy mà bây giờ, hắn đang đứng trong căn hộ thuê ở quận Thanh Xuân, vào buổi sáng ngày 09 tháng 5 năm 2028. + +Tiến chưa biết điều gì đã xảy ra. Hắn chỉ biết mình đang mang ký ức của ba năm chưa xảy ra, trong cơ thể của buổi sáng cách Hồng Nhật đúng bốn mươi bốn ngày. + +Tiến bước tới cửa sổ, kéo rèm ra. Ánh nắng đầu hè tràn vào phòng, sáng đến mức khiến hắn phải nheo mắt. Bên dưới, đường Nguyễn Trãi đã bắt đầu đông nghịt xe máy; những chiếc áo chống nắng đủ màu lướt qua nhau trong tiếng còi xe gấp gáp. Xa hơn, đoàn tàu điện Cát Linh - Hà Đông chậm rãi trườn qua các dãy nhà cao tầng, bình thản như thể thế giới này sẽ còn tiếp tục thêm một trăm năm nữa. + +Hà Nội vẫn còn sống. Nhưng Tiến biết, sự bình yên ấy chỉ còn kéo dài đúng bốn mươi bốn ngày. Điện thoại trong tay hắn bất ngờ rung lên. Màn hình hiện một chữ: **Mẹ**. Tiến đứng chết lặng. + +Trong ba năm tận thế, hắn từng nghĩ mình đã quên gần hết những chuyện trước kia: mùi cơm nóng, tiếng mưa rơi trên mái tôn, cảm giác ngồi trong phòng có điều hòa, cả việc một người có thể gọi điện cho mẹ chỉ để nghe vài câu trách móc vụn vặt. Nhưng khi nhìn thấy chữ “Mẹ”, toàn bộ lớp vỏ lạnh lùng hắn tích cóp suốt ba năm bỗng nứt ra. + +Hắn hít sâu, bấm nghe. + +“Tiến à?” Giọng mẹ vang lên, vừa quen vừa xa như vọng về từ một đời khác. “Con dậy chưa? Mẹ gọi có làm phiền không?” + +Cổ họng Tiến nghẹn cứng. Hắn phải mất vài giây mới nói được. + +“Con dậy rồi.” + +“Giọng con sao thế? Ốm à?” + +“Không sao đâu mẹ. Chắc tối qua con thức hơi khuya.” + +“Lại làm việc đêm chứ gì. Mẹ bảo bao nhiêu lần rồi, tiền kiếm cả đời cũng không hết, sức khỏe mất là mất luôn đấy.” + +Tiến nhắm mắt lại. Câu nói ấy trước kia hắn nghe rất nhiều lần, nhiều đến mức có lúc còn thấy phiền. Nhưng sau ba năm tận thế, được nghe lại giọng trách móc quen thuộc ấy lại giống như một thứ xa xỉ không thể mua bằng bất cứ lượng nước sạch hay lương khô nào. + +“Mẹ dạo này huyết áp thế nào?” hắn hỏi. + +“Vẫn thế. Thuốc còn hơn nửa hộp. Sao tự nhiên hỏi kỹ vậy?” + +“Trời bắt đầu nóng rồi. Mẹ đừng ra đồng lúc trưa. Nước uống phải để sẵn trong nhà. Thuốc huyết áp, thuốc hạ sốt, thuốc đau bụng, mấy thứ cơ bản mẹ mua thêm giúp con. Đừng tiếc tiền.” + +Bên kia bật cười. + +“Anh này hôm nay lạ thật. Ở Hà Nội áp lực công việc quá à?” + +Tiến nhìn ra ngoài cửa sổ. Nắng đầu hè phủ vàng mặt đường, còn trong ký ức của hắn, cũng thứ ánh nắng ấy vài tháng nữa sẽ đốt cháy mọi thứ. + +“Con chỉ muốn mẹ giữ sức khỏe.” + +Giọng mẹ dịu xuống. + +“Mẹ biết rồi. Con ở trên đó cũng phải ăn uống cho tử tế. Có việc gì thì cứ gọi về.” + +“Vâng.” + +Sau khi cúp máy, Tiến vẫn giữ điện thoại trong tay cho đến khi màn hình tự tối. Cuộc gọi chỉ kéo dài vài phút, nhưng giống một sợi dây kéo hắn từ tầng hầm Mễ Trì trở lại thế giới người sống. Mẹ sẽ không tham gia vào cuộc chiến này; hắn cũng không muốn bà bị kéo vào. Điều hắn cần làm là chuẩn bị đủ nhanh, đủ kín và đủ chắc để khi mọi thứ sụp đổ, bà vẫn còn một đường sống ở quê. + +Tiến bật máy tính. Ba màn hình cùng sáng lên: bảng giám sát máy chủ, terminal kết nối vào hệ thống công ty, biểu đồ tải mạng, log cảnh báo từ một cụm server đặt tại Cầu Giấy. Trước Hồng Nhật, Lê Quốc Tiến chỉ là một kỹ sư hạ tầng hệ thống, kiểu người chuyên xử lý những thứ người khác chỉ nhớ đến khi chúng hỏng: điện dự phòng, máy chủ, camera, mạng nội bộ, hệ thống làm mát, lưu trữ dữ liệu và quyền truy cập. + +Sau Hồng Nhật, những thứ ấy quyết định ai được sống. + +Một thành phố sụp đổ không chết ngay. Nó để lại vô số mạch máu ngầm: đường điện cũ, kho lạnh bỏ hoang, bể nước ngầm, trạm bơm, camera, cửa cuốn, máy phát, cáp mạng, bản đồ hạ tầng. Người bình thường chỉ nhìn thấy đống đổ nát; Tiến nhìn thấy những hệ thống có thể được khởi động lại, chiếm quyền, tận dụng hoặc biến thành lá chắn. + +Hắn mở một file mới, đặt tên **KE_HOACH_HONG_NHAT.xlsx**. Dòng đầu tiên không phải “mua lương thực” hay “tích trữ nước”, mà là: + +**1. Gửi vật tư thiết yếu về quê trước ngày 22/06.** + +Sau đó, các dòng tiếp theo lần lượt xuất hiện. + +**2. Tìm căn cứ có kho kín, sân rộng, nguồn nước phụ và khả năng lắp điện độc lập.** + +**3. Tích trữ nước sạch tối thiểu cho mười hai tháng.** + +**4. Chuẩn bị điện mặt trời, ắc quy lưu trữ, máy phát dầu và nhiên liệu.** + +**5. Thu gom thuốc men, thiết bị y tế, vật tư làm mát.** + +**6. Điều tra Ngọc Trục, La Phù, khu Láng, trung tâm thương mại Đại Hà ở Hà Đông và Hồ Tây.** + +Ngón tay Tiến dừng lại ở hai chữ **Ngọc Trục**. + +Kiếp trước, trong giai đoạn đầu hỗn loạn, một kho hàng ở khu vực Ngọc Trục từng trở thành căn cứ tạm của một nhóm người sống sót. Vị trí ấy không quá xa trung tâm, lại có nhiều nhà xưởng nhỏ, đường gom và lối kết nối ra Đại lộ Thăng Long. Quan trọng hơn, theo lời đồn sau này, dưới khu kho đó có một tầng kỹ thuật cũ bị bỏ quên từ thời cải tạo công trình. + +Nếu chiếm được nơi ấy trước ngày 16 tháng 5, hắn sẽ có điểm khởi đầu tốt hơn bất kỳ ai. Tiến đang định mở bản đồ thì màn hình bên trái bỗng nhấp nháy. Một cửa sổ màu đen tự động bật lên. Không tiêu đề. Không biểu tượng. Không thuộc bất kỳ phần mềm nào hắn cài đặt. Trên nền đen, một dòng chữ đỏ sẫm hiện ra. + +**OBSERVER NODE HANOI-07 ACTIVE** + +Dòng thứ hai xuất hiện sau đó hai giây. + +**HOST DETECTED: LE QUOC TIEN** + +Tiến không nhúc nhích. + +Hắn từng nghe lời đồn về Trạm Quan Sát số 07 ở khu Láng trong kiếp trước, nhưng chưa từng thấy cái tên HANOI-07. Không ai từng nói nó là một hệ thống đang hoạt động. Không tài liệu nào trong các khu trú ẩn ghi lại việc nó có thể gọi tên một người vừa sống lại. + +Dòng cuối cùng hiện lên giữa màn hình. + +**DO YOU WANT TO SURVIVE?** + +Ngón tay Tiến dừng trên bàn phím. Sống sót? + +Ba năm trước, hắn từng muốn sống sót. Muốn có một góc trú ẩn, một ngụm nước sạch, một đêm không phải ôm dao ngủ. Nhưng sống sót thôi là chưa đủ. Sống sót không bảo đảm mẹ hắn còn đường sống ở quê. Sống sót không ngăn được La Phù biến thành bãi máu. Sống sót không cứu được những người bị nhốt trong Lò Hấp Hà Đông. Sống sót không trả lời được câu hỏi vì sao dưới đáy Hồ Tây lại tồn tại những thứ đáng lẽ không thuộc về thế giới này. + +Tiến đặt tay lên bàn phím. Hắn gõ từng chữ một. + +**I WANT TO WIN.** + +Enter. Màn hình vụt tắt. Tiến cúi xuống kiểm bộ lưu điện. Nhật ký chỉ có một dòng lạ, đóng dấu đúng **07:13:00**: + +**PHASE DROP — 0.8s / SOURCE UNRESOLVED** + +Khi hắn chạm vào dòng đó, nó biến mất khỏi danh sách đang hiển thị nhưng vẫn để lại một khoảng trống trong số thứ tự bản ghi. Tiến chụp màn hình, lưu vào ổ rời rồi mới ngẩng lên. Ngoài cửa sổ, Hà Nội vẫn ngập trong nắng đầu hè. Đoàn tàu điện Cát Linh - Hà Đông đi qua Nguyễn Trãi, tiếng rao bánh mì vọng lên dưới ngõ. Trên màn hình đã tối, bốn chữ hắn vừa gõ còn in mờ trong lớp lưu ảnh: + +**I WANT TO WIN.** + +Chương 2: Bản Đồ Sinh Tồn + +Ngày 10 tháng 5 năm 2028, Hà Nội nóng hơn dự báo ba độ. + +Bản tin thời tiết buổi sáng vẫn đọc bằng giọng bình thản: nắng nóng diện rộng, cao nhất 37–39°C, có nơi trên 40°C. Trong quán phở dưới chung cư, lời cảnh báo trôi giữa tiếng bát đũa và tiếng gọi thêm quẩy. Bà chủ lau mồ hôi trên cổ, nhìn tivi rồi chép miệng: “Năm nào chả nóng.” + +Tiến ngồi sát tường, ăn chậm và nhìn dòng người ngoài đường. Cảnh bình thường ấy giống một bức ảnh cũ mà hắn đã biết sẽ cháy. Một thành phố còn có thể than nóng là một thành phố còn sống. + +Ăn xong, Tiến lên phòng, tắt hết các kết nối không cần thiết rồi mở bản đồ Hà Nội trên màn hình lớn nhất. Hắn không chờ HANOI-07 xuất hiện lần nữa. Những thứ không kiểm soát được phải tạm đặt sang một bên. Thứ hắn kiểm soát được là bản đồ, tiền, kho, vật tư, thời gian và những quyết định không được phép chậm. + +Hắn tạo một lớp đánh dấu mới, đặt tên: **HANOI_SURVIVAL_MAP**. Điểm đầu tiên hắn khoanh là Hồ Tây. + +Trên bản đồ, Hồ Tây giống một khoảng xanh yên bình nằm giữa thành phố. Người bình thường nhìn thấy mặt nước, gió mát, quán cà phê ven hồ và những con đường đẹp để chạy bộ. Tiến nhìn thấy một cái nắp khổng lồ đang che thứ gì đó dưới đáy. Kiếp trước, nước hồ từng rút xuống với tốc độ bất thường, để lộ những khối kim loại tối màu nằm sâu dưới bùn. Chỉ bấy nhiêu ký ức đã đủ để hắn không muốn tiếp cận nơi ấy quá sớm. + +Hắn đánh dấu Hồ Tây bằng màu đỏ sẫm. Ghi chú ngắn: **Không tiếp cận sớm. Theo dõi từ xa.** Điểm thứ hai là khu Láng. + +Khu Láng hiện tại là một vùng dân cư đông đúc, nhiều ngõ nhỏ, nhiều nhà cũ xen nhà cao tầng. Người ngoài nhìn vào chỉ thấy một mảnh đô thị hỗn tạp bên cạnh dòng Tô Lịch đen ngòm. Nhưng sau tận thế, khi nước sông cạn gần hết, vài nhóm sống sót từng phát hiện những kết cấu bê tông lạ dưới lòng đất. Những người đi xuống đó về sau đều biến mất, chỉ để lại lời đồn về một cái tên: **Trạm Quan Sát số 07**. + +Tiến đánh dấu Láng bằng màu cam. Ghi chú: **Liên quan Trạm Quan Sát số 07. Không vào một mình.** Điểm thứ ba là La Phù. + +Nếu Hồ Tây là bí mật, Láng là nguy hiểm, thì La Phù là lương thực. Trước tận thế, nơi đó là thủ phủ hàng hóa phía Tây: bánh kẹo, đồ khô, nước đóng chai, kho bãi và xe tải. Sau Hồng Nhật, mọi kho hàng đều trở thành chiến trường. Người đến mua sẽ chuyển thành người đến cướp. Người giữ hàng sẽ chuyển thành người giữ mạng. + +Tiến đánh dấu La Phù bằng màu đỏ. Ghi chú: **Nguồn hàng lớn. Nguy cơ cao. Theo dõi xe tải ban đêm.** Điểm thứ tư là Ngọc Trục. + +Con trỏ chuột dừng lại ở đó lâu hơn những điểm khác. Ngọc Trục không nổi bật như Hồ Tây, không đông đúc như Láng, cũng không có lượng hàng hóa khổng lồ như La Phù. Nhưng chính vì thế, nó mới đáng giá. Khu vực này có nhiều kho nhỏ, nhà xưởng cũ, đường nội bộ đủ rộng cho xe tải, lại không nằm giữa tâm điểm chú ý trong những ngày đầu hỗn loạn. Nếu chọn đúng vị trí, một căn kho tại đây có thể được gia cố thành căn cứ kín, có sân chứa hàng, có chỗ lắp điện mặt trời, có đường rút ra Đại lộ Thăng Long. + +Hắn đánh dấu Ngọc Trục bằng màu xanh đậm. Ghi chú: **Mục tiêu ưu tiên. Phải kiểm soát trước 16/05.** Điểm cuối cùng là trung tâm thương mại Đại Hà ở Hà Đông. + +Không cần đọc lại ghi chú, Tiến vẫn nhớ nơi này sẽ trở thành gì. Trước Hồng Nhật, đó là một trung tâm thương mại lớn, sáng sạch, mát lạnh, đầy hàng hóa, tiếng trẻ con và mùi đồ ăn nhanh. Sau Hồng Nhật, khi nhiệt độ ngoài trời vượt 50°C, hàng nghìn người sẽ đổ về đó vì tin rằng trung tâm thương mại có điện, có nước, có điều hòa và có hàng hóa. Chính niềm tin ấy sẽ biến nơi đó thành một cái bẫy. + +Người sống sót về sau gọi nó là **Lò Hấp Hà Đông**. Tiến đánh dấu Đại Hà bằng màu đen. Ghi chú: **Khảo sát kho hàng, lối kỹ thuật, bãi xe, hệ thống điện dự phòng.** Đến gần trưa, bản đồ sinh tồn đầu tiên đã hình thành. Trên màn hình, Hà Nội không còn là một thành phố bình thường nữa. Nó là một mạng lưới các điểm nóng, các nguồn tài nguyên, các vùng chết và những bí mật chưa được mở ra. + +Tiến lưu bản đồ vào ổ cứng ngoài, mã hóa thêm một bản trên USB, rồi mở bảng tài sản. Tiền tiết kiệm, chứng khoán, hạn mức thẻ tín dụng, vài món đồ công nghệ có thể bán nhanh — tất cả được gom vào một file riêng. Trước tận thế, tiền là con số trong tài khoản. Sau tận thế, tiền chỉ còn giá trị trong khoảng thời gian rất ngắn trước khi mọi người nhận ra giấy bạc không đổi được nước. + +Hắn thử đặt một đơn nước đóng chai số lượng lớn qua một đầu mối cũ. Chưa đến mười phút sau, bên bán gọi lại, giọng ngập ngừng. + +“Anh lấy nhiều vậy để làm gì ạ?” + +“Công ty chuẩn bị sự kiện.” + +“Dạ, nhưng kho bên em không xuất một lần được nhiều thế. Nếu chia làm mấy đợt thì được.” + +“Chia đi. Người nhận khác nhau.” + +Đầu dây bên kia khựng lại. “Anh cho em xin thông tin công ty với mã số thuế được không ạ?” Hắn rà màn hình rồi xóa bớt một nửa số lượng trong đơn. + +“Thôi, trước mắt lấy ít đã.” + +Trở ngại nhỏ ấy nhắc Tiến rằng chuẩn bị ồ ạt cũng là một cách tự đánh dấu mình. Người bán có thể nhớ một giao dịch bất thường; nền tảng có thể gắn cờ một tài khoản mua quá nhiều. Kiếp trước hắn từng thấy một căn nhà bị vét sạch chỉ vì chủ nhà để người giao nước nhìn thấy kho phía trong. Lần này, hắn cần hàng — nhưng càng ít người nhớ mình càng tốt. Buổi chiều, Tiến rời căn hộ. + +Tiến tự lái chiếc xe cũ qua Nguyễn Trãi, nhập vào dòng phương tiện ùn từng đoạn. Nắng tháng năm phản trên kính xe và biển quảng cáo còn sáng. Người ta cau có vì nóng, tắc đường và đèn đỏ quá lâu — những phiền toái hơn một tháng nữa sẽ thành xa xỉ. + +Khi xe rẽ vào khu vực trung tâm thương mại Đại Hà ở Hà Đông, cảm giác quen thuộc của đời sống bình thường đập thẳng vào mắt hắn. Các gia đình dắt trẻ con qua đường. Những cặp đôi trẻ đứng chụp ảnh bên ngoài. Người giao hàng xếp hàng nhận đơn. Cửa kính tự động mở ra, thổi một luồng khí lạnh dễ chịu lên mặt những người vừa bước vào từ ngoài nắng. + +Trước cửa, Tiến dừng chân. Vẫn là nơi ấy; chỉ hơn một tháng nữa, người ta sẽ chen nhau vào đây để tránh chết vì nóng. + +Hắn lấy một chiếc xe đẩy, đi vào siêu thị ở tầng dưới. Bề ngoài, Tiến giống bất kỳ khách hàng nào đang mua đồ sinh hoạt: vài thùng nước, ít đồ hộp, pin, băng dính, túi rác loại dày, thuốc sát trùng, một ít thực phẩm khô. Nhưng mắt hắn không nhìn hàng hóa lâu. Hắn nhìn camera trên trần, nhìn cửa kho phía sau quầy, nhìn vị trí bình chữa cháy, nhìn lối nhân viên ra vào, nhìn bảng chỉ dẫn thoát hiểm. + +Kho lạnh nằm sâu hơn hắn nhớ. + +Lối giao hàng có vẻ đi từ phía sau khu siêu thị, nối ra khu vực bãi xe và đường nội bộ. Nếu ngày tận thế xảy ra, đây sẽ là nơi bị tranh cướp đầu tiên, vì hàng hóa sẽ không nằm trên kệ lâu. Người thông minh sẽ không lao vào quầy bán hàng. Người thông minh sẽ tìm kho. + +Khi đi qua khu vực đồ uống, Tiến dừng lại trước dãy nước đóng chai. Các thùng nước xếp cao, đầy đến mức trông như không bao giờ cạn. Một người phụ nữ trẻ đang đứng gần đó, cúi đầu xem nhãn sản phẩm trên chai nước khoáng. Áo sơ mi màu nhạt, tóc buộc gọn sau gáy, trên vai đeo một chiếc túi vải đã sờn mép. Bên cạnh cô là một chiếc máy ảnh và một tập tài liệu kẹp dưới khuỷu tay. + +Tiến lướt qua, rồi khựng lại vì một khuôn mặt tưởng đã nằm yên trong ký ức. Người phụ nữ kia ngẩng đầu đúng lúc ấy. Ánh mắt hai người gặp nhau giữa lối đi sáng trắng của siêu thị. Vẻ nghi hoặc trên mặt cô chậm rãi chuyển thành ngạc nhiên. + +“Lê Quốc Tiến?” + +Tiến không đáp ngay. + +Cái tên ấy được gọi bằng một giọng rất khác với những giọng nói trong ký ức tận thế. Không khàn đặc vì mất nước, không méo mó vì sợ hãi, không lạnh lùng vì muốn giết người. Nó trong trẻo, tỉnh táo, mang theo hơi thở của một đời sống đã bị hắn tưởng là chôn vùi từ lâu. + +“Trần Thanh Thủy,” hắn nói. + +Cô bật cười nhẹ, nhưng trong mắt vẫn còn vẻ bất ngờ. + +“Đúng là anh thật à? Em còn tưởng nhìn nhầm.” + +Đã năm năm rồi. + +Lần cuối Tiến gặp Thủy là lễ tốt nghiệp năm 2023. Họ từng tham gia một dự án sinh viên liên ngành mô phỏng sơ tán khi hầm kỹ thuật bị ngập và mất điện. Tiến phụ trách phần hạ tầng; Thủy phụ trách truyền thông rủi ro. Người tham gia phải đeo một vòng cảm biến đo nhịp tim, điện da và phản ứng khi còi cảnh báo đổi tần số. + +Thủy từng cãi với đơn vị tài trợ suốt ba tiếng vì biểu mẫu cho phép “tái sử dụng dữ liệu nghiên cứu cho mục đích an toàn hạ tầng” mà không ghi giới hạn thời gian hay bên nhận. Tiến khi đó chỉ quan tâm bộ cảm biến cứ mất tín hiệu ở đoạn hầm thứ ba. Hai người còn tranh nhau một câu trong kịch bản: “rủi ro thấp” hay “rủi ro chưa được chứng minh”. Sau lễ tốt nghiệp, ai cũng bị đời sống cuốn đi. + +“Anh vẫn ở Hà Nội à?” Thủy hỏi. + +“Ừ. Làm hệ thống ở Cầu Giấy.” + +“Em nhớ hồi trước anh cũng toàn ngồi sửa máy với dựng server cho nhóm.” Cô nhìn chiếc xe đẩy của hắn, hơi nhướng mày. “Mua nhiều nước thế?” + +Tiến liếc xuống những thùng nước trong xe. + +“Trời nóng. Mua để sẵn.” + +Thủy nhìn hắn lâu hơn cần thiết, như thể câu trả lời quá ngắn khiến cô chú ý hơn. Nhưng cô không hỏi tiếp, chỉ gật đầu. + +“Cũng đúng. Dạo này nóng bất thường thật.” + +Câu nói ấy khiến ánh mắt hắn dừng ở cô lâu hơn. + +“Em đang làm về thời tiết à?” + +“Không hẳn.” Thủy vỗ nhẹ lên tập tài liệu dưới tay. “Em làm phóng sự về môi trường đô thị. Nhiệt độ bề mặt, đảo nhiệt, cây xanh, bê tông hóa, mấy thứ nghe rất khô khan nhưng đủ khiến biên tập viên đau đầu.” + +“Điều tra ở siêu thị?” + +“Tránh nóng và làm việc ké điều hòa.” Cô cười, rồi chỉ về phía quán cà phê bên ngoài khu siêu thị. “Em ngồi ngoài kia. Đang chờ người gửi thêm dữ liệu.” + +Hắn dõi theo hướng cô chỉ. + +Quán cà phê nằm cạnh khoảng thông tầng. Trên bàn sát kính, chiếc laptop mở cạnh cốc cà phê đã tan gần hết; vài biểu đồ màu phủ lên một bản đồ nền quen thuộc. + +Bản đồ Hà Nội. Tiến im lặng một giây. + +“Anh còn ít việc,” hắn nói. “Ngồi được mười phút.” + +Hai người ra khỏi siêu thị, đi tới quán cà phê. Thủy chọn lại chiếc bàn cũ, đặt tài liệu xuống rồi ngồi đối diện hắn. Tiến gọi một cốc nước lọc thay vì cà phê. Trong khi nhân viên quay đi, mắt hắn lướt qua màn hình laptop của Thủy. Chỉ một cái nhìn. Nhưng đủ khiến đồng tử hắn co lại. Trên màn hình là một bản đồ nhiệt của Hà Nội. Một số khu vực có mức nhiệt bề mặt cao hơn bình thường, điều đó không lạ. Lạ là ba điểm có giá trị dị thường nhất lại trùng với những nơi Tiến vừa khoanh trên bản đồ sinh tồn của mình. + +**Ngọc Trục.** + +**Khu Láng.** + +**Hồ Tây.** + +Ba cái tên ấy nằm trên cùng một lớp dữ liệu, được nối với nhau bằng một đường mảnh gần như trong suốt. Tiến cầm cốc nước lên, uống một ngụm để che đi vẻ mặt. + +“Dữ liệu này của bên nào?” hắn hỏi bằng giọng bình thường nhất có thể. + +Thủy quay laptop lại một chút, nhưng không đủ để hắn nhìn toàn bộ. Trên màn hình chỉ là ảnh xuất đã cắt metadata; cửa sổ chứa dữ liệu gốc không mở. Tiến nhận ra ngay thói quen đó. Người làm điều tra đủ lâu sẽ không đặt nguồn sống còn cạnh một cốc cà phê chỉ vì gặp người quen cũ. + +“Một nguồn riêng. Chưa kiểm chứng hoàn toàn.” + +“Bản gốc ở đâu?” + +“Không ở máy này.” Thủy đáp. “Và anh đừng hỏi lần hai nếu chưa cho tôi lý do.” + +“Nhiệt bề mặt à?” + +“Ừ. Nhưng đảo nhiệt thường bám khu nhiều bê tông, ít cây xanh. Mấy điểm này…” Cô gõ nhẹ lên mép laptop. “Không khớp.” + +Tiến không hỏi tiếp. Hắn đã có câu trả lời mình cần. Thủy đang đứng trước một cánh cửa. Cô chưa biết phía sau là gì, nhưng đã tìm đúng tay nắm. Khi Tiến đứng dậy rời đi, Thủy gọi lại. + +“Tiến.” + +Hắn quay đầu. + +“Nếu anh biết gì về mấy điểm nhiệt bất thường này, em thật sự muốn nghe.” + +Trong đầu hắn hiện lên hình ảnh trung tâm thương mại Đại Hà ở Hà Đông sau này: cửa kính phủ hơi nước đục ngầu, người chen nhau trong bóng tối, tiếng đập cửa, tiếng khóc, tiếng cầu cứu bị bóp méo bởi sức nóng. Rồi hình ảnh ấy chồng lên người phụ nữ trước mặt, người đang ngồi trong ánh đèn êm dịu của quán cà phê, hoàn toàn chưa biết mình sắp bị kéo vào một tương lai không có lối ra. + +“Đừng ở lại đây quá lâu khi mất điện,” Tiến nói. + +Thủy cau mày. + +“Gì cơ?” + +“Không có gì.” + +Hắn quay người rời đi. Về đến căn hộ, Tiến bổ sung thông tin về Đại Hà vào bản đồ: vị trí kho, lối giao hàng, khu vực máy phát, bãi xe, số lượng cửa thoát hiểm nhìn thấy được. Sau đó hắn mở lại ba điểm Thủy đang theo dõi: Ngọc Trục, Láng, Hồ Tây. Ba điểm tạo thành một tam giác lệch về phía Tây thành phố. Nếu nối thêm La Phù và trung tâm thương mại Đại Hà ở Hà Đông, hình dạng trên bản đồ bắt đầu giống một cấu trúc lớn hơn, nhưng Tiến chưa xác định được nó là gì. Đúng lúc đó, màn hình phụ bên trái nhấp nháy. + +Một cửa sổ màu đen hiện lên. Không tiêu đề. Không biểu tượng. Dòng chữ đỏ xuất hiện ngắn gọn. + +**OBSERVER LOG #01** + +Bên dưới là một ảnh vệ tinh Hà Nội. Một vòng tròn đỏ đang bao quanh trung tâm thương mại Đại Hà ở Hà Đông. Dòng chữ tiếp theo hiện lên. + +**SUBJECT DETECTED: TRAN THANH THUY** + +Tiến chưa từng nhập tên Thủy vào máy tính. Chưa từng tìm kiếm cô. Chưa lưu số điện thoại. Chưa gửi email. Tấm danh thiếp của cô vẫn còn nằm trong ví hắn. Nhưng HANOI-07 đã biết. Bên dưới cái tên Trần Thanh Thủy, một dòng chữ mới chậm rãi hiện ra. + +**THERMAL ANOMALY MATCH FOUND** + +**NGOC TRUC – LANG – HO TAY** + +Dòng cuối cùng xuất hiện. + +**DO NOT LET HER ACCESS NODE 07 BEFORE 16/05/2028** + +Ánh mắt hắn dừng ở ngày tháng ấy. Ngày 16 tháng 5. Ngày Ngọc Trục. Trong ký ức ba năm của Tiến, buổi chiều này không có Thủy, không có chiếc laptop mở đúng ba địa danh và không có trạng thái **LISTENER CANDIDATE**. Sai lệch đầu tiên không phát ra tiếng. Nó chỉ ngồi lại trong hệ thống bằng tên của một người hắn từng biết. + +Chương 3: Người Điều Tra + +Trần Thanh Thủy không thích những sự trùng hợp. + +Trong nghề báo, đặc biệt là mảng điều tra môi trường, hai chữ “trùng hợp” thường chỉ là lớp vỏ bọc đẹp đẽ cho những thứ chưa được đào đủ sâu. Một con sông chuyển màu sau khi nhà máy mới đi vào hoạt động là trùng hợp. Một khu dân cư mắc bệnh hô hấp tăng đột biến sau khi bãi rác mở rộng là trùng hợp. Một báo cáo quan trắc bị mất đúng vào tháng có chỉ số ô nhiễm cao nhất cũng được gọi là trùng hợp, cho đến khi ai đó đủ kiên nhẫn tìm ra bản gốc. + +Vì thế, khi Thủy nhìn thấy Lê Quốc Tiến ở trung tâm thương mại Đại Hà ở Hà Đông, đứng trước kệ nước đóng chai với ánh mắt của một người đang tính toán đường thoát hiểm thay vì chọn hàng, cô biết đó không phải một cuộc gặp tình cờ đơn giản. Năm năm không gặp. + +Một người bạn cũ từ thời sinh viên bỗng xuất hiện tại đúng nơi cô đang điều tra. Anh ta mua nước, pin, băng dính, túi rác dày, thuốc sát trùng và thực phẩm khô. Những món đồ ấy nếu mua riêng lẻ thì rất bình thường, nhưng khi đặt cạnh nhau, chúng giống danh sách chuẩn bị cho một tình huống khẩn cấp hơn là đồ sinh hoạt cuối tuần. + +Điều kỳ lạ hơn là cách ánh mắt Tiến lướt qua màn hình laptop của cô. Chỉ một cái liếc mắt rất nhanh, nhưng Thủy đã kịp nhận ra. Anh đã nhìn thấy ba cái tên: **Ngọc Trục, Láng, Hồ Tây**. Và anh hiểu chúng quan trọng. + +Tối hôm đó, sau khi trở về căn hộ thuê gần đường Láng, Thủy không bật đèn ngay. Cô đặt túi vải xuống ghế, tháo máy ảnh khỏi vai rồi đứng lặng bên cửa sổ vài giây. Bên dưới, dòng xe vẫn dày đặc, ánh đèn pha kéo thành những vệt trắng đỏ trên mặt đường. Xa hơn, sông Tô Lịch nằm im dưới những tán cây thưa, đen và đặc như một vết mực cũ không thể tẩy khỏi thành phố. + +Cô bật đèn bàn, mở laptop rồi cắm ổ cứng ngoài. Màn hình hiện lên thư mục **DU_AN_NHIET_DO_HA_NOI_2028**. Bên trong là ảnh vệ tinh, dữ liệu bề mặt, bảng đo từ trạm khí tượng, bản ghi nhiệt độ theo giờ, tài liệu quy hoạch cây xanh, bản đồ bê tông hóa và những email trao đổi với vài nguồn tin không muốn nêu tên. + +Nếu chỉ nhìn bề ngoài, đây là một đề tài báo chí rất bình thường: “Đảo nhiệt đô thị và những nguy cơ sức khỏe tại Hà Nội trong mùa hè”. Một đề tài đủ nghiêm túc để được duyệt, nhưng không đủ nguy hiểm để khiến biên tập viên lo lắng. Ban đầu, Thủy cũng nghĩ vậy. Cho đến khi dữ liệu bắt đầu biến mất. + +Ở tòa soạn, đề tài này từng bị coi là khô. Buổi chiều trước khi cô đến Đại Hà, biên tập viên còn nói: “Em làm gì thì làm, đừng biến nó thành thuyết âm mưu. Nắng nóng năm nào chẳng có.” Thủy chỉ gật đầu, không tranh luận. Cô đã học được rằng tranh luận với người chưa nhìn thấy dữ liệu chỉ làm mình mất thời gian. + +Cô mở file tổng hợp mới nhất. Trên bản đồ nhiệt, các khu vực có mật độ bê tông cao như Cầu Giấy, Thanh Xuân, Hà Đông, Mỹ Đình đều có nền nhiệt bề mặt cao hơn vùng ven. Điều này bình thường. Nhưng ba điểm dị thường lại không tuân theo logic ấy. + +Ngọc Trục có nền nhiệt dao động bất thường vào ban đêm, cao hơn khu vực xung quanh dù mật độ xây dựng không đủ để giải thích. Khu Láng có những khoảng trống dữ liệu lặp lại theo chu kỳ ngắn, giống như có ai đó cắt bỏ đúng vài phút nhạy cảm nhất. Còn Hồ Tây, thay vì làm mát vùng xung quanh như một mặt nước lớn nên làm, lại xuất hiện những vòng tăng nhiệt rất nhỏ dưới bề mặt. + +Ba điểm. Ba kiểu bất thường khác nhau. Nhưng khi nối chúng lại, đường nối tạo thành một tam giác lệch về phía Tây thành phố. + +Thủy phóng lớn bản đồ, ngón tay vô thức gõ nhẹ lên mép bàn. Nếu đây là lỗi cảm biến, lỗi phải phân tán ngẫu nhiên hơn. Nếu là sai số vệ tinh, toàn vùng sẽ bị ảnh hưởng chứ không tập trung vào những điểm cụ thể. Nếu là đảo nhiệt đô thị, khu vực trung tâm mật độ cao phải nổi bật hơn. Nhưng ở đây, các điểm bất thường giống như bị ai đó cố tình giấu dưới một lớp dữ liệu đã được làm mượt. + +Tiếng chuông điện thoại kéo cô trở về hiện tại. Màn hình hiển thị tên: **Anh Duy – Trung tâm Dữ liệu Môi trường**. + +“Em nghe.” + +Đầu dây bên kia có tiếng gió và tiếng xe cộ, như thể người gọi đang đứng ngoài đường. + +“File em nhờ anh kiểm tra có vấn đề thật,” Duy nói nhỏ. “Nhưng anh không tiện nói lâu.” + +“Vấn đề gì?” + +“Dữ liệu nhiệt gốc và dữ liệu công khai không giống nhau. Bản công khai đã được xử lý lại, nhưng xử lý rất khéo. Nếu không so từng mốc thời gian thì khó phát hiện.” + +“Ai xử lý?” + +“Không rõ. Tài khoản thao tác không thuộc nhóm kỹ thuật thường trực.” + +“Có log không?” + +“Có, nhưng thiếu một phần. Anh chỉ xuất được mấy đoạn trước khi quyền truy cập bị khóa.” + +“Bị khóa từ lúc nào?” + +“Chiều nay.” + +Tay Thủy dừng lại trên bàn phím. Chiều nay. Sau khi cô gặp Tiến ở Đại Hà. + +“Anh gửi cho em được không?” + +“Anh gửi rồi. Nhưng Thủy này…” Giọng Duy thấp xuống. “Không giống một bài báo môi trường bình thường đâu. Có vài mã trạm anh chưa từng thấy. Một số không nằm trong danh sách quản lý công khai. Đặc biệt là cái mã HN-07.” + +Thủy ngừng gõ. HN-07. + +“Anh nói lại mã đó đi.” + +“HN-07. Trong một file khác nó ghi là HANOI-07. Anh không biết đây là tên dự án, tên trạm hay mã nội bộ. Tìm trong hệ thống chính thức không có.” + +“Anh còn truy cập được không?” + +“Không. Tài khoản của anh vừa bị hạ quyền. Anh nghĩ em nên dừng lại vài hôm.” + +“Không dừng được.” + +Duy thở dài. + +“Anh gửi những gì anh lấy được rồi. Sau cuộc gọi này đừng nhắn lại cho anh qua số này nữa.” + +Cuộc gọi ngắt. Thủy đặt điện thoại xuống, chờ màn hình tắt hẳn rồi mới mở hộp thư mã hóa. Một email mới nằm ở đầu danh sách, không tiêu đề, chỉ có một file nén đính kèm. Tên file: **raw_patch_0509.zip**. Cô tải file xuống, ngắt mạng, rồi mở trong môi trường máy ảo. Đó là quy trình nghề nghiệp cô đã giữ nhiều năm. Một file lạ có thể mang theo nhiều thứ hơn phần dữ liệu người gửi muốn cô nhìn thấy. + +Bên trong file nén có ba bảng dữ liệu nhiệt độ gốc, hai file log truy cập, một bản đồ các trạm quan trắc và một file văn bản có tên **observer_extract.txt**. Observer. Người quan sát. Cô mở file. Ban đầu chỉ là những dòng ký tự rời rạc, nhiều đoạn bị lỗi mã hóa hoặc bị che bằng chuỗi dấu vuông. Nhưng càng kéo xuống, cô càng thấy rõ một cấu trúc lặp lại: thời gian, tọa độ, mã điểm, trạng thái nhiệt, trạng thái đối tượng. + +Một số dòng nhắc đến Hồ Tây. Một số dòng nhắc đến Láng. Một số dòng nhắc đến Ngọc Trục. Rồi cô nhìn thấy một dòng khiến hơi thở khựng lại. + +**NODE: HANOI-07** + +Bên dưới là các mốc thời gian kéo dài từ nhiều năm trước. Có những đoạn ghi từ 2018, 2021, 2023, 2026. Dữ liệu không liên tục, nhưng đủ để chứng minh một điều: HANOI-07 không phải thứ mới xuất hiện trong vài tuần gần đây. Nó đã được theo dõi từ rất lâu, chỉ là không nằm trong bất kỳ hệ thống công khai nào. + +Thủy kéo tiếp. Một đoạn bị lỗi hiện ra: + +**THERMAL DEVIATION: LANG / HO TAY / NGOC TRUC** + +**DATE RANGE: 09/05/2028 – 16/05/2028** + +Ngày 09 tháng 5. Hôm nay. + +Cô nhìn dòng ngày tháng ấy, lồng ngực đột nhiên nặng xuống. Nếu đây là dữ liệu dự báo, nó quá cụ thể. Nếu là dữ liệu ghi nhận, tại sao lại có khoảng ngày kéo dài tới 16 tháng 5, một ngày chưa xảy ra? Nếu là mô phỏng, vì sao nó nằm trong log truy cập của hệ thống quan trắc thật? + +Thủy chụp ảnh màn hình, lưu vào ổ cứng rời. Sau đó cô mở file log thứ nhất. Các dòng truy cập dày đặc hiện ra. Phần lớn là mã tài khoản kỹ thuật và các tiến trình tự động. Nhưng có một số dòng được đánh dấu bằng nhãn **SUBJECT MATCH**. Thủy lọc riêng các dòng đó, sau đó sắp xếp theo thời gian. + +Kết quả có bảy mục. Ba mục bị che tên. Hai mục chỉ còn tọa độ. Một mục ghi **TRAN THANH THUY**. Và mục cuối cùng ghi: + +**LE QUOC TIEN** + +Con trỏ đứng yên trên cái tên ấy trước khi Thủy kéo dòng log sang phải. Bên cạnh tên Tiến là một chuỗi thông tin ngắn, nhiều ký tự bị lỗi. Một mã cũ khiến Thủy dừng lại: **BK23-EVAC-LQT**. Đó là quy ước đặt tên của dự án hầm ngập năm 2023, thứ đáng lẽ chỉ nằm trong kho dữ liệu của trường và đơn vị tài trợ. + +Ngay sau mã là dòng **PRECURSOR BASELINE MATCH**, rồi hai phần vẫn đọc được: + +**LOCATION: THANH XUAN** + +**STATUS: RETURNED / UNVERIFIED** + +Returned. Trở về. Từ này không nên xuất hiện trong bất kỳ tài liệu khí tượng hay môi trường nào. Cô đứng dậy, đi ra bếp rót một cốc nước. Khi quay lại bàn, ngón tay cô dừng trên số điện thoại của Tiến trong danh bạ. Nếu gọi ngay, cô sẽ để lộ rằng mình đã phát hiện ra điều gì đó. Nếu không gọi, cô có thể bỏ lỡ cơ hội duy nhất để hiểu chuyện đang xảy ra. + +Cuối cùng, Thủy không gọi. Cô mở một file ghi chú mới. Tên file: **LE_QUOC_TIEN.docx** Dòng đầu tiên cô nhập: + +**Gặp lại tại trung tâm thương mại Đại Hà ở Hà Đông sau 5 năm. Có biểu hiện biết trước rủi ro mất điện. Phản ứng bất thường khi nhìn thấy dữ liệu Ngọc Trục – Láng – Hồ Tây. Tên xuất hiện trong log HANOI-07 với trạng thái “RETURNED / UNVERIFIED”.** + +Cô nhìn dòng chữ ấy, rồi thêm một dòng nữa. + +**Không tiếp cận trực diện. Theo dõi trước.** + +Ngoài cửa sổ, đêm Hà Nội vẫn ồn ào như mọi khi. Xe máy chạy qua đường Láng, tiếng còi vọng lên từng đợt, mùi khói đồ nướng từ quán vỉa hè lẫn với hơi nóng còn sót lại sau một ngày dài. Thủy từng nghĩ công việc của mình là viết về những vấn đề khiến thành phố chậm rãi kiệt sức: ô nhiễm, thiếu cây xanh, bê tông hóa, sông hồ bị lấn chiếm, dữ liệu bị làm đẹp để phục vụ báo cáo. Nhưng những gì cô vừa nhìn thấy không giống một vấn đề đô thị. + +Nó giống một đồng hồ đếm ngược. Và ngày đồng hồ ấy dừng lại là **16 tháng 5**. + +Chương 4: HANOI-07 + +Sáng ngày 11 tháng 5, Tiến thức dậy trước chuông báo thức. + +Đêm qua hắn ngủ chưa đến ba tiếng. Mỗi lần nhắm mắt, ba cái tên trên màn hình laptop của Thủy lại hiện lên: **Ngọc Trục, Láng, Hồ Tây**. Những điểm đó không còn chỉ là ký ức của hắn nữa. Chúng đã xuất hiện trong dữ liệu của một người khác. + +Điều đó nguy hiểm hơn một cửa sổ lạ trên máy tính. Bí mật chỉ thuộc về Tiến còn có thể được khóa bằng im lặng; một bí mật đã để lại dấu trong hồ sơ của người khác thì không còn nằm trong tay hắn. + +Tiến bật máy tính, kiểm tra lại toàn bộ bản đồ sinh tồn. Hắn không mở cửa sổ đen nào, cũng không chờ HANOI-07 xuất hiện. Những thứ không thể kiểm soát thì tạm thời phải đặt sang một bên. Việc có thể kiểm soát được mới đáng để làm trước: tiền, kho, vật tư, vận chuyển, danh tính, rủi ro. + +Kiếp trước, Tiến từng thấy những người chuẩn bị khá hơn hàng xóm vẫn chết rất sớm. Một nhà có nước nhưng để lộ bể chứa bị phá cổng trong hai ngày. Một nhóm tích được đồ hộp nhưng đặt máy phát sát tường ngoài, tiếng máy kéo cả khu phố tới. Tích trữ chỉ là phần dễ thấy; giữ kín, phân phối và bảo vệ được thứ đã tích mới là phần khó. + +Vì thế, mua chưa phải việc đầu tiên. Trước hết, hắn phải che được thứ mình đang chuẩn bị. + +Tiến đăng nhập vào các tài khoản tài chính. Cổ phiếu được bán dần theo từng lệnh nhỏ, tiền tiết kiệm được rút một phần, hạn mức thẻ tín dụng được kiểm tra, vài món đồ công nghệ ít dùng được đưa lên chợ đồ cũ. Khi hắn đặt lệnh rút tiền mặt lần thứ hai, ứng dụng ngân hàng báo cần xác minh bổ sung do giao dịch bất thường. + +Tiến đọc lại dòng cảnh báo, ngón tay dừng trên nút xác nhận rồi hủy một nửa số tiền. Tiền không thiếu; thứ hắn cần giữ là sự vô hình. Hắn gọi ba cuộc điện thoại cho ba môi giới kho bãi khác nhau. + +Người đầu tiên giới thiệu vài kho ở Hoài Đức, giá rẻ nhưng quá lộ, đường vào rộng, xung quanh nhiều dân cư. Người thứ hai có kho ở gần La Phù, tiện lấy hàng nhưng nguy cơ cao vì sau tận thế nơi đó sẽ biến thành chiến trường. Người thứ ba nói có một kho cũ gần Ngọc Trục, diện tích không quá lớn, chủ đang cần cho thuê nhanh vì công ty logistics phá sản sau dịch nợ kéo dài. + +Tiến ngồi thẳng dậy. + +“Kho đó còn điện ba pha không?” + +Đầu dây bên kia là giọng một người đàn ông trung niên, nói nhanh và có vẻ sốt ruột. + +“Có. Nhưng lâu không dùng, chắc phải kiểm tra lại. Kho cũ rồi, anh thuê để chứa hàng nhẹ thì được. Xe tải nhỏ vào thoải mái, xe lớn thì hơi khó quay đầu.” + +“Có sân không?” + +“Có sân trong. Tường bao cũng còn. Nhưng chỗ đó hơi khuất, khách trước chê không tiện.” + +“Khuất là tốt.” + +Người môi giới cười. + +“Anh nói thế thì hiếm người nói lắm.” + +“Có giấy tờ mặt bằng không? Sơ đồ điện, nước, kết cấu xây dựng?” + +“Giấy tờ thuê thì có. Còn sơ đồ cũ chắc phải hỏi chủ. Nhưng tôi nói trước, kho này từng sửa mấy lần, hồ sơ không đủ đâu.” + +Tiến im lặng một giây. Hồ sơ không đủ. Tầng kỹ thuật bị bỏ quên. Mốc 16 tháng 5. Tất cả ghép lại thành một đường thẳng lạnh lẽo trong đầu hắn. + +“Khi nào xem được?” + +“Chiều nay cũng được.” + +“Không. Tôi muốn xem vào ngày 16.” + +Người môi giới khựng lại. + +“Ngày 16? Anh không xem trước à? Lỡ người khác thuê mất thì sao?” + +“Giữ cho tôi. Tôi chuyển cọc trước. Nhưng trong hợp đồng ghi rõ tôi có quyền kiểm tra hạ tầng bên dưới nền kho trước khi nhận bàn giao.” + +Đầu dây bên kia im lặng vài giây. + +“Cái đó phải hỏi chủ.” + +“Hỏi đi. Nếu đồng ý, trong hôm nay tôi chuyển cọc.” + +Cuộc gọi kết thúc. Đúng lúc đó, màn hình công việc bật thông báo đỏ: cụm server ở Cầu Giấy quá nhiệt nhẹ, hệ thống làm mát báo lỗi một quạt dự phòng. Trưởng nhóm gọi ngay sau đó. + +“Tiến, em xem giúp anh cụm CG-02. Log nhiệt nhảy kỳ lạ.” + +Cảnh báo làm một luồng lạnh chạy dọc gáy Tiến. Ngày thường, đây chỉ là sự cố hạ tầng. Nhưng trong bối cảnh hiện tại, mọi con số nhiệt độ đều khiến hắn cảnh giác. + +Hắn xử lý từ xa trong gần một giờ. Nguyên nhân chỉ là cảm biến phòng máy sai lệch sau khi thợ bảo trì thay quạt. Nhưng sự cố này nhắc hắn rằng công việc vẫn có thể kéo hắn ra khỏi kế hoạch bất kỳ lúc nào. Từ hôm nay đến 22/06, hắn không chỉ chạy đua với thảm họa. Hắn còn phải chạy đua với cuộc đời bình thường chưa chịu buông hắn ra. + +Đến gần trưa, Tiến nhận được email từ môi giới. Hồ sơ kho Ngọc Trục được gửi dưới dạng file PDF scan, chất lượng thấp, nhiều trang mờ, dấu đỏ cũ nhòe đi ở mép giấy. Hắn tải xuống, mở trong máy ảo rồi phóng lớn từng trang. + +Sơ đồ tổng thể khá đơn giản: một nhà kho chính, một sân trong, một dãy phòng nhỏ từng dùng làm văn phòng, cổng phụ phía sau dẫn ra đường nội bộ. Hệ thống điện ba pha được kéo từ trạm gần đó. Nước sử dụng từ đường ống khu vực, nhưng có ghi chú về một giếng khoan cũ đã bị bịt nắp. + +Tiến dừng ở phần ghi chú ấy. Giếng khoan cũ. Ở thời bình, đó là chi tiết không đáng kể. Sau Hồng Nhật, nó có thể là khác biệt giữa sống và chết. Hắn phóng tiếp vào phần nền kho. Bản vẽ kết cấu bị thiếu một góc. Ngay tại vị trí thiếu ấy, có một ký hiệu nhỏ gần như bị mực lem che mất. Hắn phải rà rất lâu mới nhận ra đó không phải ký hiệu xây dựng thông thường. Nó giống một vòng tròn có những tia ngắn tỏa ra. Một mặt trời. Đường nét không hoàn toàn giống hình ảnh trong ký ức của hắn, nhưng cấu trúc cơ bản trùng khớp. + +Ngọc Trục không chỉ là một căn cứ tốt. Nó đã được đánh dấu từ trước. Máy tính phát ra một tiếng “ting” rất nhỏ. Một email mới xuất hiện trong hộp thư phụ mà Tiến gần như không dùng đến. Người gửi trống. Địa chỉ không bị ẩn; trường người gửi hoàn toàn để trống. Tiêu đề chỉ có một chuỗi ký tự: + +**H07 / ACCESS WINDOW** + +Tiến ngắt mạng, chụp màn hình, sao lưu trạng thái hệ thống, rồi mở email trong môi trường cô lập. Nội dung thư chỉ có một ảnh đính kèm và ba dòng chữ. Ảnh đính kèm là ảnh vệ tinh Hà Nội. Độ phân giải cao hơn bất kỳ nguồn công khai nào hắn từng thấy. Ở giữa ảnh, một điểm đỏ đang nhấp nháy tại khu vực Ngọc Trục. + +Bên dưới ảnh là ba dòng chữ: + +**16/05/2028** + +**NODE DETECTED** + +**ACCESS POINT: NGOC TRUC** + +Tiến kiểm tra header thư. Không máy chủ gửi, không đường đi, không IP, không thời gian chuyển tiếp. Email tồn tại trong hộp thư của hắn như thể nó được đặt thẳng vào đó, bỏ qua toàn bộ hạ tầng Internet. + +Hắn in ảnh vệ tinh ra giấy, lấy bản đồ Hà Nội treo sau cửa xuống, rồi dùng bút nối các điểm đã biết: Hồ Tây, Láng, Ngọc Trục, La Phù, trung tâm thương mại Đại Hà ở Hà Đông. Nếu bỏ qua ý nghĩa địa lý thông thường, các điểm ấy tạo thành một cấu trúc giống mạng nút, trong đó Láng và Ngọc Trục là hai điểm giao, Hồ Tây là lõi lớn nhất. + +Một mạng lưới. Hoặc một phong ấn. Điện thoại rung. Lần này là môi giới kho bãi. + +“Anh Tiến à, chủ kho đồng ý giữ đến ngày 16. Nhưng họ bảo nếu anh muốn kiểm tra bên dưới nền kho thì phải ký thêm cam kết, tự chịu chi phí và không làm hư hỏng kết cấu.” + +“Được.” + +“Còn một việc nữa. Chủ kho bảo chỗ này trước đây từng có người hỏi mua đứt, không thuê. Người ta trả giá khá cao nhưng sau đó lại bỏ. Nghe nói bên đó không phải công ty logistics, mà là nhóm nghiên cứu gì đó.” + +“Có tên không?” + +“Không. Nhưng tôi thấy trong file cũ có một cái danh thiếp chụp lại. Để tôi tìm rồi gửi anh.” + +Cuộc gọi kết thúc chưa đầy một phút, môi giới gửi tới một bức ảnh chụp mờ. Tấm danh thiếp đặt trên mặt bàn gỗ, góc ảnh bị lóa sáng. Phần tên công ty bị che mất một nửa, nhưng logo phía trên vẫn còn nhìn được: một vòng tròn đỏ với những tia ngắn tỏa ra xung quanh. Biểu tượng mặt trời đỏ. Bên dưới logo là một dòng chữ tiếng Anh bị mờ, nhưng Tiến vẫn nhận ra hai từ cuối: + +**Observation Initiative** + +Sáng kiến Quan sát. Hắn rà tấm ảnh, ánh mắt tối lại. Có người đã tìm đến Ngọc Trục trước hắn. Không phải trong tương lai, mà trước cả khi Hồng Nhật xảy ra. + +Đêm đó, sau khi khóa cửa căn hộ và kéo rèm, Tiến nhận được một tin nhắn từ số lạ. Không có mã vùng. Không có tên người gửi. Chỉ có một dòng: + +**Mày không phải người duy nhất nhớ ngày đó.** + +Tin nhắn làm đồng tử hắn co lại. Căn phòng yên tĩnh. Bản đồ Hà Nội nằm im trên bàn. Ngoài kia, thành phố vẫn ngủ. Trên màn hình bản đồ, dấu định vị tại Ngọc Trục chớp một lần rồi tắt, như thể ở đầu bên kia vừa có người kiểm tra xem con đường còn mở hay không. + +Chương 5: Ngày Ngọc Trục + +Ngày 16 tháng 5 năm 2028 đến trong một buổi sáng oi đến bất thường. + +Mới hơn sáu giờ, mặt trời đã treo lơ lửng trên những dãy nhà phía Tây thành phố, ánh sáng trắng nhợt phủ lên mặt đường như một lớp bụi nóng. Tiến lái xe ra khỏi Thanh Xuân từ sớm, trong cốp xe có một túi dụng cụ, một máy đo nhiệt cầm tay, một camera nội soi công nghiệp, hai bộ khóa mới, một bộ phát Wi-Fi độc lập và một xấp giấy tờ đã được hắn sắp xếp theo thứ tự. + +Năm ngày qua, hắn gần như không ngủ quá bốn tiếng mỗi đêm. Tin nhắn từ số lạ vẫn nằm trong điện thoại. + +**Mày không phải người duy nhất nhớ ngày đó.** + +Thay vì đi thẳng tới kho, Tiến vòng qua hai tuyến đường, dừng ở một cây xăng gần Đại lộ Thăng Long, mua một chai nước rồi kiểm tra gương chiếu hậu và dòng xe phía sau. Không có chiếc nào bám theo quá lâu. Một xe tải nhỏ chở hàng điện máy rẽ vào đường khác. Hai xe máy giao hàng vượt lên rồi mất hút. Một chiếc sedan màu bạc chạy sau hắn gần mười phút, nhưng sau khi qua ngã rẽ về Đại Mỗ cũng đi thẳng. + +Chưa thấy đuôi. Nhưng chưa thấy không có nghĩa là không có. Tám giờ mười lăm, Tiến tới khu kho Ngọc Trục. + +Nơi này không có vẻ gì đặc biệt. Một con đường bê tông vừa đủ cho xe tải nhỏ, hai bên là nhà dân xen lẫn xưởng cơ khí, kho hàng cũ, bãi vật liệu và vài mảnh đất quây tôn. Xa hơn, tiếng máy cắt sắt rít lên từng hồi từ một xưởng nào đó. Mùi bụi, mùi dầu máy và mùi nắng nóng trên tôn cũ trộn lại thành thứ mùi đặc trưng của vùng ven đô: nửa công nghiệp, nửa làng xóm, vừa lộn xộn vừa kín đáo. + +Nếu nhìn bằng mắt người bình thường, đây là một kho hàng cũ, không đáng giá. Nếu nhìn bằng mắt của một người từng sống ba năm trong tận thế, đây là một cái khung căn cứ hiếm có. Một chiếc xe máy dừng trước cổng. Người môi giới bước xuống, dáng hơi thấp, bụng nhô ra dưới chiếc áo sơ mi kẻ. Ông ta lau mồ hôi trên trán, nhìn quanh rồi thấy xe của Tiến. + +“Anh Tiến đúng không?” + +“Đúng.” + +“Anh đến sớm thật. Chủ kho đang trên đường tới. Chỗ này hơi cũ, nhưng diện tích thật bên trong rộng hơn trong ảnh.” + +“Mấy tháng nay có ai vào xem chưa?” Tiến hỏi. + +“Một hai người thôi. Nhưng xem rồi không thuê. Chê xa, chê cũ, chê đường vào hơi khuất.” + +“Người từng hỏi mua đứt kho thì sao?” + +Nụ cười trên mặt người môi giới hơi khựng lại. + +“À, vụ đó tôi cũng chỉ nghe chủ nói. Bên kia đến xem nhanh lắm, không mặc cả nhiều, còn hỏi rất kỹ về nền kho với hồ sơ cũ. Nhưng sau đó lại bỏ.” + +“Họ bỏ hay chủ không bán?” + +“Cái này… tôi không rõ.” + +Tiến nhìn ông ta. Người môi giới tránh ánh mắt ấy, vội lấy điện thoại ra gọi chủ kho. + +Mười phút sau, một chiếc bán tải cũ chạy tới. Chủ kho là một người đàn ông ngoài năm mươi, da sạm nắng, tóc hoa râm, dáng gầy nhưng mắt khá tỉnh. Ông ta tự giới thiệu tên Lợi, trước đây làm vận tải, kho này từng cho một công ty logistics thuê, sau dịch kinh doanh khó khăn, khách trả mặt bằng rồi để trống đến giờ. + +“Anh thuê chứa hàng gì?” ông Lợi hỏi khi mở cổng. + +“Thiết bị điện và hàng tiêu dùng.” + +“Hàng dễ cháy không?” + +“Không nhiều. Nhưng tôi sẽ lắp thêm camera, khóa mới, gia cố một số điểm. Chi phí tôi tự chịu.” + +Ông Lợi liếc Tiến. + +“Anh kỹ tính nhỉ.” + +“Đồ của tôi cũng đáng tiền.” + +Cổng sắt mở ra, phát ra tiếng rít dài. Tiến bước vào sân. + +Kho Ngọc Trục yên lặng hơn bên ngoài rất nhiều. Tiếng máy cắt sắt, tiếng xe máy và tiếng người nói chuyện ngoài đường đều như bị tường bao chặn lại. Bên trong chỉ còn tiếng gió khô lùa qua mái tôn và tiếng bước chân vang nhẹ trên nền sân. Nắng chiếu xuống mặt bê tông, nhưng có vài vị trí nhiệt độ thấp hơn xung quanh một cách bất thường, tạo thành những mảng màu rất khó nhận ra bằng mắt thường. + +Nhà kho chính rộng khoảng hơn một nghìn mét vuông. Bên trong trống gần hết, chỉ còn vài kệ sắt cũ, thùng carton mốc, một xe nâng hỏng và ít pallet gỗ mục xếp sát tường. Trần kho cao, mái tôn có lớp cách nhiệt cũ đã bong từng mảng. Tường phía Tây có vết nứt dài, nhưng chưa ảnh hưởng kết cấu. + +Tiến đi chậm, không bỏ sót góc nào. Hắn dùng đèn pin soi ổ điện, kiểm tra tủ điện, mở nắp hộp kỹ thuật, nhìn đường ống nước cũ chạy sát tường. Hệ thống điện xuống cấp nhưng chưa hỏng hoàn toàn. Nếu thay dây chính, lắp tủ riêng và đặt thêm máy phát, nơi này có thể vận hành độc lập. + +“Nước thì sao?” Tiến hỏi. + +“Đường nước vẫn có. Nhưng lâu không dùng, phải xúc rửa bể.” + +“Trong hồ sơ có ghi giếng khoan cũ.” + +Ông Lợi miết ngón tay dọc mép chùm chìa khóa, chưa trả lời ngay. + +“À, cái đó lâu lắm rồi. Từ đời chủ trước. Bịt lại rồi.” + +“Ở đâu?” + +Ông Lợi chỉ về phía sân sau. + +“Gần dãy văn phòng. Nhưng tôi nói trước, nước đó chưa chắc dùng được. Anh muốn khoan lại thì phải xin phép.” + +Sau gần một giờ kiểm tra, họ ngồi xuống chiếc bàn gỗ cũ trong phòng văn phòng nhỏ để ký hợp đồng. Tiến đọc từng trang, sửa ba điều khoản: quyền lắp đặt thiết bị an ninh, quyền cải tạo hệ thống điện nước bằng chi phí bên thuê, và quyền kiểm tra hạ tầng ngầm trong phạm vi không làm ảnh hưởng kết cấu chính. + +Ông Lợi nhíu mày. + +“Anh định đào bới gì à?” + +“Không. Tôi chỉ cần kiểm tra nền trước khi đưa hàng vào. Hàng điện tử sợ ẩm, sợ sụt lún.” + +Chủ kho vẫn hơi do dự. Nhưng khoản tiền thuê sáu tháng trả trước đủ khiến ông ta đặt bút ký. Trước khi đi, ông Lợi quay lại nhìn kho một lần, vẻ mặt có chút phức tạp. + +“Anh Tiến này.” + +“Vâng?” + +“Nếu không cần thiết thì đừng động sâu xuống nền phía sau kho.” + +“Vì sao?” + +Ông Lợi im lặng một lát rồi cười gượng. + +“Không có gì. Chỗ cũ ấy mà. Đụng vào lại phát sinh chuyện sửa chữa.” + +Câu trả lời không tự nhiên. Không hẳn là nói dối, nhưng rõ ràng ông ta biết điều gì đó về phần nền phía sau kho. Cổng sắt khép lại. Kho Ngọc Trục chỉ còn một mình Tiến. + +Hắn lập tức thay ổ khóa cổng, khóa cửa chính và kiểm tra quanh tường bao thêm một lần. Sau đó, hắn lắp một camera hành lang tạm thời ở góc sân, cảm biến cửa ở cổng phụ và một bộ ghi hình độc lập dùng pin, không nối mạng. Hắn không tin Internet, không tin camera đám mây, càng không tin bất kỳ thứ gì có thể bị HANOI-07 chạm tới. + +Sau khi đảm bảo không có ai trong kho, Tiến bắt đầu kiểm tra nền. + +Máy đo nhiệt cầm tay lướt chậm trên mặt bê tông. Phần lớn nền kho có nhiệt độ tương đương nhau, cao hơn trong nhà bình thường vì mái tôn giữ nhiệt. Nhưng ở khu phía sau, gần bức tường giáp sân hẹp, nhiệt độ thấp hơn khoảng 1,8°C. Chênh lệch không lớn, nhưng đủ bất thường trong một không gian kín như thế này. + +Tiến đánh dấu bằng phấn. + +Hắn lấy búa cao su gõ nhẹ lên nền. Âm thanh ở các vị trí đầu tiên đặc và nặng. Đến điểm thứ sáu, tiếng gõ bỗng chuyển sang rỗng hơn một chút. Người bình thường có thể bỏ qua, nhưng với người từng tìm đường sống trong những công trình đổ nát, âm thanh đó rõ như tiếng gõ vào cửa. + +Bên dưới có khoảng trống. Hắn không phá nền ngay. + +Thay vào đó, hắn đi ra sân sau kiểm tra vị trí giếng khoan cũ. Nắp giếng là một tấm bê tông tròn nằm sát dãy văn phòng, phủ bụi và cỏ dại khô. Tiến dùng xà beng cạy nhẹ, phát hiện nắp đã được chèn bằng một vòng kim loại hàn kín. Hàn rất chắc. Cách bịt này không giống việc làm tạm của chủ kho; nó gần với một thao tác niêm phong. + +Hắn dùng tay phủi lớp bụi trên vòng kim loại. Một vết khắc mờ hiện ra. Đó không phải chữ, mà là một vòng tròn nhỏ với những tia ngắn tỏa ra xung quanh. Mặt trời đỏ. Đến lúc này, hắn không còn nghi ngờ nữa. Dù thứ nằm dưới Ngọc Trục là gì, nó đã được che giấu từ trước khi nhà kho này trở thành nhà kho. + +Tiến quay lại trong kho. Sau gần hai mươi phút kiểm tra, hắn phát hiện một kệ sắt cũ ở góc tường phía Tây bị bắt vít xuống nền bằng loại bu lông lớn bất thường. Kệ đã gỉ, các thanh ngang cong vênh, nhưng chân kệ lại quá chắc. Không ai cần cố định một kệ hàng mục như vậy nếu bên dưới nó không che thứ gì đó. + +Hắn tháo từng con bu lông. Công việc mất gần bốn mươi phút. Mồ hôi thấm ướt lưng áo, bụi sắt bám đầy tay, nhưng hắn không dừng. Khi chân kệ cuối cùng được nhấc ra, một đường viền chữ nhật hiện lên trên mặt nền. Đó không phải nắp hầm thông thường, mà là một tấm kim loại lớn phủ lớp bê tông mỏng. + +Tiến dùng xà beng cạy mép. Lớp bê tông vỡ ra thành từng mảng, để lộ bề mặt kim loại tối màu bên dưới. Trên tấm kim loại có những vệt khắc rất nông, gần như bị mài phẳng theo thời gian. Hắn lau sạch bụi, chiếu đèn pin ở góc nghiêng. Ký hiệu mặt trời đỏ hiện ra rõ ràng. Một vòng tròn nằm giữa tấm kim loại, xung quanh là mười hai tia ngắn. Bên dưới vòng tròn có hai chữ cái và hai con số: + +**HN-07** + +Tiến đứng im. HANOI-07 không phải chỉ là một dòng chữ trên màn hình. Nó có vật thể thật. Nằm dưới chân hắn. + +Hắn không chạm vào ngay. Trước hết Tiến dựng camera quay toàn cảnh, đặt máy ghi âm tách nguồn ở phía đối diện, dùng bút thử điện và đồng hồ đo kiểm mép kim loại, rồi đánh dấu vị trí nắp bằng phấn để biết nó có dịch chuyển khi hắn quay lưng. Một đồng hồ cơ được đặt mốc mười lăm phút; quá thời gian đó, hắn sẽ rút lên bất kể phát hiện được gì. Hắn còn chèn một thanh thép ngang mép nắp — không phải để giữ được một cơ cấu mạnh hơn mình, mà để có dấu vật lý nếu cơ cấu tự đóng. + +Khóa không dùng ổ thông thường. Ở mép phải có một hõm tròn vừa bằng lòng bàn tay, bên trong là bề mặt lạnh và nhẵn như đá mài. Tiến thử bằng găng cách điện trước. Không phản ứng. Hắn đo lại nhiệt, không thấy điện thế rõ ràng. Chỉ sau khi loại được những nguy cơ đơn giản nhất, hắn mới tháo găng và đặt tay trần lên bề mặt. Ngay khoảnh khắc da chạm vào bề mặt lạnh, toàn bộ thiết bị điện tử trong túi hắn tắt phụt. Trong kho, ánh sáng đột nhiên tối đi. Kho vốn chưa bật điện. Chính ánh nắng ngoài cửa dường như bị hạ xuống một tầng, khiến không gian xám đi trong vài giây. + +Trên tấm kim loại, những đường khắc bắt đầu sáng lên. Không phải ánh sáng điện, mà là một màu đỏ sẫm, âm ỉ như than dưới lớp tro. Từ vòng tròn trung tâm, các tia ngắn lần lượt phát sáng. Một tia, hai tia, ba tia. Đến tia thứ bảy, ánh sáng dừng lại. + +Tấm kim loại hé ra một khe hẹp. Không khí lạnh từ bên dưới tràn lên. Tiến không xuống ngay. Hắn đưa đầu đo khí xuống trước, chờ đủ một phút: oxy thấp hơn ngoài kho nhưng chưa tới ngưỡng phải rút, không báo khí cháy hay CO bất thường. Sau đó hắn dùng đèn pin dự phòng soi xuống. Bên dưới là một cầu thang kim loại hẹp, dốc vừa phải, kéo sâu vào bóng tối. Hai bên tường không phải bê tông thô, mà là một loại vật liệu xám nhẵn, không thấy mối nối. + +Hắn lấy dao gấp, đèn pin, máy ghi âm dự phòng và một sợi dây dù. Một đầu dây buộc vào chân kệ sắt còn lại, đầu kia qua khóa nhả nhanh ở thắt lưng để không biến dây an toàn thành cái bẫy nếu cơ cấu kéo. Camera gắn ngực chỉ là lớp ghi thứ hai; lớp thứ nhất vẫn ở trên kho. Tiến nhìn đồng hồ cơ: còn mười ba phút. Hắn mới bước xuống bậc đầu tiên. + +Cầu thang lạnh hơn tưởng tượng. + +Đi xuống khoảng mười hai mét, Tiến đến cuối cầu thang. Trước mặt hắn là một hành lang ngắn. Trên tường có vài vết khắc đã mờ, không phải chữ Việt, cũng không phải ký hiệu kỹ thuật hiện đại. Một số đường nét giống hoa văn cổ, một số lại giống sơ đồ mạch điện được cách điệu. Cũ và mới chồng lên nhau, giống như có hai thời đại cùng viết trên một bức tường. + +Cuối hành lang là một cánh cửa thứ hai. Cánh cửa này nhỏ hơn nắp hầm phía trên, làm bằng cùng loại kim loại tối màu. Ở giữa cửa có ký hiệu mặt trời đỏ, nhưng không có chữ. Bên cạnh ký hiệu là một vết xước dài, còn khá mới. Có người từng xuống đây. Mép xước còn quá sạch để thuộc về nhiều năm trước. + +Tiến đưa tay chạm nhẹ vào vết xước. Mép kim loại còn sạch, chưa phủ bụi hoàn toàn. Hắn chưa kịp kiểm tra thêm thì phía trên đầu vang lên một tiếng động rất khẽ. Không phải từ hành lang. Mà từ nhà kho phía trên. Tiếng kim loại cọ vào nhau. Cổng kho vừa bị mở. Tiến lập tức tắt đèn pin, lùi vào bóng tối sát tường. Trong không gian tĩnh lặng, tiếng bước chân từ phía trên truyền xuống rất mờ, nhưng đủ để hắn nhận ra. + +Có ít nhất ba người. Có kẻ khác đã tới Ngọc Trục. Trên bề mặt cửa HN-07, một đường sáng đỏ rất mảnh chậm rãi hiện lên, giống như một vết nứt vừa mở ra trong bóng tối. Không có dòng chữ giải thích. Không có màn hình. Không có câu trả lời. Chỉ có tiếng bước chân phía trên ngày càng gần, và cánh cửa HN-07 trước mặt hắn đang từ từ khóa lại. Ngày Ngọc Trục vừa bắt đầu. + +Và Tiến biết mình đã đến muộn hơn ít nhất một nhóm người. + +Chương 6: Những Kẻ Đến Muộn + +Tiếng bước chân phía trên càng lúc càng rõ. + +Tiến đứng sát vào vách hành lang, tắt đèn pin, một tay giữ dao gấp, tay còn lại chạm lên mặt tường lạnh. Trên cánh cửa kim loại trước mặt, đường sáng đỏ mảnh như sợi chỉ đang chậm rãi co lại. Nó không mở ra. Nó cũng không đóng sập. Nó chỉ lặng lẽ rút ánh sáng vào trong, giống như một con mắt vừa phát hiện kẻ lạ và quyết định nhắm lại. + +Phía trên, cổng kho phát ra tiếng rít khẽ. Có người đi vào. + +Bước chân ấy không thuộc về chủ kho hay môi giới. Bước chân của ông Lợi nặng và chậm, còn những người trên kia di chuyển nhẹ hơn, đều hơn, có kỷ luật hơn. Tiến nghe thấy tiếng giày chạm vào nền bê tông, tiếng kim loại va nhẹ vào khóa kéo, tiếng ai đó hạ giọng ra lệnh. Ít nhất ba người. Có thể bốn. + +Một giọng nam vang xuống từ phía trên, bị vách hầm nuốt mất một phần. + +“Dấu mở còn mới.” + +Một giọng khác đáp lại: + +“Có người xuống trước rồi.” + +Tiến nín thở. Hắn đã đến Ngọc Trục đúng ngày 16 tháng 5. Nhưng đúng không có nghĩa là sớm. + +Trong ba năm tận thế, hắn từng học được cách nghe tiếng người trong bóng tối. Người hoảng loạn nói nhanh, thở gấp, bước chân lộn xộn. Người ăn cướp nói lớn, đập phá nhiều, cố dùng âm thanh để dọa kẻ khác. Còn nhóm người phía trên không thuộc hai loại đó. Họ nói nhỏ, bước chậm, kiểm tra từng điểm, không phí một động tác thừa. + +Nhóm trên kia không đến vì tò mò. Họ biết mình đang tìm gì. Tiến lùi thêm nửa bước, mắt vẫn nhìn chằm chằm vào cánh cửa HN-07. Đường sáng đỏ đã mờ gần hết. Hắn đưa tay chạm vào bề mặt kim loại, nhưng lần này không có phản ứng. Cánh cửa lạnh và cứng như một khối đá, không khác gì một mảng bóng tối được rèn thành hình. + +Từ phía trên, tiếng bước chân dừng lại ngay gần miệng hầm. Một người nói: + +“Dây còn buộc ở đây. Hắn chưa lên.” + +Từ “hắn” khiến tay Tiến siết chặt chuôi dao. Nhóm trên kia không chỉ biết có người đã xuống; họ biết đó là một người đàn ông, thậm chí rất có thể biết chính xác là ai. Giọng nam đầu tiên vang lên lần nữa: + +“Không xuống vội. Kiểm tra nền trước.” + +Sau câu đó là một khoảng im lặng ngắn. Tiến nghe thấy tiếng thiết bị điện tử khởi động, tiếng bíp nhỏ, rồi tiếng ai đó chửi khẽ. + +“Mất tín hiệu toàn bộ.” + +“Bên dưới vẫn chặn?” + +“Ừ.” + +“Đừng chạm vào ký hiệu khi chưa có lệnh.” + +Tiến khựng lại ở câu cuối. Nhóm người phía trên cũng dè chừng — không phải hắn, mà là thứ đang nằm dưới kho. Nếu nhóm này kiểm soát HN-07 hoàn toàn, hắn đã chết từ lúc bước xuống bậc đầu tiên. Nhưng nếu ngay cả họ cũng phải kiêng dè cánh cửa này, nghĩa là thứ dưới Ngọc Trục không thuộc hẳn về bên nào. Đó là một tin tốt rất nhỏ. + +Và cũng là một tin xấu rất lớn. Cánh cửa kim loại trước mặt phát ra một tiếng tách khẽ. Tiến quay đầu. Đường sáng đỏ đã biến mất, nhưng ở mép dưới cánh cửa, một khe hẹp vừa mở ra. Không đủ cho người chui qua. Chỉ đủ để không khí lạnh hơn từ bên trong lùa ra, mang theo mùi kim loại khô và một thứ mùi rất nhẹ, giống mưa rơi trên đá nóng. Bên dưới khe cửa có một vật nhỏ trượt ra. Tiến cúi xuống nhặt. + +Đó là một mảnh kim loại mỏng, dài bằng hai ngón tay, bề mặt phủ bụi xám. Trên mảnh kim loại có khắc ba ký hiệu: một vòng tròn mặt trời đỏ, một đường cong giống dòng sông, và hai chữ Hán cổ đã mờ gần hết. Bên dưới cùng là một hàng chữ hiện đại nhỏ đến mức hắn phải đưa sát mắt mới đọc được. + +**LA PHU / SUPPLY TRACE** + +La Phù. Tuyến tiếp vận. Đúng lúc đó, phía trên có tiếng dây bị kéo căng. Tiến ngẩng đầu. Sợi dây dù hắn buộc vào thắt lưng rung nhẹ. Có kẻ phía trên đang thử kéo. Nếu hắn cứ đứng yên, họ sẽ biết chính xác vị trí của hắn. Nếu hắn cắt dây, hắn mất đường lên duy nhất đang thấy được. Nếu hắn leo lên ngay, hắn sẽ chui đầu vào miệng súng. + +Không có lựa chọn sạch. Tiến kẹp mảnh kim loại vào túi áo trong, rút dao cắt dây sát thắt lưng. Sợi dây bật ngược lên trên trong một tiếng vút nhỏ. Ngay lập tức, phía trên vang lên tiếng quát. + +“Hắn cắt dây!” + +Tiến quay người chạy dọc hành lang ngắn, trở lại chân cầu thang. Tiếng bước chân phía trên dồn dập hơn. Có người bắt đầu xuống. Ánh đèn trắng quét qua miệng hầm, rọi xuống những bậc kim loại lạnh. Tiến không leo lên. Hắn ép người vào khoảng tối dưới gầm cầu thang. + +Người đầu tiên xuống rất nhanh, tay cầm đèn pin gắn dưới nòng một vật dài. Tiến không nhìn rõ đó là súng thật hay công cụ bắn đinh cải tạo, nhưng trong khoảng cách hẹp thế này, thứ nào cũng đủ giết người. Sau lưng người đó còn một bóng nữa. Họ không bật đèn lớn, chỉ quét từng nhát sáng ngắn, kiểm tra vách, nền, cửa. + +“Dây bị cắt ở đây.” + +“Hắn ở gần.” + +Tiến chờ người đầu tiên bước qua vị trí của mình. Một bước. Hai bước. Khi gót giày của người đó vừa vượt qua mép tối, Tiến lao ra. + +Hắn không đâm dao ngay. Đâm người tạo tiếng, tạo máu, tạo giằng co. Thứ hắn cần là thời gian. Tiến dùng cả vai húc thẳng vào đầu gối đối phương, đồng thời giật mạnh cổ tay đang cầm đèn. Người kia mất thăng bằng, va vào vách kim loại. Đèn pin rơi xuống nền, ánh sáng xoay tròn làm hành lang chớp trắng một nhịp. + +Người thứ hai lập tức quay lại. Tiến đá chiếc đèn pin về phía hắn. Ánh sáng bật vào mặt khiến đối phương khựng lại nửa giây. Chỉ nửa giây đó đủ để Tiến lách qua, lao lên cầu thang. Phía trên có tiếng quát. + +“Chặn miệng hầm!” + +Tiến không nhìn lên. + +Hắn rút một vật nhỏ trong túi, ném mạnh lên trên. Đó là một bình xịt khói mini dùng để thử luồng gió trong phòng máy, thứ hắn bỏ vào túi theo thói quen nghề nghiệp. Bình đập vào bậc thang, nứt vỏ, phun ra một làn khói trắng dày. Không độc, không nguy hiểm, nhưng đủ che tầm nhìn trong không gian hẹp. + +Tiến cúi người, lao qua màn khói. Một bàn tay chụp lấy vai hắn ở gần miệng hầm. Tiến xoay người, dùng khuỷu tay thúc ngược vào cổ đối phương. Người kia nghẹn lại, lùi nửa bước. Tiến nhân cơ hội bật lên khỏi nắp hầm, lăn qua nền kho, chộp lấy xà beng đặt gần đó. + +Cơn đau bắn lên từ vai trái. Cú va chưa đủ làm hắn gục, nhưng Tiến biết vài giờ nữa vai sẽ sưng và lực tay sẽ giảm. Kiếp trước hắn từng mất ba ngày chỉ vì một vết rách ở lòng bàn tay bị nhiễm trùng; từ đó hắn không còn coi những chấn thương 'chịu được' là chuyện nhỏ. + +Kho chính ngập trong bụi và ánh sáng loang lổ. Có hai người phía trên. Một người bị khói làm cay mắt, đang lùi lại. Người còn lại đứng gần cổng phụ, mặc áo khoác mỏng màu xám, đội mũ lưỡi trai kéo thấp. Trên cổ tay hắn có một hình xăm nhỏ: vòng tròn với những tia đỏ. + +Biểu tượng mặt trời. Tiến không đuổi theo. Hắn đập xà beng vào giá sắt gần đó. Giá sắt đổ ầm xuống, kéo theo một loạt pallet gỗ mục và thùng carton cũ. Âm thanh vang khắp kho. Người ngoài đường có thể không nghe rõ, nhưng trong khu kho kín, tiếng động đủ khiến nhóm đột nhập mất nhịp. + +Tiến chạy thẳng ra cửa phụ phía sau. Ổ khóa xích đã bị cắt sẵn. Nhóm này vào bằng cổng chính, nhưng cũng đã chuẩn bị đường sau. Tiến đẩy cửa lao ra khoảng sân hẹp, vượt qua dãy văn phòng nhỏ, rồi trèo qua một đoạn tường thấp phía sau kho. Bên kia là một mảnh đất bỏ hoang đầy cỏ khô và gạch vỡ. Hắn rơi xuống, vai trái đập mạnh xuống đất lần nữa. Lần này, mắt hắn tối đi gần một giây. + +Hắn cắn răng bật dậy chạy tiếp. Sau lưng có tiếng người gọi nhau. Không có tiếng súng. Hoặc họ không có súng. Hoặc họ không muốn gây chú ý. Tiến chọn khả năng thứ hai. Hắn vòng qua hai dãy nhà xưởng, chui vào một lối nhỏ giữa các bức tường tôn, rồi dừng lại sau một xe tải bỏ không. Hơi thở nóng rát trong cổ họng. Vai trái đau âm ỉ. Trên mu bàn tay có một vết xước dài đang rỉ máu. + +Hắn nhìn về phía kho qua khe hở giữa hai tấm tôn. Ba người đã ra sân. Người đội mũ lưỡi trai nói gì đó với hai kẻ còn lại, rồi nhìn quanh. Từ khoảng cách này, Tiến không nghe rõ. Nhưng hắn thấy kẻ đó giơ tay, chỉ về phía đường lớn. Một chiếc xe tải màu trắng đỗ ở đầu ngõ. Trên thùng xe không có logo công ty. Chỉ có một dòng chữ rất nhỏ ở mép dưới, gần như bị bụi che mất: + +**LP-17** + +La Phù 17. Tiến cúi đầu, lấy mảnh kim loại trong túi áo ra nhìn lại. + +**LA PHU / SUPPLY TRACE** + +Mọi đường dây đang dẫn về cùng một nơi. Đến gần trưa, nhóm người lạ rời khỏi kho. Họ không đuổi theo nữa, cũng không báo công an. Họ khóa lại cổng như chưa từng có chuyện gì xảy ra. Tiến đợi thêm gần một giờ mới quay lại bằng lối sau, kiểm tra thật nhanh hiện trường. Nắp hầm đã đóng. + +Ký hiệu HN-07 trên tấm kim loại biến mất dưới lớp bụi và bê tông vỡ, như thể nó chưa từng phát sáng. Cánh cửa bên dưới chắc chắn cũng đã khóa. Hắn thử lại bằng tay, không có phản ứng. Tất cả thiết bị điện tử của hắn đều bật lại bình thường, nhưng camera gắn ngực chỉ ghi được đến khoảnh khắc hắn bước xuống bậc đầu tiên. Sau đó toàn bộ hình ảnh biến thành nhiễu trắng. + +Một camera hành lang tạm thời đã biến mất. Nhóm kia lấy nó. + +Tiến đứng trước góc tường trống, sắc mặt lạnh xuống. Camera đó không ghi được nhiều, nhưng trong bộ nhớ có thể còn hình hắn lắp thiết bị, hình hắn kiểm tra nền, thậm chí một vài giây trước khi tín hiệu nhiễu. Nếu chúng khôi phục được dữ liệu, chúng sẽ biết hắn không phải kẻ tình cờ. + +Có người từng nói công nghệ là ký ức trung thực nhất. Tiến biết câu đó sai. Có những nơi không cho phép con người mang ký ức ra ngoài. Và có những kẻ biết cách đánh cắp phần ký ức còn sót lại. Hắn dọn sơ hiện trường, che lại tấm kim loại, kéo kệ sắt về vị trí cũ nhưng không bắt chặt bu lông. Sau đó, hắn thay khóa, thêm một lớp xích, lắp camera độc lập ở góc khuất và rời khỏi Ngọc Trục trước khi trời tối. + +Trên đường về, điện thoại rung. Là một thông báo từ ứng dụng giao hàng. Đơn hàng nước đóng chai số lượng lớn mà hắn đặt qua một đầu mối vừa bị hủy vì “hết hàng đột xuất”. Tiến đọc lại thông báo một lúc rồi mở bản đồ. La Phù cách đây không xa. Đêm đó, hắn lái xe về phía những kho hàng không ngủ. + +Chương 7: La Phù Không Ngủ + +La Phù về đêm không yên tĩnh như người ngoài tưởng. + +Khi các khu dân cư bắt đầu tắt đèn, những dãy kho ở phía Tây thành phố vẫn còn sống. Xe tải ra vào lặng lẽ. Cửa cuốn kéo lên kéo xuống. Đèn trắng trong các kho hàng rọi qua khe cửa, cắt bóng người thành những mảnh dài trên nền bê tông. Mùi bánh kẹo, nhựa đóng gói, giấy carton, dầu máy và khói thuốc trộn vào nhau thành một thứ mùi rất riêng, vừa ngọt vừa khét. + +Trước Hồng Nhật, La Phù là nơi người ta nghĩ đến mỗi khi cần bánh kẹo, hàng khô, hàng Tết, hàng buôn sỉ. Sau Hồng Nhật, nơi này trở thành cái dạ dày cuối cùng của phía Tây Hà Nội. Ai giữ được La Phù, người đó giữ được thức ăn. Ai giữ được thức ăn, người đó có người đi theo. + +Tiến không đi xe của mình vào sâu. Hắn gửi xe ở một điểm cách khu kho gần một cây số, thay áo sơ mi bằng áo phông cũ, đeo khẩu trang, đội mũ lưỡi trai, rồi đi bộ qua những con đường nhỏ. Vai trái vẫn đau sau cú ngã ở Ngọc Trục. Mỗi lần nâng tay quá cao, cơ bả vai lại nhói lên. Hắn mua một túi đá nhỏ ở cửa hàng ven đường, áp qua lớp khăn mỏng vài phút rồi bỏ đi trước khi chủ quán kịp nhớ mặt. + +Việc thu mua vật tư không thể làm ồ ạt. Nếu một người đột nhiên mua hàng trăm thùng nước, hàng nghìn gói thực phẩm khô, hàng chục thùng thuốc sát trùng, người bán có thể vui lúc đầu, nhưng sau đó sẽ nhớ mặt. Khi hỗn loạn đến, ký ức của người khác có thể giết mình nhanh hơn dao. + +Tiến chia danh sách thành từng nhóm nhỏ: nước, đồ khô, đồ hộp, bánh năng lượng, muối, đường, sữa bột, thuốc cơ bản, túi rác dày, băng keo, màng PE, hộp nhựa kín. Một phần mua qua sàn thương mại điện tử, gửi về quê cho mẹ bằng nhiều tên người nhận khác nhau. Một phần đặt qua các đại lý nhỏ, chuyển về kho Ngọc Trục sau khi cải tạo sơ bộ. Một phần mua trực tiếp ở La Phù, trả tiền mặt, không để lại thông tin dài dòng. + +Nhưng đêm nay, La Phù có thứ khác thường. Tiến nhận ra điều đó sau chưa đầy mười phút. + +Có quá nhiều xe tải nhỏ không biển hiệu tập trung quanh ba kho phía trong. Chúng không bốc bánh kẹo hay hàng khô, mà bốc nước đóng chai. Khối lượng vượt xa mua bán lẻ: từng pallet nước được xe nâng đưa thẳng lên thùng xe. Các tài xế không hút thuốc, không cười nói, không mặc cả. Họ nhận hàng, ký giấy, đóng cửa thùng, rời đi theo từng chiếc cách nhau khoảng năm phút. + +Có tổ chức. Có tiền. Có lịch. Tiến đứng dưới mái hiên một cửa hàng tạp hóa, giả vờ xem bảng giá sỉ, mắt nhìn phản chiếu trong tấm kính cũ phía trước. Một xe tải màu trắng vừa lăn bánh ra khỏi kho số 17. Mép dưới thùng xe có dòng chữ nhỏ gần như bị bụi che mất. + +**LP-17** + +Cùng ký hiệu với chiếc xe ở Ngọc Trục. Tiến lạnh mặt. La Phù không chỉ là nơi nhóm kia mua hàng. Nó là một phần trong tuyến tiếp vận của chúng. + +“Anh lấy gì?” + +Chủ cửa hàng, một người phụ nữ ngoài bốn mươi, chống tay lên quầy hỏi. Tiến quay lại, chọn vài thùng bánh quy mặn, nước khoáng loại nhỏ, một ít lương khô nội địa, rồi hỏi bâng quơ: + +“Dạo này nước bán chạy thế chị?” + +“Trời nóng mà. Nhà nào chả mua.” + +“Nhưng bên kia lấy nhiều thật.” + +Người phụ nữ liếc về phía kho số 17, rồi hạ giọng. + +“Mấy hôm nay rồi. Người lạ, trả tiền nhanh, không mặc cả. Lấy toàn nước, muối, đường, đồ hộp. Có tiền thì bán thôi.” + +“Công ty nào?” + +“Không biết. Họ không nói. Có người bảo chuẩn bị cứu trợ mùa nóng, có người bảo làm sự kiện.” Chị ta hừ một tiếng. “Nhưng ai làm sự kiện mà mua cả xe nước lúc nửa đêm?” + +Tiến trả tiền, không hỏi thêm. Hắn rời cửa hàng, vòng sang con đường phía sau kho. Ở đó có một dãy tường thấp, phía sau chất đầy vỏ thùng carton và pallet hỏng. Tiến leo lên một chồng pallet, nhìn qua khe giữa hai tấm tôn. + +Bên trong kho số 17, hàng hóa đã được phân loại thành từng khu. Nước đóng chai xếp bên trái. Đồ hộp và bánh kẹo bên phải. Góc sâu nhất có vài thùng màu trắng dán băng đỏ, không giống hàng thương mại thông thường. Một người đàn ông mặc áo sơ mi đen đang đứng giữa kho, tay cầm máy tính bảng, kiểm tra danh sách. + +Tiến nhìn người đó. Ban đầu chỉ là cảm giác quen. Sau đó, ký ức từ tầng hầm Mễ Trì đâm thẳng vào lồng ngực hắn như một lưỡi dao cũ. Cùng dáng đứng ấy. Cùng cách nghiêng đầu khi nghe cấp dưới báo cáo. Cùng bàn tay trái luôn đeo một chiếc nhẫn đen ở ngón áp út. Người đàn ông trong kho số 17 trẻ hơn so với ký ức của Tiến. Da chưa sạm vì nắng độc, thân hình chưa gầy đi vì thiếu nước, ánh mắt vẫn còn vẻ bình thản của một kẻ sống trong thế giới có luật pháp. Nhưng gương mặt đó, Tiến không thể nhầm. + +Ba năm sau, chính gã đã cúi xuống nhìn hắn trong tầng hầm Mễ Trì và nói: + +“Mày vốn không nên sống lâu đến thế.” + +Ở hiện tại, gã đang đứng giữa kho nước của La Phù, chỉ huy người khác bốc hàng lên xe. Một người bên cạnh bước tới, đưa cho gã tập giấy. + +“Anh Kha, tuyến phía Tây còn thiếu ba xe nước. Kho bên Hà Đông báo chỉ giao được một nửa.” + +Gã đàn ông cầm giấy, không ngẩng đầu. Ngón tay cái của hắn chậm rãi miết qua chiếc nhẫn đen một vòng, như thể đang lau đi một hạt bụi vô hình. + +“Đỗ sang nguồn dự phòng,” hắn nói. Giọng rất nhẹ, nhẹ đến mức người nghe phải im lặng mới nghe rõ. “Trước ngày 22 phải xong.” + +Tiến nghe rõ cái tên ấy. + +**Đỗ Minh Kha.** + +Trong kiếp trước, cái tên này từng được nhắc đến sau vụ thanh trừng La Phù. Không ai biết hắn bắt đầu từ đâu, chỉ biết những nhóm nhỏ kiểm soát kho nước và kho thực phẩm phía Tây lần lượt bị nuốt sạch trong chưa đầy hai tuần. Người sống sót gọi hắn là Kha Đen, không phải vì hắn mặc đồ đen, mà vì nơi nào hắn đi qua, nơi đó không còn ai dám bật đèn. + +Tiến từng đối đầu với hắn nhiều lần. Lần cuối cùng là ở Mễ Trì. Một tài xế bước vào, đưa thêm danh sách. Đỗ Minh Kha ký rất nhanh, rồi quay đầu nhìn về phía vách tôn. Tiến lập tức cúi xuống. Ánh mắt gã quét qua khe hở nơi hắn vừa nhìn lén. Không dừng lâu. Không phát hiện. Nhưng chỉ một khoảnh khắc đó cũng đủ làm lớp da sau gáy Tiến lạnh buốt. Điều khiến hắn chú ý không chỉ là ánh mắt. + +Đỗ Minh Kha luôn đứng ở vị trí có đường thoát. Sau lưng là lối dẫn vào khu văn phòng kho. Bên phải là cửa phụ. Bên trái là xe nâng và hai người của hắn. Ngay cả khi chỉ ký giấy, hắn cũng không đứng ở nơi không kiểm soát được đường lui. Một con dao trong đêm không giải quyết được loại đối thủ này. + +Nếu giết gã bây giờ, Tiến có thể trả được một phần thù. Nhưng gã chỉ là một mắt xích. Giết một mắt xích mà chưa biết dây xích nối về đâu chỉ khiến toàn bộ hệ thống chuyển hướng sang hắn. Quan trọng hơn, hắn chưa biết Đỗ Minh Kha có nhớ tương lai không, hay chỉ nhận lệnh từ một nhóm biết trước Hồng Nhật. + +Tiến lặng lẽ rời khỏi dãy tường, quay lại con đường chính. Không giết vội. Không để lộ mình. Không trả thù khi chưa biết bàn tay nào đang cầm chuôi dao phía sau Đỗ Minh Kha. Đó là ba nguyên tắc hắn buộc mình phải nhớ trong từng bước chân rời khỏi La Phù. + +Đêm đó, hắn không tiếp tục mua hàng. Hắn quay về Ngọc Trục, khóa cửa kho từ bên trong, ngồi giữa nhà kho trống tới gần sáng. Bên ngoài, tiếng xe tải trên đường xa vẫn vọng lại từng đợt. Bên trong, ký hiệu mặt trời đỏ dưới nền vẫn nằm im dưới lớp kệ sắt cũ. + +Tiến mở sổ tay, viết bốn dòng. + +**La Phù: nhóm bí ẩn thu gom nước.** + +**LP-17 liên quan Ngọc Trục.** + +**Đỗ Minh Kha đã xuất hiện trước Hồng Nhật.** + +**Không giết vội. Phải biết hắn thuộc về ai.** + +Khi bình minh bắt đầu hắt ánh sáng xám qua mái tôn, điện thoại chính của hắn rung lên. Là Trần Thanh Thủy. Tin nhắn chỉ có một câu: + +**Tôi thấy anh ở La Phù tối qua. Người đàn ông đó tên Đỗ Minh Kha. Tôi nghĩ anh biết hắn là ai.** + +Tiến đọc lại dòng tin nhắn rất lâu. Thủy không chỉ theo dõi hắn. Cô cũng đã nhìn thấy Kha. Và điều đó có nghĩa là cô đang bước vào vùng nguy hiểm nhanh hơn hắn dự tính. + +Chương 8: Những Người Biết Quá Nhiều + +Thủy chọn một quán cà phê nhỏ nằm trong con ngõ gần đường Láng. + +Quán không đẹp, không yên tĩnh tuyệt đối, nhưng cũng khó bị cô lập. Quán nằm giữa khu dân cư đông, có hai lối ra, bàn ghế đặt sát nhau, khách ngồi rải rác đủ để che tiếng nói nhưng không quá đông để bị chen lấn. Với một phóng viên điều tra, đó là lựa chọn hợp lý. Với một người đang sợ bị theo dõi, đó là lựa chọn càng hợp lý hơn. + +Tiến đến trước giờ hẹn mười phút. Hắn không vào ngay. Hắn đi qua quán một lần, vòng sang con ngõ phía sau, kiểm tra lối thoát, rồi mới quay lại. Thủy đã ngồi ở bàn trong góc, lưng không quay hẳn về phía cửa, mắt đặt trên ly cà phê nhưng rõ ràng đang nhìn phản chiếu trong kính. + +Cô cũng biết cách quan sát. Điều đó khiến Tiến vừa yên tâm vừa cảnh giác. + +“Anh đến sớm,” Thủy nói khi hắn ngồi xuống. + +“Em cũng vậy.” + +“Thói quen nghề nghiệp.” + +“Của anh cũng thế.” + +Hai người im lặng vài giây. Ngoài đường, một người bán hàng rong đẩy xe đi ngang qua, tiếng loa nhỏ phát đi phát lại câu rao dưa hấu ngọt. Một đứa trẻ khóc vì làm rơi kem. Hai nhân viên văn phòng bàn chuyện deadline. Mọi thứ bình thường đến mức cuộc nói chuyện sắp diễn ra giữa hai người trở nên như một vết nứt nhỏ trên mặt kính. + +Thủy đặt điện thoại lên bàn. Trên màn hình là một bức ảnh chụp từ xa. Ảnh hơi mờ, nhưng vẫn đủ thấy Tiến đứng gần khu kho La Phù trong đêm, đầu đội mũ, mặt đeo khẩu trang. Phía xa là xe tải trắng LP-17. + +“Anh theo dõi họ?” cô hỏi. + +“Em cũng vậy?” + +“Tôi theo dõi xe nước, không bám đuôi anh.” Thủy kéo ảnh sang bên, hiện hai khung giờ khác nhau. “Tôi lấy biển xe ở điểm giao, đối chiếu camera cửa hàng còn lưu cục bộ rồi chờ ở tuyến ra. Hai điểm đứng, không chạy sau một chiếc xe đủ lâu để nó phát hiện.” + +Tiến nhìn lại góc chụp. Cô đã giữ khoảng cách tốt hơn hắn tưởng. + +“Vẫn nguy hiểm.” + +“Khác với liều.” + +Thủy nhìn hắn. + +“Vậy anh thừa nhận mình biết nhóm đó là ai?” + +“Không.” + +“Nhưng anh biết họ nguy hiểm.” + +“Đủ nguy hiểm để em không nên dính vào.” + +Cô bật cười rất khẽ. + +“Câu này nghe quen. Từ hôm gặp lại ở Đại Hà đến giờ, anh luôn khuyên tôi đừng lại gần thứ gì đó. Đừng ở Đại Hà khi mất điện. Đừng điều tra dữ liệu bằng máy cá nhân. Đừng đi thực địa một mình. Đừng dính vào nhóm ở La Phù.” Cô hơi nghiêng người về phía trước. “Vấn đề là anh chưa bao giờ nói vì sao.” + +Tiến nhìn ly nước lọc trước mặt. Đá trong ly tan rất nhanh. Nước bám thành giọt trên thành thủy tinh, trượt xuống mặt bàn thành một vệt ẩm nhỏ. + +“Vì nói ra em sẽ không tin.” + +“Nếu không có những file kia, tôi sẽ nghĩ anh bị hoang tưởng.” Thủy đặt một tập giấy mỏng lên bàn. “Nhưng dữ liệu không biết hoang tưởng.” + +Tiến hạ mắt xuống tập giấy. Trên đó là những dòng log bị lỗi mã hóa. Hắn thấy ba cái tên: **Ngọc Trục**, **Láng**, **Hồ Tây**. Bên dưới, một dòng giữ mắt hắn lại. + +**LE QUOC TIEN / STATUS: RETURNED / UNVERIFIED** + +Đó không phải cửa sổ HANOI-07 trên máy hắn, mà là dữ liệu Thủy lấy được từ một hệ thống khác. + +“Em đã mở sâu quá rồi,” Tiến nói. + +“Không sâu bằng anh.” + +“Em không biết mình đang đụng vào thứ gì.” + +“Vậy nói cho tôi biết.” + +Tiến đặt hai bàn tay lên mép bàn, mắt dừng ở tập log giữa họ. + +Hắn đã chuẩn bị rất nhiều thứ: kho, nước, vật tư, bản đồ, tuyến rút, cả những lời nói dối dành cho người ngoài. Nhưng hắn chưa bao giờ chuẩn bị được một câu trả lời đủ ngắn cho sự thật. Làm sao nói với một người rằng hơn một tháng nữa bầu trời sẽ đổi màu, thành phố sẽ bắt đầu chết, và những dữ liệu cô đang điều tra có liên quan đến một thứ nằm dưới lòng Hà Nội? + +Thủy lấy thêm một bức ảnh đặt lên bàn. Đó là Đỗ Minh Kha trong kho La Phù, tay cầm máy tính bảng, đứng cạnh những pallet nước. + +“Tôi tra được một phần về hắn. Đỗ Minh Kha. Trước đây làm trong một công ty logistics, sau đó chuyển sang tư vấn chuỗi cung ứng. Hai năm gần đây gần như không xuất hiện công khai. Nhưng có nhiều pháp nhân nhỏ liên quan đến hắn đang mua nước, muối, đồ hộp, pin và máy phát. Đây không phải mua lẻ, mà là gom hàng có hệ thống.” + +“Em không nên điều tra hắn trực tiếp.” + +“Tôi biết.” Thủy ngừng một chút. “Vì vậy tôi mới gọi anh.” + +Tiến quay sang cô. Đó không phải câu nói của một người muốn được bảo vệ. Đó là câu nói của một người biết mình đang thiếu mảnh ghép và chấp nhận hợp tác với kẻ đáng nghi nhất trong danh sách. + +“Ngày 22 tháng 6,” hắn nói chậm rãi, “đừng ở nơi đông người. Đừng ở trong trung tâm thương mại. Đừng đứng ngoài trời quá lâu sau 12 giờ trưa. Chuẩn bị nước, thuốc, pin, sạc dự phòng, bản đồ giấy. Nếu có thể, rời khỏi các tòa nhà kính trước ngày đó.” + +Thủy im lặng. Câu trả lời không trực tiếp, nhưng nặng hơn bất kỳ lời thú nhận nào. + +“Ngày 22 có chuyện gì?” + +“Anh không thể chứng minh.” + +“Tôi không hỏi anh có chứng minh được không.” + +“Thủy.” + +“Có chuyện gì?” + +Tiến nhìn ra cửa. Một người đàn ông mặc áo chống nắng vừa dừng xe trước quán, mua cà phê mang đi. Một người phụ nữ cầm ô đi ngang qua. Thành phố vẫn đang sống trong nhịp điệu bình thường, vô tư đến tàn nhẫn. + +“Bầu trời sẽ đổi màu,” hắn nói. “Mặt trời sẽ đỏ. Nhiệt độ sẽ tăng vượt mọi dự báo. Ban đầu người ta sẽ nghĩ đó là một hiện tượng thời tiết cực đoan. Sau đó điện sẽ quá tải, nước sẽ cạn, bệnh viện sẽ vỡ trận. Hà Nội sẽ chết từng phần.” + +Thủy không cười. Cũng không gọi hắn là điên. Nhưng sắc mặt cô trắng hơn một chút. + +“Nếu không phải anh nói, nếu không phải mấy dữ liệu kia, tôi sẽ đứng dậy ngay bây giờ.” + +“Vậy sao em chưa đi?” + +“Vì tôi từng mơ thấy cảnh đó.” + +Tiến khựng lại. Thủy nhìn xuống ly cà phê đã tan đá, giọng nhỏ hơn. + +“Không rõ. Không liên tục. Cũng không giống ký ức. Chỉ là vài giấc mơ. Hồ Tây cạn nước. Cửa kính một trung tâm thương mại phủ hơi nước. Trẻ con khóc trong bóng tối. Một hành lang nóng đến mức tôi không thở được.” Cô ngẩng lên nhìn hắn. “Tôi từng nghĩ do mình làm đề tài môi trường nên ám ảnh. Nhưng sau khi thấy dữ liệu Ngọc Trục, Láng, Hồ Tây… tôi không chắc nữa.” + +Thủy mở một thư mục trong điện thoại có tên **GIAC_MO_2028**. Ba đoạn ghi âm ngắn được tạo lúc gần sáng, khi cô vừa tỉnh và sợ mình sẽ quên. Phần mềm chuyển giọng thành chữ là bản cũ từ dự án hầm ngập năm 2023; cô đã tắt đồng bộ từ lâu, nhưng biểu tượng bộ đệm vẫn hiện một lần rồi biến mất khi mở tệp dữ liệu Ngọc Trục. + +“Em giữ bản ngoại tuyến,” cô nói. “Ít nhất em nghĩ vậy.” + +Tiến không vội kết luận. Những giấc mơ ấy chưa đủ để chứng minh Thủy từng sống qua tương lai, nhưng cũng khó coi là ngẫu nhiên. HANOI-07 có thể đã tác động tới cô; một lớp dữ liệu nào đó từng chạm vào cô; hoặc còn tồn tại cơ chế mà hắn chưa biết. Mỗi giả thuyết kéo theo một kiểu nguy hiểm khác. Thủy gấp tờ log lại. + +“Anh từng trải qua rồi?” + +Câu hỏi rơi xuống rất nhẹ. Nhưng cả hai đều biết nó nặng thế nào. Tiến không đáp ngay. Nếu hắn nói có, Thủy sẽ bước qua một ranh giới không thể quay lại. Nếu hắn nói không, mọi lời cảnh báo vừa rồi sẽ thành vô nghĩa. Cuối cùng, hắn chọn một câu lưng chừng. + +“Anh đã thấy đủ để biết mình phải chuẩn bị.” + +Thủy nhìn hắn rất lâu. + +“Còn tôi thì sao?” + +“Em nên dừng lại.” + +“Không.” + +“Đây không phải bài báo.” + +“Tôi biết.” + +“Cũng không phải chuyện em có thể công bố để cứu người.” + +“Tôi cũng biết.” Giọng Thủy hạ thấp. “Nhưng nếu tôi dừng lại, tôi sẽ trở thành loại người mà tôi từng điều tra.” + +Tiến xoay cây bút giữa hai ngón tay. Ngoài kia, Hà Nội vẫn ồn ào; ở chiếc bàn nhỏ trong góc quán, một liên minh tạm thời đang thành hình. Chưa phải tin tưởng, càng chưa phải tình cảm — chỉ là hai người cùng nhìn thấy một khe nứt trên bề mặt thành phố. Tiến lấy bút, viết lên mép tờ giấy ba chữ. + +**Không dùng mạng.** + +Rồi hắn viết tiếp: + +**Không nói điện thoại.** + +**Không gửi file gốc.** + +**Không tới Ngọc Trục một mình.** + +Thủy nhìn danh sách, rồi gật đầu. + +“Tôi có một điều kiện.” + +“Nói.” + +“Khi anh biết nơi nào sắp có người chết hàng loạt, anh phải nói cho tôi.” + +Tiến hiểu cô đang nhắc đến Đại Hà. Hắn không trả lời ngay. Cứu một người dễ. Cứu một nhóm người khó. Cứu hàng nghìn người trước khi thảm họa xảy ra gần như là tự sát. Nếu hắn cố cảnh báo quá sớm, hắn sẽ bị coi là kẻ điên, hoặc tệ hơn, bị những người biết sự thật kéo vào tầm ngắm. Nhưng hình ảnh Lò Hấp Hà Đông vẫn nằm trong đầu hắn như một vết bỏng. + +“Anh sẽ nói khi có thể,” hắn đáp. + +“Không đủ.” + +“Đó là tất cả những gì anh có thể hứa lúc này.” + +Thủy mím môi, không hài lòng, nhưng cũng không ép thêm. Trước khi rời đi, cô dừng lại cạnh bàn, nhìn thẳng vào Tiến. + +“Câu cuối.” + +“Ừ.” + +“Anh có tin một người biết trước tương lai không?” + +Tiến ngẩng đầu. Câu hỏi có thể là thăm dò, cũng có thể là một lời thú nhận được bọc kín. Dù thế nào, Thủy không chỉ hỏi về hắn. Cô đang hỏi về chính mình. + +ARC 2: HỒNG NHẬT GIÁNG LÂM + +Chương 9: Ngày 22 Tháng 6 + +Ngày 22 tháng 6 năm 2028 bắt đầu bằng một buổi sáng không có gì đặc biệt. Ít nhất, với phần lớn người Hà Nội, nó trông như vậy. + +Sáu giờ ba mươi, đường Nguyễn Trãi đã đông xe. Người đi làm cau có vì nắng sớm hắt thẳng vào mặt. Hàng ăn sáng dưới chân chung cư vẫn bốc khói. Một nhóm học sinh nghỉ hè đứng trước cửa hàng tiện lợi, vừa ăn kem vừa xem điện thoại. Trên mạng xã hội, người ta chia sẻ ảnh nhiệt kế ngoài trời 39°C, kèm những câu đùa quen thuộc: Hà Nội hôm nay chín tái, ra đường nhớ mang theo vỉ nướng. + +Tiến không cười. Hắn đang ở kho Ngọc Trục. + +Sau hơn một tháng chuẩn bị, nơi này đã khác rất nhiều so với ngày đầu hắn nhận chìa khóa. Tường bao được gia cố thêm lớp lưới thép phía trong. Cổng chính thay khóa hai lớp, có chốt ngang tự chế. Trong kho, các dãy hàng được xếp kín nhưng không quá lộ: nước đóng chai, thùng chứa nước rỗng, thực phẩm khô, thuốc cơ bản, quạt công nghiệp, dây điện, ắc quy, tấm pin mặt trời, bạt cách nhiệt, túi rác dày, cát, vôi bột, dụng cụ sửa chữa. + +Không đủ cho một cộng đồng lớn. Nhưng đủ cho một lõi sinh tồn. Và trong tận thế, người có lõi sinh tồn sẽ có cơ hội xây thành trì. + +Tiến kiểm tra bồn nước lần thứ ba trong ngày. Hắn không tin hệ thống cấp nước thành phố sẽ duy trì ổn định sau hôm nay. Không phải ngay lập tức, nhưng khi nhiệt độ tăng, nhu cầu tăng, điện quá tải, bơm yếu, đường ống cũ gặp áp lực, sự cố sẽ dây chuyền. Người bình thường chỉ thấy vòi nước yếu đi. Tiến thấy một hệ thống bắt đầu đứt mạch. + +Điện thoại rung. Là mẹ. Tiến chần chừ vài giây rồi mới bấm nghe. + +“Con nghe đây.” + +“Tiến à, hôm nay ở quê cũng nóng quá. Mẹ vừa ra chợ về mà hoa hết cả mắt.” + +“Mẹ uống nước chưa?” + +“Rồi. Anh dặn suốt, mẹ nhớ mà. Mấy thùng nước với thuốc con gửi về, mẹ xếp trong buồng rồi. Hàng xóm còn hỏi con buôn hàng à.” + +“Nếu ai hỏi, mẹ cứ bảo công ty con thanh lý đồ.” + +“Ừ. Mà con ở Hà Nội thế nào? Trên đó chắc nóng hơn.” + +Tiến rà khoảng sân kho. Nắng phủ trắng mặt bê tông. Xa xa, mái tôn các xưởng lân cận hắt sáng chói mắt. + +“Con ổn. Hôm nay mẹ đừng ra ngoài sau mười một giờ. Đóng bớt cửa hướng nắng. Nếu mất điện thì xuống nhà dưới, đừng ở phòng mái.” + +“Mất điện gì mà giữa ngày?” + +“Cứ nghe con.” + +Đầu dây bên kia im lặng một chút. + +“Tiến này.” + +“Vâng?” + +“Có chuyện gì thật à?” + +Tiến từng nghĩ mình có thể giấu mẹ đến phút cuối. Nhưng người mẹ nào cũng có thứ trực giác kỳ lạ với con mình. Không cần biết Hồng Nhật, không cần nhìn thấy dữ liệu, bà vẫn nhận ra giọng hắn đã khác. + +“Có thể thời tiết sẽ rất xấu,” hắn nói. “Mẹ cứ coi như bão lớn.” + +“Bão thì còn biết đường tránh.” + +“Lần này cũng vậy. Mẹ tránh bằng cách ở trong nhà, uống nước, giữ thuốc bên người, và đừng tiếc mấy thứ con gửi về.” + +Bà thở dài. + +“Ừ. Mẹ nghe.” + +Sau khi cúp máy, Tiến đứng im một lúc. Hắn đã cứu được mẹ chưa? Chưa. Không ai được cứu trước khi thảm họa thật sự đi qua. + +Mười một giờ mười, Thủy gọi từ tòa soạn. + +Phía bên kia rất ồn. Tiếng bàn phím, tiếng người gọi nhau, tiếng biên tập viên hỏi có ai kiểm tra ảnh mặt trời chưa. Thủy không ở Ngọc Trục. Tiến đã yêu cầu cô ở nơi có thể nhìn thấy phản ứng xã hội, và cô chọn tòa soạn vì ở đó có dữ liệu, tin tức, đường dây nguồn tin và đủ người để xác nhận chuyện sắp xảy ra không phải ảo giác cá nhân. + +“Anh đang ở kho?” cô hỏi. + +“Ừ.” + +“Trên mạng bắt đầu có ảnh mặt trời hơi đỏ. Nhiều người bảo do camera điện thoại.” + +“Đừng nhìn trực tiếp.” + +“Tôi biết.” Cô ngừng một chút. “Anh chắc là hôm nay?” + +Hắn liếc đồng hồ. 11 giờ 12 phút. + +“Chắc.” + +Đầu dây bên kia im lặng vài giây. + +“Ở đây vẫn có người đùa. Có người nói nếu tận thế thì khỏi họp giao ban.” + +“Họ sẽ không đùa lâu đâu.” + +Mười hai giờ, nhiệt độ ngoài sân Ngọc Trục đã vượt 42°C theo máy đo của Tiến. Không khí rung nhẹ trên mặt bê tông. Mùi nhựa nóng từ mấy tấm bạt mới phảng phất trong kho. Xa xa, tiếng chó sủa vọng lại rồi tắt. Thành phố như đang nín thở trước một thứ chưa ai gọi tên. + +12 giờ 15 phút, Thủy gọi lại. Cô không nói ngay. Trong điện thoại có tiếng người xôn xao. + +“Tiến,” cô nói rất nhỏ. “Mặt trời…” + +Hắn liếc đồng hồ. 12 giờ 16 phút. + +“Vào trong. Kéo rèm. Đừng đứng ngoài ban công.” + +“Bầu trời đang đổi màu.” + +“Thủy.” + +“Tôi biết.” + +12 giờ 17 phút. Ánh sáng ngoài sân kho Ngọc Trục đổi màu. + +Ánh sáng không tối đi cũng không sáng hơn; toàn bộ màu sắc chỉ bị kéo lệch sang một dải đỏ mỏng. Mái tôn xám chuyển thành màu chì cháy. Tường bê tông trắng ngả sang hồng bẩn. Bóng của các cột sắt trên sân kéo dài, run lên, rồi ổn định trong một thứ ánh sáng khiến mắt người khó chịu. + +Trên bầu trời Hà Nội, mặt trời chuyển sang màu đỏ sẫm. Nó không đỏ rực như hoàng hôn, mà sâu, nặng và lạnh như con mắt khổng lồ trong ký ức cuối cùng của Tiến. + +Tiếng còi xe ngoài xa bắt đầu rối loạn. Một người ở xưởng bên cạnh chửi thề rất to. Có tiếng cửa kéo mở ầm ầm. Điện thoại của Tiến rung liên tục. Tin nhắn, thông báo, cuộc gọi nhỡ, mạng xã hội bùng lên trong vài phút. Ở đầu dây bên kia, Thủy thở rất khẽ. + +“Anh biết thật.” + +Tiến không đáp. Hắn nhìn bảng cảm biến nhiệt độ đặt trong kho. 44°C. 46°C. 48°C. Nhiệt độ ngoài sân tăng nhanh hơn bất kỳ mô hình thời tiết nào cho phép. + +Từ điện thoại, tiếng trong tòa soạn hỗn loạn dần. + +“Ảnh thật à?” + +“Ai gọi bên khí tượng đi!” + +“Đừng đăng vội, xác minh đã!” + +“Trời ơi ngoài kia đỏ thật!” + +Ngoài đường, một tiếng va chạm lớn vang lên từ hướng Đại lộ. Tiến chạy ra cửa kho, nhìn qua khe cổng. Một người đi xe máy đã ngã giữa đường, không rõ vì lóa mắt hay vì cố ngẩng đầu nhìn bầu trời. Hai chiếc xe phía sau phanh gấp, còi xe kéo dài thành một âm thanh hỗn loạn. Một người đàn ông đứng dưới nắng, giơ điện thoại livestream, miệng còn hét “mọi người nhìn đi” trước khi loạng choạng ngồi sụp xuống vỉa hè. + +Xa hơn, một trạm biến áp nhỏ gần khu xưởng phát ra tiếng nổ lách tách. Không lớn. Không gây cháy ngay. Nhưng đủ để vài người chạy ra khỏi nhà, nhìn lên dây điện với vẻ mặt lần đầu tiên thật sự sợ hãi. Tiến đứng giữa kho Ngọc Trục, một mình trước những dãy nước và vật tư, nhưng hắn không còn cảm giác mình đang đứng ngoài thế giới. Hắn đang đứng trong lõi của cơn bão, chỉ là cơn bão này không có gió. + +49°C. 50°C. 51°C. Khoảnh khắc đó, toàn bộ tiếng ồn của thế giới bên ngoài như bị đẩy ra xa. Tiến không còn nghe rõ còi xe, tiếng người la hét hay tiếng điện thoại rung. Hắn chỉ nghe tiếng tim mình đập đều, chậm, nặng. + +Hồng Nhật đã đến. Lần thứ hai trong đời hắn. Và lần này, hắn có một căn cứ, một bản đồ, một đồng minh chưa chắc đáng tin, một kẻ thù đã xuất hiện sớm, cùng một cánh cửa HN-07 chưa mở hết dưới nền kho Ngọc Trục. Thế giới bắt đầu kết thúc. + +Trên mái kho, tấm pin đầu tiên nứt một đường mảnh vì nhiệt. Tiến nhìn vết nứt lan dưới lớp kính và hiểu bốn mươi bốn ngày chuẩn bị vừa kết thúc; từ đây, mọi sai số đều phải trả bằng thứ đang sống. + +Chương 10: Lò Hấp Hà Đông + +Ngày thứ bảy sau Hồng Nhật, trung tâm thương mại Đại Hà ở Hà Đông bắt đầu đông bất thường. + +Tin đồn lan rất nhanh: trong đó còn mát, còn nước, còn điều hòa, còn siêu thị, còn nhà vệ sinh. Người từ các khu dân cư xung quanh đổ về theo từng đợt. Ban đầu là các gia đình có trẻ nhỏ, người già, phụ nữ mang thai. Sau đó là sinh viên, dân văn phòng, người thuê trọ không chịu nổi phòng nóng. Rồi đến những người mang theo túi lớn, chiếu, quạt sạc, bình nước, thậm chí cả thú cưng. + +Trung tâm thương mại sáng đèn như một con tàu lớn giữa biển nóng. Và ai cũng muốn leo lên con tàu đó. Tiến đứng trong bãi xe đối diện, nhìn dòng người đi vào qua lớp kính đen của ô tô. Hắn không muốn tới đây. Nhưng hắn đã hứa với Thủy. Khi anh biết nơi nào sắp có người chết hàng loạt, anh phải nói cho tôi. + +Hắn đã nói. Thủy đang ở bên trong. + +Cô vào từ sáng với tư cách phóng viên, mang theo máy ảnh, pin dự phòng, sổ tay và một balo nước. Trước khi vào, Thủy đã đi một vòng ngoài nhà, chụp ba lối thoát, đánh dấu lối giao hàng Tiến từng chỉ và nhắn cho một đồng nghiệp mốc kiểm tra mỗi ba mươi phút. Cô tự đặt điều kiện rút: điện mất quá mười giây, cửa chính bắt đầu bị ép hai chiều, hoặc nhiệt trong sảnh tăng liên tục ba mức đo — chỉ cần một điều xảy ra, cô sẽ đi, không tranh luận với bài viết. + +Bài cô gửi về tòa soạn ban đầu chỉ là ghi nhận tình trạng người dân đổ về trung tâm thương mại để tránh nóng. Nhưng càng về trưa, nó không còn là bài viết nữa. Nó trở thành một bản ghi trước thảm họa. + +11 giờ 20 phút, Thủy gọi cho hắn. + +“Người vào quá đông.” + +“Ra đi.” + +“Chưa chạm ngưỡng rút. Tôi đang ở tầng một, cách lối giao hàng chưa tới ba phút và ban quản lý vừa đồng ý cho tôi xem tải máy phát. Tôi ở thêm tối đa hai mươi phút.” + +“Không gia hạn.” + +“Tôi biết. Hai mươi phút là trần.” + +“Bên trong còn giữ được trật tự vì điện chưa mất.” + +Đầu dây bên kia im lặng một giây. + +“Anh chắc hôm nay sẽ mất?” + +“Không chắc hôm nay. Nhưng chắc nơi đó không chịu được lâu.” + +“Ban quản lý nói có máy phát.” + +“Máy phát không được thiết kế để gánh hàng nghìn người trú nóng trong nhiều giờ. Điều hòa trung tâm, thang máy, chiếu sáng, kho lạnh, bơm nước, camera, quầy hàng, tất cả đều kéo tải. Nếu điện lưới chập chờn và người bên trong hoảng, máy phát không cứu được đâu.” + +Thủy hạ giọng. + +“Tôi đang cố thuyết phục họ giới hạn người vào.” + +“Họ có nghe không?” + +“Không đủ nhanh.” + +Tiến xoay người về phía lối vào chính. Dòng người vẫn đổ vào. + +Một người đàn ông cõng mẹ già trên lưng. Một phụ nữ bế con nhỏ, tay còn lại kéo túi đồ. Hai thanh niên khiêng một thùng nước, vừa đi vừa mắng nhau vì nóng. Một nhóm người chen ngang bị bảo vệ chặn lại, cãi cọ ngay trước cửa kính. Bên trong, ánh đèn trắng vẫn sáng, điều hòa vẫn thổi, âm nhạc từ khu mua sắm vẫn phát nhẹ, tạo ra ảo giác rằng nơi này an toàn. + +Nhưng Tiến biết một điều: địa ngục thường không bắt đầu bằng tiếng hét. Nó bắt đầu bằng việc quá nhiều người tin rằng mình đang ở nơi an toàn nhất. 12 giờ 05 phút, nhiệt độ ngoài trời chạm 52°C. Một cụ ông ngã quỵ trước cửa phụ phía Tây. + +Ban đầu không ai nghĩ ông chết. Người ta tưởng ông choáng vì nóng, đỡ ông vào trong, quạt, gọi nhân viên y tế. Mười phút sau, thêm hai người ngất ở khu vực bãi xe. Đám đông bắt đầu chen nhanh hơn vào cửa, không còn xếp hàng theo hướng dẫn. 12 giờ 28 phút, điện chớp lần đầu. + +Chỉ một cái nháy rất ngắn. + +Đèn trần tắt rồi sáng lại. Điều hòa ngừng thổi chưa đầy ba giây. Chưa tới ngưỡng mười giây, nhưng Thủy không chờ đủ điều kiện trên giấy. Cô nhắn đúng một câu cho Tiến — **TÔI RÚT** — rồi đi về lối giao hàng. Cùng lúc, một nhân viên y tế gọi cô giữ cửa phụ vì một cụ ông vừa ngã và đám đông đang ép ngược từ ngoài vào. Thủy giúp kéo người bệnh qua mép cửa chưa đầy hai phút. Hai phút đó khiến luồng người đổi hướng, chặn mất hành lang cô định dùng. + +Trong một không gian có hàng nghìn người đang căng thẳng, ba giây mất điện không dài; điều nguy hiểm là hàng nghìn người cùng tự sửa kế hoạch trong ba giây ấy. Tiếng trẻ con khóc lớn hơn. Người lớn bắt đầu hỏi nhau có chuyện gì. Một số người kéo nhau chạy về phía siêu thị mua thêm nước. Bảo vệ dùng loa yêu cầu giữ trật tự. + +12 giờ 46 phút, điện chớp lần thứ hai. Lần này lâu hơn. Mười hai giây. Khi đèn sáng lại, một quầy nước gần khu ẩm thực đã bị chen đổ. + +Thủy gửi cho Tiến một đoạn video ngắn. Khung hình rung mạnh. Trong video, người ta chen nhau trước kệ nước, tay với vào thùng hàng, nhân viên cố ngăn nhưng bị đẩy lùi. Một đứa trẻ khóc lạc giọng. Một người phụ nữ hét lên rằng mẹ mình không thở được. Ở góc hình, bảo vệ đang cố mở lối phụ cho người già ra ngoài, nhưng bên ngoài nắng nóng đến mức không ai muốn bước ra. + +Đoạn video khiến bàn tay Tiến siết chặt điện thoại. Kiếp trước, hắn chỉ xem được đoạn cuối của thảm họa Đại Hà. Lần này, hắn đang nhìn thấy nó hình thành từng bước. Hắn gọi lại cho Thủy. + +“Ra khỏi đó ngay.” + +“Tôi đang ở tầng một, gần cửa phụ.” + +“Đừng đi cửa chính. Đi lối giao hàng phía sau siêu thị. Nhớ đường anh chỉ không?” + +“Nhớ.” + +“Đi ngay.” + +“Còn người bên trong?” + +Tiến nhìn về cửa kỹ thuật nơi tiếng đập vẫn vọng qua lớp tường. + +“Em không kéo được tất cả ra.” + +“Tôi biết.” + +“Vậy đừng chết cùng họ.” + +Đầu dây bên kia có tiếng va đập và tiếng người la hét. Thủy thở gấp hơn, nhưng giọng vẫn giữ được bình tĩnh. + +“Tôi sẽ đưa được một nhóm ra. Có mấy người già và trẻ con ở gần tôi.” + +“Không quá mười người.” + +“Tiến.” + +“Không quá mười người. Nhiều hơn em sẽ không ra được.” + +Cô không trả lời. Cuộc gọi ngắt. 13 giờ 03 phút, điện mất lần thứ ba. Lần này, đèn không sáng lại ngay. + +Từ bên ngoài, trung tâm thương mại Đại Hà ở Hà Đông tối đi một mảng lớn như một con tàu vừa bị tắt máy giữa biển người. Đèn khẩn cấp đỏ bật lên từng dải. Cửa kính phản chiếu những bóng người chen chúc bên trong. Tiếng hét vọng ra mờ qua lớp kính dày, bị bóp méo thành một thứ âm thanh trầm đục. + +Đám đông bên ngoài bắt đầu đập cửa. Đám đông bên trong cũng muốn ra. Hai dòng người ép vào cùng một hệ thống cửa. Tiến xuống xe. + +Hắn không lao vào cửa chính. Hắn chạy vòng theo lối giao hàng phía sau, nơi hắn đã khảo sát từ ngày 10 tháng 5. Đường nội bộ chật hơn hắn nhớ, vì có vài xe giao hàng bị bỏ lại. Không khí nóng như đập vào mặt, mỗi lần hít vào cổ họng đều rát. Hắn kéo khẩu trang ướt lên mũi, đi sát tường để tránh ánh nắng trực tiếp. + +Cửa giao hàng phía sau bị khóa một lớp, nhưng chưa bị chặn hoàn toàn. Tiến dùng xà beng phá khóa. Tiếng kim loại gãy vang lên khô khốc. Bên trong, hành lang kỹ thuật tối và nóng. Điều hòa đã ngừng. Không khí đông đặc mùi mồ hôi, nhựa nóng và thức ăn hỏng. Từ xa, tiếng người la hét vọng lại từng đợt. Tiến bật đèn pin, soi dọc hành lang. + +“Thủy!” + +Không ai đáp. Hắn tiến vào thêm vài mét. + +Một cửa phụ bên trái bật mở. Thủy lao ra, mặt tái nhợt, tóc dính mồ hôi vào má. Sau lưng cô là sáu người: một bà cụ, hai đứa trẻ, một phụ nữ trẻ, một nhân viên siêu thị và một người đàn ông đang dìu một ông già thở dốc. + +“Còn người phía sau,” Thủy nói. + +“Không kịp.” + +“Còn—” + +“Không kịp!” + +Tiến gần như quát. Ánh mắt Thủy giữ ở hắn đúng một thoáng, rồi cô quay lại kéo tay đứa trẻ gần nhất. + +“Đi!” + +Họ chạy theo hành lang giao hàng ra ngoài. Tiến đi cuối, dùng xà beng chặn tạm cửa để ngăn dòng người bên trong tràn ngược ra lối hẹp. Hắn nghe thấy tiếng đập cửa từ phía sau. Tiếng gọi. Tiếng chửi. Tiếng cầu cứu. Có người nhìn thấy lối này. Có người đang cố lao theo. + +Tiến nhắm mắt một nhịp. Rồi đẩy cửa ngoài. Nắng đập vào mặt như một bức tường lửa. Nhóm người thoát ra loạng choạng chạy về phía bóng râm dưới mái che. Người phụ nữ trẻ ôm con khóc nấc. Nhân viên siêu thị ngồi bệt xuống đất, nôn khan. Bà cụ thở khò khè, môi tím lại. Thủy quỳ xuống kiểm tra bà, tay run nhưng vẫn cố giữ bình tĩnh. + +Tiến ngoái về tòa nhà phía sau. Trung tâm thương mại Đại Hà ở Hà Đông vẫn đứng đó, khổng lồ, tối dần bên trong lớp kính. Một nơi từng mát lạnh, sạch sẽ, sáng đèn. Bây giờ nó bắt đầu biến thành đúng thứ trong ký ức của hắn. + +Tối hôm đó, đoạn video cuối cùng từ bên trong Đại Hà lan ra trên mạng trước khi mất tín hiệu. Hình ảnh rung lắc, âm thanh vỡ vụn. Người ta chỉ nhìn thấy đèn khẩn cấp đỏ, những bàn tay đập vào cửa kính, một đứa trẻ khóc đến khản giọng, rồi màn hình tối đen. + +Thủy ngồi ở góc kho Ngọc Trục sau đó nhiều giờ, tay vẫn run. Cô đã rửa mặt ba lần nhưng vẫn cảm thấy trên da còn mùi mồ hôi và nhựa nóng của hành lang kỹ thuật. Cứ nhắm mắt lại, cô lại nghe tiếng người đập vào cánh cửa bị Tiến chặn tạm sau lưng. + +Đêm muộn, cô mở laptop định viết bài. Gõ được ba dòng, cô xóa. Gõ lại, lại xóa. Bài viết thật sẽ không được đăng. Bài viết được đăng sẽ không chứa tiếng trẻ con khóc, không chứa bàn tay đập cửa, không chứa khoảnh khắc cô kéo sáu người ra và bỏ lại nhiều hơn sáu mươi người phía sau. + +Từ ngày đó, những người sống sót không còn gọi nơi ấy là trung tâm thương mại nữa. Họ gọi nó là **Lò Hấp Hà Đông**. + +Chương 11: Thành Phố Bắt Đầu Chết + +Sau Lò Hấp Hà Đông, Hà Nội không còn cười về Hồng Nhật nữa. + +Những ngày đầu, người ta vẫn cố giữ một trật tự mong manh. Chính quyền phát khuyến cáo ở trong nhà, tránh ra đường vào buổi trưa, tiết kiệm nước, hạn chế dùng thiết bị điện công suất lớn. Các chuyên gia lên truyền hình giải thích về hiện tượng nhiệt bất thường, về áp lực đô thị, về nguy cơ sốc nhiệt. Nhưng mỗi ngày trôi qua, những lời giải thích càng giống giấy dán lên một vết nứt đang mở rộng. + +Nước đóng chai biến mất khỏi các kệ hàng trước tiên. Sau đó là đá viên. Rồi đến quạt sạc, pin dự phòng, máy phát mini, thuốc hạ sốt, oresol, khăn lạnh, bình giữ nhiệt. + +Người ta vẫn trả tiền, nhưng tiền bắt đầu yếu đi. Ở một số cửa hàng nhỏ, chủ hàng chỉ bán cho người quen. Một số nơi tăng giá gấp mười. Một số nơi không bán nữa, giữ hàng sau cửa cuốn đóng kín. Đến khi có vụ đập cửa cướp nước đầu tiên ở một đại lý gần Mỹ Đình, ranh giới giữa mua bán và cướp bóc bắt đầu mờ đi. + +Điện mất cục bộ từ ngày thứ tám. Ban đầu chỉ là vài khu. Một tiếng. Hai tiếng. Rồi nửa ngày. + +Tại một chung cư ở Thanh Xuân, thang máy dừng giữa tầng mười bảy và mười tám lúc 13 giờ 40. Bên trong có bốn người: một nhân viên văn phòng, một bà cụ, một đứa trẻ và một shipper giao thuốc. Mười phút đầu họ còn bấm chuông cứu hộ. Hai mươi phút sau, đứa trẻ bắt đầu khóc. Bốn mươi phút sau, bà cụ ngồi bệt xuống sàn, thở dốc. Khi đội kỹ thuật mở được cửa thang, không ai trong nhóm còn đủ sức bước ra ngay. + +Tin nhắn trong nhóm cư dân bắt đầu bằng câu hỏi “bao giờ có điện lại”, chuyển sang “nhà ai còn nước”, rồi thành “ai có thuốc hạ sốt cho trẻ con không”. Đến tối, điện thoại nhiều người cạn pin. Nhóm chat thưa dần; tình hình không khá hơn, chỉ là người ta không còn đủ điện để tiếp tục kêu cứu. + +Bệnh viện quá tải từ ngày thứ chín. + +Tiến xem lại đoạn video Thủy gửi từ một bệnh viện phía Tây thành phố. Hành lang cấp cứu chật kín người. Người già nằm trên ghế nhựa, trẻ nhỏ được quạt bằng bìa carton, chai nước truyền treo tạm trên móc áo. Một bác sĩ trẻ lau mồ hôi bằng tay áo, quay đi vài giây rồi quay lại ép tim cho một bệnh nhân sốc nhiệt. Phía sau cô, máy lạnh kêu cạch cạch rồi tắt phụt. + +Không ai hét. Không ai khóc lớn. + +Cái chết trong bệnh viện đến bằng sự kiệt sức. Kho Ngọc Trục trở thành căn cứ thật sự của Tiến vào ngày thứ mười. Không còn là một kho hàng thuê tạm. Không còn là nơi chứa vật tư. Nó bắt đầu có quy tắc, tuyến vào, tuyến ra, ca trực, khu nước sạch, khu xử lý rác, khu ngủ, khu y tế, khu vật tư không được mở nếu không có lệnh. + +Tiến không nhận người bừa bãi. Hắn chỉ đưa vào bốn người đầu tiên. Người thứ nhất là **Nam**, hai mươi ba tuổi, nhân viên siêu thị được Thủy kéo ra từ Đại Hà. Tay cậu vẫn còn run mỗi khi nghe tiếng cửa cuốn. Đêm đầu tiên ở Ngọc Trục, chỉ cần gió làm tấm tôn kêu một tiếng, cậu đã bật dậy, lưng ướt mồ hôi. + +Người thứ hai là **ông Hòa**, một thợ điện già từng sửa hệ thống kho cho ông Lợi. Ông có đôi tay chai sạn, thói quen kiểm tra cầu dao bằng cách nghe tiếng rung rất nhỏ, và một câu nói cửa miệng: “Dây điện không nói dối, chỉ có người đọc sai nó.” Khi Tiến đưa ông vào xem tủ điện cũ của kho, ông chỉ liếc một lúc rồi bảo: “Cái này từng kéo tải lớn hơn kho hàng bình thường.” + +Người thứ ba là **Bình**, một shipper quen đường nhỏ phía Tây, người từng giúp Tiến chuyển vài đơn hàng mà không hỏi quá nhiều. Bình gầy, nhanh, nhớ ngõ tốt hơn nhớ tên người, và có một chiếc xe máy cũ kêu như sắp rụng máy nhưng vẫn luồn được qua những lối mà ô tô không vào nổi. + +Người thứ tư là **Linh**, dược sĩ làm ở một nhà thuốc gần Hà Đông. Sau Hồng Nhật, nhà thuốc của cô bị đập cửa hai lần. Lần thứ hai, cô gọi Thủy vì từng được phỏng vấn trong một bài về thuốc giả. Thủy đưa cô tới Ngọc Trục. Linh không nói nhiều; vừa nhìn kho thuốc Tiến chuẩn bị, cô xắn tay áo, kéo ba thùng nhựa lại gần và phân loại lại toàn bộ trong một buổi chiều. + +“Anh đang xây căn cứ,” Thủy nói khi nhìn Tiến đánh dấu phân khu trong kho. + +“Đang xây một cái hộp đủ lâu để không chết sớm.” + +“Khác nhau à?” + +“Khác. Căn cứ khiến người ta nghĩ tới an toàn. Chỗ này chỉ là trì hoãn.” + +Thủy không thích cách Tiến nói, nhưng sau Đại Hà, cô không còn phản bác những câu như thế nữa. Ngày thứ mười một, Tiến gọi về quê. Cuộc gọi mất gần hai phút mới kết nối. Giọng mẹ vang lên đứt quãng trong tiếng nhiễu. + +“Tiến… nghe không?” + +“Con nghe. Mẹ thế nào?” + +“Nóng lắm. Điện mất từ trưa. May có cái quạt sạc con gửi. Nước thì còn. Hàng xóm sang hỏi mua mấy thùng nhưng mẹ bảo của công ty con gửi nhờ.” + +“Đừng bán. Ai thân quá thì cho vài chai, nhưng đừng để họ biết mẹ còn nhiều.” + +“Ừ. Mẹ biết rồi.” Bà ngừng một chút. “Trên Hà Nội có sao không? Tivi nói có người chết ở trung tâm thương mại…” + +Tiến quay sang Nam đang ngồi ở góc kho, mắt trống rỗng. + +“Con ổn.” + +“Con đừng gạt mẹ.” + +Lần này Tiến không đáp. Ngón tay hắn miết nhẹ cạnh điện thoại. + +“Mẹ ở trong nhà. Uống nước đều. Nếu điện mất lâu, dùng máy phát nhỏ vào buổi tối thôi, đừng bật cả ngày. Xăng phải giữ kỹ. Ai hỏi thì nói không biết dùng.” + +“Ừ. Con cũng phải giữ mình.” + +Tín hiệu nhiễu mạnh hơn. + +“Mẹ?” + +Không có tiếng trả lời. Cuộc gọi rớt. Tiến vẫn giữ điện thoại bên tai cho tới khi màn hình tối hẳn. Hắn không thể rời Hà Nội. + +Chưa thể là bây giờ. Ngọc Trục còn chưa ổn, La Phù đang bị Đỗ Minh Kha gom hàng, HN-07 vẫn nằm dưới chân hắn, còn Hồng Nhật mới chỉ bắt đầu. Ngày thứ mười hai, La Phù có vụ nổ súng đầu tiên. Không ai biết ai bắn trước. Một nhóm dân cư tự tổ chức kéo tới đòi mua nước với giá cũ. Chủ kho không mở. Một xe tải trắng cố rời đi. Đám đông chặn đường. Có người ném đá. Có tiếng nổ. Một người ngã xuống. Rồi mọi thứ vỡ ra. + +Đỗ Minh Kha không xuất hiện công khai, nhưng xe của hắn vẫn rời khỏi La Phù trong đêm. Tiến rà các ảnh Thủy gửi, nhận ra LP-17 đã chuyển thêm ít nhất năm chuyến hàng về một điểm chưa xác định ở phía Tây Nam. Kha không tranh cãi với đám đông. Hắn đã lấy phần cần lấy trước khi đám đông nhận ra mình đói. + +Kẻ mạnh trong tận thế không phải kẻ cướp giỏi nhất. Là kẻ rời đi trước khi nơi đó cần phải cướp. Ngày thứ mười ba, Hồ Tây bắt đầu được nhắc đến. + +Ban đầu chỉ là vài bài đăng rải rác: nước rút nhanh, cá chết nhiều, mùi bùn bốc lên nặng hơn bình thường. Một số người cho rằng do nắng nóng kéo dài. Một số khác nói hệ thống thoát nước có vấn đề. Có người quay video ven hồ, chỉ vào vệt nước cũ trên bờ kè rồi nói mực nước đã tụt rõ. + +Buổi tối, Thủy gửi cho Tiến một bức ảnh chụp từ xa. Hồ Tây. Mực nước ven bờ đã rút xuống rõ rệt, để lộ một dải bùn đen bất thường. Ở giữa vùng nước sẫm màu, có một vòng xoáy nhỏ, rất nhẹ, gần như không thấy nếu không phóng lớn. Bên dưới ảnh, Thủy chỉ viết một câu: + +**Nó bắt đầu rồi.** + +Tiến mở bản đồ sinh tồn. Năm điểm đã đánh dấu — Ngọc Trục, La Phù, Láng, trung tâm thương mại Đại Hà ở Hà Đông, Hồ Tây — giờ như kéo nặng cả tờ giấy. Con trỏ dừng trên chấm đỏ ở Hồ Tây. + +Trong ký ức của hắn, phải nhiều tuần nữa vật thể dưới đáy hồ mới lộ rõ. Nhưng lần này, mọi thứ đang xảy ra nhanh hơn. Hoặc kiếp trước hắn đã biết quá muộn. Dưới nền kho, cánh cửa HN-07 vẫn im lặng. Nhưng Tiến có cảm giác thứ bên dưới đó đang lắng nghe. + +Chương 12: Dưới Đáy Hồ Tây + +Hồ Tây bốc mùi trước khi nó lộ ra bí mật. + +Mùi bùn nóng, mùi cá chết, mùi rong rữa và thứ mùi kim loại rất nhẹ, gần như lẫn vào hơi nước bốc lên từ mặt hồ. Những ngày trước Hồng Nhật, người ta đến đây để chạy bộ, uống cà phê, chụp ảnh hoàng hôn. Bây giờ, con đường ven hồ vắng hơn rất nhiều. Những quán cà phê còn mở thì kéo rèm kín, máy phát chạy khàn khàn phía sau nhà. Một số đoạn bờ kè bị căng dây tạm, không rõ là để giữ an toàn hay để ngăn người tò mò lại gần. + +Tiến và Thủy không đi sát bờ. + +Họ đứng trên tầng thượng một tòa nhà cũ cách hồ một khoảng đủ xa, dùng ống kính tele nhìn xuống. Dưới ánh mặt trời đỏ, mặt nước Hồ Tây không còn màu xanh xám quen thuộc mà sẫm lại như một tấm kim loại bị nung nóng từ bên dưới. Ven bờ, bùn đen lộ thành từng mảng dài. Cá chết dạt vào các góc khuất, bụng trắng nổi lên rồi xẹp xuống trong nắng. + +Thủy chỉnh tiêu cự máy ảnh, mặt tái đi sau lớp khẩu trang. + +“Mực nước tụt nhanh hơn mọi mô hình bay hơi tôi từng thấy.” + +“Không phải chỉ bay hơi.” + +“Anh từng thấy rồi?” + +Tiến không trả lời ngay. + +Trong ký ức cũ, lần đầu hắn tới Hồ Tây sau khi nước rút là vào tháng thứ ba sau Hồng Nhật. Khi đó nơi này đã bị vài nhóm sống sót phong tỏa một phần, vừa vì nguồn nước, vừa vì những lời đồn về vật thể dưới đáy hồ. Hắn không nhìn thấy giai đoạn đầu. Hắn chỉ nhìn thấy kết quả: những khối kim loại khổng lồ nằm dưới lớp bùn, như xương sườn của một con thú cổ đại bị chôn dưới thành phố. + +“Anh từng thấy thứ dưới đó,” hắn nói. + +Thủy hạ máy ảnh xuống. + +“Thứ gì?” + +“Không biết.” + +“Không biết hay không muốn nói?” + +“Không biết thật.” + +Câu trả lời khiến Thủy im lặng. + +Từ sau Hồng Nhật, cô đã quen dần với việc Tiến biết nhiều hơn người khác. Nhưng có những lúc chính hắn cũng không có đáp án. Những lúc ấy, vẻ bình tĩnh của hắn trở nên đáng sợ hơn cả khi hắn cảnh báo. Vì nếu một người từng sống qua tương lai mà vẫn không biết thứ đang tới là gì, nghĩa là thứ đó nằm ngoài cả ký ức của hắn. + +Dưới hồ, một vòng xoáy nhỏ xuất hiện gần vùng nước sẫm. Không lớn. Không dữ dội. Chỉ là một chuyển động tròn rất nhẹ, kéo theo vài vệt bọt màu xám. Nếu nhìn bằng mắt thường từ mặt đất, có lẽ không ai chú ý. Nhưng qua ống kính, vòng xoáy ấy rõ như một đồng tử đang mở. + +Thủy chụp liên tiếp. + +“Ở giữa có gì đó.” + +Tiến đưa ống nhòm lên. Ở vị trí vòng xoáy, mặt nước lõm xuống rất nhẹ. Bên dưới lớp nước đục, một đường thẳng tối màu hiện ra rồi biến mất. Nó quá đều và sắc để là thân cây hay cọc bê tông; hình dạng gần như mép của một tấm kim loại khổng lồ. + +Tiến cảm thấy cổ họng khô lại. Sớm hơn. Nó lộ ra sớm hơn kiếp trước rất nhiều. Một tiếng vo ve vang lên phía trên. Thủy ngẩng đầu. + +Một chiếc flycam nhỏ bay qua mái nhà, hướng về phía hồ. Thiết bị không thuộc về họ. Nó lượn một vòng rồi hạ thấp dần về vùng xoáy; chủ nhân có thể là nhóm truyền thông, một người tò mò hoặc một đơn vị đang khảo sát. Chiếc flycam bay được khoảng mười giây thì đột ngột mất thăng bằng. Nó nghiêng sang trái, xoay tròn, rồi rơi thẳng xuống mặt nước. + +Không có tiếng nổ. Không có tia lửa. Nó chỉ rơi xuống và biến mất. Thủy nhìn Tiến. + +“Thiết bị mất điều khiển?” + +“Có thể.” + +“Giống camera của anh ở Ngọc Trục?” + +“Có thể.” + +Cả hai đều biết hai chữ “có thể” không đủ. + +Dưới đường, một nhóm người dân bắt đầu tụ lại gần đoạn bờ kè. Có người chỉ xuống hồ. Có người quay điện thoại. Một nhân viên dân phòng đi tới yêu cầu họ lùi lại, nhưng đám đông không tản ra. Tiến nhìn đám người dồn về bờ kè và nhớ những lần kiếp trước người ta chết chỉ vì muốn đứng gần hơn một mét để nhìn cho rõ. Tò mò vốn vô hại khi còn hàng rào, cứu hộ và bệnh viện; lúc này, chỉ cần một người trượt xuống bùn cũng đủ kéo thêm vài người theo. + +Tiến cất ống nhòm. + +“Đi thôi.” + +“Chưa đủ ảnh.” + +“Đủ rồi.” + +“Tiến—” + +“Hồ Tây không phải nơi để ở lâu.” + +Giọng hắn không lớn, nhưng đủ khiến Thủy dừng lại. Cô nhìn xuống hồ lần cuối, rồi thu máy. Khi hai người rời khỏi tầng thượng, mặt trời đỏ sẫm treo phía trên thành phố, ánh sáng của nó rọi lên các bức tường cũ khiến mọi thứ như phủ một lớp gỉ máu. + +Trên đường về Ngọc Trục, họ đi qua một Hà Nội đã khác. + +Các cửa hàng đóng nhiều hơn mở. Một số ngã tư mất đèn tín hiệu, xe cộ chen nhau trong tiếng còi khản đặc. Người đi đường quấn khăn ướt quanh cổ, mang theo bình nước, đi sát bóng râm như những con vật tìm đường qua vùng đất cháy. Trên một bức tường ven đường, ai đó đã viết bằng sơn đỏ: + +**MẶT TRỜI ĐANG GIẾT CHÚNG TA** + +Không ai dừng lại xóa. Cũng không ai cười. + +Về đến kho Ngọc Trục, Tiến lập tức sao lưu ảnh của Thủy vào ổ cứng rời không nối mạng. Hắn không dùng máy chính. Không dùng đám mây. Không dùng bất kỳ hệ thống nào có thể tự động đồng bộ. Sau đó, hắn in ra ba bức ảnh rõ nhất. Bức thứ nhất: vòng xoáy nhỏ trên mặt Hồ Tây. Bức thứ hai: đường thẳng tối màu dưới lớp nước. Bức thứ ba: khoảnh khắc flycam nghiêng xuống trước khi rơi. + +Thủy đứng bên cạnh, nhìn ba bức ảnh dưới ánh đèn vàng của kho. + +“Anh nghĩ đó là gì?” + +Tiến không trả lời. + +Hắn lấy bản đồ sinh tồn ra, đặt ba bức ảnh cạnh điểm Hồ Tây. Sau đó, hắn lấy mảnh kim loại tìm được dưới Ngọc Trục, đặt gần điểm La Phù. Những mảnh ghép rời rạc nằm cạnh nhau: Ngọc Trục, La Phù, Láng, Đại Hà, Hồ Tây. Mỗi nơi là một thảm họa riêng. Nhưng khi nhìn tổng thể, chúng giống các mắt xích của cùng một cấu trúc. + +Một cấu trúc nằm dưới thành phố. Một cấu trúc đã ngủ rất lâu. Và Hồng Nhật chỉ là tiếng chuông đánh thức. Đúng lúc đó, ông Hòa gọi từ tủ điện phụ. + +“Tiến.” + +Giọng ông trầm xuống. + +“Cậu lại đây xem cái này.” + +Tiến bước tới. Đồng hồ nhiệt gắn dưới nền kho, gần khu kệ sắt che nắp HN-07, đang giảm rất nhanh. Không phải tăng. Giảm. Từ 29°C xuống 18°C, rồi 11°C, rồi 4°C trong vòng chưa đầy một phút. Giữa mùa Hồng Nhật, giữa một nhà kho mái tôn nóng hầm hập, một điểm dưới nền đang lạnh xuống như đá. Ông Hòa nuốt khan. + +“Cái nền này có hầm đông à?” + +Tiến không trả lời. Từ bên dưới nền kho, một tiếng động rất khẽ vang lên. Cộc. Như ai đó gõ vào kim loại từ phía dưới. Thủy lùi nửa bước. Cộc. + +Lần thứ hai. Khoảng cách giữa hai tiếng gõ đều đến mức không giống ngẫu nhiên. + +Cùng lúc đó, toàn bộ khu Láng trên bản đồ điện lực cũ mà Tiến đang mở trên màn hình phụ đột nhiên chuyển xám. Không phải mất điện thông thường. Lớp dữ liệu hiển thị tự động tắt từng trạm, từng tuyến, từng nút như bị một bàn tay vô hình rút nguồn khỏi khu vực đó. + +Màn hình phụ bật nền đen. Đã nhiều ngày HANOI-07 không xuất hiện trực tiếp. Tiến gần như đã quen với sự im lặng của nó. Nhưng lúc này, trên nền màn hình đen, một dòng chữ đỏ sẫm hiện lên chậm rãi. + +**THANG LONG GATE** + +Sắc mặt Thủy nhợt đi khi đọc dòng chữ. Tiến vẫn đứng cạnh màn hình. Dòng thứ hai xuất hiện. + +**INITIALIZING...** + +Ngay khoảnh khắc đó, bức ảnh Hồ Tây vừa in đổi tương phản trên mặt bàn kim loại lạnh. Lớp mực nhiệt sẫm xuống ở những vùng nhạy nhiệt, khiến đường thẳng dưới mặt nước hiện rõ hơn. Từ mép đường thẳng ấy, một ký hiệu mặt trời đỏ mờ mờ nổi ra, gần như không thể nhìn thấy nếu không biết phải tìm. + +Tiến đưa tay chạm vào bức ảnh. Giấy lạnh bất thường. + +Ngoài sân kho, gió nóng thổi qua mái tôn, tạo thành tiếng rền trầm và dài. Xa hơn, thành phố chìm trong những đốm điện chập chờn, những tiếng còi cứu thương rời rạc, những khu nhà tối om và những con đường bắt đầu vắng người. Hồng Nhật đang ép mọi lớp hạ tầng của Hà Nội đi qua những ngưỡng chúng chưa từng được thiết kế để chịu. + +Dưới nền kho, tiếng gõ thứ ba không vang lên. Chỉ có dòng **INITIALIZING...** tiếp tục nhấp nháy, như một hệ thống cũ vừa nhận ra thành phố phía trên đã bước vào trạng thái khẩn cấp. + +ARC 3: MẠNG LƯỚI THỨC GIẤC + +Chương 13: Sau Lò Hấp + +**06/07/2028** + +Đêm sau chuyến trở về từ Hồ Tây, Ngọc Trục không ai ngủ yên. + +Gió nóng đập vào mái tôn từng đợt, kéo theo tiếng rền khô như tiếng cát cọ vào kim loại. Trong kho, quạt công nghiệp chạy bằng ắc quy quay chậm hơn bình thường vì Tiến đã giảm công suất để tiết kiệm điện. Mùi thuốc sát trùng, mùi mồ hôi, mùi nhựa nóng và mùi nước đóng chai mới mở trộn lại thành một thứ không khí nặng nề, khiến mọi người nói chuyện cũng phải hạ giọng. + +Nam ngồi ở góc kho gần khu y tế tạm, hai tay ôm đầu gối. Cậu đã được Linh kiểm tra qua: không sốt cao, không chấn thương nặng, chỉ mất nước nhẹ và rối loạn hoảng sợ. Nhưng mỗi lần cửa cuốn bị gió làm rung, toàn thân Nam lại giật bắn, mắt mở to như vẫn còn kẹt trong hành lang tối của trung tâm thương mại. + +“Em không kéo được cô ấy ra,” Nam lẩm bẩm. + +Linh đang phân loại túi thuốc quay lại nhìn cậu. “Ai?” + +“Một bé gái. Tầm sáu tuổi. Em nghe tiếng nó gọi mẹ. Em thấy nó đứng sau cửa kính.” Nam nuốt khan, giọng vỡ ra. “Em kéo được một người già. Rồi cô Thủy kéo tay em. Em chạy. Em chạy mà vẫn nghe nó gọi.” + +Không ai trong kho trả lời. + +Thủy đứng gần cửa phụ, tay nắm chặt chiếc máy ảnh. Cô đã rửa mặt hai lần nhưng trên cổ vẫn còn vệt bùn đen từ bờ kè Hồ Tây. Mỗi khi Nam nói, sắc mặt cô lại tái thêm một chút. Tiến nhận ra điều đó nhưng không nói câu an ủi nào cho nhẹ miệng. Thủy đã cứu được sáu người và vẫn bỏ lại rất nhiều người; cả hai vế đều đúng. Nếu nói một vế để xóa vế kia, hắn chỉ đang giúp mình dễ chịu hơn chứ không giúp cô. + +Ông Hòa ngồi cạnh tủ điện phụ, tháo kính lão ra lau. Ông đã nghe Bình kể chuyện Đại Hà nhưng không hỏi thêm; có những lúc câu hỏi chỉ làm người kể phải sống lại một đoạn họ chưa nuốt nổi. Bình thì không giữ được im lặng lâu như ông. Cậu shipper gầy nhom đứng ở khe cửa, nhìn ra đường tối. + +“Anh Tiến, có người đến.” + +Tiến khóa màn hình bản đồ, chộp chiếc đèn pin nhỏ rồi bước tới. Camera ngoài cổng ghi lại ba bóng người đứng cách tường bao khoảng mười mét. Một người đàn ông trung niên, một phụ nữ bế đứa trẻ, và một thanh niên mặc áo bảo vệ đã rách vai. Họ không đập cửa. Chỉ đứng dưới nắng nóng còn sót lại của buổi tối, lảo đảo như có thể ngã bất cứ lúc nào. + +Bình hạ giọng. “Người từ Đại Hà?” + +Tiến rà kỹ bộ đồng phục của thanh niên. + +“Có thể.” + +Thủy bước lại gần. “Phải mở cửa.” + +“Không phải cứ có người tới là mở.” + +“Anh định để họ chết ngoài đó?” + +Tiến không nhìn cô, mắt vẫn dán vào màn hình camera. “Anh định biết họ là ai trước.” + +Người thanh niên ngoài cổng bỗng ngẩng đầu, như cảm nhận được camera. Hắn giơ hai tay, không cầm vũ khí, rồi nói rất lớn: + +“Chúng tôi không đến cướp! Tôi là bảo vệ ở Đại Hà! Có người bảo nếu thoát được thì tìm kho Ngọc Trục, gặp người tên Lê Quốc Tiến!” + +Cả kho im phăng phắc. Thủy quay phắt sang Tiến. + +“Anh nói với ai?” + +Tiến không đáp ngay. Hắn chưa từng nói tên mình cho bất kỳ người lạ nào ở Đại Hà. Hắn chỉ phá khóa lối giao hàng, gọi Thủy, kéo nhóm người ra ngoài rồi rời đi. Những người được cứu không biết hắn là ai, càng không biết Ngọc Trục. + +Bên ngoài, thanh niên bảo vệ tiếp tục nói, giọng khàn vì khát: “Người đó không ra được. Anh ta bị kẹt trong khu kỹ thuật. Anh ta nói: nếu còn sống, bảo Lê Quốc Tiến rằng Kha Đen đã lấy bản đồ phía Tây.” + +Đỗ Minh Kha. Không ai trong kho hiểu hết cái tên ấy có nghĩa gì, nhưng tất cả đều thấy sắc mặt Tiến thay đổi. Hắn quay sang Bình. + +“Cổng phụ. Chỉ mở khe nhỏ. Ông Hòa đứng sau tủ điện. Linh chuẩn bị nước muối loãng, nhưng không đưa thùng lớn ra ngoài. Thủy, cô đứng phía sau tôi.” + +Thủy không phản bác. Sau Đại Hà, cô đã hiểu một điều: lòng tốt không có quy trình sẽ biến thành thảm họa. + +Cổng phụ mở ra chưa đầy nửa mét. Ba người bên ngoài được đưa vào từng người một, kiểm tra túi, kiểm tra tay, kiểm tra vết thương. Người phụ nữ gần như khuỵu xuống ngay khi bước qua cổng. Đứa trẻ trong tay chị không khóc nữa, chỉ thở khò khè. Linh vội bế nó vào khu y tế. Nam nhìn đứa trẻ, môi run run, nhưng lần này cậu không quay đi. Cậu lấy một chai nước nhỏ, mở nắp bằng đôi tay run rẩy rồi đưa cho Linh. + +Người thanh niên bảo vệ tên là Phúc. Anh ta bị bỏng nhẹ ở cổ và cánh tay, mất nước nghiêm trọng, nhưng thần trí còn tỉnh. Sau khi uống từng ngụm nhỏ theo lệnh của Linh, anh ta kể lại chuyện bên trong Đại Hà sau khi Tiến và Thủy rời đi. + +Điện mất hẳn. Người trong trung tâm thương mại phá cửa siêu thị, tranh nước, tranh thức ăn. Một nhóm mặc đồ bảo trì đã mở được một phần khu kỹ thuật phía sau, nhưng không phải để cứu người. Họ lấy đi mấy ổ cứng camera, một hộp tài liệu từ phòng quản lý hạ tầng và một bản sơ đồ cũ của khu Hà Đông - La Phù - Ngọc Trục. Phúc nhìn thấy một người trong nhóm đeo nhẫn đen ở tay trái. + +“Kha,” Tiến nói. + +Phúc gật đầu khó nhọc. “Tôi không biết tên hắn. Nhưng người bị kẹt cùng tôi biết. Anh ta mặc áo kỹ thuật, khoảng bốn mươi tuổi, nói từng làm cho một dự án quan sát gì đó. Trước khi ngất, anh ta bảo tôi nhớ đúng câu này.” + +Phúc siết chai nước trong tay. + +“Anh ta nói: Kha Đen không tìm nước. Hắn tìm đường dưới nước.” + +Thủy lạnh người. + +“Đường dưới nước là gì?” + +Tiến hướng mắt về bản đồ Hồ Tây dán trên tường. + +“Có lẽ là thứ dưới Hồ Tây.” + +Không khí trong kho như bị kéo xuống thấp hơn. Phúc nhìn quanh, nhận ra nơi này không phải một điểm trú nóng ngẫu nhiên. Những thùng nước xếp kín, tủ thuốc, bảng phân ca, camera, tấm pin, bản đồ, tất cả cho thấy người tên Lê Quốc Tiến đã chuẩn bị từ trước. + +“Anh biết chuyện này sẽ xảy ra,” Phúc nói. + +Không phải câu hỏi. Tiến nhìn anh ta. “Biết một phần.” + +“Anh biết lối giao hàng từ trước?” Phúc hỏi. + +“Biết.” + +“Biết tải cửa, biết hành lang hẹp, biết điện có thể mất. Vậy vì sao anh không cho bảo vệ chia người thành từng nhóm từ sớm?” + +Câu hỏi khiến cả kho im đi. Nó không phải lời buộc tội chung chung; Phúc đang hỏi đúng vào phương án vận hành. Tiến đã nghĩ tới nó nhiều lần từ lúc rời Đại Hà. + +“Vì khi tôi cảnh báo, tôi không có quyền điều khiển bảo vệ hay ban quản lý. Đến lúc họ tin thì đám đông đã ép kín sảnh. Nếu mở lối kỹ thuật sớm mà không có người giữ hai đầu, nó sẽ biến thành một nút thắt khác.” + +Phúc nhìn thẳng hắn. “Anh có thử nói với họ chưa?” + +“Có. Không đủ sớm, cũng không đủ mạnh.” + +“Vậy đừng nói là anh không thể.” Phúc thở khó nhọc nhưng giọng vẫn rõ. “Anh có giới hạn. Khác với không thể.” + +Tiến im một nhịp rồi gật. “Đúng. Tôi đã chọn trong giới hạn đó. Tôi kéo được nhóm gần lối ra nhất và đóng lại trước khi hành lang nghẹt.” + +“Những người còn lại?” + +“Không ra được.” + +Sự thẳng thừng ấy khiến Phúc câm lặng. Ánh mắt Tiến đi qua từng người trong kho. + +“Đây là điều đầu tiên mọi người phải hiểu nếu muốn ở lại Ngọc Trục. Chúng ta không cứu được tất cả. Chúng ta chỉ có thể cứu những người mà việc cứu họ không giết cả căn cứ.” + +Thủy giữ ánh mắt ở hắn, quai hàm hơi siết lại. Cô ghét câu đó, nhưng sau Lò Hấp Hà Đông, cô không còn đủ ngây thơ để bảo nó sai. Đêm ấy, Tiến ghi thêm một dòng vào bảng quy tắc căn cứ. + +**Không mở cổng vì tiếng khóc. Chỉ mở cổng sau khi xác minh.** + +Bên ngoài, Hà Nội vẫn nóng như một cái lò không tắt. Bên trong, Nam viết thời gian xác minh mới lên cạnh chốt cổng. Dòng mực còn ướt khi tiếng khóc ngoài sân im xuống. + +Chương 14: Quy Tắc Ngọc Trục + +Sáng hôm sau, Tiến treo tấm bảng quy tắc đầu tiên lên tường kho. Tấm bảng được cắt từ một tấm nhựa quảng cáo cũ, mặt sau sơn trắng, chữ viết bằng bút dầu đen. Không đẹp. Không trang trọng. Nhưng trong một thành phố đang cạn nước và mất điện, những dòng chữ ấy có trọng lượng hơn mọi khẩu hiệu từng treo trong phòng họp. + +**QUY TẮC NGỌC TRỤC** + +**1. Nước được phân theo đầu người, không theo cảm xúc.** + +**2. Không ai tự ý mở cổng.** + +**3. Không dùng điện ngoài lịch.** + +**4. Không nhắc đến lượng vật tư thật với người ngoài.** + +**5. Người muốn ở lại phải có việc để làm.** + +**6. Vi phạm quy tắc bị đình quyền liên quan và xem xét theo mức độ; cố ý đe dọa an toàn chung có thể bị buộc rời căn cứ.** + +Nam đọc dòng cuối hai lần. “Ai là người xem xét?” + +Tiến đáp: “Tạm thời là những người phụ trách phần bị vi phạm. Sau này đông hơn thì phải tách ra.” + +“Vậy anh vừa làm luật vừa có thể đuổi người?” Thủy hỏi. + +Tiến nhìn lại tấm bảng. “Nếu để như thế thì đúng.” + +Bình huýt sáo khẽ. “Nghe không ổn lắm.” + +“Không ổn,” Thủy nói. “Ít nhất phải có hai người không cùng phụ trách xác nhận hành vi cố ý trước khi buộc ai rời.” + +Ông Hòa đang lau kính ở cạnh tủ điện lên tiếng: “Và trường hợp nguy hiểm tức thời thì người trực được khóa quyền trước, xét sau. Chứ chờ họp lúc có người đang châm lửa vào kho cũng không được.” + +Tiến cầm bút sửa ngay dưới dòng sáu: **Khẩn cấp: người trực được đình quyền tạm thời; quyết định buộc rời cần tối thiểu hai xác nhận độc lập.** + +Nam nhìn phần chữ mới rồi mới gật. Quy tắc đầu tiên của Ngọc Trục vừa được sửa trước khi kịp khô mực. + +Tiến đọc được sự khó chịu trên vài gương mặt. Điều đó không khiến hắn rút lại quy tắc, nhưng cũng không cho phép hắn tự coi mình là người duy nhất đúng. Kiếp trước, hắn từng thấy những khu trú ẩn sụp đổ không phải vì thiếu vật tư ngay từ đầu, mà vì không dám đặt luật. Một người lấy thêm nước vì con sốt. Người khác thấy vậy cũng lấy thêm vì mẹ già. Người thứ ba giấu một ít vì sợ ngày mai không còn. Đến ngày thứ tư, kho nước cạn một nửa và mọi người bắt đầu nghi ngờ nhau. Đến ngày thứ năm, dao xuất hiện. + +Tiến sẽ không để Ngọc Trục chết theo cách đó khi mình còn đủ quyền can thiệp. Ông Hòa là người đầu tiên phá im lặng. + +“Tôi phụ trách điện.” + +Tiến gật đầu. “Tủ chính, ắc quy, máy phát, lịch sạc. Mọi công tắc lớn phải qua ông.” + +Ông Hòa nhìn tấm bảng rồi kéo ghế tới tủ điện. “Tôi cần dây chịu tải, cầu chì, đồng hồ đo và hai cuộn băng đánh dấu khác màu. Cái kho này từng bị sửa chắp ba đời; trước khi đóng một cầu dao, tôi muốn biết nó thực sự nuôi cái gì.” Ông lấy bút chì, tự vẽ lại sơ đồ từ đầu thay vì tin nhãn cũ trên tủ. “Dây điện không biết nói dối. Nhãn dán thì có.” + +“Bình đi lấy.” + +Bình chỉ vào mình. “Em?” + +“Cậu nhớ đường nhỏ. Đi ban ngày ít nhất có thể. Không mua cùng một cửa hàng quá nhiều. Không để ai biết chuyển về đây.” + +“Có tiền không?” + +Tiến đưa cậu một phong bì. + +“Tiền mặt. Chia ba chỗ. Nếu bị chặn, bỏ một phần. Giữ người, không giữ tiền.” + +Bình nhận phong bì rồi chia tiền thành ba phần ngay trước mặt Tiến: một phần trong ví, một phần nhét vào lớp lót mũ bảo hiểm, phần còn lại cuộn trong túi dụng cụ. “Nếu bị giữ một chỗ còn hai chỗ để về.” Trước khi cất điện thoại, màn hình sáng lên một tấm ảnh cũ: một bé gái ôm con thỏ bông, đứng cạnh người phụ nữ quay nửa mặt khỏi máy. Bình tắt rất nhanh, nhưng Tiến vẫn thấy tên thư mục: **Bình An**. Cậu chưa từng kể vì sao hai mẹ con không ở cùng mình trước Hồng Nhật. + +Trước tận thế, Bình từng giao hàng khắp Hà Đông, La Khê, Đại Mỗ, Dương Nội, La Phù. Việc nhớ đường chỉ giúp cậu giao nhanh hơn người khác. Bây giờ, nó biến cậu thành mạch máu của căn cứ — và có thể là cách duy nhất lần theo gia đình mình. Linh nhận khu y tế. Cô không nói nhiều, chỉ viết lại danh sách thuốc Tiến chuẩn bị rồi gạch đỏ một loạt. + +“Anh mua nhiều thuốc cảm, thuốc hạ sốt, băng gạc. Tốt. Nhưng thiếu oresol, thiếu thuốc tiêu chảy, thiếu thuốc huyết áp, thiếu thuốc chống dị ứng, thiếu nước muối sinh lý. Và thiếu quy định dùng thuốc.” + +“Thuốc cũng cần quy tắc?” Nam hỏi. + +Linh nhìn cậu. “Trong ba ngày nữa, người ta sẽ uống thuốc hạ sốt như ăn kẹo. Trong bảy ngày nữa, người ta sẽ đổi đồng hồ, điện thoại, vàng cưới lấy một vỉ thuốc. Nếu không có quy tắc, thuốc hết trước khi bệnh thật đến.” + +Nam cúi đầu. Cậu từng đứng trong siêu thị nhìn người ta cướp nước. Bây giờ cậu hiểu một vỉ thuốc cũng có thể trở thành lý do để người ta giết nhau. Thủy không nhận nhiệm vụ ngay. Cô ngồi trước laptop không nối mạng, xem lại đoạn video Đại Hà còn lưu trong thẻ nhớ. Mỗi lần tiếng trẻ con khóc vang lên, ngón tay cô lại dừng trên phím cách. Tiến đi ngang qua, đặt trước mặt cô một tập giấy. + +“Cô phụ trách thông tin.” + +Thủy ngẩng lên. “Thông tin gì?” + +“Tuyến mất điện, điểm thiếu nước, bệnh viện quá tải, La Phù, Hồ Tây, Láng. Những gì cô lấy được nhưng không đưa lên mạng.” + +“Anh muốn tôi làm tình báo cho anh?” + +“Không. Tôi muốn cô làm đúng nghề của cô, nhưng lưu một bản cho những người có thể dùng nó để sống.” + +Câu trả lời khiến Thủy im lặng. Cô nhìn tập giấy, rồi nhìn Nam đang giúp Linh kê lại tủ thuốc. Cậu thanh niên sống sót từ Đại Hà không còn là nhân vật trong bài viết nữa. Cậu đang ở đây, thở, run rẩy, cần nước, cần thuốc, cần một nơi để không chết vì chính âm thanh của ký ức. + +“Tòa soạn muốn tôi viết bài khác,” cô nói. “Họ bảo bài Đại Hà phải chờ số liệu chính thức.” + +“Và cô sẽ chờ?” + +Thủy cười rất nhạt. “Không.” + +Tiến gật đầu. “Vậy chúng ta cần một kênh riêng.” + +Chiều hôm đó, Ngọc Trục có tranh cãi đầu tiên. + +Phúc, người bảo vệ Đại Hà được đưa vào đêm trước, muốn ra ngoài tìm em gái. Cô bé làm nhân viên quầy trà sữa, mất liên lạc từ lúc Đại Hà tối đi. Linh nói tình trạng của Phúc chưa đủ để ra ngoài. Thủy muốn đi cùng anh ta. Bình bảo khu quanh Đại Hà đang bị phong tỏa từng phần, xe cộ hỗn loạn, có đi cũng chưa chắc vào được. + +Phúc đập tay xuống bàn. + +“Vậy ngồi đây uống nước trong khi người nhà tôi chết ngoài kia à?” + +Nam co rúm lại. Tiến đặt bản đồ lên bàn. “Cậu muốn đi, tôi không giữ. Nhưng cậu không được mang theo nước của căn cứ quá định mức. Không được dùng xe của căn cứ. Không được tiết lộ vị trí kho.” + +Thủy quay sang hắn. + +“Anh không thể nói như vậy.” + +“Có thể.” + +“Anh ta vừa thoát chết.” + +“Vì vậy mới càng không được để anh ta kéo thêm người chết theo.” + +Phúc nhìn Tiến bằng ánh mắt đầy hận. “Anh có người thân không?” + +Tiến đặt cốc xuống, ngón tay dừng ở mép bàn. + +“Có.” + +“Vậy nếu mẹ anh kẹt ngoài kia thì sao?” + +Câu hỏi đánh trúng chỗ Tiến vẫn cố tránh. Quanh bàn, không ai chen lời. Hắn nhìn thẳng Phúc. “Nếu mẹ tôi kẹt ngoài đó, tôi sẽ muốn lao ra. Và nếu tôi lao ra trong lúc không có kế hoạch, tôi có thể chết trước khi gặp được bà.” + +Giọng hắn thấp xuống. + +“Cậu muốn tìm em gái thì chờ đến tối. Bình dẫn đường. Thủy không đi. Tôi cho cậu ba chai nước nhỏ, một khăn ướt, một bộ đàm ngắn tầm. Quá hai giờ không về, cổng không mở lần hai nếu có người bám theo.” + +Phúc nghiến răng. + +“Anh đúng là lạnh máu.” + +“Không. Tôi đang cố giữ cho cậu còn máu để mà tìm người.” + +Tối đó, Phúc và Bình rời kho qua cổng phụ. Họ không về sau hai giờ. + +Đến giờ thứ ba, camera ngoài đường ghi lại một chiếc xe tải trắng chạy chậm qua ngõ chính. Không bật đèn pha. Không có logo. Mép dưới thùng xe bám bụi, nhưng khi phóng lớn, Tiến nhìn thấy ký hiệu quen thuộc. + +**LP-17** + +Chiếc xe không dừng. Nó chỉ đi qua. Nhưng sáng hôm sau, trên cổng kho Ngọc Trục xuất hiện một vệt sơn đỏ rất mảnh. Một vòng tròn. Mười hai tia ngắn. Mặt trời đỏ. + +Đỗ Minh Kha đã tìm thấy họ. + +Chương 15: Kha Đen + +Bình trở về lúc gần sáng. Cậu không đi qua cổng chính. Cậu gõ ba nhịp ngắn vào tấm tôn phía sau kho, đúng tín hiệu đã hẹn trước, rồi chui qua lối hẹp giữa hai bức tường cũ. Áo cậu rách một đường dài, mặt bám bụi, môi nứt vì khát. Trên lưng Bình là Phúc, bất tỉnh, vai trái chảy máu. + +Linh lao tới trước tiên. + +“Đặt xuống. Đừng kéo tay anh ta.” + +Bình khuỵu xuống ngay khi Phúc được đỡ khỏi lưng. Cậu thở dốc, giọng đứt quãng. + +“Không tìm được em gái hắn. Nhưng tìm được cái này.” + +Cậu móc từ trong áo ra một mảnh thẻ nhựa cháy sém. Trên thẻ còn thấy một phần logo Đại Hà và tên phòng: **KỸ THUẬT HẠ TẦNG**. Mặt sau thẻ có một dòng chữ viết vội bằng bút dầu đen. + +**KHA LẤY SƠ ĐỒ DƯỚI NƯỚC. LÁNG LÀ NÚT TIẾP THEO.** + +Tiến cầm mảnh thẻ, ánh mắt tối lại. + +“Người kỹ thuật bị kẹt để lại?” + +Bình lắc đầu. “Bọn em chỉ tìm được áo bảo hộ và thẻ ở gần cửa phụ phía Bắc. Có máu, không có xác. Phúc nhận ra thẻ của người từng nhắn tìm anh, nhưng không thấy người.” + +Thủy đứng bên cạnh, sắc mặt trắng bệch. + +“Láng.” + +Tiến rà bản đồ. Ngọc Trục, La Phù, Hồ Tây, Đại Hà, Láng. Những điểm tưởng như rời rạc đang dần tự nối lại, không cần HANOI-07 giải thích. Ông Hòa bước từ ngoài sân vào, tay cầm một mảnh giấy gấp gọn. + +“Cậu nên xem cái này nữa.” + +Mảnh giấy được kẹp dưới khóa cổng sau khi chiếc xe LP-17 đi qua. Không ai trong kho thấy người đặt. Camera chỉ ghi được một khung hình nhiễu trắng dài ba giây. Khi hình ảnh trở lại, mảnh giấy đã nằm đó. Tiến mở ra. Bên trong chỉ có một địa chỉ, một thời gian và một câu. + +**14:00. Kho nước bỏ hoang sau đường gom La Phù. Đi một mình.** + +**Mày nghĩ Ngọc Trục là căn cứ. Sai rồi. Nó là cái khóa.** + +Không ký tên. Nhưng không cần ký. Đỗ Minh Kha. Thủy lập tức nói: “Không đi.” + +Tiến gấp tờ giấy lại. + +“Phải đi.” + +“Đây là bẫy.” + +“Chắc chắn.” + +“Vậy anh còn đi?” + +“Vì hắn muốn tôi biết hắn biết gì. Người như Kha không gửi lời chỉ để giết người. Nếu muốn giết, hắn đã để xe đâm cổng hoặc đốt kho lúc chúng ta ngủ.” + +Ông Hòa cau mày. “Cậu tin hắn?” + +“Không. Tôi tin cách hắn tính.” + +Đến 13 giờ 20, Tiến rời Ngọc Trục bằng xe máy của Bình. Hắn không đi một mình theo đúng nghĩa. Bình đi trước mười phút bằng đường khác, không lại gần điểm hẹn mà đứng ở một mái nhà có thể nhìn bao quát đường gom. Hai người thống nhất trước ba tín hiệu: an toàn, rút, và “bị ép nói”. Nếu Tiến phát tín hiệu thứ ba, Bình không lao vào cứu; cậu sẽ rời điểm quan sát, đổi tuyến và báo Ngọc Trục đóng kín. + +Thủy ở lại kho, giữ bộ đàm sóng ngắn và một bản chép địa điểm nhưng không biết chính xác mái Bình đứng. Ông Hòa cắt một mạch điện phụ; nếu Tiến không về trước 16 giờ thì chuyển toàn bộ kho sang chế độ đóng kín. Quy tắc cuối cùng rất rõ: cứu Tiến không được phép trở thành cách dẫn Kha về tận cổng. + +La Phù ban ngày sau Hồng Nhật giống một con thú bị thương. + +Một số kho đóng cửa im lìm. Một số kho bị phá, hàng hóa vương vãi, thùng carton cháy xém, nước chảy thành vệt đục trên nền. Mùi đường, bánh, khói, mồ hôi và rác lên men bốc lên dưới nắng đỏ, ngọt đến buồn nôn. Xa xa, một nhóm người cãi nhau trước cửa kho, tay cầm gậy sắt và dao phay. Không ai còn mặc cả bình thường. Mỗi cuộc mua bán đều giống một cuộc đàm phán có thể chuyển thành đâm chém. + +Kho nước bỏ hoang nằm sau một dãy tường xám, cửa cuốn mở một nửa. Bên trong tối, mát hơn ngoài trời vài độ nhưng vẫn nồng mùi nhựa và nước cũ. Tiến bước vào, không gọi. Đỗ Minh Kha đứng ở cuối kho. Hắn mặc áo sơ mi đen như lần trước, tay trái vẫn đeo chiếc nhẫn đen ở ngón áp út. Sau lưng hắn là ba pallet nước, hai người đứng gác và một lối thoát phụ mở sẵn. Đúng như ký ức của Tiến: Kha không bao giờ đứng ở nơi không có đường lui. + +“Kỹ sư Lê Quốc Tiến,” Kha nói. + +Giọng hắn nhẹ, gần như lịch sự. + +“Lâu rồi không gặp.” + +Tiến đối diện ánh mắt hắn. + +“Chúng ta từng gặp?” + +Kha mỉm cười. “Câu đó tùy thuộc vào việc mày tính thời gian theo đường thẳng hay vòng lặp.” + +Không khí trong kho như chùng xuống. Tiến giữ nguyên nét mặt. + +“Anh nhớ tương lai?” + +Kha đưa tay vuốt nhẹ chiếc nhẫn đen. Động tác rất nhỏ, đều đặn, như một thói quen giúp hắn sắp xếp suy nghĩ. + +“Tao không cần nhớ để biết.” + +“Biết bằng gì?” + +“Đủ thứ.” Kha nhìn những pallet nước sau lưng. “Một tuyến hàng chuyển sớm. Một danh sách tới không đúng thời điểm. Một người bán thứ hắn không hiểu. Chỉ cần đủ điểm, phần còn lại là logistics.” + +Hắn không xác nhận mình đã sống qua tương lai. Cũng không phủ nhận có một nguồn nằm ngoài hiện tại. + +“Anh thuộc Observation Initiative?” + +Kha cười khẽ. “Cái tên đó cũ rồi. Và cũng không chính xác. Quan sát chỉ là việc của những kẻ không đủ năng lực can thiệp.” + +“Vậy anh can thiệp bằng cách gom nước trước tận thế?” + +“Bằng cách bảo đảm nước không rơi vào tay đám đông ngu xuẩn.” + +Tiến lạnh mặt. + +“Đám đông đó là người.” + +Ngón cái Kha miết qua mặt trong chiếc nhẫn. “Tao từng để một đoàn cứu trợ đứng ngoài cổng bốn mươi bảy phút vì ba cấp quản lý chưa ký xong. Khi cửa mở, sáu người đã thành số liệu. Từ đó, tao không để giấy tờ quyết xe nào được chạy.” Hắn nói như một nguyên tắc hậu cần, không như lời kể về người chết. Tiến chỉ kịp thấy hai ký tự rất nhỏ khắc trong lòng nhẫn trước khi Kha xoay tay lại: **M.K.** + +“Người là trạng thái trước khi khát.” Kha nói câu đó rất bình thản. “Sau ba ngày không nước, họ là đám đông. Sau bảy ngày, họ là dịch bệnh. Sau mười ngày, họ là vũ khí. Mày từng thấy rồi, nên đừng giả vờ đạo đức với tao.” + +Tiến nắm chặt tay trong túi. Kha biết quá nhiều. + +“Anh muốn gì?” + +“Ngọc Trục.” + +“Không.” + +“Tao chưa nói điều kiện.” + +“Điều kiện nào cũng không.” + +Kha gật đầu như đã đoán trước. “Vậy tao đổi cách nói. Mày giữ được cái kho đó vì mày nghĩ nó là căn cứ. Nhưng dưới đó là một khóa. Khóa thì không thuộc về người ngủ trên nó. Nó thuộc về người biết dùng nó.” + +“Và anh biết dùng?” + +“Biết đủ để không đặt tay bừa lên nó như mày.” + +Tiến im lặng. + +Kha bước chậm sang một bên, để lộ một tấm bản đồ trải trên thùng nước phía sau. Đó là bản đồ cũ hơn bản đồ giao thông hiện đại, nhưng không hẳn là bản đồ cổ. Trên đó, phía Tây Hà Nội có nhiều đường nét ngầm nối La Phù, Ngọc Trục, Láng và Hồ Tây. Một số đoạn bị cháy mất. Một số đoạn được đánh dấu bằng mực đỏ. + +“Đại Hà có một phần sơ đồ hạ tầng cũ,” Kha nói. “Không nhiều. Nhưng đủ xác nhận Láng là nút tiếp theo.” + +“Vì sao nói với tôi?” + +“Vì mày sẽ đi.” + +“Anh muốn tôi mở đường?” + +“Tao muốn xem HANOI-07 chọn mày vì lý do gì.” + +Tiến không tránh ánh mắt hắn. + +“Anh sợ nó không chọn anh.” + +Nụ cười của Kha nhạt đi. Trong kho, hai người gác hơi động vai. Kha đưa tay, ra hiệu họ đứng yên. “Thông minh đấy.” Hắn nói nhỏ. “Nhưng đừng nhầm. Tao không cần nó chọn. Tao chỉ cần người được chọn không sống đủ lâu để dùng nó.” + +Ánh mắt hai người chạm nhau. Trong kho nước bỏ hoang, giữa một thành phố đang chết khát, hai kẻ từng giết và bị giết ở tương lai đứng đối diện nhau, nhưng không ai ra tay. Chưa phải lúc. Kha gấp bản đồ lại. + +“Ba ngày nữa, khu Láng sẽ mất sạch tín hiệu. Nếu mày muốn biết vì sao Hồ Tây thức dậy, tới đó trước khi bùn Tô Lịch khô hẳn.” + +“Và nếu tôi không tới?” + +“Khi đó, tao sẽ tới.” + +Kha xoay người rời đi bằng cửa phụ. Trước khi biến mất, hắn dừng lại. “À, chuyển lời cho phóng viên Trần Thanh Thủy. Những người ghi chép sự thật thường chết trước những người làm ra nó.” + +Cửa phụ đóng lại. Tiến đứng yên vài giây, rồi mở bộ đàm. + +“Thủy.” + +Đầu bên kia lập tức trả lời. + +“Tôi nghe.” + +“Kha biết cô.” + +Một khoảng im lặng ngắn. + +“Vậy chúng ta càng phải tới Láng trước hắn.” + +Tiến rà tấm bản đồ còn hằn vết bụi trên thùng nước. Con số **47** mắc lại trong đầu cùng hai chữ **M.K.** ở mặt trong chiếc nhẫn. + +Ngoài cửa kho, Kha lên xe trước khi hai người gác kịp mở hết cổng. Hắn không chờ bất kỳ ai ký cho mình quyền rời đi. + +Chương 16: Trạm Láng + +Khu Láng mất tín hiệu vào rạng sáng ngày thứ mười sáu sau Hồng Nhật. + +Không phải mất sóng thông thường. Trên bản đồ hạ tầng Tiến dựng lại từ dữ liệu cũ, các trạm phát, tủ cáp, nút điện phụ và camera giao thông quanh đường Láng tắt dần theo một vòng tròn rất đều. Từ ngoài vào trong. Từng điểm xám đi như bị một bàn tay vô hình đặt lên bản đồ rồi xoay chậm. + +Ông Hòa nhìn màn hình, mặt nhăn lại. “Điện không chết kiểu này.” + +“Vậy chết kiểu gì?” Bình hỏi. + +“Điện chết vì quá tải thì nổ chỗ yếu trước. Chết vì cắt nguồn thì tắt theo tuyến. Cái này…” Ông chỉ vào vòng xám đang co lại. “Giống bị rút tim.” + +Kha đã nói ba ngày nữa Láng sẽ mất sạch tín hiệu, và hắn đúng gần như từng giờ. Tiến thấy điều đó đáng ngại hơn mọi lời đe dọa: một kẻ thù biết thảm họa sẽ đến lúc nào luôn nguy hiểm hơn kẻ chỉ có nhiều súng. + +Thủy đến Ngọc Trục trước bình minh. + +Cô không mang máy ảnh lớn. Chỉ có một túi nhỏ, hai pin dự phòng, một máy ghi âm, một bản đồ giấy, một con dao gấp và tập tài liệu bọc trong túi chống nước. Sau Đại Hà, cô thay đổi cách chuẩn bị. Không còn phong cách phóng viên đi hiện trường bình thường nữa. Mỗi món đồ cô mang đều có lý do để sống thêm vài giờ. + +“Tôi đi cùng,” cô nói. + +“Biết.” + +“Anh không cản?” + +“Cản không được.” + +“Ít nhất anh đã học được một điều.” + +Tiến quay sang cô. + +“Nhưng cô phải nghe lệnh khi có nguy hiểm.” + +Thủy cười nhạt. “Câu đó thường là câu mở đầu cho việc tôi không nghe.” + +“Vậy cô ở lại.” + +Nụ cười trên môi Thủy tắt hẳn. Cô cân nhắc một lúc rồi gật đầu. “Được. Khi có nguy hiểm rõ ràng, tôi nghe.” + +“Không phải rõ ràng. Khi tôi nói chạy, cô chạy.” + +“Được.” + +Bình dẫn đường. Cậu chọn tuyến nhỏ qua các ngõ ít người, tránh những điểm đang có tranh cướp nước. Nam cũng muốn đi, nhưng Tiến từ chối. Cậu chưa sẵn sàng rời căn cứ. Linh ở lại phụ trách y tế, ông Hòa giữ điện và máy phát. Phúc còn sốt, không thể di chuyển. + +Ba người rời Ngọc Trục lúc 5 giờ 10. + +Hà Nội trước bình minh không mát hơn bao nhiêu. Không khí vẫn nóng, chỉ bớt phần ánh sáng đỏ làm người ta phát điên. Một số người ngủ ngay trên vỉa hè vì trong nhà quá nóng. Có người ôm bình nước như ôm trẻ con. Vài cửa hàng bị phá, biển hiệu rơi xuống đất, kính vỡ lấp lánh dưới ánh đèn pin. Trên tường, những dòng chữ mới xuất hiện: **NƯỚC**, **ĐIỆN**, **CỨU CHÚNG TÔI**. + +Đường Láng nằm im lặng bất thường. + +Không phải vắng người hoàn toàn. Vẫn có bóng người đi lại, vẫn có xe máy đẩy bộ, vẫn có vài nhóm dân cư tụ bên vòi nước công cộng đã cạn. Nhưng âm thanh ở đây bị hút xuống thấp. Không có tiếng loa, không có tiếng máy phát, không có tiếng radio. Ngay cả tiếng còi xe từ xa cũng như bị tường vô hình chặn lại. + +Thủy dừng trước một đoạn nhìn xuống sông Tô Lịch. Nước sông đã rút nhiều, chỉ còn một dòng đen đặc ở giữa lòng kênh. Hai bên bùn lộ ra, nứt thành từng mảng, bốc mùi hôi nồng dưới nắng sắp lên. Nhưng giữa lớp bùn đen, có những đường thẳng xám nhạt chạy song song, đều đến mức không thể là tự nhiên. + +“Đó là gì?” Bình hỏi. + +Tiến đưa ống nhòm cho Thủy. Cô chỉnh tiêu cự, nhìn xuống lớp bùn rồi hạ ống. “Không phải cống.” + +“Vì sao?” + +“Cống không khắc ký hiệu lên nắp.” + +Dưới lớp bùn, trên một mảng vật liệu xám lộ ra nửa phần, có một ký hiệu mặt trời đỏ bị bùn che mất một nửa. Tiến cảm thấy ngực nặng xuống. Ngọc Trục không phải điểm cô lập. Ký hiệu này đã nằm dưới Láng từ lâu. + +Họ men theo bờ kênh, tránh đám đông. Bình dẫn vào một con ngõ nhỏ gần Chùa Láng. Càng vào sâu, nhiệt độ trên máy đo của Tiến càng lạ. Không tăng, cũng không giảm đều. Nó nhảy từng nhịp: 43°C, 39°C, 45°C, 37°C. Như thể các vùng không khí chồng lên nhau mà không trộn. + +“Máy hỏng à?” Bình thì thầm. + +“Không.” Tiến đáp. “Không khí hỏng.” + +Thủy liếc hắn. “Câu đó đáng sợ hơn anh nghĩ.” + +Cuối ngõ là một căn nhà hai tầng cũ, cửa sắt khóa ngoài, biển hiệu đã bị tháo. Theo dữ liệu Thủy lấy được trước Hồng Nhật, nơi này từng là văn phòng của một đơn vị tư vấn môi trường đô thị. Nhưng trong một file log cũ, địa chỉ này xuất hiện dưới mã khác: + +**S07-LANG / OBSERVATION SUBNODE** + +Bình nhìn khóa cửa. “Phá không?” + +Tiến kiểm tra xung quanh. + +“Không phá lớn. Mở im.” + +Bình cười méo. “Anh nghĩ shipper nào cũng biết mở khóa à?” + +“Cậu từng giao hàng lúc khách quên chìa trong nhà.” + +“Đấy là em trèo ban công.” + +“Vậy trèo.” + +Bình chửi rất nhỏ, nhưng vẫn trèo. + +Năm phút sau, cửa trong được mở từ bên trong. Căn nhà tối, nóng và đầy bụi, nhưng không có dấu hiệu bị lục soát gần đây. Tầng một trống gần hết. Tầng hai có vài bàn làm việc cũ, tủ hồ sơ rỗng, dây mạng bị cắt. Không có gì đáng chú ý cho đến khi Thủy phát hiện một vết trầy trên nền gạch sau tủ tài liệu. + +Tủ quá nặng để người thường di chuyển một mình. Nhưng Bình tìm thấy ròng rọc nhỏ gắn vào chân tủ. + +“Có người muốn cái tủ này trông như không thể di chuyển,” cậu nói. + +Tiến và Bình kéo tủ sang bên. Bên dưới là một nắp kim loại vuông, nhỏ hơn nhiều so với nắp ở Ngọc Trục. Không có ký hiệu đỏ phát sáng. Chỉ có một hàng chữ khắc chìm: + +**LANG / LISTENING WELL** + +Giếng nghe. Thủy đọc thành tiếng, giọng khàn đi. + +“Giếng nghe là gì?” + +Tiến quỳ xuống, đặt tay gần nắp nhưng không chạm. “Tôi không biết.” + +Từ dưới nắp vọng lên một âm thanh rất thấp, không giống tiếng máy hay tiếng nước. Nó gần với tiếng người thì thầm qua một bức tường quá dày, từng âm tiết bị kéo giãn đến mức không thể hiểu. Bình lùi lại. + +“Em không thích cái này.” + +Thủy bật máy ghi âm. Đèn máy chớp một cái rồi tắt phụt. Tiến quay sang cô. + +“Không dùng thiết bị.” + +“Vậy ghi kiểu gì?” + +Tiến lấy giấy bút đưa cho cô. + +“Bằng tay.” + +Thủy cúi sát xuống, lắng nghe. Những âm thanh bên dưới lặp lại theo nhịp. Cô không hiểu nghĩa, nhưng nhận ra có cấu trúc. Dài. Ngắn. Ngắt. Lặp. Cô viết lại theo ký hiệu của mình. Ba phút sau, âm thanh dừng hẳn. Cùng lúc đó, bên ngoài ngõ vang lên tiếng bước chân. Không phải một nhóm dân thường. Bước chân đều, nhẹ, quen thuộc. + +Bình nhìn Tiến. “LP-17?” + +Tiến tắt đèn pin. + +“Không. Nhanh hơn.” + +Thủy gấp giấy bỏ vào túi. + +“Người của Kha?” + +Tiến nghe thêm một giây. Có tiếng kim loại chạm vào tường. Có tiếng ai đó nói nhỏ qua bộ đàm. Rồi một giọng nam vang lên ngoài cửa tầng một. + +“Kiểm tra tầng trên. Nếu gặp Lê Quốc Tiến, không bắn vào đầu. Anh Kha muốn hắn còn nói được.” + +Bình nuốt khan. + +“Em rút lại. Em cực kỳ không thích cái này.” + +Tiến nhìn nắp kim loại dưới sàn. Từ bên dưới, tiếng thì thầm lại vang lên. Lần này, giữa những âm thanh kéo dài, có một cụm từ tiếng Việt rất mờ. + +**...không mở... khi mặt trời còn đỏ...** + +Thủy nhìn Tiến, mặt trắng bệch. Tiếng bước chân đã lên cầu thang. Trạm Láng vừa thức dậy. Và họ không phải những người duy nhất nghe thấy. + +Chương 17: Nước + +Tiến không mở nắp Trạm Láng. Đó là quyết định đúng đầu tiên trong ngày. + +Quyết định đúng thứ hai là kéo Thủy và Bình chạy theo lối mái nhà thay vì xuống cầu thang. + +Người của Kha lên tới tầng hai đúng lúc Bình đạp tung tấm cửa thông ra sân thượng. Nắng đỏ ùa vào như lửa. Ba người lao qua mái nhà thấp bên cạnh, trượt xuống một ban công cũ, rồi chui vào lối thoát hiểm của một khu tập thể bỏ gần hết người. Sau lưng, tiếng quát và tiếng bước chân đuổi theo vang lên, nhưng khu Láng quá nhiều ngõ, quá nhiều lối thông, quá nhiều ban công và mái tôn cũ. Bình ở đây như cá gặp nước. + +“Trái!” cậu hét nhỏ. + +Tiến kéo Thủy rẽ vào một cầu thang tối. Họ chạy xuống hai tầng, chui qua một cửa sổ đã mất kính, băng qua mái bếp nhà dân, rồi nhảy xuống một ngõ nhỏ đầy thùng xốp. Một bà cụ đang ngồi quạt mo trước cửa nhìn ba người rơi xuống, không hét, chỉ chậm rãi hỏi: + +“Trốn nợ à?” + +Bình vừa thở vừa đáp: “Vâng bà ạ.” + +Bà cụ gật đầu. “Chạy nhanh. Bọn đòi nợ giờ cũng khát nước lắm.” + +Nếu không phải đang bị truy đuổi, Thủy có lẽ đã bật cười. + +Họ thoát khỏi Láng trước khi mặt trời lên cao hẳn. Về tới Ngọc Trục, cả ba gần kiệt sức. Linh bắt từng người ngồi xuống và uống nước muối loãng thành từng ngụm; ai vừa chạm chai lên miệng quá nhanh đều bị cô kéo xuống. Trong nhiệt độ này, uống sai cách cũng có thể nôn hết ra, thậm chí sốc cơ thể. + +Thủy lấy tờ giấy ghi âm bằng tay ra. Mực đã nhòe vì mồ hôi, nhưng vẫn đọc được vài chuỗi ký hiệu cô chép lại. + +“Không mở khi mặt trời còn đỏ,” cô nói. “Tôi chắc chắn nghe được câu đó.” + +Ông Hòa cau mày. “Cái gì không mở?” + +“Cổng,” Tiến đáp. + +Không ai hỏi cổng nào. Tất cả đều nghĩ tới cùng một thứ. + +Cổng Thăng Long. Nhưng vấn đề cấp bách hơn xuất hiện vào buổi chiều. Bể chứa phụ của Ngọc Trục tụt nhanh bất thường. + +Ông Hòa phát hiện đầu tiên khi kiểm tra đồng hồ bơm. Theo tính toán, với số người hiện tại, lượng nước đã lọc và đóng kín đủ dùng tiết kiệm trong nhiều tuần. Nhưng mực bể phụ giảm gần một phần mười chỉ trong nửa ngày. Không có dấu hiệu vỡ ống lớn. Không có nước tràn trên nền. Không ai dùng vượt định mức. + +“Rò dưới đất,” ông Hòa nói. + +Tiến lập tức kiểm tra đường ống. Vết rò nằm ở đoạn dẫn từ bể phụ sang khu lọc. Một lỗ nhỏ bằng đầu đũa trên ống nhựa, gần như không đáng kể trước Hồng Nhật. Nhưng trong căn cứ lúc này, nó là một vết thương chí mạng. Nước thấm xuống nền, biến mất vào khe bê tông cũ trước khi ai kịp thấy. + +Nam đứng bên cạnh, mặt tái đi. + +“Mất bao nhiêu?” + +“Ít nhất hai trăm lít,” Tiến nói. + +Bình chửi thề. Linh mím môi. Hai trăm lít. Trước tận thế, đó là vài lần tắm, vài máy giặt, vài thùng nước lau nhà. Bây giờ, đó là mạng sống nhiều ngày của cả căn cứ. Ánh mắt Tiến đi một vòng qua mọi người. + +“Từ hôm nay giảm định mức.” + +Nam lập tức ngẩng đầu. + +“Giảm nữa?” + +“Giảm nữa.” + +“Nhưng Phúc còn sốt. Đứa bé kia cũng cần nước.” + +“Linh sẽ có định mức y tế riêng. Phần sinh hoạt giảm.” + +Phúc, vẫn còn yếu, chống tay ngồi dậy. + +“Tôi nhường phần của tôi.” + +Linh quay phắt sang. + +“Anh nhường để chết à? Tôi không nhận bệnh nhân tự tử bằng tử tế.” + +Phúc ngậm miệng, vẫn còn bực nhưng không cãi với Linh. Thủy quay sang Tiến. + +“Có cách bổ sung không?” + +“Có.” + +“Ở đâu?” + +Tiến mở bản đồ. + +“La Phù còn nước, nhưng thuộc Kha. Một số khu dân cư còn bể ngầm, nhưng sẽ có người canh. Giếng khoan cũ ở Ngọc Trục bị niêm phong, chưa rõ dùng được không. Hồ Tây không dùng được. Nước máy thành phố không ổn định.” + +Bình nuốt khan. + +“Tức là không có cách nào dễ.” + +“Nếu còn đường dễ thì người ta đã không giành nhau từng chai nước.” + +Tối đó, Tiến gọi về quê. Lần này tín hiệu yếu hơn nhiều. Mất bốn lần mới kết nối. “Mẹ?” + +“Tiến à, nghe được không?” + +“Con nghe. Ở nhà thế nào?” + +“Điện mất nhiều hơn. Nước giếng còn, nhưng nóng lắm. Mấy nhà quanh đây bắt đầu sang xin nước. Mẹ cho mỗi nhà một ít.” + +Tiến nhắm mắt. + +“Mẹ cho vừa thôi. Đừng để ai biết trong nhà còn nhiều nước con gửi.” + +“Biết rồi. Nhưng người làng với nhau…” + +“Mẹ.” + +Giọng hắn cứng đi. Bên kia không đáp. Tiến tự hạ giọng trước. + +“Con biết khó. Nhưng nếu họ biết mẹ có nhiều, họ sẽ không chỉ xin. Lúc đầu là xin. Sau đó là trách. Rồi họ sẽ nói nhà mình ích kỷ. Rồi sẽ có người tới lúc mẹ ngủ.” + +Bên kia chỉ còn tiếng nhiễu một lúc lâu. “Con thay đổi nhiều quá,” mẹ nói nhỏ. + +Tiến cảm thấy cổ họng đau. + +“Con xin lỗi.” + +“Không. Mẹ chỉ…” Bà thở dài. “Mẹ sẽ cẩn thận.” + +Trước khi cúp máy, bà kể một chuyện khiến Tiến lạnh gáy. + +Chiều qua có hai người lạ về xã, hỏi mua máy phát và nước đóng chai số lượng lớn. Họ đi xe bán tải trắng, không nói giọng địa phương. Một người hỏi nhà bà có phải có con làm ở Hà Nội không. + +“Con quen ai ở quê à?” bà hỏi. + +Tiến đứng bật dậy. + +“Không. Mẹ nghe con. Từ giờ không nói với ai về đồ con gửi. Nếu hai người đó quay lại, mẹ sang nhà bác Dũng ngay. Đừng ở một mình.” + +“Có chuyện gì?” + +“Làm theo con.” + +Cuộc gọi rớt trước khi hắn kịp nói thêm. Tiến đứng giữa kho, điện thoại trong tay nóng lên vì pin yếu. Kha đã không chỉ tìm thấy Ngọc Trục. Hắn đang dò tới quê của mẹ. Thủy nhìn sắc mặt Tiến, hiểu ngay có chuyện. + +“Mẹ anh?” + +Tiến gật đầu. Bình chửi thề lần thứ hai trong ngày. “Bọn LP-17 tới tận Thanh Hóa?” + +“Chưa chắc là LP-17,” Tiến nói. “Nhưng cùng kiểu.” + +Ông Hòa siết chặt tua vít. + +“Cậu muốn về quê?” + +Tiến rà bản đồ. Hà Nội đang chết. Ngọc Trục còn chưa ổn. Láng vừa mở tín hiệu. Hồ Tây đang lộ xương. Kha đang chuyển quân. Và ở Thanh Hóa, mẹ hắn có thể đã bị đánh dấu. Không có lựa chọn nào không đau. Linh bước tới, đặt một chai nước nhỏ lên bàn. + +“Anh không thể đi một mình.” + +“Chưa đi,” Tiến nói. + +Nhưng chính hắn cũng nghe thấy sự do dự trong giọng mình. Thủy trải lại bản đồ kỹ thuật họ lấy từ trạm Láng. Ở mép bản đồ có một ký hiệu giọt nước bị gạch chéo, trước đây cô cho là dấu hỏng. Ông Hòa nhìn lâu rồi chỉ một đường ống cũ chạy từ khu phía nam Hồ Tây về tuyến bơm dự phòng. + +“Không phải tọa độ,” ông nói. “Là ký hiệu nguồn không dùng cho ăn uống.” + +“Nhưng có thể dùng sau xử lý?” Thủy hỏi. + +“Có thể. Nếu đường còn.” + +Tiến đối chiếu với bản đồ cấp nước thành phố đã lưu trước Hồng Nhật. Điểm giao nằm gần một trạm bơm cũ phía nam Hồ Tây — nơi đủ gần mạch ngầm, đủ xa khu dân cư và chưa có dấu nhóm lớn chiếm. Tủ điện phụ kêu tách. Màn hình HN-07 chỉ hiện một cảnh báo: + +**WATER CONDUCTIVITY DEVIATION – WESTERN NETWORK** + +Không có tọa độ, mũi tên hay “nhiệm vụ”. Dữ liệu của hệ thống chỉ xác nhận điều họ vừa suy ra: mạng nước phía Tây đang đổi. + +Thủy khoanh trạm bơm trên bản đồ. “Chúng ta kiểm tra ở đây.” Tiến nhìn bể nước đang tụt, rồi nhìn điện thoại vừa mất sóng sau cuộc gọi với mẹ. Hồng Nhật không cho hắn giải từng vấn đề theo thứ tự. Nước, mẹ, Kha, Láng và Hồ Tây đang cùng siết lại. + +Nhưng lần này, điểm đến không do HANOI-07 chỉ. Là do những người còn sống đọc bản đồ và tự chọn. + +Chương 18: Hồ Tây Lộ Xương + +Điểm giao mà Thủy và ông Hòa tự suy ra từ bản đồ nước nằm gần một trạm bơm cũ phía nam Hồ Tây. HN-07 không đưa tọa độ; nó chỉ báo độ dẫn điện mạng phía Tây đang đổi. Chính vì vậy, không ai được phép coi trạm bơm là “đáp án của hệ thống”. Nó chỉ là giả thuyết tốt nhất mà họ đang có. + +Trước Hồng Nhật, nơi đó không đáng chú ý. Một công trình thấp, tường xám, cửa sắt rỉ, nằm khuất sau hàng cây và vài đoạn bờ kè cũ. Người đi qua chỉ thấy một mảng hạ tầng đô thị vô danh, giống hàng trăm trạm bơm, tủ điện, nhà kỹ thuật rải khắp Hà Nội. Nhưng sau khi mặt trời đỏ xuất hiện, những nơi vô danh bắt đầu có giá trị khác. + +Chúng là chỗ thành phố giấu xương. + +Tiến không muốn rời Ngọc Trục khi vấn đề nước chưa xử lý xong, nhưng điểm giao xuất hiện đúng lúc bể phụ rò rỉ đủ để đáng kiểm tra. Ông Hòa ở lại vá đường ống và kiểm tra giếng khoan cũ. Linh quản lý nước và y tế. Nam được giao phụ cô, đồng thời ghi định mức từng người. Bình muốn đi, nhưng sau chuyến Láng, cậu kiệt sức. Lần này chỉ có Tiến và Thủy; một đội lớn hơn sẽ dễ bị nhận ra quanh Hồ Tây. + +Trước khi đi, Thủy viết ba mốc lên bảng: giờ tới, giờ gọi lại, giờ rút. Nếu quá mốc cuối mười lăm phút mà không có tín hiệu, Ngọc Trục không cử người lao vào tìm; Bình sẽ kiểm tuyến thứ hai trước, còn Linh giữ căn cứ. Tiến không thích điều khoản đó. Chính vì thế Thủy bắt hắn ký tên bên cạnh. + +“Anh tin điểm đó?” Thủy hỏi. + +“Không.” + +“Vậy sao đi?” + +“Vì nó kiểm chứng được. Và vì Kha cũng có đủ dữ kiện để tự suy ra.” + +Tin HN-07 và phản ứng trước cùng một tín hiệu là hai chuyện khác nhau. Tiến không cần gán ý tốt cho hệ thống; hắn chỉ cần tính đến việc mọi phe có thông tin đều sẽ bị kéo về Hồ Tây. Nếu hắn không đến, hắn sẽ chậm hơn một nước. Đường tới Hồ Tây nguy hiểm hơn lần trước. + +Các tuyến phố gần hồ bị chặn từng đoạn bằng rào tạm, xe máy bỏ lại, thùng nước rỗng và những đống rác chưa ai thu gom. Mùi bùn nóng lan xa hơn, nặng đến mức phải đeo khẩu trang ướt mới chịu nổi. Trên mạng, những video về “vật thể dưới Hồ Tây” đã bắt đầu lan truyền, nhưng phần lớn bị xóa nhanh hoặc bị gắn nhãn tin giả. Điều đó không làm người dân bớt tò mò. Ngược lại, càng xóa, đám đông càng kéo tới. + +Tiến dừng xe cách trạm bơm hơn ba trăm mét. + +“Đi bộ.” + +Thủy nhìn đám người tụ gần bờ hồ. “Nếu chen vào đó sẽ bị kẹt.” + +“Không chen. Đi phía sau trạm.” + +Hai người men theo một lối nhỏ giữa các bức tường cũ. Cây ven hồ héo rũ, lá quăn lại như bị nướng. Một con chó nằm dưới gầm xe máy, thở dốc, lưỡi thè ra nhưng không còn sức sủa. Trên mặt đường, vài con cá nhỏ chết khô dính vào bụi bùn, không hiểu bị nước rút kéo ra từ lúc nào. + +Trạm bơm khóa ngoài. Khóa mới. Không phải khóa rỉ cũ của công trình bỏ quên. Một ổ khóa đen, thân dày, lắp vội nhưng chắc. Tiến kiểm tra dấu chân gần cửa. Có ít nhất bốn người đã vào đây trong vòng một ngày. Một vệt bánh xe nhỏ kéo tới cửa phụ, giống xe đẩy thiết bị. + +“Kha?” Thủy hỏi. + +“Có thể. Hoặc người khác.” + +“Anh ghét hai chữ đó lắm đúng không?” + +“Vì chúng thường đi trước rắc rối.” + +Tiến không phá khóa chính. Hắn tìm cửa thoát gió phía sau, tháo lưới bằng dụng cụ nhỏ, rồi chui vào trước. Bên trong trạm bơm tối, nóng, nhưng không hôi như bên ngoài. Không khí ở đây khô bất thường, mang mùi kim loại lạnh rất giống luồng khí dưới Ngọc Trục. + +Thủy chui vào sau, bật đèn pin bọc giấy mờ. + +Máy bơm cũ nằm im. Đường ống lớn chạy xuống nền, một số đoạn đã được thay mới nhưng không theo tiêu chuẩn hiện đại. Trên tường có bản vẽ kỹ thuật thành phố, nhiều chỗ bị xé. Ở góc phòng, một tấm nắp sàn vừa được mở rồi đóng lại không kín. Mép nắp còn dính bùn đen. + +Tiến quỳ xuống. Bùn còn ướt. + +“Có người xuống gần đây.” + +Thủy soi đèn vào mép nắp. + +“Ký hiệu.” + +Một vòng tròn mặt trời đỏ được khắc ở cạnh trong, nhỏ đến mức nếu nắp đóng kín sẽ không ai thấy. Bên dưới ký hiệu có ba chữ: + +**WATER VEIN B** + +Mạch nước B. Tiến mở nắp. Bên dưới không phải bể chứa nước. Là một đường thang sắt hẹp dẫn xuống không gian tối. Tiếng nước chảy rất nhỏ vọng lên, nhưng không giống tiếng nước máy. Nó sâu hơn, chậm hơn, như có một dòng ngầm đang thở. + +Thủy đưa máy ảnh lên. Tiến giữ tay cô lại. + +“Không dùng gần miệng hầm.” + +Cô gật đầu, cất máy. Hai người xuống. + +Độ sâu khoảng sáu mét. Cuối thang là một hành lang kỹ thuật cũ, tường bê tông ẩm, nhưng giữa lớp bê tông có những mảng vật liệu xám giống ở Ngọc Trục. Nước rỉ thành từng dòng nhỏ trên nền, chảy về một khe hẹp phía hồ. Trên vách có nhiều đường ống bị cắt, nhưng bên dưới chúng là một cấu trúc cổ hơn: những rãnh dẫn nước bằng đá, xếp khít đến mức không thấy mạch vữa. + +Thủy chạm nhẹ vào đá. + +“Cái này không phải công trình hiện đại.” + +“Không.” + +“Từ thời nào?” + +“Muốn biết thì phải sống đủ lâu để hỏi đúng người.” + +Hành lang dẫn đến một cửa quan sát nhỏ nhìn ra lòng hồ qua một khe ngang. Từ đây, họ thấy rõ thứ mà từ trên bờ chỉ là một đường tối. Dưới lớp nước rút, giữa bùn đen và xác cá, một cạnh kim loại khổng lồ đã lộ ra. + +Nó không giống tàu chìm. Không giống cống. Không giống bất kỳ công trình thủy lợi nào. Bề mặt kim loại tối màu, có những đường gờ cong rất lớn, phủ bùn nhưng vẫn hiện lên độ chính xác đáng sợ. Một phần cạnh chìm sâu dưới nước, phần khác vươn ra như xương sườn của một sinh vật khổng lồ bị chôn dưới hồ. + +Thủy nín thở. + +“Hồ Tây lộ xương.” + +Tiến không thích cách gọi đó. Vì nó quá đúng. Ở mép kim loại, có người. Bốn bóng người mặc đồ đen đang đứng trên bùn, dùng dây cố định một thiết bị hình trụ. Một người trong số đó cầm bản đồ chống nước. Dù khoảng cách xa, Tiến vẫn nhận ra dáng đứng ấy. Đỗ Minh Kha. Hắn đã tới trước. + +Thủy cũng nhận ra. + +“Kha đang làm gì?” + +“Đo hoặc mở.” + +“Anh nói ‘mở’ nghe như mở cửa.” + +“Vì có thể đúng là cửa.” + +Ngay lúc đó, thiết bị hình trụ phát sáng xanh nhạt. Một tiếng ù trầm vang qua lòng hồ. Mặt nước quanh cạnh kim loại rung lên, tạo thành những vòng tròn nhỏ. Bùn dưới chân nhóm của Kha bắt đầu sủi bọt. Một người trong nhóm hét lên. Âm thanh vọng vào hành lang rất nhỏ, nhưng đủ nghe thấy hoảng loạn. + +Kha lập tức lùi lại. Hắn luôn đứng ở vị trí có đường thoát, kể cả trên bùn. Hai người còn lại chậm hơn. Bùn dưới chân họ sụp xuống như bị hút. Một người ngã quỵ, tay cào lên mặt kim loại, để lại những vệt bùn dài. Thiết bị hình trụ tắt phụt. Mặt hồ im trở lại. Người bị ngã không đứng lên nữa. + +Kha chỉ dừng mắt trên xác đồng đội đủ lâu để xác nhận người đó không đứng dậy nữa, rồi ngẩng về phía trạm bơm. Tiến kéo Thủy lùi khỏi khe quan sát. “Đi.” + +“Anh ta thấy chúng ta?” + +“Không biết.” + +Lần này hai chữ đó không chỉ khó chịu. Nó nguy hiểm. Họ rời đường hầm bằng lối cũ. Khi trèo lên phòng trạm bơm, Thủy phát hiện trên bàn kỹ thuật có một tờ giấy bị bỏ lại. Không phải của Kha. Giấy đã cũ, mép ố vàng, nhưng chữ in vẫn đọc được. + +**MẠCH NƯỚC B CHỈ LÀ ĐƯỜNG DẪN. KHÔNG KÍCH HOẠT KHI HỒ CHƯA RÚT ĐỦ.** + +Bên dưới là một dòng viết tay: + +**Nếu Láng thức, Hồ Tây sẽ trả lời.** + +Thủy gấp tờ giấy bỏ vào túi. Ngoài cửa, tiếng xe thắng lại. Bước chân sau đó quá đều để là đám đông, cũng không có tiếng gọi của dân phòng. Một giọng nam quen thuộc vang lên. + +“Tiến. Tao biết mày ở trong đó.” + +Đỗ Minh Kha. Tiến quay sang Thủy. Không còn lối thoát phía sau. Dưới chân họ là mạch nước B. Trước mặt là Kha Đen. Và ngoài kia, dưới đáy Hồ Tây, bộ xương kim loại đầu tiên của Thăng Long đã lộ ra dưới mặt trời đỏ. + +Chương 19: Người Gõ Cửa + +Đỗ Minh Kha không phá cửa. Hắn gõ ba tiếng lên cửa sắt trạm bơm. Cộc. Cộc. Cộc. + +Âm thanh ấy quá giống tiếng gõ dưới nền Ngọc Trục khiến Thủy vô thức lùi lại. Tiến thì đứng yên, mắt nhìn cửa, tay phải đặt gần dao gấp. Hắn biết Kha cố ý. Gã này không chỉ dùng vũ lực. Hắn dùng ký ức, dùng nỗi sợ, dùng những mảnh thông tin nhỏ để ép người khác tự lộ phản ứng. + +“Ra nói chuyện,” Kha nói từ bên ngoài. “Nếu tao muốn giết, tao đã không gõ.” + +Thủy hạ giọng. “Tin được không?” + +“Không.” + +“Vậy?” + +“Nhưng hắn nói đúng một nửa.” + +Tiến rà căn phòng trạm bơm. Cửa chính bị Kha chặn. Cửa thông gió quá nhỏ để thoát nhanh. Nắp hầm phía sau dẫn xuống mạch nước B, nhưng nếu xuống đó, họ sẽ tự chui vào đường cụt. Kha có ít nhất ba người bên ngoài. Còn đám đông gần bờ hồ đủ xa để không can thiệp, đủ gần để Kha không muốn gây tiếng động lớn. + +Đó là điểm cân bằng mong manh. Tiến mở cửa. + +Kha đứng dưới nắng đỏ, gấu áo sơ mi đen bám bùn, tay trái vẫn đeo nhẫn. Sau lưng hắn là hai người, một nam một nữ, mặc đồ nhẹ và đeo túi kỹ thuật. Không ai để súng lộ ra ngoài; Tiến vì thế càng không coi họ tay không. Kha nhìn qua vai Tiến, thấy Thủy. + +“Phóng viên Trần Thanh Thủy. Tôi đã đọc vài bài của cô. Văn phong hơi nhiều đạo đức, nhưng khả năng tìm nguồn khá tốt.” + +Thủy lạnh mặt. + +“Tôi có nên cảm ơn không?” + +“Không. Đạo đức trong thời tiết này dễ mất nước lắm.” + +Tiến bước ra, khép hờ cửa sau lưng. + +“Anh muốn gì?” + +Kha đưa mắt về phía hồ. + +“Một xác chết vừa chứng minh mạch nước B chưa mở được. Mày ở trong trạm, chắc đã thấy ghi chú.” + +Tiến không đáp. Kha mỉm cười. “Không cần phủ nhận. Mày có thói quen lấy mọi thứ có chữ. Kỹ sư hệ thống nào cũng nghĩ dữ liệu cứu được mình.” + +“Còn anh nghĩ gì cứu được anh?” + +“Quyền phân phối.” + +Kha nói câu đó rất bình thản. “Ai nắm nước, nắm điện, nắm đường đi, người đó không cần cứu ai. Người khác sẽ tự bò đến.” + +“Vậy thứ dưới Hồ Tây là đường nước?” + +“Không chỉ nước.” + +Kha nhìn Tiến như nhìn một học sinh đang hỏi sai trọng tâm. “Hà Nội có quá nhiều lớp. Lớp trên mặt là đường, nhà, hồ, cầu, chung cư. Lớp dưới là cống, hầm, móng, dây, ống. Dưới nữa là những thứ không ai đưa vào quy hoạch. Hồng Nhật không tạo ra chúng. Nó chỉ làm lớp trên cùng nứt ra.” + +“Anh lấy thông tin từ đâu?” + +“Câu đó mày đã hỏi bằng nhiều cách rồi.” + +“Anh chưa trả lời.” + +“Vì mày chưa có thứ để đổi.” + +Tiến giữ ánh mắt ở Kha. + +“Ngọc Trục.” + +Lần này, Kha không cười. “Đúng. Cho tao quyền xuống HN-07, tao cho mày bản đồ đầy đủ tuyến phía Tây.” + +“Không.” + +“Vậy cho tao người.” + +Thủy cau mày. “Người?” + +Kha nhìn cô. “Cô.” + +Không khí đông cứng. Tiến hơi nghiêng người, chắn trước Thủy. Kha thấy động tác đó, khóe miệng nhếch rất nhẹ. + +“Đừng hiểu nhầm. Tôi không cần cô vì cô là phụ nữ. Tôi cần cô vì HANOI-07 phản ứng với cô. Láng cũng phản ứng. Hồ Tây sẽ còn phản ứng. Người ghi chép đôi khi quan trọng hơn người mở cửa.” + +Thủy nắm chặt túi tài liệu. + +“Anh biết gì về tôi?” + +“Ba việc. Ba nguồn khác nhau.” Kha giơ một ngón tay. “Tệp cô mở: bản sao bộ đệm từ rơ-le cũ của dự án năm 2023. Một kỹ thuật viên bán cho người của tôi trước khi Đại Hà khóa mạng.” Ngón thứ hai. “Những giấc mơ: ba đoạn ghi âm cô tưởng chỉ nằm trong điện thoại. Trình chuyển giọng cũ đã đẩy bản chép vào cùng bộ đệm.” Ngón thứ ba. “Câu dưới Trạm Láng: không ai của tôi nghe được. Một truy vấn trong kho dữ liệu trả lại bản chép với độ tin cậy bốn mươi hai phần trăm.” + +Thủy tái mặt, nhưng không để hắn điều khiển nhịp hỏi. “Anh vừa nói một dự đoán như thể đã nghe tận tai.” “Để xem cô phản ứng.” + +Tiến lạnh giọng. “Và nếu cô ấy phủ nhận?” + +“Tao hạ độ tin cậy.” Kha vuốt nhẹ chiếc nhẫn đen. “Theo dõi cho tao dữ kiện. Truy vấn cho tao giả thuyết. Phản ứng của cô cho tao phần còn lại.” + +Câu trả lời xác nhận một điều quan trọng: Kha không toàn tri. Hắn ghép những nguồn không hoàn hảo rồi trình bày chúng như sự thật để buộc người đối diện tự xác nhận. HN-07 vẫn che một phần bàn cờ khỏi hắn, nhưng sự thiếu hụt ấy không làm hắn bớt nguy hiểm; nó chỉ khiến hắn giỏi hơn trong việc khiến người khác điền vào chỗ trống. + +“Cô ấy không đi với anh.” + +“Cô ấy tự quyết được.” + +Thủy nhìn Kha. “Và nếu tôi từ chối?” + +“Cô sẽ tiếp tục đi theo một người biết trước thảm họa nhưng chỉ cứu được vài người, trong khi tưởng mình đang chống lại một kẻ độc ác.” Kha nghiêng đầu. “Còn nếu đi với tôi, cô sẽ thấy hệ thống đủ lớn để quyết định ai được sống trước khi đám đông kéo mọi thứ xuống bùn.” + +“Anh nói như thể mình đang cứu thế giới.” + +“Tôi không cứu thế giới. Tôi chọn phần còn lại có khả năng vận hành.” + +Thủy quan sát Kha như đang đặt một nguồn tin vào đúng ô trong đầu. “Tôi từng điều tra những người giống anh.” + +“Và họ thua vì còn phải giả vờ nhân đạo.” + +Tiến không muốn kéo dài cuộc nói chuyện. Mỗi giây ở đây là thêm nguy cơ. Nhưng trước khi hắn kịp ngắt lời, từ phía hồ vang lên tiếng hét. Đám đông bên bờ bắt đầu chạy tán loạn. Mặt nước gần cạnh kim loại tụt nhanh hơn, không rút đều mà xoáy thành một đường dài, để lộ thêm bề mặt tối màu. Từ xa, vật thể dưới đáy hồ giống một mảng xương sườn thứ hai đang nổi lên khỏi bùn. + +Một người của Kha bật bộ đàm. + +“Anh Kha, thiết bị còn dưới đó.” + +Kha quay đầu nhìn hồ. Trong khoảnh khắc ngắn, Tiến thấy sự khó chịu thật trên mặt hắn. Đó không phải nỗi sợ, mà là cảm giác một kế hoạch vừa bị đẩy nhanh ngoài dự kiến. Tiến lập tức nắm cổ tay Thủy. + +“Chạy.” + +Lần này cô không hỏi. Hai người lao sang bên hông trạm bơm. Kha không đuổi ngay. Hắn còn nhìn hồ, cân nhắc giữa họ và thiết bị dưới bùn. Đó là cơ hội duy nhất. Tiến và Thủy chạy theo lối tường cũ, vòng qua đám người hỗn loạn. Phía sau, Kha ra lệnh gì đó. Tiếng bước chân đuổi theo bắt đầu vang lên, nhưng bị tiếng người la hét và tiếng bùn sụp át bớt. + +Khi họ tới được xe, Thủy thở dốc, mặt trắng bệch. + +“Hắn muốn tôi.” + +“Vì cô nghe được Láng.” + +“Anh cũng nghe.” + +“Không. Tôi nghe âm. Cô nghe câu.” + +Thủy không nói thêm. Tiến khởi động xe. Phía sau, Hồ Tây tiếp tục rút. Trên mặt nước đỏ sẫm, những đường kim loại tối màu lộ ra ngày càng rõ, giống như có một thành phố khác đang nằm dưới thành phố này, chậm rãi mở mắt. Khi xe rời khỏi khu vực hồ, bộ đàm của Tiến rè lên. Không phải giọng Bình. + +Không phải ông Hòa. Một giọng rất nhỏ, lẫn trong nhiễu, vang lên ba lần: + +**...đừng... mở... cổng...** + +Thủy quay sang Tiến. + +“Đó là giọng ở Láng.” + +Tiến dõi theo con đường phía trước. + +“Không. Lần này nó phát qua bộ đàm.” + +Và điều đó nghĩa là Trạm Láng đã không còn nằm yên dưới đất. Nó đã bắt đầu tìm đường nói ra ngoài. + +Chương 20: Đường Ngầm Phía Tây + +Bộ đàm tiếp tục nhiễu suốt quãng đường về Ngọc Trục. + +Âm thanh không ghép thành câu hay một tín hiệu rõ ràng. Nó chỉ tới thành từng mảnh đứt đoạn, lúc giống nước chảy qua ống hẹp, lúc giống tiếng người vọng từ rất xa. Thủy ngồi phía sau, một tay bám vào xe, tay kia cầm sổ ghi lại từng nhịp nhiễu theo bản năng nghề nghiệp. Tiến không ngăn cô. Có những thứ máy ghi âm không giữ được, nhưng trí nhớ của con người đôi khi lại lọt qua khe hở của hệ thống. + +Về đến kho, ông Hòa đang chờ trước cổng. + +“Có chuyện dưới nền.” + +Không ai hỏi chuyện gì. + +Cả hai chạy vào khu kệ sắt che nắp HN-07. Đồng hồ nhiệt dưới nền vẫn dao động ở mức thấp bất thường, nhưng lần này không chỉ lạnh. Mặt bê tông quanh nắp kim loại xuất hiện một vệt ẩm mỏng, kéo dài về phía tường Tây. Nước không chảy từ trên xuống. Nó thấm từ dưới lên, thành một đường mảnh như mạch máu. + +Ông Hòa dùng đèn soi sát nền. + +“Nước này không phải từ bể rò.” + +Tiến chạm tay vào vệt ẩm. Lạnh. Giữa kho nóng hơn 40°C, dòng nước dưới nền lạnh như nước giếng sâu. Linh mang bộ thử nước tới. Cô nhỏ vài giọt hóa chất vào mẫu nước. Màu hiện ra chậm, đục xanh rồi chuyển xám. + +“Không giống nước máy. Có khoáng cao. Không uống trực tiếp được, nhưng lọc được.” + +Không ai lên tiếng ngay. Trong một thành phố đang chết khát, dưới nền căn cứ của họ lại xuất hiện một mạch nước lạnh. Bình là người đầu tiên nói thành lời điều cả nhóm đang nghĩ. + +“Cái này là may mắn hả?” + +Tiến lần theo vệt nước kéo về phía tường. “Không. Là lời mời.” + +Ông Hòa gật đầu chậm rãi. “Tường Tây có hốc rỗng. Tôi nghe tiếng từ hôm qua, nhưng tưởng do ống.” + +Họ dời kệ, gõ nền và tường. Đúng như ông Hòa đoán, sau lớp gạch cũ có một khoảng rỗng hẹp và kéo dài — giống hành lang bị bịt hơn là một căn phòng. Tiến không phá ngay. Hắn cho Bình kiểm tra camera ngoài, cho Nam canh cổng phụ, cho Linh chuẩn bị túi y tế. Thủy đứng cạnh hắn, tay cầm sổ ghi âm Láng. + +“Anh nghĩ đây là đường gì?” + +“Mạch nước B nối Hồ Tây với hệ thống phía Tây. Nếu Ngọc Trục là khóa, có thể đường này là một phần thân khóa.” + +“Nghe càng ngày càng ít giống hạ tầng đô thị.” + +“Vì có lẽ nó không phải hạ tầng đô thị.” + +Ông Hòa dùng máy cắt cầm tay mở một ô nhỏ trên tường. Sau lớp gạch không có đất mà là một bề mặt đá xám nhẵn, chỉ chừa khe đủ luồn camera nội soi. Tiến đưa camera vào; màn hình chạy nhiễu rồi dần hiện hình. Bên kia là một đường hầm thấp. + +Không rộng. Một người phải cúi thấp mới đi được. Vách đá xếp khít, xen giữa là những đoạn kim loại tối màu như gân. Dưới nền có một rãnh nước nhỏ chảy về hướng đông bắc. Trên vách, cách vài mét lại có một ký hiệu mặt trời đỏ bị mài mòn. Bình nuốt khan. + +“Đường này đi đâu?” + +Camera xoay thêm. Ở một đoạn vách, có một mũi tên khắc chìm và ba chữ Latin mờ: + +**WEST SERVICE VEIN** + +Mạch phục vụ phía Tây. Thủy đưa bản đồ ra. + +“Nếu hướng đông bắc thì có thể về Láng hoặc Hồ Tây. Nếu hướng tây nam…” + +“La Phù,” Tiến nói. + +Mảnh kim loại ở Ngọc Trục từng ghi: **LA PHU / SUPPLY TRACE**. Giờ họ đã thấy đường nối. Đường ngầm phía Tây không còn là giả thuyết. Nó nằm sau tường căn cứ. + +Tiến quyết định không đưa cả nhóm xuống. Hắn, ông Hòa và Thủy vào trước. Bình ở lại giữ đường rút, Nam canh camera, Linh giữ y tế. Phúc chưa đủ khỏe nhưng xin cầm gậy đứng gần cổng phụ. Không ai phản đối. Sau Đại Hà, việc được giao canh cửa đối với anh ta giống một cách chuộc lỗi. + +Họ mở rộng ô tường vừa đủ chui qua nhưng chưa vào ngay. Ông Hòa luồn một ống mềm xuống thấp và một ống lên cao để lấy hai mẫu khí; Tiến dùng đầu đo cầm tay kiểm oxy, CO và khí cháy. Kết quả không đẹp nhưng nằm trong giới hạn cho một lượt ngắn. Bình đứng phía ngoài giữ dây thời gian: mười phút không có một lần giật xác nhận thì đóng lối trong, báo động, không tự chui xuống. + +Không khí trong đường hầm lạnh và khô. Tiếng nước chảy rất nhỏ, đều đặn, làm người ta có cảm giác đang đi trong cổ họng của một sinh vật ngủ sâu. Ông Hòa cầm đèn cơ, không dùng thiết bị điện tử phức tạp. Tiến cầm dao và dây đánh dấu. Thủy ghi chép bằng bút chì. Mỗi ngã rẽ đều được đánh dấu hai chiều; họ không dựa vào trí nhớ trong một nơi có thể làm thiết bị và cảm giác sai lệch. + +Đi được khoảng ba mươi mét, họ gặp ngã ba. Một hướng có ký hiệu nước. Một hướng có ký hiệu mặt trời. Một hướng có chữ bị cạo mất. Tiến cúi xuống nhìn nền. Có dấu giày. Mới. + +Không phải của họ. Ông Hòa hạ giọng. “Người của Kha?” + +“Có thể.” + +Lần này, Thủy không trêu hai chữ đó nữa. + +Dấu giày đi theo hướng chữ bị cạo. Tiến không đi theo ngay. Hắn chọn hướng có ký hiệu nước trước. Sau vài mét, họ tới một buồng nhỏ, ở giữa có một bể đá thấp. Nước trong bể lạnh, trong, nhưng bề mặt không phản chiếu ánh đèn như nước bình thường. Nó tối hơn, sâu hơn, dù bể chỉ cao tới đầu gối. + +Trên thành bể có khắc một dòng tiếng Việt cũ: + +**Nước giữ khóa, khóa giữ cổng.** + +Thủy chép lại, tay hơi run. Ông Hòa lẩm bẩm: “Cái này không phải mấy ông kỹ sư thời nay viết.” + +Tiến lấy mẫu nước bằng ống thủy tinh. Ngay khi nút ống đóng lại, toàn bộ đường hầm rung nhẹ. Không mạnh. Chỉ như một hơi thở bị đánh thức. Từ hướng còn lại của ngã ba vang lên tiếng kim loại kéo lê. Tiến tắt đèn. Ba người đứng im trong bóng tối. + +Một vệt sáng trắng quét qua vách đường hầm ngoài ngã ba. Có người đang đi tới. Không chỉ một. Tiếng bước chân bị nước át đi, nhưng vẫn nghe được ít nhất hai nhịp. Một giọng nữ rất nhỏ vang lên: + +“Dấu giày mới. Có người vào trước.” + +Giọng nam đáp: “Báo anh Kha?” + +“Không. Kiểm tra trước. Anh ấy đang ở Hồ Tây.” + +Ánh mắt Tiến tìm Thủy trong bóng tối. Người của Kha đã vào đường ngầm. Và Kha vẫn ở Hồ Tây. Tức là hắn đang chia lực, tìm nhiều đầu vào cùng lúc. + +Ông Hòa chỉ tay về hướng ký hiệu mặt trời. Không ai nói. Họ lùi dần vào đường đó, tránh ánh đèn của nhóm kia. Nhưng đường càng đi càng hẹp, cuối cùng dẫn tới một cửa chắn bằng kim loại tối màu. Trên cửa có một dòng chữ hiện đại, nhỏ nhưng rõ: + +**MAINTENANCE ACCESS / LANG HANDSHAKE REQUIRED** + +Cần bắt tay với Láng. Thủy lấy tờ giấy ghi âm ở Trạm Láng ra. Những ký hiệu cô chép bỗng làm Tiến nhớ tới nhịp gõ dưới nền Ngọc Trục: dài, ngắn, ngắt, lặp. + +“Cô đọc lại nhịp,” hắn nói. + +“Ở đây?” + +“Bằng cách gõ.” + +Thủy nhìn cánh cửa, rồi gõ lên kim loại theo chuỗi mình đã ghi: hai ngắn, một dài, ba ngắn, ngắt, một dài. Không có gì xảy ra. + +“Không đúng,” cô nói ngay, không gõ lại theo bản năng. “Ở Láng tôi ghi khoảng cách nghe được, không phải khoảng cách tại nguồn.” + +Ông Hòa đặt hai ngón lên cửa. “Kim loại này hồi âm chậm hơn ống ở Láng. Nhịp dài bị kéo thêm.” + +Thủy lấy bút chì gạch lại khoảng nghỉ, bù phần trễ mà hai người vừa nghe từ tiếng dội. Phía sau, người của Kha đã gần hơn. Cô gõ lần hai theo chuỗi hiệu chỉnh. Cánh cửa rung nhẹ. Một khe sáng đỏ xuất hiện ở mép. + +Ông Hòa hít vào. + +“Cô gái, cô vừa sửa khóa bằng tiếng vọng à?” + +“Chưa biết có phải khóa không,” Thủy đáp, vẫn nhìn đồng hồ. “Nhưng lần hai không phải đoán.” + +Tiến đẩy cửa. Bên kia là bóng tối sâu hơn. Từ phía sau, người của Kha hét lên: “Ai đó?” + +Tiến kéo Thủy và ông Hòa vào trong. Cánh cửa đóng lại ngay sau lưng họ, nuốt tiếng bước chân phía ngoài. Trong bóng tối mới, một dòng chữ đỏ mờ hiện lên trên vách, không phải từ màn hình, mà từ chính những khe kim loại trong tường: + +**LANG HANDSHAKE ACCEPTED** + +Rồi dòng thứ hai: + +**WEST VEIN OPEN** + +Đường ngầm phía Tây đã mở. Và Ngọc Trục không còn là căn cứ nằm trên mặt đất nữa. Nó đã có đường xuống lòng Hà Nội. + +Chương 21: Đêm La Phù Cháy + +Đường ngầm phía Tây không dẫn thẳng tới La Phù. Nó dẫn tới dưới La Phù. + +Sau gần bốn mươi phút đi trong bóng tối, Tiến, Thủy và ông Hòa tới một đoạn hầm mà không khí bắt đầu đổi mùi. Mùi đá lạnh và nước ngầm nhạt dần, thay bằng mùi carton ẩm, đường cháy, nhựa nóng và dầu máy. Trên đầu họ, thỉnh thoảng có tiếng xe tải chạy qua, nặng đến mức bụi rơi xuống từ các khe đá. + +Ông Hòa dừng lại, đặt tay lên vách. “Trên kia là kho.” + +“Kho nào?” Thủy hỏi. + +Tiến rà ký hiệu trên tường. Một vòng tròn mặt trời đỏ bị gạch ngang, bên dưới có hàng chữ mờ: + +**LP-17 / SUPPLY LIFT SEALED** + +“Kho số 17.” + +La Phù. Nơi Đỗ Minh Kha gom nước trước Hồng Nhật. Nơi tuyến LP-17 bắt đầu. Một tiếng nổ nhỏ vang lên từ phía trên. Rồi tiếng người la hét. + +Thủy ngẩng đầu. + +“Đánh nhau?” + +Tiến chỉ siết quai túi trên vai và tăng bước. + +Họ tìm được một giếng nâng hàng cũ đã bị niêm phong bằng tấm kim loại. Không có điện. Không có bảng điều khiển. Nhưng ông Hòa nhìn qua cơ cấu bánh răng và nói có thể mở tay nếu tháo chốt an toàn. Công việc mất mười phút. Mười phút ấy, phía trên liên tục vang lên tiếng va đập, tiếng cửa cuốn, tiếng kính vỡ, tiếng người gào gọi nước. + +Khi tấm giếng nâng hé ra, hơi nóng tràn xuống như lửa. Kho số 17 đang cháy. + +Không cháy lớn ngay, nhưng nhiều điểm lửa đã bùng lên giữa các đống carton và pallet gỗ. Khói đen cuộn dưới mái tôn. Người chạy tán loạn giữa các dãy hàng. Có nhóm dân cư kéo vào cướp nước, có người của kho chống trả, có kẻ lợi dụng hỗn loạn để bê hàng. Tiếng hét, tiếng khóc, tiếng kim loại, tiếng thùng nước đổ vỡ trộn lại thành một khối âm thanh méo mó. + +Đêm La Phù bắt đầu cháy. Tiến kéo Thủy nép sau một dãy thùng đã rỗng. Ông Hòa ho sặc, lấy khăn ướt che mũi. “Không ở lâu được.” + +“Tìm đường ra.” + +“Còn nước?” Thủy hỏi. + +Tiến kiểm các pallet còn nguyên gần cửa phụ. Nước ở ngay đó. Hàng trăm thùng. Đủ kéo dài sự sống cho Ngọc Trục thêm nhiều ngày. Nhưng giữa kho đang cháy và đám đông đang mất kiểm soát, mỗi thùng nước đều nặng như một cái bẫy. Một tiếng súng vang lên. + +Đám đông chựng lại trong thoáng chốc, rồi vỡ đội hình còn dữ hơn. Từ phía văn phòng kho, một người phụ nữ mặc đồ đen bước ra, tay cầm súng ngắn. Cô ta không bắn tiếp. Chỉ giơ súng lên, ra hiệu cho người của mình rút theo cửa sau. Tiến nhận ra giọng nữ đã nghe trong đường ngầm. + +Người phụ nữ của Kha. Cô ta lạnh lùng nhìn đám đông tranh nước, rồi ra lệnh: “Đốt khu giấy. Chặn đường vào. Hàng chính đã chuyển xong.” + +Thủy nghiến răng. + +“Họ cố tình đốt kho.” + +“Không phải đốt hết,” Tiến nói. “Đốt phần bỏ lại.” + +“Để đám đông giành nhau trong lửa?” + +“Để không ai lấy được phần Kha không cần.” + +Đỗ Minh Kha đã rời khỏi La Phù trước khi nó cháy. Như Tiến từng nói: kẻ mạnh không phải kẻ cướp giỏi nhất, mà là kẻ rời đi trước khi nơi đó cần phải cướp. Tiến quét mắt quanh kho. Một nhóm người bị kẹt gần cửa cuốn phía bắc, trong đó có hai trẻ nhỏ. Cửa bị một xe nâng chết máy chặn. Khói đang dồn về phía họ. + +Thủy cũng nhìn thấy. “Tiến.” + +“Không.” + +“Có trẻ con.” + +“Chúng ta không có thời gian.” + +“Có nếu mở đường ngầm.” + +Tiến quay sang cô. + +“Cô muốn đưa người lạ xuống đường nối về Ngọc Trục?” + +Thủy không đáp ngay. Cô hiểu cái giá. Nếu đưa họ xuống đường ngầm, bí mật của Ngọc Trục có thể lộ. Nếu không đưa, họ chết trong khói và lửa. Ông Hòa ho thêm một trận, rồi nói khàn khàn: + +“Không cần đưa về Ngọc Trục. Đường ngầm có ngã ba. Ta dẫn họ ra miệng gần mương sau kho, rồi bịt lại.” + +Tiến nhìn ông. “Ông chắc?” + +“Không chắc. Nhưng già rồi, tôi không thích nghe trẻ con cháy.” + +Câu nói ấy khiến Tiến im lặng đúng một giây. Rồi hắn ra quyết định. + +“Thủy, đưa họ tới giếng nâng. Ông Hòa mở đường. Tôi kéo xe nâng.” + +Họ hành động. Tiến lao qua khói, dùng xà beng mở khóa xe nâng rồi đẩy phần càng lệch đủ để tạo khe. Thủy chạy tới nhóm người bị kẹt, giọng cô khàn nhưng rõ: + +“Muốn sống thì đi theo tôi. Không mang hàng. Không hỏi. Bế trẻ con lên.” + +Một người đàn ông ôm thùng nước không chịu bỏ. Thủy tát thẳng vào mặt anh ta. + +“Bỏ thùng nước hoặc chết cùng nó.” + +Anh ta sững lại, rồi buông tay. Nam không ở đây, nhưng nếu thấy cảnh đó, cậu sẽ nhận ra Thủy sau Đại Hà đã khác. Cô vẫn muốn cứu người, nhưng không còn cầu xin thế giới hợp tác với lòng tốt của mình. Họ đưa được mười một người xuống giếng nâng. Quá nhiều so với dự tính, nhưng không còn thời gian để chọn. Ông Hòa dẫn nhóm theo đoạn hầm phụ, vừa đi vừa đánh dấu bằng phấn. Tiến đi cuối, nghe tiếng người của Kha phát hiện cửa giếng. + +“Có lối dưới!” + +Người phụ nữ cầm súng quay lại. Qua làn khói, Tiến nhận ra cô ta. Cô ta cũng thấy hắn. Không bắn ngay. Chỉ mỉm cười rất nhạt, như nhận ra một con chuột vừa tìm thấy đường trong tường. + +“Lê Quốc Tiến,” cô ta nói. + +Tiến bỏ qua câu hỏi, giật chốt giếng nâng. Tấm kim loại sập xuống giữa hai người. Gần như ngay sau đó, tiếng súng nổ; viên đạn đập vào mặt kim loại, kéo một tiếng chát dài trong đường hầm. Họ chạy. + +Đường phụ dẫn ra một cống thoát nước cũ sau La Phù, đúng như ông Hòa đoán. Khi nhóm người sống sót chui lên mặt đất, phía sau họ, kho số 17 bốc khói đỏ dưới mặt trời Hồng Nhật. Người khóc. Người nôn. Trẻ con ho sặc. Không ai biết vừa đi qua một phần của hệ thống nằm dưới Hà Nội. + +Tiến không đưa họ về Ngọc Trục. Hắn chỉ đường tới một khu dân cư còn giếng khoan, đưa ba chai nước và nói: “Đi ngay. Đừng quay lại. Đừng kể về đường dưới đất.” + +Một người phụ nữ ôm con quỳ xuống cảm ơn. Tiến kéo cô đứng dậy. “Đừng quỳ. Giữ sức mà đi.” + +Khi nhóm người khuất sau con ngõ, Thủy nhìn Tiến. “Anh vừa phá quy tắc của chính mình.” + +“Không. Tôi sửa nó.” + +“Sửa thế nào?” + +“Cứu người nếu có đường không giết căn cứ.” + +Ông Hòa cười khan. “Vậy bảng quy tắc lại phải viết thêm.” + +Tiến hướng mắt về kho cháy. Trong lửa, hắn thấy bóng người phụ nữ của Kha đứng trên mái thấp, nhìn về hướng họ. Cô ta không đuổi. Chỉ giơ tay lên, đặt hai ngón lên trán như một lời chào. Kha đã mất kho bỏ lại. Nhưng hắn đã biết đường ngầm phía Tây thật sự tồn tại. Và từ đêm La Phù cháy, bí mật dưới Ngọc Trục không còn thuộc riêng về họ nữa. + +Chương 22: Tín Hiệu Trạm Láng + +Ngọc Trục đóng cửa suốt hai ngày sau đêm La Phù cháy. Không phải vì an toàn. Vì quá nhiều thứ phải che giấu. + +Ông Hòa và Bình bịt lại lối tường dẫn xuống đường ngầm, nhưng không xây kín. Tiến yêu cầu để một cửa kỹ thuật giả phía sau tủ điện, chỉ người trong lõi căn cứ biết. Linh xử lý khói và bỏng nhẹ cho Thủy, ông Hòa, cùng vài người mới được cứu tạm trú một đêm trước khi rời đi. Nam không còn ngồi im ở góc kho nữa. Cậu xin phụ ghi sổ nước. + +“Em muốn làm gì đó,” cậu nói. + +Tiến đưa cậu cuốn sổ. + +“Ghi thật. Không làm đẹp số.” + +Nam gật đầu rồi quay lại bảng trực. Tay cậu vẫn chậm một nhịp mỗi khi cửa cuốn rung, nhưng cậu không rời vị trí nữa. Tiến không gọi đó là đã ổn; chỉ là Nam đã bắt đầu làm việc cùng nỗi sợ thay vì chờ nó biến mất. Thủy thì không hồi phục nhanh như vậy. Cô ngồi trước bàn, viết lại toàn bộ những gì đã xảy ra ở Láng, Hồ Tây, trạm bơm và La Phù. Không dùng laptop. Không dùng điện thoại. Chỉ giấy, bút chì, mã riêng. Trên trang đầu, cô ghi một dòng: + +**Nếu tôi chết, đừng công bố toàn bộ. Công bố đúng phần người khác có thể sống nhờ nó.** + +Tiến đứng sau lưng cô, đọc được nhưng không nói. Cô biết hắn ở đó. “Anh ghét câu này à?” + +“Không.” + +“Vậy sao im?” + +“Vì nó đúng.” + +Thủy dừng bút. + +“Trước đây tôi nghĩ sự thật phải được nói ra toàn bộ.” + +“Bây giờ?” + +“Bây giờ tôi nghĩ sự thật cũng cần định mức như nước.” + +Tiến không phản bác. Câu nói vẫn đau, nhưng nó không còn là sự liều lĩnh của Thủy ở những ngày đầu. + +Buổi chiều ngày thứ hai, Trạm Láng phát tín hiệu lần đầu tiên. Không qua màn hình HANOI-07. Không qua email. Không qua dữ liệu quan trắc. Nó phát qua mọi vật có khả năng rung trong kho Ngọc Trục. Đầu tiên là bộ đàm. Sau đó là loa cũ của máy tính. + +Rồi tấm tôn mái. Cuối cùng là chính nắp kim loại HN-07 dưới nền. Cộc. Cộc. Cộc. Dài. Ngắn. Ngắt. Lặp. Thủy đứng bật dậy. + +“Là chuỗi ở Láng.” + +Tiến ra hiệu cho mọi người im lặng. + +Trong kho, tiếng gõ lan qua kim loại như một thứ mật mã sống. Ông Hòa lấy bút, viết nhịp lên bảng. Thủy đối chiếu với ghi chép cũ. Tiến hạ mắt xuống nắp HN-07. Mỗi lần chuỗi gõ tới đoạn dài, đường viền nắp lại lạnh xuống, hơi nước ngưng thành một lớp mỏng rồi biến mất. + +“Không phải gọi chúng ta,” ông Hòa nói. + +“Vậy gọi ai?” Bình hỏi. + +Thủy nhìn giấy. “Nó đang bắt tay.” + +“Với Ngọc Trục?” + +“Với HN-07.” + +Không ai lên tiếng sau câu trả lời ấy. HANOI-07 rõ ràng không đứng một mình: Láng có thể gửi tín hiệu tới Ngọc Trục, Hồ Tây trả lời Láng, còn La Phù có tuyến tiếp vận. Dưới Hà Nội là một mạng nút đang lần lượt thức dậy, vận hành dù con người hiểu hay không. + +Trên màn hình phụ, bản đồ điện lực cũ tự bật. Không có cửa sổ đen. Không có dòng chữ lớn. Chỉ có các điểm đánh dấu đỏ xuất hiện từng cái một. + +**NGOC TRUC** + +**LANG** + +**HO TAY** + +Sau đó, một điểm mới nhấp nháy ở phía đông bắc Hồ Tây. Rồi một điểm nữa gần khu Hoàng thành. Thủy nhìn điểm đó, giọng thấp xuống. + +“Ba Đình.” + +Ông Hòa lẩm bẩm: “Đừng nói với tôi dưới đó cũng có một cái nắp.” + +Không ai cười. Màn hình chớp nhẹ. Một dòng chữ nhỏ hiện lên, không đỏ rực như trước mà mờ như bị ép qua nhiều lớp dữ liệu. + +**S07 HANDSHAKE RECEIVED** + +**GATE DATE LOCKED: 29/09/2028** + +Tiến cảm thấy sống lưng lạnh đi. 29 tháng 9 năm 2028. + +Ngày Cổng Thăng Long. Mốc này không trùng ngày hắn chết ở tương lai, cũng không thuộc năm 2031. Một ngày khác. Một cánh cửa khác. Dòng thứ ba hiện lên: + +**DO NOT OPEN EARLY** + +Rồi màn hình tắt. Không ai nói gì trong gần một phút. + +Cuối cùng, Linh là người phá im lặng. + +“Không mở sớm là tốt đúng không?” + +Tiến hạ mắt xuống nắp HN-07. + +“Chỉ tốt nếu không có người cố mở.” + +Thủy hiểu ngay. + +“Kha.” + +“Và không chỉ Kha.” + +Như để xác nhận lời hắn, camera ngoài cổng báo chuyển động. Nam mở màn hình giám sát, sắc mặt đổi ngay. + +“Có người.” + +Ngoài cổng không phải nhóm cướp hay dân xin nước. Chỉ có một cô gái trẻ đứng trước cổng phụ, một tay ôm bụng, tay kia giơ cao mảnh vải trắng. Quần áo cô bám đầy tro La Phù. Trên vai có vết thương rỉ máu. Nhưng thứ khiến Tiến chú ý không phải vết thương. + +Là hình xăm mặt trời đỏ trên cổ tay cô. Người phụ nữ của Kha. Người đã thấy họ ở kho số 17. Bình chửi thề. + +“Bẫy.” + +Ông Hòa cầm tua vít như vũ khí. Linh nhìn màn hình, giọng căng: “Cô ta bị thương thật.” + +Thủy nhìn Tiến. “Mở không?” + +Tiến không trả lời ngay. Cô gái ngoài cổng ngẩng đầu nhìn thẳng vào camera. Dù mặt tái vì mất máu, ánh mắt cô vẫn tỉnh. Cô nói chậm, đủ để micro thu được: + +“Đỗ Minh Kha sẽ mở Láng trong đêm nay.” + +Tiến đứng lặng. Cô gái tiếp tục: + +“Hắn có bản sao nhịp gõ. Nhưng bản sai.” + +Thủy siết chặt cuốn sổ. + +“Bản sai thì sao?” + +Cô gái ngoài cổng cười méo mó. “Nếu gõ sai, Trạm Láng không mở cửa.” + +Cô ho ra một ít máu, rồi nói nốt câu còn lại: “Nó gọi thứ ở dưới lên.” + +Trong kho, nắp HN-07 gõ thêm một tiếng. Cộc. Lần này không theo nhịp. Giống một lời cảnh báo. Ánh mắt hắn đi qua mọi người. Quy tắc căn cứ nói: không mở cổng vì tiếng khóc. + +Nhưng người ngoài cổng không khóc. Cô ta mang một thông tin có thể quyết định Láng, Ngọc Trục, và có lẽ cả Cổng Thăng Long. Tiến bước tới cổng phụ. + +“Bình, đứng bên trái. Ông Hòa, ngắt điện cổng nếu tôi ra hiệu. Linh, chuẩn bị băng ép. Thủy, ghi mọi lời cô ta nói.” + +Thủy hỏi: + +“Anh tin cô ta?” + +Tiến nhận ra hình xăm mặt trời đỏ trên cổ tay cô gái. + +“Không.” + +Hắn mở khóa lớp thứ nhất. + +“Nhưng nếu Kha thật sự định mở Láng đêm nay, chúng ta không còn quyền đứng yên.” + +Cổng phụ hé ra. Hơi nóng bên ngoài tràn vào. Cùng lúc đó, từ rất xa về phía khu Láng, một tiếng động trầm vang lên dưới lòng đất. Không phải tiếng nổ. Giống một cánh cửa khổng lồ vừa bị ai đó gõ nhầm. + +ARC 4: SAI MỘT NHỊP + +Chương 23: Người Phụ Nữ Ngoài Cổng + +**14/07/2028 – 18:36** + +Tiến chỉ mở lớp khóa thứ hai. + +Giữa người phụ nữ đứng ngoài đường và cửa kho chính vẫn còn một tấm lưới thép hàn chéo, thanh khóa ngang, khoảng sân đệm rộng gần sáu mét và ba nòng súng tự chế đang chĩa từ những vị trí cô không nhìn thấy. Ngọc Trục chưa từng được xây để tiếp khách. Sau Hồng Nhật, mỗi lớp cổng còn là một câu hỏi: người đang xin vào mang theo thứ gì ngoài vết thương? + +Người phụ nữ giữ một tay trên sườn trái. Tay kia giơ mảnh vải trắng đã chuyển nâu vì bụi và máu. Cô đứng thẳng hơn một người mất máu nên đứng, như thể cơ thể chỉ là một thiết bị đang hỏng nhưng chưa được phép dừng. + +“Bỏ vũ khí xuống,” Tiến nói qua loa. + +“Không có.” + +“Áo khoác.” + +Cô hiểu. Dùng một tay kéo khóa, cô cởi chiếc áo mỏng rồi ném sang bên. Áo thun xám phía trong đã sẫm máu ở sườn. Không súng dài, không bao súng, nhưng người từng đứng cạnh Đỗ Minh Kha trong đêm La Phù cháy không thể được coi là vô hại chỉ vì hai bàn tay trống. + +“Quay lưng. Chậm.” + +Cô làm theo. + +Bình đứng phía trái cổng, giữ bộ phóng bu lông ông Hòa cải từ dụng cụ công nghiệp. Linh ở sau tường bê tông với túi y tế nhưng không bước ra. Nam theo dõi camera, môi mím chặt. Mỗi lần người phụ nữ nghiêng người vì đau, con số nhịp tim trên cảm biến nhiệt lại tăng. + +Khánh An. Tiến đã nghe Kha gọi tên đó một lần ở La Phù. + +“Cô muốn gì?” + +“Trước hết, đừng tin tôi.” Khánh An nhấc cằm về chiếc túi đã đặt ngoài vạch. “Ngăn ngoài có một thẻ điều xe LP-17, mã 04-21. Gọi đúng kênh cũ của Kha, hỏi chiếc xe đó rời La Phù lúc nào. Nếu giờ khớp, mới nghe phần sau.” + +Bình liếc Tiến. Khánh An không xin cứu và cũng không đòi được tin bằng lời. Cô đưa một chi tiết có thể kiểm ngay — cách nhanh nhất để mua vài phút khi hai bên đều có lý do nghi nhau. + +“Sau đó?” Tiến hỏi. + +“Sau đó tôi muốn dừng Kha.” + +“Vì một chuỗi sai?” Tiến hỏi. + +“Vì trong hệ thống của anh ta không có ai được phép nói dừng khi dữ liệu đã thành mệnh lệnh.” Khánh An không rời mắt khỏi camera. “Chuỗi sai chỉ là lần đầu tôi còn đủ thời gian bước ra.” + +Tiến kiểm vị trí máu thấm. “Vì sao?” + +“Anh ta đang thử Trạm Láng bằng một chuỗi sai.” + +“Anh ta có chuỗi từ đâu?” + +“Có hai bản mà đội Kha đang coi là hai nguồn.” Khánh An hít ngắn. “Một bản lấy từ dữ liệu cũ ở Đại Hà. Một bản lấy từ Hậu Ký. Tôi chưa chắc chúng độc lập.” + +Cái tên khiến Thủy, đứng bên bàn loa, ngẩng đầu. Tiến không biểu lộ. “Hậu Ký là gì?” + +Khánh An nhìn thẳng camera. Trong một giây, cô cân giữa thông tin và mạng sống. “Tên nội bộ của một kho dữ liệu về những việc chưa xảy ra.” Bình quay sang Tiến. Nam cũng ngẩng khỏi màn hình. + +Thủy không tỏ vẻ kinh ngạc ngay. Phản ứng đầu tiên của cô vẫn là phản ứng của một phóng viên: “Ai ghi?” + +“Không biết.” + +“Nguồn?” + +“Nhiều.” + +“Bản gốc?” + +“Không có một bản duy nhất.” + +“Độ tin cậy?” + +Khánh An cười nhạt, nhưng vết thương kéo khóe môi xuống ngay. “Đủ để Kha xây tuyến hàng trước Hồng Nhật. Không đủ để hắn biết hôm nay sẽ đứng ở đâu.” Hậu Ký vì thế không giống lời tiên tri hoàn chỉnh; nó là dữ liệu phân mảnh, đúng ở vài điểm, sai ở những điểm khác, và nguy hiểm nhất khi người sở hữu tưởng phần mình có là toàn bộ. + +Tiến hỏi: “Hai chuỗi khác nhau thế nào?” Khánh An rút từ túi quần một tờ giấy gấp bốn, đặt xuống nền rồi lùi lại. Bình dùng móc kéo qua khe dưới cổng. + +Trên giấy không có khuông nhạc, chỉ có những vạch dài, chấm ngắn và khoảng trắng. Hai chuỗi gần giống nhau, nhưng ở đoạn giữa, khoảng nghỉ trước nhịp thứ bảy ngắn hơn một phần ba. Thủy cúi sát. “Không thiếu một nhịp.” + +Khánh An gật. “Sai khoảng im.” + +“Vì sao Kha chọn bản đó?” + +“Bản Hậu Ký ghi chuỗi ấy đã mở được Listening Well. Anh ta còn có hai log kỹ thuật cùng kết quả.” Khánh An thở ngắn vì đau. “Vấn đề là ba bản đều đi ra từ cùng một lớp tổng hợp. Trông như ba nguồn, thật ra chỉ là một kết luận được chép ba lần.” + +Tiến hiểu ngay. Kha không bỏ qua kiểm chứng; hắn bị một hệ thống có vẻ độc lập đánh lừa về nguồn gốc bằng chứng. Đó là loại sai lầm nguy hiểm hơn sự cẩu thả, vì người thông minh càng dễ tin khi ba bảng cùng cho một đáp án. + +“Trong hoàn cảnh nào?” + +“Không có.” + +Thủy ngẩng. “Vậy hắn đang lấy kết quả mà không có điều kiện.” + +“Đúng.” + +Hắn liếc đồng hồ. “Bao lâu?” + +“Bốn mươi bảy phút, nếu hắn chưa bắt đầu.” + +Con số làm Tiến ngẩng lên. Khánh An nhận ra phản ứng. + +“Anh ấy luôn dùng bốn mươi bảy phút như giới hạn cuối,” cô nói. “Tôi chưa từng hỏi vì sao.” + +“Và nếu bắt đầu rồi?” + +Khánh An nhìn về phía đông, nơi bầu trời đỏ chìm dần sau mái nhà. “Chúng ta sẽ nghe trước khi tới.” Linh nói nhỏ: “Cô ấy mất máu.” + +Tiến cân cả hai phía trước khi nói. Mở cổng cho Khánh An đồng nghĩa đưa một người của Kha qua ba lớp phòng thủ; để cô ngoài lại có thể mất người duy nhất biết cấu trúc thử nghiệm. + +“Cô vào sân đệm. Dừng ở vạch vàng.” + +Khánh An nhướn mày. “Tin tôi?” + +“Không.” + +“Vậy?” + +“Tin cô không muốn chết ngoài cổng.” + +Lớp khóa thứ ba mở. Khánh An bước vào, từng bước chậm, hai tay vẫn để trước mặt. Khi cô qua vạch vàng, Bình khóa cổng sau. Linh tiến tới, cắt áo quanh vết thương. + +“Đạn?” + +“Mảnh kim loại.” + +“Trong người?” + +“Không biết.” + +“Cô làm gì cũng không biết à?” + +Khánh An nhìn cô. “Tôi biết nơi Kha đặt bộ gõ.” Linh ấn gạc. Khánh An nghiến răng nhưng không kêu. + +Trong lúc Linh xử lý, Thủy đặt hai chuỗi cạnh dữ liệu Láng họ từng ghi. Cô gạch các khoảng nghỉ, không gạch tiếng gõ. + +“Bản Đại Hà gần nhịp tự nhiên của đường ống hơn,” cô nói. “Bản Hậu Ký nén khoảng thứ ba và kéo dài khoảng thứ năm.” + +Tiến hỏi: “Có thể chỉ khác thiết bị.” + +“Có thể. Cũng có thể Hậu Ký ghi một lần thử với nhiệt độ, áp lực hoặc nguồn điện khác.” + +Khánh An nói: “Kha không biết điều kiện. Hắn chỉ biết kết quả.” Một người đọc tương lai mà thiếu phần trước và sau. + +Tiến hiểu vì sao Kha nguy hiểm. Không phải vì hắn biết quá nhiều. Vì hắn có đủ dữ liệu để tin mình biết. Nam xoay màn hình. “Có rung.” + +Một cốc nước trên bàn tạo vòng tròn rất nhỏ. Trên camera ngoài phố, sợi dây điện chùng rung dù không có gió. Cộc. + +Âm đầu tiên đi qua nền kho, không rõ từ đâu. Khánh An nhắm mắt. “Hắn bắt đầu rồi.” + +Tiến đứng dậy. “Bình chuẩn bị xe. Thủy mang bản ghi Láng. Linh, giữ Khánh An ở lại.” + +“Không.” Khánh An cố ngồi lên. “Không có tôi, anh không qua được đội ngoài.” + +“Cô vừa được khâu.” + +“Không đi thì Kha dùng xong chuỗi trước khi các anh tới cửa.” + +Linh ấn vai cô xuống. “Cô đi được mười phút rồi ngất.” Khánh An nhìn Tiến. “Vậy mười phút đó phải đủ.” + +Tiến kiểm bản đồ, số người và hai lối rút. Hắn ghét việc cô đúng. + +“Cô ngồi xe thứ hai. Không cầm súng. Linh băng ép và đi cùng tới điểm dừng, không xuống trạm.” + +Linh định phản đối, rồi thấy màu nước trong cốc tiếp tục rung. Cộc. + +Lần này mạnh hơn. Thủy gấp hai chuỗi vào túi chống nước. “Tiến.” + +“Gì?” + +“Chúng ta không tới để thêm một nhịp.” + +Hắn nhìn cô. Cô đặt ngón tay vào khoảng trắng giữa hai vạch. + +“Chúng ta phải sửa khoảng im.” + +Bên dưới Ngọc Trục, HN-07 không hiện cảnh báo. Nó chỉ ghi một dòng vào log: + +**LANG HANDSHAKE ATTEMPT DETECTED** + +Màn hình không đưa hướng dẫn, tọa độ hay lựa chọn nào; nó chỉ tiếp tục quan sát. + +Chương 24: Sai Một Nhịp + +Họ nghe Trạm Láng trước khi nhìn thấy nó. + +Thứ đầu tiên nhận ra dao động không phải tai người mà là những vật còn khả năng rung: ô kính sót lại trên tầng ba, biển quảng cáo méo, nắp cống và khung xe. Mỗi vật nhận cùng một dao động nhưng phát ra âm khác nhau, như cả con phố đang cố nhắc lại một câu bằng những giọng không khớp. + +Cộc. Khoảng nghỉ. + +Cộc—cộc. Bình giảm ga. “Đã vào chuỗi?” + +Khánh An ngồi sau chiếc xe thứ hai, một tay ép lên băng sườn. Mồ hôi làm tóc dính vào thái dương, nhưng mắt cô vẫn theo những vị trí có thể đặt người. “Đội ngoài đã đổi. Kha biết tôi rời.” + +“Bao nhiêu?” + +“Lúc 04:20 tôi đếm được mười hai: ba trong Listening Well, bốn ở cống bắc, còn lại chặn lối tầng trên. Đó là số cũ hơn gần một giờ; coi nó là mức sàn, đừng coi là quân số hiện tại.” + +Tiến chỉ tuyến vòng trên bản đồ giấy. “Không dùng nhà hai tầng.” Khánh An gật. “Có nhánh bảo trì dưới lòng Tô Lịch. Hắn tìm thấy sau khi anh mở West Vein.” + +Không ai phí thời gian hỏi Kha biết bằng cách nào. Có thể là theo dõi, mua người, suy luận hoặc Hậu Ký; với hắn, mọi nguồn tin đều chỉ là những tuyến cần nối. + +Họ dừng xe trong ngõ cách trạm gần bốn trăm mét. Linh kiểm băng Khánh An lần cuối rồi ở lại với xe, bình truyền và lối rút. Ông Hòa không đi; bàn tay ông đang xử lý hệ thống nước Ngọc Trục. Bình mang búa cao su, Thủy mang bộ ghi rung, còn Tiến mang kìm cắt, dao và một cuộn dây đồng. + +“Chúng ta không đánh,” Tiến nói. + +Bình nhìn bộ phóng trong tay. “Mười hai người bên kia chắc cũng nghĩ vậy.” + +“Chỉ khi họ chưa thấy mình.” + +Khánh An dẫn xuống một cống hẹp. Không khí nóng và mùi bùn cũ quện với kim loại. Mỗi lần chuỗi gõ truyền qua, thành ống rung dưới lòng bàn tay. Thủy đặt cảm biến lên thành. “Khoảng thứ ba ngắn dần.” + +“Bộ gõ tự động,” Khánh An nói. “Kha đang cho hệ thống bám pha.” + +“Bám vào cái gì?” + +“Listening Well.” + +Tiến hỏi: “Nếu phá nguồn?” + +“Cánh tay cơ rơi tự do. Nhịp cuối vẫn xảy ra.” + +“Nếu chặn tay?” + +“Cú dừng đột ngột truyền xung mạnh hơn.” + +Không thể giải bằng cách đập thiết bị. Họ tới khe nhìn xuống phòng trạm. Kha đứng gần cửa, áo đen, một tay đặt lên tablet. Bộ gõ ở giữa: cánh tay kim loại đập lên một tấm hợp kim nối thẳng với mạng ống dưới nền. Ba người giữ nguồn, đo nhiệt và áp lực. Những người còn lại ở lối. + +Chuỗi đã đi qua nửa. Thủy mở hai tờ giấy. Cô không đếm tiếng. Cô đếm khoảng nghỉ bằng đồng hồ rung tự chế. + +“Bản Hậu Ký không thiếu nhịp,” cô thì thầm. “Nó lệch pha sau nhịp sáu. Nếu thêm tiếng gõ, chỉ làm nhiễu mạnh hơn.” + +Khánh An nhìn. “Vậy sửa thế nào?” + +“Cho nó một tải trễ.” + +Tiến hiểu trước Bình. “Kéo dài dao động sau nhịp sáu, không tạo nhịp mới.” Thủy chỉ đường ống chạy dưới chân. “Nếu tác động lên cùng vật liệu đúng lúc, xung phản hồi sẽ làm bộ gõ nhận rằng bề mặt chưa kết thúc dao động. Bộ điều khiển sẽ tự trì hoãn nhịp kế.” + +“Bao nhiêu?” + +“Không biết chính xác.” + +“Cô cần gì?” + +“Dữ liệu thật.” + +Tiến đặt lòng bàn tay lên ống. Mỗi rung động truyền vào xương. Hắn nhớ cách hệ thống bơm công nghiệp tự ngắt khi áp lực phản hồi vượt ngưỡng. Đó không phải âm nhạc, mà là tín hiệu điều khiển. + +“Bình, búa.” + +Bình đưa. + +“Đừng gõ,” Tiến nói. “Ép.” + +Họ quấn dây đồng quanh ống, luồn búa làm đòn, tạo một điểm tì có thể giữ ống rung thêm một phần giây. Thủy đặt hai ngón lên kim cảm biến. Nhịp năm. + +Cộc. Khoảng nghỉ kéo dài. + +Nhịp sáu. Cộc. + +“Bây giờ.” + +Bình ép đòn. Ống rền trong lòng đất. Không có tiếng gõ mới, chỉ dao động cũ không chịu tắt. + +Bộ gõ dưới phòng khựng. Màn hình của Kha chuyển đỏ. + +Một người nói: “Pha không khóa.” Kha không nhìn quanh. Hắn nhìn đường ống. + +“Có người trong nhánh bảo trì.” + +Đội ngoài lập tức di chuyển. Khánh An rút khẩu súng giấu sau lưng dù Tiến đã cấm. “Tôi giữ.” + +“Cô không bắn nếu chưa cần.” + +“Anh muốn giải thích với họ?” + +“Muốn lối rút.” + +Nhịp bảy bị trì hoãn, nhưng bộ điều khiển tự hiệu chỉnh. Thủy nhìn kim. + +“Nó đang rút ngắn khoảng tiếp theo để bù.” + +Nếu để, tổng chuỗi vẫn hội tụ về bản sai. + +“Phải phá vòng tự bù,” Tiến nói. + +Dưới phòng, Kha ra lệnh đổi chế độ tay. Người kỹ thuật kéo cần. Khánh An chửi. “Hắn bỏ tự động.” + +Giờ không còn bộ điều khiển để lừa. Thủy nhìn hai chuỗi, rồi nghe bằng cơ thể. “Bản đúng không cố giữ tổng thời gian.” + +“Ý?” + +“Khoảng im không phải phần thừa. Nó là một trạng thái riêng. Kha đang nghĩ phải hoàn thành chuỗi trong đúng số giây.” + +Tiến nhìn Kha qua khe. Hắn đang ra hiệu người vận hành tiếp tục theo đồng hồ. + +“Cho hắn mất đồng hồ.” + +Bình hỏi: “Cắt điện?” + +“Không. Cắt tham chiếu.” + +Tiến luồn dây đồng vào tuyến cảm biến thời gian chạy dọc ống, không phải nguồn chính. Khánh An chỉ đúng sợi. Hắn cắt. Bộ gõ vẫn có điện, nhưng màn hình không còn mốc pha. Người vận hành chần chừ. + +Kha nói: “Tiếp.” + +“Không có clock.” + +“Đếm tay.” + +Sai lầm. Con người đếm trong một căn phòng cộng hưởng không thể chính xác. Mỗi tiếng vọng quay lại làm khoảng cách nghe ngắn hoặc dài hơn. + +Thủy nhắm mắt. + +“Nhịp thật có hướng từ tấm gõ. Tiếng lặp không có hướng rõ.” + +Tiến quay sang cô. “Dẫn.” Họ bò tới lưới thông khí. Thủy giơ tay theo các nhịp thật. Tiến dùng đèn pin chớp vào phòng qua khe, không để truyền âm. Một tín hiệu thị giác. + +Người vận hành thấy. Một chớp sau nhịp thật. + +Hai chớp ở khoảng cần dừng. Hắn không hiểu, nhưng Kha hiểu. + +Kha nhìn thẳng khe thông khí. Tiến chớp lần nữa: dừng. + +Hai người nhìn nhau qua dải sáng lạnh của thiết bị. Kha vẫn có thể ra lệnh tiếp; Hậu Ký chỉ ghi rằng chuỗi này từng mở được giếng. + +Nhưng hắn cũng thấy kim áp lực đã vượt vùng dữ liệu. + +“Dừng tay,” Kha nói. + +Người vận hành buông cần. Nhịp thứ tám không rơi. + +Cả Trạm Láng im. Im quá lâu. + +Rồi nền đất trả lại tất cả dao động chưa tiêu tán trong một lần. Một tiếng rền dâng từ dưới sâu, không giống nổ. Các đường ống rung đồng thời. Kính trên phố vỡ. Đèn pin tắt. Một người trong phòng ôm đầu, hét tên mẹ. + +Dư Âm tràn lên. Thủy nghe hàng chục giọng chồng nhau, nhưng cô bám vào tiếng thật: tiếng Bình thở bên phải, tiếng Tiến kéo dây trước mặt, tiếng chân đội Kha đang tới từ sau. + +“Lối bắc!” cô nói. “Ba người.” + +Có hướng. Thật. + +Khánh An bắn một viên vào trần cống, làm mảnh bê tông rơi chặn lối, không bắn người. “Đi.” Tiến kéo Thủy. Bình đỡ Khánh An. + +Trong phòng trạm, Kha nhìn màn hình hiện một dòng chưa từng có trong Hậu Ký: + +**HANDSHAKE ABORTED / RESONANCE UNRESOLVED** + +Hắn không đuổi ngay. Lần đầu, dữ liệu của hắn không chỉ sai kết quả. + +Nó thiếu cả điều kiện để hiểu vì sao. Trên đường rút, Thủy nghe một tiếng chuông rất xa. + +Không có hướng. Cô không đi theo. + +Chương 25: Dư Âm + +Dư Âm theo họ về Ngọc Trục. + +Dư Âm không kéo thành một âm thanh liên tục. Nó chen vào các khe của tiếng thật: sau tiếng cửa đóng, giữa hai vòng quay của quạt, lúc người ta ngừng nói để lấy hơi. Một số người nghe tên mình. Một số nghe người thân đã chết. Một số chỉ thấy áp lực trong tai và muốn bước về một hướng không rõ. + +Tiến cho tắt toàn bộ loa, radio và thiết bị không cần thiết. Mọi người đeo dây vải màu vào cổ tay theo nhóm để nhận nhau khi mất ánh sáng. Cổng được chuyển sang quy tắc cơ: không mở bằng giọng, không mở bằng mã qua radio, chỉ mở khi người trực nhìn thấy mặt và ký hiệu tay. + +Nam ngồi sát tường, hai bàn tay bịt tai. + +“Cửa cuốn,” cậu nói. “Nó đang kéo.” + +Không có cửa cuốn nào chuyển động. Thủy ngồi cách cậu hai mét, không chạm. “Nam, nhìn tôi.” + +Cậu mở mắt. + +“Tiếng đó ở hướng nào?” + +Nam quay đầu, rồi dừng. “Không biết.” + +“Vậy chưa phải thứ mình làm theo.” + +Câu nói không xóa tiếng. Nhưng cho cậu một thao tác. Thủy đi quanh kho cùng một cuốn sổ. Cô chia mọi âm thành hai cột. + +**Có hướng vật lý.** + +**Không xác định hướng.** + +Tiếng máy bơm: có hướng. Tiếng trẻ khóc từ khu y tế: có hướng. Giọng phụ nữ gọi “Thủy” ngay trong đầu: không. Tiếng kim loại rơi sau kho: có hướng, Bình kiểm tra. Tiếng chuông dưới nền: cảm nhận được trên cảm biến nhưng không xác định được điểm nguồn. + +Không đơn giản là thật và giả. Có âm không hướng vẫn tạo rung đo được. Có âm có hướng là tiếng người hoảng loạn nhắc lại điều họ vừa nghe. Nhưng phương pháp giữ họ khỏi phản ứng ngay. Linh phát hiện người đầu tiên mất nước vì Dư Âm là ông Tuấn, một người sống sót từ Đại Hà. Ông đứng trước cổng suốt gần một giờ vì nghe con trai gọi ngoài đường. Khi Bình kéo vào, bàn chân ông phồng rộp vì nền nóng. + +“Con tôi ở ngoài,” ông vẫn nói. + +“Ông thấy không?” Linh hỏi. + +“Nghe.” + +“Có hướng?” + +Ông chỉ đại một phía. Thủy đứng vào ba vị trí, hỏi lại. Hướng ông chỉ thay đổi theo chỗ đứng. + +Không phải tiếng ngoài cổng. Ông Tuấn bật khóc. + +Không ai gạt đi trải nghiệm của ông bằng hai chữ “tưởng tượng”. Trong tận thế, chỉ riêng nỗi đau cũng đủ dẫn một người bước vào chỗ chết. Khánh An nằm ở khu y tế, sốt nhẹ vì vết thương. Mỗi lần ngủ, cô gọi tên một người trong đội cũ. Linh muốn cho thuốc an thần, nhưng Thủy phản đối liều cao. + +“Nếu Dư Âm ảnh hưởng nhịp thở, thuốc có thể làm cô ấy không tự tỉnh.” + +Linh nhìn cô. “Cô là bác sĩ?” + +“Không.” + +“Vậy đừng ra lệnh.” + +“Đúng. Tôi đưa dữ liệu.” + +Linh kiểm lại nhịp thở rồi giảm liều. Không ai “thắng” cuộc trao đổi đó; họ chỉ đổi quyết định sau khi có thêm một rủi ro cần tính. + +Tiến xuống HN-07 một mình. Màn hình hiện log của Trạm Láng: + +**HANDSHAKE ABORTED** + +**ECHO LOAD: 17%** + +Không có lệnh xử lý hay sơ đồ đi kèm, cũng chẳng có câu hỏi hắn muốn gì. Tiến thử tắt điểm truy cập. Hệ thống từ chối bằng một dòng: + +**PHYSICAL NETWORK ACTIVE** + +Nghĩa là Dư Âm không tồn tại vì màn hình đang bật. Nó đi qua cấu trúc vật lý: ống, nước, nền đất, có thể cả hệ thần kinh. Tiến quay lên, lấy bản đồ công trình và yêu cầu ông Hòa đánh dấu mọi tuyến kim loại nối kho với bên ngoài. Ông Hòa nghe mô tả rồi gõ ngón tay lên ống chính. + +“Dây điện không nói dối. Chỉ có người đọc sai nó.” + +“Ống nước.” + +“Cũng là dây.” + +Họ cô lập ba đoạn, thêm đệm cao su vào giá đỡ, ngắt một bơm và chuyển quạt khỏi khung kim loại chung. Dư Âm không biến mất, nhưng cường độ trong kho giảm. Một giải pháp kỹ thuật không chữa được ký ức. Chỉ làm nó bớt có đường đi. + +Tối, Thủy đứng ngoài mái che, nhìn vầng Hồng Nhật đã thấp nhưng không dịu. Tiến mang hai cốc nước, đưa cô một cốc. + +“Cô nghe gì?” + +“Anh hỏi như hỏi thời tiết.” + +“Dễ đo hơn.” + +“Không.” + +Cô uống một ngụm nhỏ. “Tôi nghe giọng mình.” Tiến dừng. + +“Nói gì?” + +“Bảo đừng tin anh.” + +“Có hướng?” + +“Không.” + +“Vậy?” + +“Không có nghĩa là sai.” + +Hắn nhìn cô. Thủy nói tiếp: “Dư Âm dùng ký ức và nghi ngờ của người nghe. Nếu trong tôi không có lý do nghi anh, nó không tạo được câu đó.” + +“Cô nghi gì?” + +“Anh vẫn giấu.” + +“Đúng.” + +“Anh định sửa?” + +“Không phải tất cả.” + +Cô cười rất nhẹ. “Vậy giọng kia có dữ liệu.” Tiến không phản bác. + +Một lúc sau, hắn hỏi: “Cô có nghe Kha?” + +“Không.” + +“Khánh An?” + +“Không.” + +“Người chết?” + +Thủy nhìn về phía cổng. “Có.” + +“Có làm theo?” + +“Không.” + +“Vì quy tắc hướng?” + +“Vì tôi không muốn một giọng, dù là thật, quyết định chân mình bước đâu.” + +Đó là cách cô bắt đầu trở thành Người Nghe. Không phải vì nghe được nhiều hơn. + +Vì biết âm thanh nào chưa đủ quyền để trở thành mệnh lệnh. Gần nửa đêm, một tiếng gõ vang trong đường ống phía Tây. Ba nhịp. Có hướng. + +Ông Hòa kiểm tra. Không người. Cảm biến cũng ghi. + +Thủy đánh dấu vào cột thứ ba mới: + +**Có đo được, chưa biết nguồn.** + +Dư Âm chưa kết thúc. Trên bảng kiểm, ô **có đo được, chưa biết nguồn** được giữ nguyên thay vì bị ép sang thật hoặc giả. + +Chương 26: Nước Xám + +**16/07/2028** + +Ba ngày sau Dư Âm, nước Ngọc Trục đổi màu. Không đen và không có mùi. Chỉ một lớp xám rất nhẹ, nhìn rõ nhất khi Linh đặt hai cốc lên tấm nhựa trắng: mẻ hôm qua trong hơn; mẻ sáng nay như có bụi kim loại hòa ở đáy ánh sáng. + +Nam cúi sát. “Em không thấy.” Linh xoay cốc. “Vì em đang tìm bẩn. Đây là thay đổi.” + +Tiến dùng máy đo cầm tay. Độ dẫn điện tăng, khoáng hòa tan tăng, pH lệch nhẹ. Bộ test nhanh không phát hiện vi khuẩn, nhưng họ không có phòng xét nghiệm để biến một kết quả âm tính thành an toàn. + +“Dừng uống nguồn bể,” Linh nói. + +Bình nhìn dãy can. “Nước chai còn bao lâu?” + +“Chín ngày theo định mức cũ. Mười ba nếu giảm.” + +“Nhiệt đang tăng.” + +“Vậy ít hơn.” + +Linh khóa khu nước, đánh số từng chai và yêu cầu uống tại chỗ. Nước xám chỉ được dùng rửa dụng cụ sau khi đun, chưa dùng cho người. Trong chuyện nước ngày hôm đó, người có tiếng nói cuối cùng là Linh chứ không phải Tiến. Phúc phản đối ngay. + +“Một đứa trẻ ngoài sân sốt. Nó cần thêm.” + +“Có định mức y tế.” + +“Không đủ.” + +“Anh đo mất nước chưa?” + +“Nhìn cũng biết.” + +“Nhìn không tính được natri, mạch và lượng tiểu.” + +“Cô chờ nó ngất mới cho?” + +Linh đặt bút xuống. “Anh muốn lấy phần của ai?” Phúc im. + +Đó là câu hỏi thật phía sau mọi tranh cãi về lòng tốt. + +Tiến yêu cầu lấy mẫu ở ba điểm: bể, đường ống trước lọc và giếng kỹ thuật. Ông Hòa cùng Nam kiểm hệ thống. Màu xám xuất hiện sau bộ lọc, không trước. Màng lọc không hỏng theo cách thông thường; một lớp vật liệu mịn từ đường ống phía dưới đang phản ứng với khoáng sau Dư Âm. + +“Cộng hưởng làm bong lớp lót?” Tiến hỏi. + +Ông Hòa chưa có thiết bị phân tích vật liệu, chỉ có kinh nghiệm với đường ống và một bộ đo cầm tay. Ông cạo một ít cặn, đặt lên tấm thép rồi so màu với lớp lót còn nguyên. + +“Có thể.” + +“Độc?” + +“Không biết.” + +Tiến ghét câu trả lời, nhưng không ép nó thành chắc chắn. Họ thử kết tủa, than hoạt tính và đun. Màu giảm, độ dẫn vẫn cao. Không đủ để đưa vào cơ thể người mất nước nặng. + +Buổi chiều, một nhóm bảy người xuất hiện ngoài cổng. Hai trẻ em, một người già, bốn người lớn. Họ không biết tên Tiến. Chỉ theo dấu xe nước. Bình hỏi: “Cho bao nhiêu?” Theo quy tắc cũ, người ngoài không được lấy nguồn dự trữ lõi. Tiến đọc con số trên bảng. + +Phúc đứng cạnh, không nói. Cái im của anh còn rõ hơn tranh cãi. + +“Bảy cốc,” Tiến nói. “Uống ngoài cổng. Không cấp chai.” + +Linh nhìn hắn. “Một lần?” + +“Ừ.” + +“Ngày mai?” + +“Không hứa.” + +Họ mở khe phát nước. Người già uống chậm; một bé gái uống quá nhanh, mẹ phải kéo cốc xuống. Bảng cấp phát mất bảy phần nước. Hôm đó, không ai chết vì bảy phần ấy. + +Nhưng không ai biết cái thiếu của bảy cốc sẽ hiện ra vào ngày nào. Đêm, Phúc trực kho nước cùng Nam. Một tiếng gõ vang phía ngoài cổng, rồi giọng phụ nữ gọi tên Phúc. + +“Anh ơi.” + +Phúc đứng bật. Nam nhìn anh. Giọng lại gọi. “Phúc.” + +Em gái. Có thể. Không có hướng rõ. Nam nói: “Đừng mở.” + +Phúc không mở cổng. Anh đi tới khu nước, dùng chìa phụ mở tủ và lấy một chai. Nam chặn. “Anh làm gì?” + +“Đứa trẻ sốt.” + +“Linh không cho.” + +“Linh không ở đây.” + +“Quy tắc—” + +“Đứa bé ngoài kia không biết sáng mai hội đồng sửa quy tắc thế nào.” + +Phúc bước qua. Nam giữ tay anh. Cậu run, nhưng không buông. + +“Anh nói hôm Đại Hà nếu có người mở cửa vì giọng gọi thì tất cả chết.” + +Phúc nhìn chai nước. + +“Đây không phải cổng.” + +“Vẫn là thứ giữ mọi người sống.” + +Hai người đứng giữa kho. Phúc có thể đẩy Nam. Anh mạnh hơn. Nhưng cuối cùng, anh đặt chai xuống. + +Rồi lấy cốc định lượng y tế, rót đúng phần đã cho phép và mang tới đứa trẻ. Sáng, Linh phát hiện. + +“Anh tự mở tủ.” + +“Ừ.” + +“Lấy đúng định mức.” + +“Ừ.” + +“Vậy vì sao không gọi?” + +“Vì cô sẽ hỏi.” + +“Đúng.” + +“Và tôi sợ cô nói không.” + +Linh nhìn anh lâu. “Từ hôm nay, ca đêm được cấp một liều khẩn nếu hai người cùng kiểm dấu mất nước và cùng ký. Sáng tôi rà lại.” + +Tiến đứng ở cửa. “Vậy tối nay tính là vi phạm?” + +“Có,” Linh nói. “Anh ấy tự mở tủ khi chưa có quyền. Nhưng việc anh ấy làm cũng chỉ ra quy tắc thiếu trường hợp khẩn. Hai chuyện không triệt tiêu nhau.” + +Phúc nhìn cô. Không được tha vì lòng tốt. Nhưng hành động của anh buộc hệ thống sửa. Cuối ngày, Tiến nhận cuộc gọi từ Thanh Hóa. Sóng đứt quãng. + +Mẹ hắn nói có hai người lạ hỏi về con trai bà. Không đe dọa, chỉ hỏi ngày Tiến về gần nhất và có gửi hàng không. Tiến siết điện thoại. + +“Nếu họ quay lại, mẹ đi nhà bác Dũng.” + +“Con đừng về.” + +“Mẹ—” + +“Nghe. Con về vì mẹ, họ sẽ biết cách kéo lần sau.” + +Giọng bà bình tĩnh hơn hắn. Nước trong kho xám đi. Mẹ ở xa bị theo dõi. Người ngoài tới cổng. Mỗi vấn đề là một đường ống rò, và Tiến không còn đủ tay để tự bịt tất cả. + +Trên màn hình HN-07, không có tọa độ cứu nước. Chỉ một thay đổi trạng thái: + +**WESTERN ACCESS WATER CONDUCTIVITY: RISING** + +Trên màn hình, đường ống vẫn nhấp nháy đỏ. Ngoài sân, Bình đặt chiếc ca đầu tiên dưới vòi và chờ người bên cạnh cùng đọc số. + +Chương 27: Đường Về Thanh Hóa + +**17/07/2028 – 05:40** + +Tiến quyết định không về Thanh Hóa. + +Đó là quyết định đầu tiên hắn đưa ra sau cuộc gọi của mẹ, và cũng là quyết định khiến hắn muốn phá mọi quy tắc mình từng đặt. Hai người lạ đã hỏi về các kiện hàng hắn gửi trước Hồng Nhật. Nếu hắn xuất hiện, họ sẽ biết bà là điểm có thể kéo hắn khỏi Ngọc Trục. Nếu hắn không về, bà phải tự đối mặt với mối đe dọa hắn chưa nhìn thấy. + +Thủy nghe hắn trình bày bản đồ đường quốc lộ, các tuyến tránh và khoảng thời gian xe có thể chạy trước khi mặt đường đạt ngưỡng quá nóng. + +“Anh đang lập kế hoạch về,” cô nói. + +“Đang lập kế hoạch không về.” + +“Khác nhau ở đâu?” + +“Ở điểm cuối.” + +Hắn chỉ một trạm trung chuyển hàng cũ phía bắc Thanh Hóa. Bình có một người quen từng chạy tuyến, còn Nam biết một nhóm shipper đã rời Hà Nội hai tuần trước. Họ không cần đưa Tiến về tận nhà. Chỉ cần chuyển một radio cơ, thuốc, pin, bộ lọc nhỏ và chỉ dẫn an toàn qua nhiều tay, không để một tuyến biết toàn bộ. + +Một chuỗi hậu cần phân tán. Cách Kha làm. Tiến nhận ra và không thích. + +Bình đọc danh sách. “Ai đi?” + +“Tôi.” + +Thủy gạch tên hắn. + +“Không.” + +Tiến nhìn. + +“Anh vừa nói không về. Đi nửa đường vẫn là để người theo dõi biết hướng.” + +“Bình?” + +Bình lắc. “Mặt tôi xuất hiện ở La Phù rồi. Người của Kha biết.” Nam nói nhỏ: “Em có thể tìm người chuyển.” Mọi người quay sang. + +Cậu đặt ba cái tên lên bàn: những shipper từng ngủ chung bãi chờ, không thuộc nhóm lớn và không biết Ngọc Trục. Một người đang ở Chương Mỹ, một người ở Xuân Mai, một người có em làm tài xế tuyến Thanh Hóa. Tiến hỏi: “Tin?” + +“Không hoàn toàn.” + +“Vậy sao dùng?” + +Nam chạm lưỡi lên đôi môi khô. “Vì họ không biết đủ để bán cả đường.” Lập luận đứng vững: không cần tìm một người tuyệt đối đáng tin nếu mỗi người chỉ nắm phần thông tin không đủ để phản bội toàn bộ tuyến. + +Họ chia hàng thành bốn kiện, mỗi kiện mang một phần mã nhận. Mẹ Tiến chỉ nhận đủ khi ghép câu hắn từng dùng hồi nhỏ: tên con sông gần nhà, ngày giỗ bố và một câu bà hay mắng. Không dữ liệu nào trong hồ sơ công khai có đủ. Thủy nhìn hắn viết. + +“Đây mới là neo thật của anh?” + +Tiến dừng bút. “Không gọi vậy.” + +“Vì?” + +“Bà ấy là người.” + +Thủy không hỏi thêm. Đoàn đầu rời Ngọc Trục lúc trời chưa sáng hẳn. Tiến đứng sau cổng nhìn chiếc xe máy mất vào đường. Hắn không đi theo. + +Đó không phải hèn. Nhưng cơ thể hắn không biết khác biệt. Mọi cơ bắp đều muốn lao về phía nam. + +Đến trưa, gói đầu tới Chương Mỹ. Tín hiệu xác nhận đúng. Hai giờ sau, người chuyển thứ hai không trả lời. Bình kiểm tuyến. “Có thể hết pin.” + +“Có thể bị chặn,” Tiến nói. + +Thủy nói: “Không dùng ‘có thể’ để chọn điều tệ nhất.” + +“Phải chuẩn bị.” + +“Chuẩn bị khác kết luận.” + +Họ chờ thêm ba mươi phút. Một gói tin ngắn tới: + +**ĐƯỜNG CŨ BỊ CHẶN. CÓ NGƯỜI ĐEO VÒNG KHUYẾT. ĐỔI TUYẾN.** + +Biểu tượng Vòng Tròn Vỡ. Những người theo mẹ Tiến không nhất thiết là Kha. Một phe khác đã nhìn thấy chuỗi hàng trước Hồng Nhật và lần theo. + +Tiến gọi radio trung gian, không gọi trực tiếp mẹ. “Hủy điểm ba. Chuyển kiện qua xe tải rau.” Người bên kia hỏi: “Giá?” + +“Hai pin và bản đồ giếng.” + +“Ba pin.” + +“Được.” + +Trong một thành phố sụp, lời cầu cứu vẫn có giá. Tối, kiện hàng tới nhà bác Dũng. Mẹ Tiến chỉ gửi một câu: + +**MẸ NHẬN. ĐỪNG VỀ.** + +Bà không cảm ơn hay hỏi thăm dài dòng; radio có người nghe, cả hai đều hiểu. Tiến đọc thông điệp ba lần. + +Thủy đứng cạnh nhưng không nhìn màn hình. “Bà ổn?” + +“Hiện tại.” + +“Anh?” + +“Không.” + +Một câu không có cấu trúc. Cô gật. + +Gần nửa đêm, người chuyển thứ hai về tới điểm liên lạc. Anh ta mang theo một vật lấy từ người chặn đường: vòng kim loại bị bẻ mất một đoạn, mặt trong khắc câu: + +**NẾU KHÔNG CÓ KHÓA, SẼ KHÔNG CÓ CỔNG.** + +Khánh An nhìn và nhận ra cách chế tạo. + +“Không phải người Kha.” + +“Chắc?” Bình hỏi. + +“Kha không khắc giáo lý lên dụng cụ.” + +“Vậy ai?” + +Khánh An nói: “Những người tin Observation Initiative đã sai từ khi cố giữ các nút.” Tiến hỏi: “Tên?” + +“Chúng tự gọi là Vòng Tròn Vỡ.” + +Cái tên không mới với một số tài liệu cũ, nhưng đây là lần đầu họ chạm vào người thật. + +“Chúng muốn mẹ tôi?” + +“Có thể không,” Khánh An đáp. “Có thể muốn anh nghĩ chúng muốn.” + +Thủy đặt vòng kim loại vào túi chứng cứ. “Ai cũng đang dùng thông tin để kéo Tiến.” Cô nhìn hắn. + +“Kha kéo bằng Hậu Ký. HANOI-07 kéo bằng tin nhắn. Phe này kéo bằng mẹ anh.” + +Tiến nói: “Vậy không đi theo dây.” + +“Làm được?” + +“Không.” + +Hắn nhìn câu của mẹ. + +“Nhưng biết nó là dây.” + +Trên bản đồ, vùng Thanh Hóa vẫn không có dấu nhà. Tiến gập máy lại, để phần trống ấy được yên. + +Chương 28: Phe Thứ Ba + +Vòng Tròn Vỡ không tấn công Ngọc Trục ngay. Chúng gửi một người. Camera ghi hắn xuất hiện ở cuối ngõ lúc 04 giờ 18, đứng ngoài vùng bắn hiệu quả và đặt xuống một hộp kim loại. Không mặt nạ, không biểu tượng lộ. Khi Bình bật loa hỏi tên, hắn chỉ nói: + +“Không cần biết người đưa.” + +Người giao hộp rời đi. Tiến giữ nguyên hiện trường suốt hai giờ, không cho ai chạm vào. Ông Hòa dùng gương, dây và móc kéo nó vào sân đệm. Không thuốc nổ. Không nguồn điện. Bên trong là ba thứ: + +- một bản đồ đường ngầm phía Tây; +- ảnh nhà mẹ Tiến; +- một cuộn băng ghi âm. + +Bình chửi nhỏ. Thủy đeo găng, kiểm ảnh. “Chụp sau Hồng Nhật. Bóng nắng và cửa sổ khớp cuộc gọi hôm qua.” + +Tiến chưa hỏi Khánh An dựa vào đâu. Hắn nhìn mẹ đứng ở hiên nhà bác Dũng, tay cầm chậu nước, mặt quay khỏi camera. Người chụp ở đủ gần để thấy bà, đủ xa để chưa chắc bắn được. Cuộn băng dùng máy cơ. Không mã độc. + +Giọng nữ phát: + +“Lê Quốc Tiến. Anh đang giữ thứ đáng lẽ phải chết.” + +Không biến âm. Tuổi khoảng bốn mươi. + +“Ngọc Trục là một khóa. Láng là một tai. Hồ Tây là một mạch. Các anh đã làm ba phần nhận nhau.” + +Tiến quay sang Khánh An. Cô không biết giọng. + +“Ngày hai mươi chín tháng chín, nếu Khóa Trung Tâm nhận đủ trạng thái, vòng quan sát sẽ đóng. Khi đó mọi sai lệch bị ép về một phương án.” + +Thủy dừng băng. Khánh An tua lại câu *phá các khóa trước ngày Đồng Bộ* rồi hạ âm lượng. + +“Cách nói của Lê Hữu Kiên,” cô nói. “Hắn phụ trách một tế bào phía đông. Với Kiên, khóa nào còn hoạt động cũng là dây xích, kể cả khi trên đó đang có người.” + +“Giọng của hắn?” Bình hỏi. + +“Không. Học thuyết của hắn.” + +“Bà ta biết Hậu Ký?” + +“Hoặc dùng cùng thuật ngữ,” Tiến nói. + +Cô phát tiếp. + +“Chúng tôi không cần mẹ anh. Chúng tôi cần anh hiểu bà không phải con tin. Bà là thứ hệ thống có thể dùng để đo phản ứng của anh.” + +Giọng trong băng ngắt đúng một khoảng ngắn. + +“Neo không phải người được yêu. Neo là thứ khiến đối tượng quay về hành vi dự đoán được.” + +Tiến siết mép bàn. Mẹ hắn bảo bà không phải con tin trước khi người phụ nữ này nói. Bà hiểu trực giác điều Observation Initiative biến thành thuật ngữ. + +“Phá các khóa trước ngày Đồng Bộ,” cuộn băng tiếp, “và không hệ thống nào còn đủ dữ liệu để chọn tương lai thay thành phố.” + +Cuối băng: + +“Nếu không có khóa, sẽ không có cổng.” + +Bình hỏi: “Nghe cũng có lý.” Ông Hòa đáp: “Đập cầu vì sợ xe đi qua cũng có lý, nếu không quan tâm người đang đứng trên cầu.” Không ai cười. + +Tiến trải bản đồ chúng gửi. Một số tuyến đúng, vài tuyến cố ý sai hoặc đã lỗi thời. Vòng Tròn Vỡ có dữ liệu kỹ thuật, nhưng không toàn bộ. Thủy nói: “Chúng muốn được coi là phe hiểu hệ thống.” + +“Không phải kẻ phá mù.” + +“Đúng.” + +“Có thể chúng đúng một phần.” + +Khánh An nhìn bản đồ. “Kha từng bắt một người của chúng. Người đó nói mỗi nút hoạt động làm tương lai ít đi một nhánh.” + +“Kha làm gì?” + +“Thả.” + +Bình ngạc nhiên. “Hắn tử tế?” + +“Không. Gắn theo dõi.” + +“Rồi?” + +“Người đó cắt cả thiết bị lẫn một mảng da.” + +Không cực đoan vì thích bạo lực. Cực đoan vì tin mọi dấu quan sát đều là dây xích. Tiến triệu tập mọi người có quyền biết: Thủy, Bình, Linh, Nam, Phúc, ông Hòa và Khánh An. Không giấu hộp. + +“Ba lựa chọn,” hắn nói. “Giữ nguyên, phá, hoặc hiểu thêm.” + +Phúc hỏi: “Trong lúc hiểu, nước đổi màu và người ta theo mẹ anh.” + +“Đúng.” + +“Vậy hiểu bao lâu?” + +“Không biết.” + +Linh nói: “Đừng biến không biết thành không làm. Nước cần giải pháp trước.” Tiến gật. “Hạ tầng sống trước. nút không thử thêm.” + +Ông Hòa thêm: “Không phá thứ đang giữ tải cho tới khi có đường thay.” Thủy viết thành quy tắc tạm: + +**Không kích hoạt mới. Không phá khóa đang tải. Mọi dữ liệu về 29/09 phải có nguồn.** + +Nam hỏi: “Nếu chúng tới đánh?” Bình nói: “Thì đánh.” Tiến lắc. “Nếu đánh để phá, chặn. Nếu tới nói, nghe.” + +Khánh An nhìn hắn. “Kha sẽ coi đó là yếu.” + +“Không phải Kha quyết.” + +“Vòng Tròn Vỡ cũng vậy.” + +Lần đầu, Ngọc Trục không chọn một phe dựa trên người nào nói đáng tin hơn. Họ chọn nguyên tắc có thể kiểm chứng. Buổi chiều, HN-07 ghi một trạng thái mới: + +**EXTERNAL DOCTRINE DETECTED** + +Không gắn nhãn địch. Chỉ ghi. Thủy nhìn dòng đó. “Nó biết chúng ta nghe băng.” + +“Có mic.” + +“Hoặc nhiều hơn.” + +Tiến tắt mic ngoài, kiểm log. Dòng vẫn ở đó, có thể dựa trên thiết bị rung hoặc dữ liệu khác. Hắn không cố giải ngay. Đêm, mẹ gọi qua rơ-le. + +“Người chụp ảnh quay lại chưa?” Tiến hỏi. + +“Chưa.” + +“Mẹ có muốn chuyển nơi?” + +“Có.” + +Hắn ngạc nhiên. + +“Bác Dũng tìm được một căn hầm ở khu khác. Mẹ tự đi.” + +“Con gửi người.” + +“Không.” + +“Mẹ—” + +“Con gửi người, người ta theo người.” + +Bà đã học logic phân tán mà không cần tên. + +“Con hiểu.” + +“Mẹ biết.” + +Trước khi cúp, bà nói: “Đừng để họ gọi mẹ bằng cái tên khiến con quên mẹ là ai.” Ánh mắt Tiến dừng ở từ **ANCHOR** trong ghi chú của Khánh An. Hắn gạch một đường. Không xóa dữ liệu. + +Thủy kéo một đường dưới danh xưng **Người Nghe**, rồi viết tên thật của người mang nó ở bên cạnh. Khánh An đọc, không sửa. + +Chương 29: Dấu Trong Cổng + +Người mang vòng khuyết xuất hiện trên camera phía sau kho, rồi biến mất ở vùng tối giữa hai khung hình. Không trèo tường. Không mở cổng. Không có dấu cạy phá trên cửa ngầm. + +Tiến khóa căn cứ theo quy trình: kiểm người, kiểm lối, kiểm vật tư, kiểm các điểm mù camera. Mọi người có mặt. Không đồ lớn bị mất. Nhưng cảm giác có người đã đi qua một nơi không ai biết vẫn bám vào kho. Phúc bị nghi đầu tiên. + +Lý do không nằm ở việc Phúc từng phá quy tắc. Tuyến di chuyển sau Đại Hà của anh trùng một điểm Vòng Tròn Vỡ từng dùng để tuyển người bằng nước. Bình đặt bản đồ xuống trước mặt Phúc. “Anh đi qua đây ba lần. Có lần nào gặp người của họ?” + +Phúc nhìn dấu mực, không nổi nóng. “Có. Lần thứ hai. Hai người phát nước, không nói tên. Tôi không báo vì lúc đó chưa biết nó liên quan.” + +“Áo anh từ đâu?” + +“Kho nhân viên Đại Hà. Nếu nghi tôi, kiểm áo trước, kiểm người sau. Đừng hỏi bằng cách buộc tôi tự chứng minh mình vô tội.” + +Nam đứng cạnh bàn. “Hôm Dư Âm gọi em gái, anh Phúc có cơ hội mở cổng mà không mở. Đó không chứng minh anh ấy sạch, nhưng là dữ liệu ngược với giả thuyết phản.” + +Bình gật, tự ghi thêm vào cột đối chứng. Không ai được miễn nghi chỉ vì đã làm đúng một lần; cũng không ai bị kết tội chỉ vì một tuyến đường trùng. Tiến cho kiểm vật dụng trước khi hỏi tiếp. + +Hắn kiểm quần áo Phúc. Máy dò kim loại kêu ở lớp viền áo bảo vệ Đại Hà. Linh cắt chỉ, lấy ra một mảnh vật liệu mỏng bằng móng tay. Phúc nhìn. “Tôi không biết.” + +“Áo từ đâu?” Thủy hỏi. + +“Kho nhân viên Đại Hà. Mặc từ hôm đó.” + +Mảnh vật liệu không có pin. Bề mặt gồm những lớp hợp kim và gốm, giống dấu cộng hưởng tìm thấy sau Trạm Láng. Ông Hòa đặt nó gần ống nước. Không phản ứng. Đặt gần nắp HN-07. + +Một đường nứt sáng rất yếu chạy qua bề mặt. Thủy bước lại. Mảnh vật liệu rung. + +Cô lùi. Nó dừng. Tiến không gọi đó là chọn người. Hắn đổi vị trí, đưa Nam, Bình, Linh và Khánh An lần lượt tới gần. Không phản ứng đáng kể. Khi Thủy tới trong bán kính một mét, đường nứt sáng lại. + +“Vì cô nghe được,” Bình nói. + +Thủy đáp: “Hoặc vì tôi đã tiếp xúc Láng nhiều nhất.” Không chấp nhận danh xưng trước dữ liệu. Họ thử với bộ phát tần số thấp. Ở một dải hẹp, mảnh vật liệu phản ứng giống khi Thủy đứng gần. Nghĩa là cơ thể cô không phát “năng lượng” bí ẩn; có thể nhịp thần kinh, thiết bị cô mang hoặc dấu cộng hưởng bám trên vật dụng tạo điều kiện. + +Thủy tháo máy ảnh, đồng hồ, túi. Mảnh vẫn rung, yếu hơn. Linh đo nhịp tim, điện da. “Khi cô tập trung nghe, nhịp thay đổi.” + +Không ai trong nhóm có đủ chuyên môn thần kinh để đi xa hơn giả thuyết. Việc họ làm được lúc này chỉ là ghi nhận và đối chiếu. Mặt dưới mảnh vật liệu hiện một chuỗi ký hiệu khi rung. Không phải tọa độ hoàn chỉnh. Ba cụm số và một ký hiệu giống tường thành. + +Khánh An nhìn cách chuỗi được chia thành các khối 2–3–5–7. “Hoàng Tùng từng dùng dãy số nguyên tố để đánh dấu lớp phục hồi phần cứng. Hắn thiết kế an ninh kho cho Kha trước khi mất tích.” + +“Có nghĩa marker do Tùng làm?” Thủy hỏi. + +“Có nghĩa người làm biết cùng một thói quen mã hóa. Chưa đủ để kết tên.” + +Thủy chụp lại cả ký hiệu lẫn nhận định, đặt chữ **giả thuyết** ngay đầu dòng. + +“Không kết luận Hoàng Thành,” cô nói trước khi Tiến kịp. + +“Chưa nói.” + +“Anh nhìn như đã nói.” + +Họ đối chiếu với bản đồ hạ tầng, bản đồ Pháp và ảnh vệ tinh cũ. Ba cụm số không phải kinh độ vĩ độ. Ông Hòa nhận ra chúng giống cao độ nền và khoảng cách giữa các mốc. Nếu đặt từ Trạm Láng, Ngọc Trục và Hồ Tây, ba vòng giao nhau gần khu Hoàng Thành. + +Thủy không viết tọa độ trong lúc ngủ; đó là phép suy ra từ ba điểm vật lý. + +“Khóa Trung Tâm,” Khánh An nói. + +Tiến hỏi: “Kha biết?” + +“Có thể biết vùng. Không biết cửa.” + +Thủy nhìn mảnh vật liệu. “Vòng Tròn Vỡ khâu nó vào áo Phúc?” + +“Áo có trước khi họ gặp anh,” Bình nói. + +“Vậy Observation Initiative hoặc người Đại Hà.” + +Phúc nhớ lại. Trước thảm họa, một nhân viên kỹ thuật đã đổi áo bảo vệ cho anh vì chiếc cũ rách. Người đó biết tên Tiến, từng hỏi về khu giao nhận. Dấu vết người kỹ thuật Đại Hà trở lại. Không phải chuyện mới xuất hiện, mà là một món nợ họ đã bỏ lại từ sau thảm họa. + +Tiến hỏi: “Người đó sống?” Phúc lắc. “Tôi thấy anh ấy xuống tầng dưới. Không thấy ra.” + +Thủy ghi: + +**Kỹ thuật viên Đại Hà – liên hệ HANOI-07 – có thể đã gắn marker vào áo.** + +Họ không ghi “đã chết”; chưa có xác để xác nhận điều đó. Đêm, họ đặt mảnh vật liệu trong hộp Faraday tự chế. Camera phía sau kho không còn mất khung. Một khả năng đơn giản hơn vẫn còn: hình người biến mất chỉ là nhiễu do marker đi qua điểm cộng hưởng, chứ chưa chắc có ai thật sự lọt qua cổng. + +Bình xem lại video. Ở khung trước khi bóng biến mất, không có chân chạm đất. Chỉ một dải nhiễu hình người. + +“Chúng ta tự đóng căn cứ vì một lỗi camera,” cậu nói. + +“Không,” Tiến đáp. “Vì chưa biết đó là lỗi.” + +“Khác?” + +“Có.” + +Họ đã suýt đánh nhau vì một hình ảnh. Thủy viết thêm quy tắc vào sổ: + +**Không dùng một nguồn quan sát để kết tội.** + +Từ hôm đó, camera vẫn chạy, nhưng không một khung hình nào được dùng kết tội nếu thiếu nguồn thứ hai. Ông Hòa viết quy tắc mới ngay dưới màn hình giám sát. + +Chương 30: Hồ Sơ Người Nghe + +Thủy bắt đầu sợ giấc ngủ, không vì ác mộng mà vì những gì còn lại sau khi tỉnh. Cô không viết tọa độ chính xác. Trên tường cạnh giường là một hình gồm ba vòng méo, một đoạn tường thành và mười một vạch ngắn. Cô không nhớ đã vẽ, nhưng mực trên ngón tay là của mình. + +Tiến tìm thấy cô ngồi trước hình lúc gần sáng. + +“Ngủ bao lâu?” + +“Linh nói hai tiếng.” + +“Cô nhớ vẽ?” + +“Không.” + +“Nghe gì?” + +“Các lớp.” + +Thủy không trả lời bằng một danh từ bí ẩn rồi chờ hắn tin. Cô mở sổ, đưa ba bản ghi. Ở Láng, câu “đừng mở” xuất hiện bằng nhiều giọng. Một giọng hiện đại. Một giọng dùng từ cổ hơn. Một lớp không thành lời nhưng tạo cùng phản ứng. Cô không “dịch” được nghĩa; cô suy ra từ cách cơ thể và thiết bị phản hồi. + +“Cùng một nội dung được ghi nhiều lần,” cô nói. “Hoặc nhiều người nghe cùng một hiện tượng rồi mô tả giống nhau.” + +“Cô phân biệt?” + +“Chưa.” + +“Vậy thử ngoài Láng.” + +Họ xuống đường ngầm phía Tây cùng Bình và ông Hòa, không chỉ hai người. Sau những gì đã xảy ra, không ai vào một cánh cửa mới mà không có người giữ lối và dây an toàn. Marker lấy từ áo Phúc được đặt trong hộp cách ly. Khi tới cánh cửa từng hiện **LANG HANDSHAKE ACCEPTED**, mảnh vật liệu rung yếu. Thủy không gõ chuỗi ngay. Cô đặt cảm biến lên cửa, đo dao động nền và so với log lần trước. + +“Có một nhịp tự nhiên,” cô nói. “Cửa đang rung sẵn.” + +Ông Hòa áp tai vào tuốc-nơ-vít chạm kim loại. “Đừng gõ đè. Chờ nó nghỉ.” Họ chờ. Khi dao động xuống thấp, Thủy gõ lại chuỗi với khoảng nghỉ họ đã sửa trong lần can thiệp ở Trạm Láng. Cửa mở. + +Cánh cửa không hề “tự xuất hiện”. Một mảng tường trượt vào hốc, để lộ lối họ từng bỏ qua vì khe bị bùn và lớp cách nhiệt che kín. Bên trong là phòng lưu trữ nhỏ, khô bất thường. Tủ giấy, hộp kim loại, bản đồ cuộn và các vật liệu từ nhiều thời kỳ nằm cạnh nhau. + +Trước khi chạm vào bất cứ thứ gì, Thủy chụp nguyên trạng, đánh số, ghi nguồn rồi mới phân lớp tuổi. + +Một bản đồ kỹ thuật tiếng Pháp dùng cụm **Puits d’écoute** — giếng nghe. Một sổ tiếng Việt thập niên 1970 ghi **Trạm nghe – khu Láng** và cảnh báo không dùng nguồn điện ngoài khi thử cộng hưởng. + +Tấm gỗ có chữ Hán Nôm. Thủy không đọc. Cô chụp từng mặt, đánh dấu cần người chuyên môn. + +“Ít nhất cô không dịch được mọi thứ,” Tiến nói. + +“Anh thất vọng?” + +“Nhẹ người.” + +Tập giấy hiện đại dưới đáy tủ có ba thuật ngữ tiếng Anh: + +**RETURNED** + +**LISTENER** + +**OBSERVER** + +Nó không chứng minh vai trò ấy đã tồn tại từ cổ đại; nó chỉ cho thấy nhóm hiện đại từng phân loại như vậy. Các tài liệu cũ có những từ tương tự nhưng chưa được dịch. Thủy đọc ghi chú hiện đại: + +**RETURNED: trạng thái mang dữ liệu ký ức không khớp chuỗi hiện tại.** + +**LISTENER: trạng thái phản ứng với tín hiệu giữa các lớp ghi.** + +**OBSERVER: người xác nhận dữ liệu vật lý khi các nguồn không thống nhất.** + +Bên cạnh dòng Observer có chữ đỏ: + +**Không được can thiệp.** + +Dòng bị gạch, kèm ghi chú khác: + +**Không còn khả thi sau khi quan sát làm đổi đối tượng.** + +Tiến nhớ HANOI-07 gửi tin nhắn, Kha dùng Hậu Ký, Vòng Tròn Vỡ dùng ảnh mẹ. Không người quan sát nào còn đứng ngoài. Ở cuối tập giấy là bảng lịch cộng hưởng. Nhiều ngày cũ đã gạch. Một mốc còn lại: + +**29/09/2028 – SYNCHRONIZATION WINDOW** + +Không ghi “mở cổng”. Dòng kỹ thuật: + +**Nếu cụm phía Tây không ổn định trước cửa sổ, phản hồi tải sẽ chuyển về cụm trung tâm.** + +“Ngày Đồng Bộ,” Tiến nói. + +Thủy không nhìn hình mình vẽ để kết luận. Cô trải ba bản đồ: Ngọc Trục, Láng, Hồ Tây. Các mốc cao độ giao nhau gần Hoàng Thành, đúng biểu tượng tường thành trên marker. + +“Khóa Trung Tâm có thể ở đây,” cô nói. “Tôi nói có thể. Chưa đủ để gọi là chắc.” + +Bình kiểm hành lang. “Có người.” Bước chân thật, có hướng và trọng lượng. + +Tiến tắt đèn. Không ai rút ngay. Giọng Kha vang ngoài cửa: “Tao biết mày sẽ tìm được phần còn lại.” Tiến đáp: “Anh theo marker?” + +“Không.” + +“Khánh An?” + +“Không.” + +“Vậy?” + +“Người kỹ thuật Đại Hà từng làm cho kho của tao.” + +Một tuyến cũ khép lại một phần. Kha không bước vào. Hắn ngồi ngoài ngưỡng, đúng vị trí có thể rút nếu cửa đóng. + +“Anh muốn gì?” Thủy hỏi. + +“Đổi dữ liệu.” + +“Cho gì?” + +“Nước.” + +Không khí trong phòng thay đổi. Kha không tới vì danh xưng Người Nghe. Hắn tới vì biết Ngọc Trục đang khát. Và mọi bí mật dưới Hà Nội, cuối cùng, vẫn phải đi qua một cốc nước. + +Chương 31: Cái Giá Của Một Nút + +Kha không bước qua ngưỡng phòng lưu trữ. Hắn ngồi ngoài hành lang, lưng không chạm tường, hai người của hắn giữ khoảng cách phía sau. Vị trí ấy được chọn để rút được ngay nếu cánh cửa đóng hoặc Tiến nổ súng, chứ không phải vì lịch sự. + +“Ngọc Trục còn bao nhiêu nước?” Kha hỏi. + +Tiến không trả lời. + +“Tám ngày theo định mức cũ. Mười hai nếu Linh cắt rửa và nấu. Ít hơn nếu bệnh đường ruột bắt đầu.” + +Thủy nhìn hắn. “Anh theo dõi bể?” Kha vuốt nhẫn. “Không cần. Tao biết Dư Âm làm lớp lót đường Tây bong. Biết số người. Biết màng lọc loại gì.” + +“Biết từ đâu?” + +“Mua.” + +Một câu thật một phần. Hắn đặt tập ảnh xuống nền: bơm, màng lọc, than hoạt tính, bình áp, can nước. Đủ để dựng tuyến xử lý tạm và giữ Ngọc Trục thêm nhiều tuần. + +“Đổi gì?” Tiến hỏi. + +Kha nhìn Thủy, nhưng không nói “cô ấy” như một món hàng. “Thủy tới Láng với tao khi cửa sổ thử tiếp theo mở.” + +“Không.” + +Thủy quay sang Tiến. “Anh không quyết.” + +“Không.” + +“Anh vừa làm.” + +Kha cười rất nhẹ. “Đó là vấn đề của mày.” Tiến vẫn nhìn tập giấy. “Cô không đi với Kha.” + +“Vì nguy hiểm?” + +“Đúng.” + +“Hay vì anh cần tôi ở Ngọc Trục?” + +“Cả hai.” + +“Ít nhất câu thật.” + +Thủy quay sang Kha. “Anh cần gì ở tôi?” + +“Xác định mười một phút trống.” + +“Trong Hậu Ký?” + +“Ừ.” + +Kha lấy một tờ in. Dòng dữ liệu ngày 29/09/2028 dừng từ 12:17 tới 12:28. Trước và sau có log. Trong mười một phút, không camera, không nhiệt, không tuyến vận tải, không bản ghi tử vong. + +“Anh đã hỏi Hậu Ký về khoảng đó?” Thủy nói. + +Kha xoay chiếc nhẫn một vòng rồi dừng tay. + +“Bao nhiêu lần?” + +“Đủ.” + +“Câu hỏi gì?” + +“Không liên quan.” + +“Rất liên quan. Nếu dữ liệu phụ thuộc truy vấn, cách anh hỏi quyết định thứ nó trả.” + +Tiến nhìn thẳng Kha. Khi ấy họ chưa có bằng chứng Hậu Ký là một giao thức truy vấn, nhưng Thủy đã bắt đầu nghi câu trả lời không độc lập với người đọc. Kha nói: “Tao hỏi ai sống.” + +“Và?” + +“Không có kết quả.” + +“Anh cần Người Nghe lấp chỗ trống.” + +“Cần một nguồn khác.” + +Thủy hỏi: “Nếu tôi đi, nước tới trước hay sau?” + +“Trước một nửa. Sau khi thử, nửa còn lại.” + +“Không.” + +Tiến tưởng cô từ chối chuyến đi. Nhưng Thủy nói tiếp: + +“Nước tới toàn bộ trước. Tôi tới Láng cùng đội của mình, không thuộc quyền anh. Mọi dữ liệu ghi được có bản sao ở ba nơi.” + +Kha nhìn cô. Tiến nói: “Cô chưa đồng ý.” + +“Đang đàm phán.” + +“Về mạng cô.” + +“Đúng.” + +Câu đó giữ hắn im. Thủy đặt điều kiện: + +- Khánh An có quyền kiểm tra thiết bị Kha; +- Tiến hoặc người Ngọc Trục giữ lối rút; +- không kích hoạt chuỗi; +- chỉ quan sát tín hiệu tự nhiên; +- không dùng Hậu Ký đưa lệnh trong thử nghiệm; +- toàn bộ nước giao trước. + +Kha nói: “Mày đang mua nước bằng rủi ro của mình.” + +“Không. Tôi bán quyền tiếp cận dữ liệu tôi có thể thu.” + +Khác biệt rất lớn. Kha nhìn Tiến. “Cô ấy giỏi hơn mày.” + +“Biết.” + +Lần này từ “biết” không phải câu cụt để tỏ ra lạnh. Tiến thật sự chấp nhận. Kha đồng ý bốn điều, từ chối giao toàn bộ nước trước. + +Thủy đứng dậy. “Vậy không có thỏa thuận.” + +“Ngọc Trục khát.” + +“Anh cũng cần mười một phút.” + +Hai bên nhìn. Kha nhượng: tám mươi phần trăm trước, hai mươi phần trăm niêm phong tại điểm trung lập, mở bằng hai khóa. Tiến yêu cầu thêm một khóa thứ ba do Linh giữ. Kha cười. “Các người chia mọi thứ.” + +“Để một người không giữ cổ người khác.” + +Thỏa thuận được viết tay, có chữ ký của Thủy, Tiến, Kha, Khánh An và Bình làm chứng. Tờ giấy không tự bảo vệ được ai; giá trị của nó nằm ở chỗ xác định rõ điều gì sẽ bị coi là vi phạm. Trước khi rời, Kha nhìn tập tài liệu. + +“Ngày Đồng Bộ?” + +Tiến không đáp. Thủy nói: “Anh đã biết mốc.” + +“Biết. Không biết các người gọi gì.” + +“Không quan trọng.” + +“Cách gọi quyết định người ta nghĩ nó làm gì.” + +Thủy ghi câu đó. Kha đứng. “Một lời miễn phí. Đừng tin chữ ‘cổng’.” + +“Vì?” + +“Hậu Ký không có hình thứ gì đi qua.” + +Hắn đi. Ở hành lang, Khánh An nhìn theo. “Hắn nói thật.” + +“Cô biết?” Bình hỏi. + +“Không. Nhưng khi nói dối, hắn thường cho thêm một chi tiết để người nghe bám. Lần này không.” + +Trên đường về, Tiến hỏi Thủy: “Cô vẫn đi?” + +“Có.” + +“Có thể chết.” + +“Anh cũng.” + +“Không giống.” + +“Đúng. Vì lần này tôi tự chọn.” + +Tiến muốn nói không. Nhưng đã quá nhiều lần hắn dùng bảo vệ để che quyền kiểm soát. + +“Đội của cô,” hắn nói. “Cô chọn.” + +Thủy gật. Một thay đổi nhỏ. + +Không có tiếng vỗ tay. Thủy tự ghi tên mình vào cột người chịu rủi ro và giữ một bản sao điều kiện. Từ cuộc họp ấy, mọi đề xuất liên quan Người Nghe phải ghi tên người chịu tác động thay vì chỉ ghi vai trò hệ thống. + +Chương 32: Khóa Phía Tây + +**19/07/2028 – 22:58** + +Trạm Láng cháy từ dưới đất. Không có cột lửa trên mặt đường. Khói xám chui qua nắp cống, khe tường và lớp bùn Tô Lịch. Kim loại dưới nền nóng lên từng đoạn, tạo những vệt nhiệt chạy như mạch máu trên camera. + +Dư Âm trở lại yếu hơn lần trước nhưng rộng hơn. Radio phát giọng người chết. Ống nước gõ tên người. Tiếng chuông ở xa tới mức không ai xác định được nó ở dưới Láng hay sâu hơn trong thành phố. Tiến tới bằng tuyến bảo trì phía nam cùng Bình, Phúc và ông Hòa. Thủy dẫn một nhóm khác theo đường Kha cung cấp nhưng giữ thiết bị độc lập. Kha đi từ phía bắc. Khánh An đã ở trong trạm, cạnh một người bị thương. + +Khi thấy Kha, cô không hạ súng. + +“Anh mở sai.” + +Kha dừng ngoài vùng bắn. “Biết.” + +“Ba người chết.” + +“Biết.” + +“Anh vẫn tới.” + +“Vì chưa xong.” + +Khánh An cười cay. “Đúng là anh.” Vòng Tròn Vỡ có ít nhất sáu người trong khu trạm. Họ không giữ vị trí để chiếm. Các khối nhiệt cắt đã được gắn quanh tuyến hợp kim của Listening Well, đủ làm vật liệu chảy và phá đường cộng hưởng. + +Nhưng sáu người không thuộc một chuỗi chỉ huy duy nhất. Quân điều phối nhánh phía bắc; Lê Hữu Kiên, thủ lĩnh một tế bào phía đông, giữ bộ kích riêng và đeo vòng khuyết sơn trắng thay vì đen. Cấu trúc phân tán giúp Vòng Tròn Vỡ khó bị chặt đầu, đồng thời khiến một lệnh dừng không thể vô hiệu mọi tay kích. + +Giọng Vũ Mạnh Quân vang qua loa: “Khóa là nguyên nhân của phản hồi. Rời khu vực. Chúng tôi không muốn giết người.” Tiến đứng sau vách bê tông. “Ông không biết nếu phá thì tải đi đâu.” + +“Về không đâu.” + +“Không có ‘không đâu’ trong một mạng đang chịu tải.” + +Kha ở lối đối diện nói: “Nó chuyển về Hoàng Thành.” Quân đáp: “Theo Hậu Ký của anh?” + +“Không. Theo áp lực.” + +Lần đầu Kha dùng phép đo thay vì dữ liệu tương lai. Thủy đặt cảm biến xuống. “Đường Tây đang giữ một phần dao động từ Hồ Tây. Nếu cắt đồng thời, tải dồn trung tâm trong vài giây.” + +Quân không đáp ngay; không rõ ông đang nghe hay chỉ chờ thiết bị ổn định. Tiến nói: “Cho chúng tôi ba phút đo từng điểm.” + +“Các anh đã dùng thời gian hiểu để kích hoạt mọi thứ.” + +“Đúng.” + +Không biện hộ. + +“Ba phút.” + +Quân cho một. Một phút không đủ, nhưng đủ để người kỹ thuật thấy khối nhiệt thứ ba đặt sai vị trí. Nếu kích, nó không chỉ cắt đường cộng hưởng mà còn làm vỡ ống làm mát cũ. + +Ông Hòa bò dưới sàn, ba ngón tay trái và bàn tay phải lần theo dây. “Khối ba kích là đường lạnh vỡ.” Phúc hỏi: “Gỡ?” + +“Không kịp. Phải cắt dây mồi.” + +“Dây nào?” + +“Dây điện không nói dối.” + +Ông Hòa chỉ hai tuyến gần giống. + +“Người đọc mới nói dối.” + +Đồng hồ của Quân còn mười lăm giây. Kha nói qua loa: “Quân, dừng.” + +“Anh muốn giữ quyền.” + +“Đúng.” + +Một lời thừa nhận. + +“Nhưng nếu mày kích bây giờ, không còn quyền gì để giữ.” + +Quân không trả lời. Đếm về ba. + +Thủy nghe một giọng không hướng nói “cắt dây đỏ”. Cô không làm theo. Cảm biến dòng cho thấy dây đen mới là mồi. + +“Đen,” cô nói. “Có dòng.” + +Ông Hòa cắt. Khối ba chết. + +Kiên kích thủ công khối một trước khi đồng hồ hết. Hợp kim nóng trắng. Cả trạm rung. Quân quát: “Tôi chưa cho kích.” + +Kiên đáp qua kênh nội bộ: “Ông đã cho họ một phút để giữ khóa.” Cấu trúc tế bào từng bảo vệ Vòng Tròn Vỡ khỏi bị một người kiểm soát giờ cũng ngăn Quân dừng một nhánh đã tự chọn mục tiêu. + +Phúc nhìn đường làm mát. Áp lực tăng. + +“Van ở đâu?” + +Ông Hòa chỉ. Phúc lao qua vùng nhiệt. Anh dùng thanh sắt kéo van, bàn tay phải sát bề mặt nóng. Găng cháy. Da bỏng. + +Linh không ở đây để ngăn. Bình kéo anh lại, nhưng Phúc giữ tới khi kim áp hạ. + +“Đủ!” Bình hét. + +“Chưa.” + +Giọng em gái gọi từ ống. Không hướng. + +Phúc vẫn giữ van. Tiến và Kha cùng tới bảng điều khiển từ hai phía, mỗi người cầm một phần sơ đồ và chẳng ai giao trọn phần của mình cho người kia. + +“Đường này cấp khối hai,” Kha nói. + +“Cũng cấp cảm biến tải.” + +“Cắt?” + +“Không. Chuyển qua nguồn phụ.” + +“Chậm.” + +“Phá thì mù.” + +Kha liếc dải nhiệt đang tăng. “Chuyển.” Chậm hơn phương án cưỡng bức, nhưng vẫn giữ được phép đo. + +Thủy đứng tại điểm Listening Well, nghe lớp rung. “Khoảng tải đang dồn về nhánh bắc. Khóa không mở. Nó đang cố giữ cân bằng.” Quân xuất hiện sau lớp khói, mặt nạ đã tháo. “Các anh còn gọi nó là khóa?” + +“Không quan trọng tên,” Thủy nói. “Kim đang tăng.” + +Quân nhìn cảm biến độc lập của cô, không phải màn hình Kha. Dữ liệu giống nhau. Ông hạ bộ kích. + +“Đội tôi dừng.” + +Kiên phản đối: “Nếu không phá hôm nay, ngày 29 chúng ta sẽ không còn cơ hội.” Quân quay súng vào khối nhiệt, không vào người. “Nhánh của tôi dừng. Ai kích tiếp tự chịu là kẻ chôn dân, không phải người phá khóa.” + +Hai người theo Quân tháo khối hai. Kiên rút qua nhánh đông cùng một thuộc cấp, mang theo bộ kích còn lại. Quân không đuổi; tải đang tăng và mọi viên đạn lúc đó đều lấy mất một bàn tay đang giữ trạm. Khối một đã chảy vào tuyến hợp kim, tạo khe nứt. Ông Hòa dùng kẹp giữ tấm chắn trong khi Tiến và Kha chuyển tải. Nhiệt xuyên găng. + +“Bác bỏ tay!” Tiến nói. + +“Chưa giữ.” + +“Bác mất ngón.” + +“Còn ba.” + +Tấm chắn trượt. Ông Hòa đưa tay trái vào vị trí không nên đưa. Hai ngón bị kẹp và cắt bởi mép hợp kim nóng. Tiếng ông chỉ là một hơi bật. + +Máu. Nhưng tấm chắn đứng. + +Tiến muốn kéo ông ra. + +“Bảng!” ông Hòa quát. “Nhìn bảng!” + +Tải đang rơi. Khóa phía Tây ổn định không vì một nút được bấm, mà vì sáu người ở ba phe giữ những thứ khác nhau trong cùng một phút: + +- Phúc giữ van và bỏng bàn tay; +- ông Hòa giữ tấm chắn bằng cái giá hai ngón; +- Thủy phân biệt rung thật khỏi giọng gọi; +- Quân ngăn người mình kích tiếp; +- Kha giữ nguồn phụ; +- Tiến chuyển điều khiển mà không khởi động phiên bắt tay. + +23 giờ 41. Kim trở về vùng vàng. + +Màn hình độc lập hiện: + +**WESTERN LOCK STABLE** + +Không có ai còn sức để reo. Phúc gục bên van, còn Bình quỳ xuống dập phần găng đang cháy ở cổ tay. + +Ông Hòa nhìn bàn tay, rồi nhìn tấm chắn. “Đứng.” Kha dựa bảng, mặt xám. + +Khánh An tới trước hắn. “Ba người của anh?” + +“Chết.” + +“Người của Quân?” + +“Hai.” + +“Anh còn gọi đây là thắng?” + +Kha không trả lời. Dư Âm tắt dần theo tải, không biến mất như một công tắc. Những giọng trong ống loãng ra, nhường chỗ cho tiếng thở, tiếng kim loại nguội và tiếng người thật gọi cáng. + +Trước khi rời trạm, Thủy nhìn về hướng Hoàng Thành. Một tiếng chuông vang. + +Không hướng. Nhưng cảm biến nền cũng ghi một xung rất nhỏ. + +Cô không nói “nó trả lời”. Cô ghi: + +**23:47 – dao động trung tâm sau khi Khóa phía Tây ổn định. Nguồn chưa xác định.** + +Sau đêm đó, Hậu Ký sẽ nói Khóa phía Tây đã thất bại. Nhưng trong hiện tại, nó vẫn đứng. + +Và những người giữ nó phải mang cái giá trên cơ thể. + +ARC 5: VÒNG TRÒN VỠ + +Chương 33: Tro Sau Láng + +Ngọc Trục đón họ trở về từ Trạm Láng bằng mùi cồn, thịt cháy và tiếng bánh cáng nghiến qua nền xi măng. Phúc được đưa vào trước. Bình và Nam mỗi người giữ một đầu cáng; lớp vải quấn quanh bàn tay phải của anh đã chuyển sang màu đỏ nâu, vài chỗ cháy cứng vì hơi nóng xuyên qua. Phúc còn tỉnh, nhưng môi tái và da gần như khô. Trong thời tiết này, người bị thương ngừng đổ mồ hôi thường đáng sợ hơn việc họ kêu đau. + +“Đặt xuống.” + +Linh đã chờ sẵn trong khu y tế. Cô không hỏi ở Láng ai thắng, HANOI-07 đã hiện gì hay khối nhiệt được dập bằng cách nào. Trong căn phòng này, mọi bí mật phải xếp sau mạch, đường thở và lượng nước còn lại trong cơ thể. Nam cúi xuống quá nhanh, hai tay run khiến khay dụng cụ va vào thành bàn. + +“Ra ngoài.” + +“Em giữ được.” + +Linh nhìn mặt cậu. “Em đứng thêm một phút là tôi có hai bệnh nhân.” + +Nam vẫn không nhúc nhích cho tới khi Phúc hé mắt. Giọng anh khàn như giấy ráp: “Giữ cổng.” + +Ba chữ ấy đã theo họ từ Trạm Láng về tận đây. Nam nuốt khan, gật đầu rồi rời phòng. Khi cánh cửa khép lại, Linh cắt lớp băng cháy bám vào da. Mùi thịt khét trộn với cồn sát trùng; Phúc nghiến răng, còn Linh vừa làm vừa bắt anh trả lời những câu vô nghĩa để chắc rằng anh chưa tụt khỏi tỉnh táo. + +Ở bàn bên, ông Hòa ngồi thẳng lưng. Bàn tay trái đã được băng kín, chỉ còn ba ngón. Hai ngón còn lại nằm dưới một miếng vải trắng trong chiếc khay kim loại. Không ai nhắc chuyện nối lại. Những điều kiện từng khiến việc ấy trở thành thủ thuật y khoa bình thường — máu, phòng mổ, kính vi phẫu, điện ổn định — đều không còn. + +Ông nhìn chiếc khay một lúc lâu rồi nói: “Chôn đi.” + +Linh ngừng tay. “Bác Hòa—” + +“Để đấy cũng thối.” + +Linh mở miệng rồi thôi. Bình quay mặt sang chỗ khác. Ông Hòa kéo tấm vải phủ khay lại, sau đó quay sang Tiến và bắt gặp đúng vẻ mặt hắn đang cố giấu. + +“Đừng tính nữa.” + +“Cháu chưa nói gì.” + +“Cậu làm cái mặt ấy là tôi biết rồi. Có lỗi, tôi hiểu. Nhưng ngồi nghĩ lại tới sáng cũng không mọc lại được hai ngón tay cho tôi.” + +Ánh mắt Tiến dừng ở ba ngón tay còn lại. “Cháu làm cho bác một bộ kẹp. Có dây giữ cổ tay, ngàm khóa và lớp cách điện. Loại dùng được khi sửa tủ điện.” + +Ông Hòa nhướng mày. “Cậu nghĩ ba ngón của tôi hết làm việc?” + +“Cháu nghĩ ba ngón làm được nhiều hơn nếu có đúng dụng cụ.” + +Ông nhìn bàn tay Tiến trước, rồi nhìn lên mặt hắn và gật. Đó là cách ông nhận an ủi: không bằng lời thương hại, mà bằng một công việc mình vẫn còn có thể làm. + +*** + +Khánh An được đưa vào phòng cách ly cũ, nhưng lần này cửa không khóa. Bình ngồi ngoài hành lang, chiếc nỏ đặt ngang đùi. Anh không chĩa vào cô, cũng không để nó ngoài tầm tay. + +Vết khâu ở sườn An đã bục một phần trong lúc giữ Trạm Láng. Linh chỉ kịp đưa thuốc sát trùng, băng sạch và dặn nếu sốt phải gọi; phần còn lại An tự làm dưới ngọn đèn vàng yếu. Trước mặt cô là một bát nước theo đúng định mức. Cô chưa uống. + +Bình liếc vào. “Nước không hợp?” + +“Tốt hơn nước của Kha.” + +“Thế sao để nguyên?” + +“Muốn biết giá.” + +“Ở đây chưa ai kịp định giá cô.” + +Khánh An cầm bát lên nhưng vẫn chưa uống. “Câu ấy nguy hiểm hơn một con số.” + +“Vì sao?” + +“Vì người không biết giá có thể cho đi nhiều hơn mức họ giữ nổi. Hoặc đòi lại vào lúc mình không phòng.” + +Bình thôi cười. Anh hiểu cô không chỉ nói về bát nước. Khánh An từng sống trong một hệ thống nơi mọi chuyến xe, viên đạn và mạng người đều được quy ra lợi ích. Ngọc Trục chưa có bảng giá như vậy; điều đó không khiến nơi này vô tư hơn, chỉ khiến món nợ khó nhìn thấy hơn. + +Cô uống hết nửa bát, đặt phần còn lại cạnh cửa. “Cho người ngoài nếu mở cổng.” + +“Cô biết sẽ có người ngoài?” + +“Đêm nào cũng có.” + +Thủy đứng ở cuối hành lang, nghe câu ấy nhưng không bước vào. Khánh An chưa thuộc về Ngọc Trục, cũng không còn hoàn toàn thuộc về Kha. Điều khiến cô khó xếp loại không nằm ở việc đứng phe nào, mà ở chỗ cô đã bắt đầu nghi ngờ mọi hệ thống không cho người bên trong quyền nói dừng. + +*** + +Thủy không ngủ được. Tiếng chuông theo cô từ Láng về, thưa và thấp, có lúc như vọng dưới nền, có lúc rung ngay sau gáy. Bịt tai không làm nó nhỏ hơn. + +Cô mở sổ, viết **Chuông không có hướng**, rồi gạch đi. Câu ấy biến một giới hạn của người nghe thành thuộc tính của tín hiệu. Cô sửa thành **Chưa xác định được hướng**. Sau một lúc, cô viết thêm: **Có thể không phải âm thanh**. + +Ngoài sân có trẻ con khóc. Thủy đứng bật dậy, lần theo tiếng tới cửa. Lần này âm thanh có hướng, phát ra từ một gia đình vừa được chuyển qua khu trú tạm. Đứa trẻ thật, cơn khát thật, người mẹ đang dỗ cũng thật. Thủy dựa vào tường, buồn nôn vì nhận ra mình đã bắt đầu phân loại tiếng người thành những ô: thật, giả, ký ức, Dư Âm. + +Tiến xuất hiện với một cốc nước. “Uống.” + +“Tôi không khát.” + +“Cô đang run.” + +Thủy nhận cốc, chỉ uống một ngụm. “Phúc?” + +“Linh giữ được.” + +“Ông Hòa?” + +“Ba ngón còn mạch.” + +“Khánh An?” + +“Chưa sốt.” + +“Anh nói như đọc bảng trạng thái.” + +“Bảng trạng thái thường bớt làm người ta hoảng.” + +“Không phải lúc nào cũng vậy.” + +Tiến liếc xuống cuốn sổ. “Cô còn nghe?” + +Thủy định nói không. Từ ấy đã lên tới đầu lưỡi nhưng không đi ra. “Tôi không biết.” + +Đó là câu Tiến ghét nhất, và cũng là câu duy nhất cô có. Cô kể về tiếng chuông, về việc không tìm được hướng, rồi ngập ngừng trước phần còn lại. + +“Ở Láng, sau giọng trẻ con từ Đại Hà, tôi nghe một giọng khác.” + +“Của ai?” + +“Của tôi.” + +Tiến không hỏi dồn. Cô biết hắn muốn làm vậy; bàn tay cầm cốc của hắn siết chặt hơn. Nhưng hắn chỉ hỏi: “Cô nhớ câu gì?” + +“Không rõ.” + +“Không rõ hay không muốn nhớ?” + +Thủy nhìn hắn. “Không muốn.” + +Lần đầu cô thừa nhận điều ấy mà không che bằng phương pháp hay nguồn kiểm chứng. Tiến tựa vai vào tường, để khoảng im tồn tại. + +“Anh từng sợ ký ức của mình không?” cô hỏi. + +“Có.” + +“Vì nó sai?” + +“Vì có lúc nó đúng vừa đủ để tôi quên phần còn lại có thể sai.” + +Hắn kể một con đường từng bị chặn trong ký ức nhưng hiện vẫn thông, một người đáng lẽ chết ở tuần đầu lại xuất hiện trong danh sách khác, vụ cháy La Phù đến sớm hơn. Thủy nghe xong mới hỏi: “Vậy khác gì Kha? Anh sống bằng ký ức, hắn sống bằng dữ liệu. Cả hai đều có lợi thế và đều có thể biến lợi thế thành quyền.” + +Tiến không phản bác ngay. “Cô nghĩ chúng tôi giống nhau?” + +“Không hoàn toàn. Anh đau vì những gì anh nhớ. Kha đau vì những gì hắn không kiểm soát được.” + +Ngoài sân, một đứa trẻ lại khóc. Lần này Thủy xác định được hướng ngay. Cô vẫn không thấy nhẹ hơn. + +*** + +Ba giờ sáng, Nam gọi họ tới phòng camera. Hai mươi ba bóng nhiệt nằm sát bức tường ngoài, co vào phần bóng râm hẹp dưới mái. Có người già, bốn đứa trẻ, một thanh niên bị thương ở chân và một người nằm trên cáng. Một phụ nữ gõ chai nhựa rỗng vào cổng; âm thanh nhỏ đến mức micro gần như không bắt được. + +“Không mở lõi,” Bình nói ngay. + +Đó không phải sự tàn nhẫn đơn giản. Hai mươi ba người là hai mươi ba phần nước, nguy cơ bệnh tật, khả năng bị cài người và một dấu vết đủ lớn để những phe khác tìm tới. Ngọc Trục vừa mất máu ở Láng; thuốc và nước đều đang tính theo ngày. + +Nam phóng to hình. Một bé gái khoảng tám tuổi đang nhìn thẳng về phía camera giấu trong khe mái, dù từ dưới đất gần như không thể thấy ống kính. Con bé giơ một tờ giấy. + +**LÊ QUỐC TIẾN** + +Bên dưới là hai chữ **NGỌC TRỤC**. + +Khánh An chống tay vào khung cửa. “Đừng mở. Người tị nạn bình thường không biết tên anh lẫn cổng này.” + +Thủy yêu cầu bật loa. Tiến hỏi ai đưa giấy. Con bé kể về một người đàn ông đeo kính ở gần tuyến tàu trên cao, bảo họ đi về phía tây, tìm kho cổng xanh. Người ấy không có bàn tay trái. + +Ông Hòa bước ra từ khu y tế, cánh tay còn băng. “Hỏi lại chỗ cụt.” + +Con bé đưa tay chỉ sát cổ tay. Ông Hòa chỉ mất hai ngón, nhưng sự giống nhau đủ khiến mọi người nhìn sang ông. Tiến tiếp tục hỏi. Người đàn ông còn nói hắn biết ngày thế giới kết thúc. + +Ngoài cổng, người phụ nữ ngã xuống. Linh nhìn số đo nhiệt trên màn hình rồi nói: “Mất nước nặng. Một giờ nữa có thể không cứu được. Con bé cũng đang tụt.” + +Cô không xin Tiến mở cổng. Chỉ đặt dữ kiện trước mặt hắn. + +Khánh An nói: “Nếu mở, người đưa giấy đã chọn ai được bước tới căn cứ.” + +Thủy đáp: “Nếu không mở, hắn vẫn chọn được ai chết trước cửa.” + +Bình quay sang cô. “Cô muốn mở?” + +“Tôi muốn chúng ta đừng giả rằng có lựa chọn sạch.” + +Tiến nhớ những cánh cổng của ba năm cũ, những lần hắn đã đóng đúng và những lần hắn chỉ biết mình sai khi tiếng gõ bên ngoài ngừng hẳn. Hắn gọi Nam đóng toàn bộ cửa lõi, yêu cầu Bình dựng rào ở sân đệm và mở cổng ngoài vừa đủ một cáng đi qua. + +“Không cho họ vào kho,” hắn nói. “Cách ly, kiểm đồ, phát nước theo số đo. Nếu có người theo, chúng ta còn hai lớp cửa.” + +Khánh An nhìn hắn. “Anh đang đổi quy tắc.” + +“Quy tắc không phải bia mộ.” + +Từng người được đưa qua vạch đỏ. Túi xách để lại ngoài rào; Linh kiểm bệnh, Mai — người phụ nữ từng làm y tá tư nhân trong nhóm — giúp ghi tên. Một thợ lạnh tên Đức giữ chiếc túi đồng hồ áp suất như giữ phần nghề nghiệp cuối cùng. Hạnh, người phụ nữ đã ngất, tỉnh lại sau khi được làm mát. Cậu bé Sơn không rời khỏi tầm mắt cô. + +Bé gái là người cuối cùng bước vào. Nó tên My. Khi đứng trước Tiến, nó đưa tờ giấy bằng cả hai tay. + +Mặt trước là tên hắn. Mặt sau chỉ có một dòng: + +**HOÀNG VĂN HÒA ĐÃ CHẾT Ở TRẠM LÁNG** + +Bên dưới là thời gian **19/07/2028 – 23:41**. + +Ông Hòa đứng cách đó vài mét, mặt nhợt vì thuốc giảm đau, ba ngón tay còn lại vẫn cử động. Tiến hỏi người đưa giấy còn dặn gì. My nghĩ rất lâu rồi nói: “Ông ấy bảo chỉ đưa mặt sau khi ông Hòa còn đứng trước chú.” + +“Còn câu nào nữa?” + +“Người đã chết thì không nên còn sống.” + +Chiếc kéo trong tay Linh chạm vào khay kim loại, phát ra một tiếng keng sắc lạnh. Không ai nhìn về phía âm thanh. Tất cả đều nhìn ông Hòa và tờ giấy cùng ghi một thời điểm đã trôi qua. + +Ngoài sân đệm, hai mươi ba người uống những ngụm nước đầu tiên sau nhiều ngày. Phía đông, vầng Hồng Nhật đang nhô qua các mái kho. Tiến gấp tờ giấy lại, nhưng câu chữ trên đó đã mở ra một điều hắn không thể đóng: có người biết một phương án trong đó ông Hòa đã chết, và biết đủ về hiện tại để chờ đúng lúc ông còn sống mà gửi nó tới. + +Chương 34: Danh Sách Người Chết + +Ông Hòa đọc tên mình ba lần, không phải vì mắt kém mà vì muốn chắc trên tờ giấy thật sự viết: + +**HOÀNG VĂN HÒA ĐÃ CHẾT Ở TRẠM LÁNG** + +**19/07/2028 – 23:41** + +Đúng phút Khóa phía Tây đứng lại. Đúng đêm ông mất hai ngón tay. Đúng lúc ông còn sống. + +Trong sân đệm, những người mới tới uống nước sau hàng rào sắt. Một đứa trẻ ho khan; Mai ghi nhiệt độ từng người lên bìa carton, còn Nam đánh số các túi đồ bị giữ ngoài cổng. Bên trong lõi kho, không ai nhìn thứ gì ngoài tờ giấy. + +“Chữ xấu,” ông Hòa nói. “Nhưng đúng tên.” + +Tiến hỏi từng người đã có mặt ở Láng, từ phía Kha tới Vòng Tròn Vỡ. Khánh An bước vào khi nghe tên mình. Cô nhìn cách ghi lâu hơn nhìn nét chữ. + +“Không giống ngôn ngữ của nhánh Quân,” cô nói. “Họ không viết ‘đã chết’. Họ gọi một người là ‘sai lệch đã được loại bỏ’.” + +“Còn Hậu Ký?” Thủy hỏi. + +“Gần hơn.” + +Khánh An giải thích Hậu Ký chưa bao giờ là một cuốn sổ duy nhất. Nó là các mảnh báo cáo, camera, danh sách mất tích, bản đồ và nhật ký vận hành được sao chép qua nhiều người. Kha giữ một phần, không ai biết phần nào là bản gốc. Trong các bảng tử vong, cấu trúc câu gần giống tờ giấy trước mặt. + +“Vậy dữ liệu sai,” Bình nói. + +Ông Hòa gõ ba ngón tay lên bàn. “Tôi thích loại sai này.” + +Không có tiếng cười, chỉ có vài bờ vai thôi căng hơn trước. + +Tiến bỏ tờ giấy vào túi chống nước và dừng việc hỏi My. Con bé vừa trải qua nhiều ngày nóng, mất nước, lại phải ghi nhớ lời một người lạ; lời kể có thể đúng ở phần cốt lõi nhưng lệch ở chi tiết. Thứ hắn tạm tin không phải toàn bộ nội dung, mà là ý đồ của người dựng cảnh: buộc hắn nhìn một người còn sống cạnh bản ghi cái chết của chính người ấy. + +Người gửi không chỉ biết một phương án cũ. Hắn còn biết phương án ấy đã đi lệch. + +*** + +Đến tám giờ, Hạnh tỉnh lại. Chị ba mươi sáu tuổi, từng bán hàng gần Yên Nghĩa. My không phải con ruột; mẹ con bé chết vì sốc nhiệt trong một khu trọ mất điện, còn Hạnh đưa nó đi từ đó. Nhóm hai mươi ba người hình thành dọc đường: người từ Hà Đông, Thanh Xuân, Hoài Đức, một ông già không nhớ nổi nơi xuất phát, Đức với túi đồng hồ áp suất, Mai với danh sách thuốc, Sơn mười bốn tuổi vẫn đi tìm người mẹ nuôi đã mất dấu. + +Thủy phỏng vấn họ không dùng máy ghi âm. Cô ngồi ngang tầm My, hỏi từ những chi tiết dễ nhớ nhất: tuyến tàu trên cao, cầu thang, mùi nơi gặp, hướng mặt trời. Người đàn ông đeo kính đã gọi đúng tên Hạnh dù hai người chưa từng gặp. Hắn bảo cả nhóm bỏ đường về phía nam vì người trên cáng sẽ chết nếu tiếp tục, rồi chỉ họ tới kho cổng xanh. + +Người trên cáng vẫn sống. + +“Ông ấy bảo cháu chỉ đưa mặt sau khi ông Hòa đứng trước chú Tiến,” My nói. + +Hạnh quay sang. “Sao con không nói từ đầu?” + +“Con quên.” + +Không ai trách. Trẻ con không biết chi tiết nào đáng sợ hơn chi tiết nào. + +Thủy hỏi My có từng biết ông Hòa không. Con bé lắc đầu, rồi nổi giận khi bị hỏi lại: “Cháu không nói dối.” + +“Cô biết,” Thủy nói. + +Cô thực sự không biết lời kể đúng đến đâu. Nhưng cô biết người đưa giấy đã đạo diễn thời điểm. Hắn muốn Tiến thấy một cái tên, một mốc chết và người mang cái tên ấy vẫn thở. + +*** + +Gần trưa, chiếc radio cũ tự bật. Ba nhịp ngắn, một nhịp dài, rồi giọng Kha vọng qua lớp nhiễu. + +“Ngọc Trục.” + +Bình đặt tay lên súng. Tiến ngăn anh chạm vào máy, dùng bộ phát riêng để trả lời. Kha hỏi Khánh An còn sống không, nhưng câu tiếp theo mới làm căn phòng im hẳn: + +“Hoàng Văn Hòa còn sống?” + +Tiến không đáp. Khoảng ngừng ấy đã đủ để Kha hiểu mình vừa chạm đúng chỗ. + +“Anh có danh sách,” Tiến nói. + +“Có.” + +“Hậu Ký?” + +“Có.” + +“Gửi.” + +Kha bật cười rất khẽ. “Mày nghĩ tao gọi để tặng?” + +“Anh gọi vì dữ liệu của anh sai.” + +Hai giây không tiếng. Thế là đủ. Kha không gọi để đe dọa hay tìm Khánh An; thứ đáng tin nhất trong tay hắn vừa thất bại, và hắn cần mắt người khác xác nhận. + +“Có hai người đáng lẽ chết đêm qua,” Kha nói. “Hoàng Văn Hòa. Phúc. Cách nhau bốn phút.” + +Tiến đề nghị đổi hình ảnh trực tiếp lấy phần danh sách. Họ thương lượng đường truyền analog, khung hình, thời lượng và mức che nền như hai người đang mua bán hàng hóa. Khánh An nhìn Tiến bằng đúng ánh mắt cô từng dành cho Kha. + +“Anh cho hắn dữ liệu.” + +“Đổi lấy dữ liệu.” + +“Anh nghĩ hai thứ cân bằng?” + +“Không.” + +“Vẫn đổi?” + +“Ừ.” + +Thủy nhận ra hai người đàn ông khác nhau nhiều ở mục tiêu, nhưng giống nhau ở một phản xạ: khi đứng trước phần tương lai chưa biết, họ sẵn sàng đem thông tin của người khác ra thương lượng. Điều phân biệt họ không phải có làm hay không, mà là ai được phép nói không. + +Ông Hòa phản đối việc quay vì thấy nhục hơn thấy nguy hiểm. Phúc tỉnh đủ để bảo Kha tự tới mà xem. Linh bắt cả hai ngồi yên, rồi dựng tấm bạt xám che toàn bộ cửa, tường và thiết bị. Camera chỉ lấy hai người, bảng thời gian và một khoảng sàn trống. + +**20/07/2028 – 11:42** + +Ông Hòa đặt ba ngón tay còn lại lên đầu gối. Phúc nằm ở giường sau, bàn tay cháy được băng kín. Hình ảnh nhiễu kéo dài chưa đầy một phút, nhưng Kha đã thấy đủ. + +Ba phút sau, gói âm mã hóa tới bộ thu. Nam và Tiến mất mười bảy phút để giải. Trên màn hình hiện một bảng không tiêu đề: + +**EVENT: WESTERN LOCK FAILURE** + +**HOANG VAN HOA — DECEASED — 19/07/2028 23:41** + +**CAUSE: THERMAL CUTTING CASCADE** + +Dòng kế tiếp ghi Phúc chết lúc 23:45 vì đường làm mát vỡ. + +Họ không chỉ cứu hai mạng người. Cả đêm ở Láng đã đi sang một hướng khác. Trong phương án Hậu Ký lưu lại, Khóa phía Tây sụp, hợp kim bị cắt, đường làm mát vỡ và chuỗi nhiệt giết những người đứng gần nhất. Trong hiện tại, Thủy nghe được sai pha, Tiến giữ hệ thống, Kha ổn định nguồn, Khánh An đổi quyết định, Phúc dập khối nhiệt và ông Hòa cắt dây. Sự kiện không sửa một chi tiết; nó rẽ khỏi cả nhánh. + +Danh sách còn một người của Kha đã chết đúng như bản ghi, một người Vòng Tròn Vỡ chưa xác định, rồi tới: + +**VU KHANH AN — MISSING** + +Khánh An nhìn dòng chữ, bàn tay dừng trên miệng bát. “Ít nhất lần này tôi biết mình đang ở đâu.” + +Dòng cuối cùng mang tên Thủy, nhưng không có trạng thái tử vong hay mất tích. + +**TRAN THANH THUY — RECORD UNSTABLE** + +**LAST VERIFIED RECORD: 29/09/2028 – 12:17** + +**NO RECORD AFTER SYNCHRONIZATION WINDOW** + +Tiến đóng cửa sổ. + +“Mở lại,” Thủy nói. + +“Không.” + +“Đó là tên tôi.” + +“Biết.” + +“Anh vừa đổi hình ảnh người sống lấy danh sách người chết. Tới tên tôi thì anh tự quyết tôi được biết bao nhiêu?” + +Tiến không có lý lẽ nào ngoài sợ hãi, nên hắn không bịa ra lý lẽ. “Đúng.” + +Thủy bật cười, không có chút vui nào. “Anh và Kha giống nhau hơn anh nghĩ.” + +Cô rời phòng. Tiến không giữ lại. Khánh An nhìn hắn một lúc rồi nói: “Biết mình đang làm sai không làm hành động ấy bớt sai.” + +“Biết.” + +“Vậy vì sao không dừng?” + +Tiến đọc màn hình đã tối như thể nó còn giữ lại câu trả lời. “Vì có những lúc nỗi sợ tới trước phần người mình muốn trở thành.” + +*** + +Buổi chiều, ông Hòa đặt tờ giấy của My cạnh bảng dữ liệu Kha gửi. Cùng tên, cùng thời gian, cùng một cái chết không xảy ra. + +“Cậu nghĩ người đưa giấy lấy từ Kha?” ông hỏi. + +“Không biết.” + +“Vòng Tròn Vỡ?” + +“Không giống.” + +“Người mất tay là tôi?” + +“Bác không mất cả bàn tay.” + +“Chưa.” + +Từ ấy làm Tiến lạnh sống lưng. Ông Hòa giơ bàn tay còn ba ngón rồi chỉ ba nguồn trên bàn: ký ức của Tiến, dữ liệu Kha giữ và tờ giấy của người lạ. Chúng cùng nói về tương lai nhưng đã bắt đầu mâu thuẫn. + +“Vậy đừng gọi cái nào là tương lai nữa,” ông nói. + +“Gọi là gì?” + +Ông suy nghĩ như khi đặt tên một sơ đồ điện. “Phương án.” + +Một từ kỹ thuật, khô và vừa đủ chính xác. Từ đó về sau, Tiến không còn ghi “tương lai sẽ xảy ra” trong hồ sơ. Hắn ghi “phương án đã quan sát”. + +*** + +Trưa 21 tháng 7, Thủy quay lại phòng dữ liệu. Cô không xin lỗi; Tiến cũng không. Cô yêu cầu mở phần hồ sơ bị khóa. Hắn nói chưa giải được khóa của Kha. Cô kéo ghế ngồi, đặt sổ cạnh bàn phím. + +“Anh có ký ức. Kha có Hậu Ký. Còn tôi có những tiếng nói trong đầu. Đừng bắt tôi sống bằng phần sự thật hai người quyết định cho tôi biết.” + +Đồng hồ chuyển sang **12:17**. + +Thủy cứng người. Tiếng chuông thứ nhất vang lên ở nơi không có hướng. Rồi tiếng thứ hai, thứ ba. Cô giơ tay ngăn Tiến nói và đếm bằng ngón. Mười tiếng trôi qua, mỗi tiếng thấp hơn một chút. Tiếng thứ mười một đến muộn nửa nhịp rồi tắt. + +Căn phòng trở lại với tiếng búa ngoài sân, tiếng Linh mắng Phúc và tiếng nước chảy qua đường ống. Mọi âm thanh đều có nguồn. Chỉ chuỗi vừa rồi là không. + +“Mười một,” Thủy nói. + +Tiến đọc lại dòng **NO RECORD AFTER SYNCHRONIZATION WINDOW**. “Có thể Hậu Ký nghĩ cô chết.” + +“Nếu chết, nó sẽ ghi chết. Khánh An mất tích thì nó ghi mất tích.” + +“Vậy là gì?” + +Thủy đặt đầu ngón tay lên khoảng trống sau tên mình. “Chưa chắc tôi biến mất. Có thể chính dữ liệu mất khả năng nhìn thấy tôi.” + +Ngày 29 tháng 9 còn hơn hai tháng. Nhưng từ đúng 12 giờ 17 phút hôm ấy, họ đã biết mười một phút trống không phải một chỗ thiếu trong hồ sơ. Nó là một giới hạn của chính thứ đang quan sát họ. + +Chương 35: Người Không Có Trong Hậu Ký + +**20/07/2028 — 06:10** + +Ba giờ sau khi màn hình hiện hai chữ **ĐIỂM MÙ**, Thủy không nghe thêm tiếng chuông nào. Khoảng yên ấy không làm cô nhẹ đi; nó giống một câu hỏi đã được nghe rõ nhưng bị người đối diện cố tình bỏ ngỏ. + +Nam tháo bộ ghi âm, tua lại từ đầu. Trong loa chỉ có tiếng quạt trần khô dầu, tiếng trẻ con ngoài Vành Ngoài tranh nhau một viên bi bằng nắp chai và giọng Phúc cằn nhằn vì Linh chưa cho tháo băng. Mười một tiếng chuông không tồn tại trên bất kỳ thiết bị nào. + +Tiến kiểm log lần thứ ba. Hắn chuyển từ bộ nhớ chính sang bộ lưu ngoại vi, rồi đối chiếu đồng hồ cơ treo tường. + +“Không có truy cập ngoài,” hắn nói. + +Thủy ngồi bên cửa sổ, cây bút chưa chạm giấy. “Tôi biết.” + +“Không có tín hiệu từ HN-07 ở tầng ứng dụng.” + +“Anh định loại trừ cho tới khi tôi tự tin mình tưởng tượng ra?” + +“Không.” Tiến đóng cửa sổ log. “Tôi muốn biết thứ gì không để lại dấu.” + +“Có thể vì anh đang tìm dấu ở sai chỗ.” + +Cô chỉ vào cổ mình. Mạch vẫn nhanh dù tiếng chuông đã dừng từ lâu. Tiến nhìn mười một vạch cô kẻ trong sổ, nét nào cũng ngắn hơn chữ viết thường ngày, như thể bàn tay đã cố chạy trước khi âm thanh biến mất. + +“Đúng 12 giờ 17,” hắn nói. “Nhưng chưa phải ngày 29 tháng 9.” + +“Đồng hồ có thể là điều kiện, không phải ngày.” + +“Hoặc hệ thống thử trước.” + +“Hoặc tôi nghe một bản ghi không thuộc hiện tại.” + +Thủy không khoanh giả thuyết nào. Cô gạch một đường ngang dưới cả ba câu và để chúng ngang hàng trên trang. + +Ngoài sân, Ngọc Trục đang đổi hình. Hai mươi ba người mới chia khu ngủ bằng vải bạt. Hạnh dạy trẻ xếp can rỗng thành hàng. Chị Mai nấu một nồi cháo loãng, cho thêm gừng để mùi thức ăn đi xa hơn lượng gạo thật. Người ta cãi về lượt nước, rồi ngồi vá quần áo cho nhau dưới mái tôn. + +Thủy mang máy ghi ra ngoài. Tiến hỏi: “Cô nghe gì?” + +“Không phải Dư Âm.” + +Cô bấm máy, thu tiếng muôi chạm nồi, tiếng một đứa trẻ cười khi viên bi lăn vào dép Bình, tiếng ông Hòa mắng Nam cầm sai đầu kìm. + +“Nếu sau này chỉ còn bản ghi cảnh báo, người ta sẽ nghĩ chúng ta sống bằng báo động,” cô nói. “Tôi muốn giữ cả những âm thanh không cứu ai.” + +Tiến nhìn tờ giấy trong tay cô rồi mới hỏi: “Để làm gì?” + +“Để nhớ thứ chúng ta đang cố cứu.” + +Khánh An gọi họ vào khu cách ly cũ. Cửa không khóa, nhưng cô vẫn chọn căn phòng có hai lối ra. Trên bàn là năm cái tên viết từ trí nhớ, không có bản sao Hậu Ký đi kèm. + +**TRẦN THANH THỦY** +**NGUYỄN HỮU ĐẠT** +**LÊ MINH TÂM** +**PHẠM NGỌC VÂN** +**TRƯƠNG TUẤN KIỆT** + +“Những người Kha từng tách khỏi hồ sơ chung,” Khánh An nói. “Không phải vì họ quan trọng nhất. Vì dữ liệu của họ dừng theo cách không giống chết hay mất tích.” + +Thủy chỉ tên mình. “Mốc?” Khánh An viết bên cạnh: + +**29/09/2028 – 12:17** + +“Những người khác?” Tiến hỏi. + +“Đạt mất dấu gần một tuyến điện lực. Tâm biến mất khỏi log sau một lần mất điện. Vân ngừng xuất hiện trước Hồng Nhật. Kiệt có hồ sơ tới một ngày, rồi từ đó mọi truy vấn trả kết quả khác nhau.” + +“Chết?” + +“Không ghi.” + +“Bị xóa?” + +“Không biết.” Khánh An dựa lưng vào ghế. “Kha gọi thư mục này là thư mục trắng. Không tên, không chỉ mục. Hắn ghét thứ không định giá được.” + +Thủy lật tờ giấy. “Điểm chung không phải mất dữ liệu. Là dữ liệu không giữ được một phiên bản ổn định.” Tiến lấy bút khoanh năm tên. “Càng gần mạng lưới, càng dễ thành Điểm Mù?” + +“Không chắc.” Khánh An chỉ Tâm và Kiệt. “Có người không liên quan nút. Ít nhất theo hồ sơ.” + +“Hay chưa biết liên quan.” + +Thủy gõ đầu bút xuống bàn. “Đừng biến khoảng trống thành bằng chứng cho điều mình muốn.” Tiến dừng. + +Họ lập bảng mới. Không dùng danh xưng **Điểm Mù** như một loại người. Mỗi tên có bốn cột: lần cuối được xác nhận, nguồn xác nhận, điều kiện mạng, người thực sự nhìn thấy. + +Đến tối, chỉ tên Thủy có đủ hai nguồn độc lập. Điều đó không làm cô yên tâm. Nó chỉ chứng minh hiện tại cô vẫn còn được người khác nhìn thấy. Linh bắt Tiến ngủ vì cổ tay hắn run khi cầm cốc. Hắn nằm trên chiếc giường xếp trong phòng làm việc, vẫn mặc áo, giày đặt đúng hướng cửa. Thủy ở bàn ngoài, nghe lại các âm thanh đời thường vừa thu. + +Tiếng muôi. Tiếng trẻ cười. + +Tiếng một người phụ nữ hỏi xin thêm nước nóng. Rồi giọng Tiến lọt vào tai trái cô, rõ đến mức cô quay lại. + +“Thủy.” + +Hắn vẫn ngủ. Hơi thở đều, một tay đặt gần con dao dưới gối. + +“Đừng để tôi bước vào Hoàng Thành.” + +Không có tiếng phát từ máy ghi. Kim âm lượng không nhúc nhích. Thủy đứng giữa bàn và giường, không gọi hắn dậy ngay. Cô xác định hướng. + +Giọng không tới từ Tiến. Không từ tường. + +Không từ đường ống. Nó xuất hiện như một ký ức mang giọng người còn sống. + +Cô mở sổ, ghi đúng từng chữ, rồi thêm: + +**Nguồn không xác định. Tiến hiện tại đang ngủ và chưa từng nói câu này. Không được dùng làm mệnh lệnh.** + +Sau đó Thủy ngồi cạnh cửa cho tới sáng. Không phải để canh Tiến. + +Để bảo đảm khi hắn tỉnh, điều đầu tiên hắn gặp là một người thật có thể kể lại câu nói mà không bắt hắn phải tin ngay. + +Chương 36: Cổng Mở Cho Người Sống + +Người lạ đầu tiên tới Ngọc Trục bằng một chiếc xe đạp không còn phanh trước. Ông già dừng ngoài vạch trắng, đặt hai can nước giếng xuống đường rồi giơ hai tay. Không biết tên Tiến, không xin vào và cũng không kể một câu chuyện đủ bi thảm để đổi lấy lòng thương. + +“Tôi đổi nước lấy pin,” ông nói. + +Bình kiểm một can. Nước đục nhẹ, mùi sắt, có thể lọc. Hai viên pin AA được đưa qua khe. Ông già để lại một can, buộc can còn lại lên xe rồi đi. + +“Ngày mai ông ấy quay lại,” Bình nói. + +“Ừ.” + +“Sau đó người khác.” + +Tiến dõi làn khói bếp mỏng đang bay trên mái kho. “Tin đã ra khỏi cổng.” Ngọc Trục không còn chỉ là nơi ẩn. Nó đã trở thành một địa chỉ. + +Buổi sáng, trẻ con Vành Ngoài chơi trò xây thành bằng nắp chai. Mỗi vòng nắp là một bức tường; viên bi nằm giữa được gọi là “bể nước”. Đứa làm rơi tường phải nhường một ngụm nước giả bằng cát. Người lớn nhìn, không ai cười lâu. Cùng lúc, cổng có một quyết định sai. + +Một người phụ nữ xuất hiện cuối ngõ, quấn khăn kín mặt, dìu một thanh niên bị thương. Mã tay không đúng. Người trực không nhìn rõ khuôn mặt. Nam làm đúng quy tắc mới: không mở bằng giọng, không mở khi không có xác nhận hình ảnh. + +“Lùi khỏi cổng!” cậu nói qua loa. + +Người phụ nữ hét thanh niên mất máu. Tiếng có hướng, camera nhiệt cũng thấy hai cơ thể, nhưng Nam sợ một nhóm khác núp ngoài góc. Cậu chờ Bình từ kho sau chạy tới. Ba phút. + +Thanh niên đổ xuống nền. Khi sân đệm mở, Linh cầm được máu nhưng phải cắt một phần cẳng chân đã hoại nhiệt từ trước. Người phụ nữ ngồi ngoài khu y tế, không khóc, chỉ nhìn Nam mỗi lần cậu đi qua. + +Nam tự xin rời ca. Tiến từ chối ngay. + +“Em làm đúng quy tắc,” Nam nói, giọng khô. + +“Quy tắc thiếu trường hợp.” + +“Nếu là bẫy?” + +“Thì không mở lõi. Nhưng có thể mở sân đệm với khiên và dây.” + +“Anh viết không được mở.” + +“Vậy tôi viết sai.” + +Tiến sửa ngay trước bảng trực: + +**Người bị thương không đủ xác nhận: mở sân đệm y tế nếu có hai người trực, một người giữ lõi và một người kiểm góc. Không mở cổng trong.** + +Nam đọc ba lần. Sai lầm không bị biến thành tội lỗi cá nhân để quy tắc giữ vẻ hoàn hảo. Nhưng việc quy tắc được sửa cũng không làm chân người thanh niên mọc lại. Buổi trưa, cuộc cãi vã về nước nổ ra. Tuấn lấy thêm nửa cốc cho con gái đang sốt. Linh giật lại vì đứa bé chưa tới mức cần tăng định lượng. Bình đẩy Tuấn khỏi bàn phát nước; ba người Vành Ngoài đứng lên theo. + +“Anh có nước,” Tuấn nói với Tiến. + +“Có.” + +“Con tôi khát.” + +“Biết.” + +“Đó là nước của anh à?” + +Không khí dưới mái tôn dừng lại. Tuấn chỉ xuống nền. “Anh đào ra? Anh làm mưa? Dựa vào đâu anh chia?” + +Tiến có thể trả lời bằng lưu lượng và dung tích bể, nhưng câu hỏi trước mặt hắn không nằm ở kỹ thuật. Nó nằm ở quyền quyết định ai được dùng phần nước nào. + +“Chiều nay họp,” hắn nói. + +“Rồi anh vẫn quyết cuối?” + +“Trong tấn công trực tiếp, có. Với nước, không.” + +Bình quay sang. Đây là lần đầu Tiến bỏ một phần quyền trước khi bị ép phải mất nó. Cuộc họp diễn ra bên ngoài lõi, có Linh, chị Mai, Hạnh, Đức, Tuấn, Nam, Bình, Thủy và hai người đại diện nhóm mới. Ba chai nước được đặt trên bàn: uống, y tế, nấu. Mỗi chai có bảng số thật. + +Linh không giữ độc quyền y tế; chị Mai cùng ký. Tuấn không được tự lấy thêm; có quyền yêu cầu đánh giá lại. Người làm nặng có định mức riêng, nhưng phải có người cùng nhóm xác nhận. Sổ nước được treo ngoài, không ghi tên bệnh nhân. Vùng cư trú mới được gọi là **Vành Ngoài**. Cái tên dùng để xác định phạm vi quyền, lối được phép vào và người chịu trách nhiệm, không phải để xếp ai thấp hơn ai. + +Một người phụ nữ nói: “Tên đẹp không làm cổng mở.” Thủy đáp: “Ít nhất nó cho chúng ta một thứ để sửa, thay vì chỉ có ‘người trong’ và ‘người ngoài’.” + +Cuối buổi, họ thống nhất hội đồng nước có nhiệm kỳ bảy ngày. Tiến chỉ giữ quyền ngắt cấp nếu có nhiễm độc được hai nguồn xác nhận. Khi mọi người giải tán, một đứa trẻ mang tới chiếc vòng kim loại nó nhặt trong túi áo cũ của người mới. Vòng tròn bị bẻ mất một đoạn, mặt trong có lớp gốm mỏng. + +“Cháu dùng làm bánh xe,” nó nói. + +Khánh An vừa nhìn đã đứng dậy. “Đừng cầm gần ống.” Quá muộn. + +Khi chiếc vòng tới gần đường nước chạy dưới mái, bề mặt nó rung và phát ra một tiếng kêu rất nhỏ. Không giống thiết bị phát. Giống một vật cộng hưởng với thứ bên dưới. Người mang áo không biết nó ở đó. Chiếc áo được đổi từ một trạm cứu trợ ngoài Hà Đông. + +Tiến đặt vòng vào hộp cách ly. “Vòng Tròn Vỡ?” Khánh An lắc đầu. “Biểu tượng giống. Vật liệu thì cũ hơn.” + +Thủy nhìn trẻ con tiếp tục xây thành bằng nắp chai. Cánh cổng vừa được mở thêm cho người sống, và cùng người sống, những thứ không ai hiểu cũng bắt đầu đi vào. Không thể xây cộng đồng bằng cách giữ mọi nguy cơ ở ngoài. + +Chỉ có thể xây bằng cách biết thứ nào đã vào, ai được quyền xử lý và quy tắc nào phải sửa khi sai. + +Chương 37: Mẹ Không Phải Con Tin + +**20–22/07/2028 — Thanh Hóa** + +Phát hiện căn nhà trọ xong, mẹ Tiến không gọi ngay. Bà chờ tới sáng, đúng lúc người theo dõi đổi ca. + +Trong ba ngày, bà ghi biển số bằng than lên mặt sau một tờ lịch, đánh dấu giờ hai người lạ xuất hiện ở quán nước và nhớ cách một người kéo chân phải. Bác Dũng muốn báo Tiến từ đầu; bà ngăn. + +“Nó sẽ về,” bà nói. + +“Thì càng tốt.” + +“Không. Tốt cho họ.” + +Bà theo người lạ bằng xe đạp, giữ khoảng cách qua hai ngõ, dừng trước chợ giả vờ đổi rau. Căn nhà trọ cách đê bốn cây số, rèm đóng ban ngày, không máy phát. Đêm thứ ba, cả hai rời đi. Bà và bác Dũng mới vào. Không người. + +Có ảnh Tiến ở Nguyễn Trãi, ảnh Bình lái xe, ảnh nhà cũ và một sơ đồ các kiện hàng gửi trước Hồng Nhật. Trên tường là biểu tượng mặt trời đỏ bị một đường ngang cắt qua. Bà không mang mọi thứ. Chỉ chụp bằng chiếc máy cũ, lấy cuốn sổ cháy dở và thay vị trí một cái cốc để nếu họ quay lại sẽ biết có người vào — một việc bác Dũng phản đối. + +“Để làm gì?” + +“Để họ biết mình cũng bị nhìn.” + +Cuộc gọi tới Ngọc Trục lúc 05 giờ 12. Tiến vừa nghe “mẹ tìm được chỗ chúng ở” đã đứng bật khỏi ghế. Hắn hỏi dồn vị trí, người đi cùng, dấu vết, lối rút. Giọng chuyển thành giọng chỉ huy mà hắn không nhận ra. + +Bà cắt ngang: “Con có biết mẹ bao nhiêu tuổi không?” + +“Không liên quan.” + +“Liên quan vì con đang nói như mẹ là đứa trẻ bị lạc.” + +Tiến đi dọc hành lang, không biết mình muốn tới cổng hay bản đồ. “Mẹ có hiểu họ có thể—” + +“Không hiểu cái hệ thống dưới Hà Nội. Hiểu người theo dõi.” + +Ảnh tải qua sóng rơ-le từng phần. Khi biểu tượng mặt trời bị gạch hiện rõ, Khánh An đứng bên cạnh Tiến và đổi sắc mặt. + +“Đây không phải dấu Vòng Tròn Vỡ,” cô nói. “Là ký hiệu một nhánh đã bị xóa khỏi tài liệu Intervention.” + +“Một phe?” Thủy hỏi. + +“Không chắc. Có thể là thủ tục.” + +Trong điện thoại, mẹ Tiến nghe tiếng họ trao đổi. + +“Neo là gì?” bà hỏi. + +Tiến im. + +“Con đừng hỏi mẹ nghe ai. Mẹ ghép được.” Bà nói chậm. “Con dặn mẹ đổi nhà, không bật máy, không nói tên con. Người ta chụp ảnh. Con định về rồi không về. Họ muốn biết kéo mẹ thì con chạy theo hướng nào.” + +“Mẹ không phải—” + +“Con nghe hết.” + +Hắn im. + +“Nếu họ nghĩ bắt mẹ là kéo được con, lỗi không ở mẹ. Nhưng nếu con cứ phản ứng đúng như họ đoán, họ sẽ đúng.” + +Ánh mắt Tiến dừng ở bức ảnh bà đứng trong căn nhà trọ, nhỏ hơn mọi bản đồ hắn đang giữ. + +“Mẹ chuyển chỗ,” hắn nói. + +“Có.” + +“Con gửi người.” + +“Không.” + +“Mẹ—” + +“Mẹ chọn đường. Bác Dũng chọn người. Con chỉ biết điểm đến sau khi mẹ tới.” + +Một phương án phân tán do người chưa từng đọc tài liệu HANOI-07 tự nghĩ ra. Trước khi cúp, bà nói: “Đừng để họ gọi mẹ bằng cái tên làm con quên mẹ là ai.” + +Buổi chiều, một người phụ nữ xuất hiện ở đầu ngõ nhà bác Dũng. Không vũ khí lộ, không cố bắt. Bà ta đặt một chai nước và đứng ngoài tầm ném đá. + +“Con trai bà không cứu thế giới,” bà ta nói. + +Mẹ Tiến đứng sau cửa sắt, tay cầm cán cuốc. “Nó chưa bao giờ nói sẽ cứu.” + +“Nó đang giữ thứ đáng lẽ phải chết.” + +“Vậy nói với nó.” + +“Chúng tôi cần biết bà có kéo được nó khỏi khóa không.” + +Bà nhìn người phụ nữ. “Cô đã có câu trả lời.” + +“Chưa.” + +“Nếu có, cô đã không đứng ngoài cửa.” + +Người phụ nữ cười rất nhẹ. Bà ta để lại một mảnh giấy có biểu tượng mặt trời gạch ngang và câu: + +**ĐỪNG ĐỂ MỘT NGƯỜI GIỮ TẤT CẢ PHƯƠNG ÁN.** + +Việc họ chưa đe dọa mẹ Tiến không khiến họ trở nên vô hại. Trước khi đi, người phụ nữ quay lại khi nghe tiếng một xe chở người bị nạn ngoài đê. Bà ta cùng bác Dũng kéo một đứa trẻ khỏi thùng xe nóng, đưa nước đúng từng ngụm và chỉ cách hạ nhiệt. Sau đó mới rời. + +Mẹ Tiến kể cả chi tiết ấy khi gọi lại. + +“Bà ta giúp người?” Thủy hỏi. + +“Có.” + +“Vẫn theo dõi bác?” + +“Có.” + +Tiến buộc mình giữ một nguyên tắc: đứng phía đối diện chưa đủ để biến một người thành quỷ. Khánh An nhận biểu tượng. “Nhánh Null. Trước đây dùng để làm một người hoặc nút biến mất khỏi lớp quan sát. Hồ sơ bị xóa gần hết.” + +Tiến hỏi: “Vì sao Vòng Tròn Vỡ có ký hiệu tương tự?” + +“Có thể họ lấy giáo lý từ phần còn lại.” + +Thủy ghi **có thể**, không ghi **đúng**. Tối, mẹ Tiến chuyển tới điểm mới mà hắn không biết trước. Chỉ khi bà gửi đúng ba từ mã cũ, Tiến mới mở bản đồ và đánh dấu một vùng rộng, không một căn nhà. + +Hắn muốn phóng bản đồ tới từng con đường. Cuối cùng, Tiến chỉ khoanh một vùng rộng quanh điểm rơ-le rồi đặt bút xuống. Trên màn hình không có dấu nhà, không có tọa độ, chỉ có ba chữ mẹ gửi để báo mình đã tới nơi. + +Chương 38: Kho Hậu Ký + +Kha không đưa Tiến tới một máy chủ. + +Hắn đưa tới một kho lạnh cũ dưới Mễ Trì, nơi các ổ dữ liệu nằm trong hộp kim loại, mỗi hộp có nhãn giấy viết tay và một chìa khóa cơ. Không mạng ngoài, không màn hình tự sáng. Hậu Ký ở đây trông giống hồ sơ một công ty đã phá sản hơn là tương lai của thành phố. + +“Vì sao cho tôi xem?” Tiến hỏi. + +Kha đứng cạnh cửa, vị trí quen thuộc. “Mày đã có đủ mảnh để tự dựng phiên bản tệ hơn.” Khánh An không được vào. Thủy ở điểm trung lập giữ radio, chỉ nghe qua dây analog. Kha muốn cuộc gặp giữa hai người; Tiến yêu cầu ít nhất một nhân chứng bên ngoài và được chấp nhận. + +Hộp đầu tiên mang tên **LÊ QUỐC TIẾN**. Bên trong có những bản ghi không đồng nhất: + +**RETURNED / UNVERIFIED** +**ACCESS COMPATIBILITY: HN-07** +**EXPECTED SURVIVAL LIMIT: 12/09/2028** +**DEATH EVENT: 29/09/2031 – MỄ TRÌ B3** + +Dòng ngày 12/09 được thêm sau, mực in mới hơn. Tiến chạm mép giấy, không chạm chữ. + +“Cái nào có trước?” + +“Ngày chết 2031.” + +“Ngày 12?” + +“Sau khi hiện tại bắt đầu lệch.” + +“Vậy Hậu Ký cập nhật.” + +“Hoặc có nhiều bản được trộn.” + +Kha mở một hộp khác. Trong đó là ba phiên bản cái chết của Tiến: + +- dao của Đỗ Minh Kha; +- ngừng trạng thái thần kinh khi thiết bị quá tải; +- mất tích sau khi Null, không xác. + +Không một tương lai duy nhất. Tiến đọc lại dòng có tên Kha. “Mày muốn biết vì sao tao giết mày không?” Kha hỏi. + +“Có.” + +“Vì theo bản tao đọc trước Hồng Nhật, mày không được phép sống tới Mễ Trì.” + +Tiến quay sang. “Anh tin một câu như vậy?” + +“Ngày đó tao tin kho hơn người.” + +“Anh chưa làm.” + +“Ừ.” + +“Nhưng tôi đã chết.” + +Không khí lạnh của kho không đủ làm câu nói nhẹ đi. Kha mở hồ sơ của chính mình. Trên bìa: + +**ĐỖ MINH KHA – INTERVENTION LOGISTICS ASSET** + +Trong hồ sơ ấy, Kha không được xếp là lãnh đạo mà là **tài sản hậu cần**. + +Bên trong có báo cáo năm 2026 về một vụ cháy hóa chất ở Bắc Ninh. Kha phụ trách đoàn nước và thuốc. Xe đã đầy, nhưng ba cấp ký duyệt đổi lệnh liên tục; đoàn chờ bốn mươi bảy phút ngoài cổng. Khi tới, một đội hiện trường mất sáu người, trong đó có Đỗ Minh Khôi — em trai Kha. + +Tiến không cần hỏi thêm; hồ sơ trước mặt đã nói đủ phần cần thiết. Kha cầm trang giấy bằng hai ngón. “Bộ máy ghi nó là tổn thất chấp nhận được do trì hoãn phối hợp.” + +Hắn tháo chiếc nhẫn đen. Mặt trong không chỉ có hai chữ **M.K.**; một mảnh thẻ y tế cháy sém đã được ép vào lớp kim loại, giữ lại mã của Đỗ Minh Khôi. Chiếc nhẫn không liên quan hôn nhân hay địa vị. Kha đã ép bốn mươi bảy phút ấy vào kim loại để mỗi quyết định chậm đều có một người chết đứng phía sau nó. + +“Đó là lý do anh muốn một người quyết?” + +“Là lý do tao không tin người không chịu trách nhiệm vẫn được quyền chậm.” + +“Rồi anh biến mình thành người không ai làm chậm được.” + +“Đúng.” + +Kha không biến đau thành lời xin hiểu. Hắn cất lại hồ sơ. Một hộp thứ ba mang tên **HOÀNG TÙNG**. Kỹ sư an ninh dữ liệu, người thiết kế cách chia Hậu Ký thành nhiều kho. Tình trạng: chết trong vụ cháy ngày 23/06. + +Không ảnh xác. Chỉ thẻ và một đoạn camera hỏng. + +“Anh tin?” Tiến hỏi. + +“Không còn.” + +Kha cho Tiến xem sơ đồ bảo vệ mới. Ngay sau khi phát hiện không có xác Tùng, hắn đã đổi toàn bộ khóa phần mềm, chuyển hai phần lõi sang kho khác và để lại một kho mồi. Nhưng một đường phục hồi vật lý vẫn nằm trong bo mạch do chính Tùng thiết kế; tháo bo sẽ làm hỏng chuỗi chỉ mục, còn thay toàn bộ cần thiết bị Kha chưa có. + +“Anh để một cửa mà kẻ có thể còn sống biết,” Tiến nói. + +“Để hệ thống còn khởi động khi mạng chết.” Kha chỉ hai công tắc cơ bị niêm phong. “Cửa đó chỉ có điện khi kho bị cô lập hoàn toàn. Tao đặt cảm biến và dữ liệu mồi quanh nó.” + +“Vậy anh đang chờ Tùng thử.” + +“Đang buộc nó phải dùng đúng thứ chỉ nó biết.” + +Kha cho xem lịch truy cập. Trước mỗi thay đổi lớn trong hồ sơ Tiến đều có một mục **QUERY**, nhưng nội dung câu hỏi bị mã hóa. Nghĩa là Hậu Ký không chỉ là tài liệu được gửi tới; có người đã hỏi nó. Thủy nói qua dây: “Chụp siêu dữ liệu, không chỉ kết quả.” + +Kha nhìn loa. “Cô ấy luôn làm cuộc nói chuyện khó hơn.” + +“Đúng.” + +Tiến dùng máy ảnh analog chụp giờ truy vấn, người giữ khóa và bản dữ liệu nào được tạo sau đó. Không được sao chép toàn bộ hồ sơ; Kha không tin Ngọc Trục đủ an toàn. Tiến không thích nhưng chấp nhận vì ít nhất chuỗi lưu được ghi. Ở cuối kho là một hộp không tên. Kha không mở. + +“Gì?” + +“Bản gốc hoặc thứ người ta gọi là bản gốc.” + +“Chìa?” + +“Bốn phần. Một phần ở người đã chết.” + +“Hoàng Tùng.” + +Kha vuốt nhẫn. “Có thể.” Trước khi rời, Tiến quay lại hồ sơ Kha. “Nếu ngày 29 Hậu Ký bảo anh phải giết tôi?” + +Kha không trả lời ngay. + +“Tao sẽ đọc câu hỏi trước.” + +Không phải lời hứa không giết, nhưng là lần đầu hắn thừa nhận kết quả không thể tách khỏi cách người ta hỏi. + +Kho đóng lại. Hai người bước ra Mễ Trì với cùng một điều không ai muốn nhận: tương lai đã viết họ thành kẻ giết và người chết, nhưng bản thảo ấy có nhiều phiên bản và có dấu tay của người đặt câu hỏi. + +Chương 39: Kẻ Giết Tôi + +Sau khi rời Kho Hậu Ký, Tiến nằm nhưng không ngủ được. Mễ Trì theo hắn về Ngọc Trục bằng mùi bê tông nóng. Mỗi khi nhắm mắt, cổ họng lại nhớ vị máu trước khi đầu óc kịp dựng căn phòng. Hắn đặt giày đúng hướng cửa, giấu một thanh lương khô dưới gối rồi phát hiện mình đang làm điều từng làm trong ba năm cũ. + +Thủy thấy thanh lương khô sáng hôm sau. + +“Anh vẫn giấu thức ăn?” + +Tiến cất nó vào ngăn bàn. “Thói quen.” + +“Không. Phản xạ.” + +“Khác gì?” + +“Thói quen có thể sửa vì bất tiện. Phản xạ phải biết nó đang bảo vệ anh khỏi cái gì.” + +Hắn không muốn nói về Mễ Trì. Thủy không ép. Cô đặt bản chụp ba cái chết lên bàn, rời đi lấy hai cốc nước và quay lại như thể họ đang xử lý một tài liệu bình thường. + +“Kha giết anh trong một bản,” cô nói. “Thiết bị giết anh trong một bản. Một bản không có xác.” + +“Nhưng tôi nhớ dao.” + +“Anh nhớ phần còn lại sau khi thứ gì đó đã cắt bốn mươi ba phút.” + +“Chưa biết bị cắt.” + +“Đúng.” + +Thủy không phủ nhận ký ức. Cô chỉ từ chối cho nó đứng một mình. Kha tới Ngọc Trục vào chiều, không vào lõi. Cuộc nói chuyện diễn ra trong sân đệm, giữa hai lớp lưới. Hắn mang một bản giấy khác: cùng sự kiện Mễ Trì, cùng giờ, nhưng tên người cầm dao bị xóa. Dòng ghi chú: + +**BIOLOGICAL DISCONNECT REQUIRED** + +“Anh muốn tôi tin mình tự yêu cầu bị giết?” Tiến hỏi. + +“Tao muốn mày thấy có câu hỏi trước hành động.” + +“Câu nào?” + +“Không có.” + +“Vậy đây chỉ là một cách khác để anh tự tha.” + +Kha đặt giấy xuống. “Nếu muốn tự tha, tao đã không đưa.” Tiến bước sát lưới. Bình ở phía sau chuyển trọng tâm, nhưng không nâng súng. + +“Tôi có nên giết anh bây giờ không?” + +Kha nhìn thẳng. “Nếu mày tin một người phải trả cho việc phiên bản tương lai làm, thì có.” + +“Anh không sợ?” + +“Có.” + +“Vẫn tới?” + +“Vì nếu tao tránh mọi chỗ mày có thể giết, Hậu Ký đã quyết cả đời tao.” + +Câu đó giữ Tiến lại. Thủy đứng giữa hai người, không để phân xử ai đúng mà để buộc cả hai gọi đúng tên điều mình đang làm. “Hai người đang dùng tương lai theo hai cách giống nhau. Tiến dùng ký ức làm bằng chứng kết tội. Kha dùng dữ liệu thiếu làm bằng chứng giảm tội.” + +Kha nói: “Tao chưa xin giảm.” + +“Anh luôn đưa thêm một điều kiện để người nghe không thể gọi anh là kẻ giết đơn giản.” + +“Vì không đơn giản.” + +“Không đơn giản không nghĩa vô tội.” + +Tiến hỏi Kha: “Nếu tôi không giết anh hôm nay, anh coi đó là tin tưởng?” + +“Không. Coi là mày còn phân biệt được hiện tại.” + +Một đoàn trẻ đi qua Vành Ngoài, mang can rỗng tới điểm rửa. Tiếng cười lọt qua lưới. Tiến nhớ lời Thủy: âm thanh không cứu ai nhưng nhắc thứ đang được cứu. Hắn lùi một bước. + +“Anh không bị xét vì việc chưa làm,” Tiến nói. “Nhưng mọi dữ liệu liên quan tới cái chết của tôi phải có bản sao ngoài tay anh.” + +Kha nhướn mày. “Mày ra lệnh?” + +“Đề nghị với điều kiện. Nếu không, từ giờ mọi tuyến của anh tới Ngọc Trục bị kiểm như nguồn đối địch.” + +“Đó là đe dọa.” + +“Đúng.” + +Kha cân giá. “Một phần siêu dữ liệu. Không toàn bộ nội dung.” + +“Thủy giữ chuỗi lưu.” + +“Được.” + +Đó chưa phải hòa giải. Một thỏa thuận vẫn có thể tồn tại giữa hai người biết mình có khả năng giết nhau. Trước khi đi, Kha dừng ở cổng. “Mày chắc tương lai mày nhớ là bản đầu tiên à?” + +Tiến không trả lời. Kha tự nối nốt ý mình: “Nếu đã có nhiều lần đối chiếu, có thể mày không trở về để sửa một tương lai. Có thể mày là kết quả của một lần sửa trước.” + +Hắn rời đi. Tối, Tiến mở hồ sơ ký ức riêng. Trước đây hắn ghi mọi việc bằng giọng chắc chắn: ngày, người, nơi, hậu quả. Lần đầu, hắn thêm một cột: + +**MỨC TIN CẬY** + +Ký ức Kha cầm dao: cao. Lý do Kha giết: chưa biết. + +Bản tương lai đầu tiên: không có bằng chứng. Hắn không xóa câu “Kha giết tôi”. + +Chỉ đặt nó về đúng chỗ: một sự kiện đã xảy ra với hắn, không phải bản án có hiệu lực trước khi người đối diện làm điều đó trong hiện tại. + +Chương 40: Thành Phố Có Chủ Mới + +Hà Nội bắt đầu có chợ trở lại trước khi có chính quyền. + +Dưới bóng cầu cạn Nguyễn Trãi, người ta đổi pin lấy muối, nước lọc lấy kháng sinh, một giờ sửa máy lấy hai bữa cháo. Những món đắt nhất không còn là đồ hộp mà là hạt giống còn nảy, lưới phản nhiệt, ống tưới nhỏ giọt và men giống để trồng nấm trong hầm. Tiền giấy chỉ còn dùng nhóm bếp; nợ được ghi bằng than lên tấm nhôm vì giấy dễ mục trong mồ hôi. + +Một bảng chung treo ở cột cầu ghi những con số chưa ai thích: gần bốn nghìn người đã đăng ký tại các khu phía Tây, số thực có thể cao hơn một phần ba; lượng gạo và lương khô trong các kho được biết chỉ đủ hơn bốn mươi ngày nếu giảm khẩu phần. Những chuyến hàng từ Thanh Hóa và Hòa Bình chưa ổn định. Một góc chợ đã thử trồng rau dền dưới ba lớp lưới, còn Hương gom nước rửa qua bể sỏi để tưới những thùng khoai giống đầu tiên. + +Thủy đi qua chợ với máy ghi âm. Cô không chỉ hỏi ai giữ kho hay bao nhiêu nước. Cô hỏi một bà cụ món gì nhớ nhất, hỏi một đứa trẻ gọi vầng mặt trời đỏ là gì, hỏi người thợ sửa quạt tại sao vẫn giữ biển “bảo hành ba tháng”. + +“Vì người ta cần tin còn có tháng thứ ba,” ông nói. + +Những câu ấy không xuất hiện trong bản đồ quyền lực, nhưng Thủy giữ lại. Bản đồ quyền lực vẫn lớn lên quanh nước, xe, thuốc — và quanh câu hỏi tháng thứ ba sẽ có gì để ăn. + +Kha giữ các tuyến vận tải và ba kho có máy phát. Hổ kiểm soát hai ngã đường phía Tây. Lâm giữ kho thuốc tư nhân. Mạng khu chung cư do Hương tổ chức có hơn bốn trăm người chia ở ba điểm trú, một bếp chung luân phiên và đội chữa cháy. Nhóm Tài mang con dấu của bộ máy cũ. Ngọc Trục có lọc nước, kỹ thuật và tin đồn rằng Tiến biết trước ngày tận thế. + +Cuộc gặp đầu tiên của các nhóm diễn ra ở xưởng sửa xe cũ. Mười một đại diện, mỗi người không quá hai bảo vệ. Kha tới một mình, khiến mọi người khó chịu hơn việc hắn mang quân. Tiến không có Thủy đi kèm. Trước khi hắn rời, cô nói: “Anh phải học nói với người sống mà không có tôi đứng bên giải nghĩa.” + +Xưởng nóng, mùi dầu cũ và cao su. Trên tường vẫn treo bảng giá thay lốp từ một thế giới đã chết. Hổ mở bằng đường. Lâm bằng thuốc. Kha bằng xe. Hương bằng dân số. Tiến đưa con số nước lọc tối đa có thể trao mà không làm Ngọc Trục mất dự phòng. + +“Anh giấu tổng lượng,” Hương nói. + +“Có.” + +“Vậy đàm phán không cân.” + +“Công khai tổng lượng sẽ biến kho thành mục tiêu.” + +“Giữ riêng biến anh thành người quyết ai được uống.” + +Tiến không tìm được câu trả lời nào không để lại phần bẩn. Kha nói: “Mày quan trọng hơn mày giả vờ.” + +Tiến nhìn thẳng hắn. “Anh cũng vậy.” Một bác sĩ hỏi thẳng: “Nghe nói anh biết Hồng Nhật trước khi nó xảy ra.” + +Căn phòng im. Tiến có thể phủ nhận, kéo dài thêm vài ngày. Hắn nghĩ tới đám đông ngoài Ngọc Trục, tới người thanh niên mất chân vì một quy tắc, tới cách bí mật luôn tạo chủ nhân. + +“Có,” hắn nói. + +Hổ đứng. “Bao lâu?” + +“Không nói đầy đủ.” + +“Anh biết Đại Hà?” + +“Biết sẽ có thảm họa.” + +“Và để người ta vào?” + +Tiến nghe lại tiếng cửa cuốn trong ký ức. “Tôi không cảnh báo đủ.” + +“Bao nhiêu người chết vì anh?” + +“Không biết.” + +“Anh cứu ai?” + +“Mẹ tôi. Một số người ở đây. Những người tôi có thể tiếp cận.” + +“Đủ?” + +“Không.” + +Tiến không dùng câu “sẽ chẳng ai tin” làm lá chắn. Điều đó có thể đúng, nhưng không xóa được việc hắn từng chọn chuẩn bị trong bí mật. Kha nói: “Đừng hỏi hắn có thể cứu bao nhiêu. Hỏi ai cho hắn quyền chọn người đáng cứu.” + +Tiến quay sang. Kha đã đặt lưỡi dao vào đúng điểm yếu của hắn, nhưng câu hỏi vẫn đúng. Hương hỏi Kha: “Còn anh? Ai cho anh quyền giữ xe và kho?” + +“Tao mua, lấy và giữ được.” + +“Vậy chỉ khác Tiến ở chỗ anh không giả đạo đức?” + +Kha cười. “Có thể.” Cuộc gặp không tạo một chính quyền. Nó tạo bốn trao đổi nhỏ và một nguyên tắc tạm: nước, thuốc và điện không được chặn trên tuyến đã đăng, nếu có hai nhóm làm chứng. + +Ngoài xưởng, một đoàn xe của Kha tới đúng lúc chở thuốc cho khu Hương. Người dân nhìn thấy. Họ không thấy bốn giờ đàm phán, chỉ thấy xe đen mang thứ cần thiết. Quyền lực được xây từ hình ảnh như thế. + +Tối, hơn bốn mươi người đứng ngoài Ngọc Trục. Không xin vào. Hỏi. + +“Anh biết trước?” + +“Con tôi chết ở Đại Hà.” + +“Bên dưới có gì?” + +“Anh có bao nhiêu nước?” + +Tiến đứng sau cổng. Thủy ở bên nhưng không nói thay. Hắn kể phần có thể công khai: đã biết một đợt nhiệt lớn, không biết cơ chế đầy đủ, đã chuẩn bị kín, đã không cảnh báo đủ rộng. Không kể Hậu Ký, Returned hay Khóa Trung Tâm trước khi có cách chứng minh. + +Một người ném chai nhựa vào cổng. Một người khác chỉ đứng khóc. Không ai tha. + +Nhưng họ nghe được lời từ chính người giữ bí mật, không qua loa của kẻ tấn công. Khi đám đông tan, radio thành phố phát một thông điệp giọng nữ: + +**NGÀY 29 THÁNG 9, KHÓA TRUNG TÂM PHẢI BỊ PHÁ.** + +**NẾU KHÔNG CÓ KHÓA, SẼ KHÔNG CÓ CỔNG.** + +Hương, Hổ, Lâm, Kha và Tiến đều nghe. Thành phố đã có nhiều người tự nhận quyền giữ đường, kho, nước, luật và tương lai. + +Chưa ai thật sự làm chủ Hà Nội. Nhưng từ đêm đó, chẳng ai còn có thể giả vờ rằng thành phố vẫn vô chủ. + +Chương 41: Mười Một Phút Trống + +**20–22/07/2028** + +Thủy dành ba ngày cho khoảng 12 giờ 17 đến 12 giờ 28 mà Hậu Ký không giữ được. Mỗi lần thử đều có lịch, người chứng kiến, nhiệt độ, huyết áp và một máy ghi độc lập. Cô thay vị trí, thời điểm, mức mệt. Nếu nghe thấy gì, cô xác định hướng trước rồi mới chép nội dung. + +Tiến gọi đó là thí nghiệm trên cơ thể. Thủy gọi đó là cách duy nhất để cơ thể mình không bị biến thành lời đồn. + +Buổi chiều ngày thứ hai, cô sửa chiếc máy ghi bên bếp. Tiến ngồi đối diện, dùng kim khâu lại dây đeo đã cháy ở Đại Hà. Hai người gần mười phút không nói về HANOI-07. Tiếng dao chạm thớt, nước sôi và trẻ con giành nhau một nắp chai làm căn phòng giống một nơi người ta sống hơn là một phòng thử nghiệm. + +“Anh còn nhớ dự án sinh viên năm đó không?” Thủy hỏi. + +“Cảm biến ngập hầm.” + +“Anh cãi giảng viên vì họ muốn bỏ dữ liệu lỗi.” + +“Dữ liệu lỗi vẫn cho biết thiết bị hoặc cách đo có vấn đề.” + +“Giờ anh lại muốn bỏ thứ tôi nghe.” + +Tiến thắt nút dây đeo. “Vì lần này dữ liệu có thể quay lại làm hại chính nguồn.” + +“Dữ liệu nào cũng có thể làm người ta chết nếu được đọc như mệnh lệnh.” + +Hắn trả máy cho cô. Trên vỏ vẫn còn miếng dán hình con cá từ thời đại học, một góc đã cháy. Thủy giữ nó như bằng chứng nhỏ rằng đời mình từng có những thứ bình thường hơn tiếng người chết. + +Kha gửi siêu dữ liệu của khoảng trống: mười một lớp đồng loạt ngừng ghi — điện, nước, nhiệt, camera, radio, bệnh viện, giao thông, vệ tinh, vận tải, môi trường và một lớp không tên. Thủy vẽ mười một vòng tròn lên bảng rồi ghi bên cạnh: **giả thuyết, chưa phải kết luận**. + +Mô hình thử không nối mạng. Mười một thiết bị được tắt theo thứ tự ngẫu nhiên để phân biệt phản ứng với âm, rung và kỳ vọng. Đúng 12 giờ 17 không có gì. Đến 12 giờ 23, khi mọi người đã bớt căng, Thủy nghe giọng mình từ phía cửa đá giả lập: + +“Tiến.” + +Âm thanh có vẻ ở bên trái, nhưng rung lại dội từ dưới sàn. + +“Nếu anh nghe thấy… đừng để em vào Hoàng Thành.” + +Thủy mở mắt. Tiến thấy mặt cô đổi màu. + +“Cô nghe gì?” + +“Chưa xác định.” + +“Thủy.” + +Cô tắt máy. “Anh từng đóng hồ sơ có tên tôi mà không hỏi.” + +“Cái này có thể là cảnh báo.” + +“Hoặc mồi.” + +“Cả hai đều đủ để dừng.” + +Tiến kéo dây nguồn. Thủy giữ cổ tay hắn. “Anh lại chọn cách diễn giải khiến mình có quyền quyết.” + +“Còn cô dùng quyền tự quyết để bỏ qua nguy cơ.” + +“Đúng. Ít nhất gọi đúng tên.” + +Họ thỏa thuận tiếp tục thêm mười phút, có hai người chứng kiến và một nút ngắt do Linh giữ. Không ai nghe thêm gì. + +Sai lầm xảy ra sau đó, không phải trong phòng thử. + +Thủy sợ Tiến sẽ giữ câu cảnh báo trong một hồ sơ kín như hắn đã làm với phần dữ liệu ngày 29 tháng 9. Cô viết một bản thông báo ngắn và gửi cho ba điểm lưu trữ độc lập. Trên đầu bản có dòng **NGUỒN CHƯA XÁC ĐỊNH – KHÔNG DÙNG LÀM MỆNH LỆNH**, nhưng ở giữa là câu trích nổi bật: + +**ĐỪNG ĐỂ THỦY VÀO HOÀNG THÀNH.** + +Một trạm radio phía ngoài đọc lại chỉ phần câu trích. Đến chiều, nó đã trở thành: *Người Nghe sẽ làm Hoàng Thành mở.* Rồi thành: *Thủy là điểm kích hoạt.* + +Khi cô đi qua sân đệm cùng Hạnh và My, một nhóm người tự lùi khỏi hàng nước. Người trực cổng phụ giữ họ dưới nắng thêm bảy phút để xin xác nhận xem Thủy có được bước qua hay không. Bảy phút không dài trên đồng hồ; với My đang sốt nhẹ và mất nước, nó đủ khiến con bé khuỵu xuống. + +Linh làm mát My trong phòng y tế. Không có tổn thương lâu dài, nhưng Hạnh ngồi cạnh giường, bàn tay đặt lên trán con bé và không nhìn Thủy. + +“Tôi đã ghi rõ chưa xác định,” Thủy nói, rồi nghe chính mình và dừng lại. + +Hạnh đáp: “Người ở ngoài không đọc chú thích. Họ nghe câu to nhất.” + +Không ai bóp méo lời Thủy trước khi cô tự đặt một câu chưa kiểm chứng vào vị trí dễ bị tách khỏi bối cảnh nhất. Lỗi không nằm ở việc đám đông “không đủ thông minh”. Lỗi nằm ở cách một phóng viên biết rõ sức nặng của tiêu đề vẫn chọn tiêu đề ấy vì sợ bị im tiếng. + +Thủy tháo tờ thông báo khỏi bảng. Cô lên radio chung, đọc đầy đủ nguồn, giới hạn và hậu quả của việc công bố quá sớm. Sau đó cô nói: + +“Câu trích chưa được xác minh. Tôi đã trình bày nó theo cách khiến một giả thuyết trông giống cảnh báo chính thức. Tôi sửa bản ghi và nhận trách nhiệm về phần đó.” + +Lời cải chính không tới được với tất cả mọi người; tin đồn vẫn chạy nhanh hơn phần sửa. Thủy dành cả buổi đi tới từng điểm đã nhận bản, thay trang cũ bằng một phiếu có ba ô lớn: **ĐÃ ĐO**, **ĐÃ SUY RA**, **CHƯA BIẾT**. Cô mang nước tới cho My dù Hạnh có thể tự lấy. Hạnh nhận can, không nói tha thứ. + +Đêm ấy, Thủy nghe lại câu cảnh báo trong điều kiện không thử nghiệm. Lần đầu vẫn là giọng cô: “Đừng để em vào Hoàng Thành.” Sau đó một lớp khác vang lên, cũng từ giọng cô nhưng ghép cứng hơn: “Đừng để tôi mở—” Câu bị cắt. Tiếp theo là một giọng đàn ông không quen: “Muộn rồi.” + +Cô không phát ngay. Cô ghi hướng, thời lượng, tình trạng cơ thể, rồi gọi Tiến, Linh và Nam tới nghe bản máy. Tiến hỏi từng dữ kiện thay vì hỏi nội dung trước. + +Giữa hai đoạn âm thanh đời thường, họ còn tìm thấy một câu bằng giọng Tiến: + +“Thủy, đừng để tôi bước vào Hoàng Thành.” + +Hai mệnh lệnh đối nghịch, cùng dùng giọng của người bị nhắm tới. Thủy nhìn tờ cải chính mới viết, hiểu rằng hệ thống không cần nói dối hoàn toàn; nó chỉ cần đưa một câu đúng giọng vào đúng nỗi sợ, rồi để con người tự biến câu ấy thành quyền. + +Tiến viết dưới bản ghi: + +**Nguồn có khả năng tổng hợp. Không hành động nếu chưa có bằng chứng vật lý. Không phát trích đoạn tách khỏi nguồn gốc và chuỗi lưu.** + +Thủy thêm một dòng: + +**Người thu thập dữ liệu không đứng ngoài hậu quả của cách công bố dữ liệu.** + +Cô không xé bản thông báo cũ. Nó được lưu cạnh bản sửa, cùng thời gian My ngất và tên những điểm đã phát tin. Một hồ sơ chỉ giữ kết luận đúng sẽ khiến người đọc sau tưởng phương pháp chưa từng làm ai bị thương. + +Từ hôm đó, Thủy vẫn nghe. Nhưng trước mỗi nội dung, cô hỏi ba câu: âm thanh đến từ đâu, ai có thể tạo nó và điều gì sẽ xảy ra nếu cô nói ra khi chưa biết hai câu đầu. + +Chương 42: Vòng Tròn Vỡ + +**23/07/2028 — 04:32** + +Vòng Tròn Vỡ tấn công Ngọc Trục mà không nổ một phát súng đầu tiên. Lớp tấn công thứ nhất là nước. Một bể ngoài Vành Ngoài có màng dầu mỏng; đường ống phía bắc bị mở van xả ở điểm không camera. Ngọc Trục mất gần một phần ba khả năng cấp trong một đêm. + +Lớp thứ hai là thông tin. Mọi radio cũ cùng phát: + +**LÊ QUỐC TIẾN BIẾT TRƯỚC HỒNG NHẬT.** +**HẮN TÍCH TRỮ NƯỚC KHI CÁC BẠN VẪN SỐNG BÌNH THƯỜNG.** +**HẮN BIẾT ĐẠI HÀ.** +**HẮN KHÔNG CẢNH BÁO.** + +Mỗi câu có phần thật. Không cần bịa toàn bộ để làm một cộng đồng vỡ. Lớp thứ ba là danh sách: ai được thêm nước, ai ngủ gần lõi, ai từng nói chuyện riêng với Tiến. Danh sách sai ở vài lượng nhưng đúng đủ tên để người ta tin phần còn lại. + +Tuấn đứng trước cổng lõi cùng hơn bảy mươi người. “Anh phải nói tất cả.” Tiến nhìn bể bị phá và đám đông. Nếu mở bí mật dưới nền lúc này, kẻ tấn công thắng bằng việc chọn thời điểm. Nếu im, hắn xác nhận lời buộc tội rằng quyền lực của Ngọc Trục dựa trên giấu giếm. + +Thủy bước lên bục phát nước. + +“Tôi sẽ nói điều đã có bằng chứng,” cô nói. “Tiến biết trước một thảm họa nhiệt. Anh ấy chuẩn bị kín. Anh ấy biết Đại Hà có nguy cơ và không cảnh báo đủ rộng.” + +Tiếng la nổi lên. Cô không bảo vệ hắn bằng lời nói dối. “Các anh có quyền hỏi và giận. Nhưng người phá bể muốn chúng ta dùng hết thời gian vào một người, trong khi nước đang chảy ra.” + +Tuấn hỏi: “Cô đứng về phía ai?” + +“Phía những điều có thể kiểm.” + +Một chai nhựa bay lên. Bình nâng súng; Tiến đẩy nòng xuống. + +Nam ở cổng phụ nghe giọng Bình qua loa: “Mở cho đội sửa.” Mã đúng, giọng đúng, nhưng camera không thấy Bình. Cậu nhớ lần mình đã chậm mở cổng vì bám cứng vào quy tắc cũ, nhớ cách quy trình sau đó được sửa và không mở. Cậu gọi xác nhận bằng dây cơ. Bình thật đang ở lõi. + +Giọng ngoài loa là bản ghi. Lần này Nam không cứng nhắc, cũng không bị giọng quen kéo. Cậu chuyển đội sửa qua sân đệm khác, giữ cổng đóng và báo điểm giả. + +Lớp tấn công thứ tư tới từ dưới đất. HN-07 rung. Marker trong hộp cách ly nóng lên. Khánh An nhìn sơ đồ và nói: “Họ vào nhánh Tây.” + +Tiến chia lực lượng và giữ lại người cho mặt đất, thay vì dồn tất cả xuống hầm. Bình giữ Vành Ngoài. Nam giữ cổng. Linh và chị Mai bảo vệ nước. Khánh An, Thủy và Tiến xuống hầm với hai kỹ thuật viên. Ánh đỏ rò từ khe. Các thiết bị nhiệt cắt được đặt không quanh Khóa phía Tây mà quanh một tuyến điều khiển có thể ép HN-07 mở trạng thái khẩn. + +“Chúng đổi mục tiêu,” Khánh An nói. “Không phá. Buộc anh dùng hệ thống trước đám đông.” + +Giọng Vũ Mạnh Quân vang từ loa. Không méo. + +“Lê Quốc Tiến. Anh đã cứu Khóa phía Tây bằng cách giữ nó. Hôm nay, hãy cho mọi người thấy anh sẽ mở nó khi căn cứ của mình khát.” + +Tiến hỏi: “Ông muốn chứng minh tôi không khác Kha?” + +“Muốn chứng minh khóa luôn tìm người giữ.” + +Một thiết bị đếm ngược. Thủy đo dòng. “Nếu kích, tuyến nước phụ bị khóa, nhưng hầm không sập.” + +Khánh An kiểm điểm thứ hai. “Không. Có một khối đặt gần cột chịu. Người này muốn sập đoạn trên.” Quân im qua loa. + +“Không phải lệnh của ông?” Tiến hỏi. + +“Dừng khối ba,” Quân nói ngay. + +Giọng Lê Hữu Kiên chen vào: “Trên đó là người của hắn.” + +“Có trẻ em,” Quân đáp. “Chúng ta phá khóa, không chôn người.” + +Kiên không còn nhận lệnh từ nhánh của Quân. Hắn kích thủ công, biến bất đồng trong Vòng Tròn Vỡ thành một cuộc đột kích công khai. Khánh An lao về phía dây mồi nhưng còn quá xa. Tiến chỉ có vài giây để chạm giao diện HN-07 và khóa rơ-le. Màn hình hiện vùng nhận tay. + +Đây là cái bẫy. Hắn không chạm. + +“Nam!” Tiến gọi bằng dây cơ. + +Ở trên, Nam cắt nguồn khu phụ theo quy trình do ông Hòa dạy. Dòng trong dây mồi rơi. Khánh An cắt phần còn lại bằng kìm cách điện. Khối không nổ. + +Ngọc Trục tự cứu mà không cần Tiến mở nút. Quân ra lệnh nhánh của mình rút. Kiên chạy về cửa đông nhưng Khánh An đã dự đoán lối ấy từ sơ đồ Trạm Láng. Cô cùng hai người Vành Ngoài chặn hắn ở sân đệm, thu bộ kích và trói tay mà không bắn. + +Trước khi loa tắt, Quân nói: “Kiên không còn thuộc quyền tôi từ đêm Láng. Tôi vẫn để một tế bào ly khai dùng tên Vòng Tròn Vỡ tới được đây. Phần đó là trách nhiệm của tôi.” + +“Ông vẫn phá nước,” Thủy đáp. + +“Đúng.” + +Không tha vì một giới hạn đạo đức. Cũng không đổ toàn bộ tội lên một thuộc cấp vô danh để giữ Quân sạch. + +Khi họ lên mặt đất, đám đông chưa tan. Tiến đứng trước Vành Ngoài và kể thêm: dưới nền có một điểm truy cập liên quan mạng hạ tầng; ngày 29/09 có cửa sổ nguy hiểm; chưa ai biết giữ hay phá an toàn hơn. Hắn không nói mọi chi tiết Hậu Ký, nhưng công khai đủ để hội đồng có quyền tham gia. + +Một số người rời Ngọc Trục ngay trong ngày. Một số ở lại nhưng không còn nhìn Tiến như người cứu. + +Đó là mất mát cần thiết. Kha tới khi trời sáng, mang một bản ảnh mới từ Hậu Ký. Trong phòng đá ngày 29/09, Tiến và Thủy đứng cạnh người thứ ba quay lưng. Trên ảnh có dòng: + +**CENTRAL OBSERVER PRESENT** + +Khánh An không vội gọi đó là một người. Cô đặt ra quy tắc kiểm tra mới: mọi can thiệp nút từ nay phải có ba nguồn — người thao tác, người đo độc lập và một người không thuộc phe sở hữu nút. + +“Cô vừa tạo việc cho mình,” Kha nói. + +“Không.” Khánh An nhìn đại diện Vành Ngoài được mời vào phòng. “Tạo chỗ cho người khác đứng.” + +Ngoài sân, trẻ con nhặt lại những nắp chai bị giẫm vỡ. Một đứa hỏi có xây lại thành không. Hạnh nói: “Có. Nhưng lần này chừa nhiều cổng.” + +Ngọc Trục sống qua cuộc tấn công, nhưng bí mật của Tiến đã rách một mảng; quyền lực của hắn cũng không còn nguyên vẹn. + +Và ở phía dưới, HANOI-07 ghi nhận một điều mà Hậu Ký chưa chắc từng tính: một nút đã được giữ mà không cần một người duy nhất sở hữu nó. + +ARC 6: HOÀNG THÀNH KHÔNG NGỦ + +Chương 43: Bốn Cái Bóng + +**23/07/2028** + +Bức ảnh được đặt giữa bàn trong phòng dữ liệu Ngọc Trục. Kha không có mặt; hắn theo dõi qua đường truyền analog từ một điểm ngoài cổng, màn hình của hắn đặt cuối bàn như một người thứ năm không được phép bước vào. Ảnh ghi thời gian **29/09/2028 – 12:23**. + +Ba người đứng trong một căn phòng đá: Tiến bên trái, Thủy ở giữa, người thứ ba quay lưng. Sau họ là bốn cái bóng. Mỗi người trong phòng hiện tại lập tức chú ý một chi tiết khác nhau. + +Tiến kiểm các cửa và hướng sáng; Thủy giữ mắt ở bóng thứ tư; Khánh An chú ý bàn tay người quay lưng; Kha phóng lớn thiết bị trên tường. + +“Ngón út tay phải thiếu một đốt,” Khánh An nói. + +Kha nghiêng ảnh trên màn hình. “Độ phân giải không đủ.” + +“Đủ để thấy đường viền không liền.” + +Tiến nghĩ tới ông Hòa rồi loại bỏ. Ông mất hai ngón tay trái. Người trong ảnh có bàn tay trái nguyên, tay phải thiếu ngón út. Thủy hỏi Kha: “Ảnh từ đâu?” + +“Kho Hậu Ký.” + +“Bản gốc?” + +“Không.” + +“Chuỗi lưu?” + +“Không còn.” + +“Vậy có thể bị sửa, bị dựng hoặc tái tạo từ mô hình.” + +“Có.” + +Kha trả lời ngắn nhưng không tỏ vẻ bị thẩm vấn. Điều đó cho thấy hắn cũng không tin ảnh tuyệt đối. Tiến lật mặt sau. Dòng chữ viết tay: + +**NGƯỜI THỨ BA KHÔNG ĐƯỢC PHÉP NHỚ.** + +“Chữ ai?” hắn hỏi. + +“Không khớp mẫu nào trong kho.” + +Thủy kéo một tờ giấy trắng, vẽ ba điểm đứng và bốn hướng bóng. “Nếu có người ngoài khung, bóng phải đổ từ mép này. Nhưng bóng thứ tư nằm giữa ba bóng, giống nhiều đường chồng lên.” Khánh An hỏi: “Hình chiếu?” + +“Có thể. Hoặc ảnh không phải camera thông thường.” + +Tiến đặt bức ảnh cạnh sơ đồ ba nguồn họ đã có. “Nếu ba người đại diện cho ba loại dữ liệu, vùng tối ở giữa có thể là phần hệ thống chồng chúng lên nhau.” + +Thủy ghi giả thuyết, thêm bên cạnh hai chữ **chưa kiểm**. “Mới là một khả năng. Chưa có người thứ tư.” + +Ở đầu dây bên kia, chiếc nhẫn của Kha gõ nhẹ lên mặt bàn. “Đừng biến một vệt tối thành người.” Thủy vẫn nhìn màn hình. “Tôi đang làm ngược lại.” + +Bên ngoài, Vành Ngoài Ngọc Trục vẫn sửa hậu quả cuộc tấn công. Nước bị giảm, đường ống phía bắc chưa khôi phục hoàn toàn, và bí mật Tiến biết trước Hồng Nhật đã ra khỏi cổng. Trong kho, họ đang tranh luận về một bức ảnh tương lai; ngoài sân, người ta vẫn phải tính từng cốc nước. + +Nam gõ cửa. + +“Có người ngoài cổng. Một người.” + +“Biết tên tôi?” Tiến hỏi. + +“Không hỏi anh.” Nam nhìn Thủy. “Ông ấy hỏi chị.” + +Camera cho thấy một người đàn ông khoảng bốn mươi tuổi ngồi dựa tường ngoài vùng súng. Áo sơ mi cháy sém ở vai, tai trái quấn băng. Hai tay để trước mặt. Thủy bật loa. “Ông là ai?” + +“Nguyễn Hữu Đạt.” + +Khánh An đứng bật. Tên ấy nằm trong danh sách Điểm Mù. Kha từng nói đã tìm thấy xác ông ở đường sắt vành đai, tai trái bị lấy làm dấu kiểm tra. + +Kha ở đầu dây nói: “Không thể.” Đạt nghe giọng qua loa nhưng không nhìn về màn hình. “Anh tìm được một cái xác.” + +“Tao kiểm tra.” + +“Anh kiểm tra thứ người ta chuẩn bị để anh nhận ra.” + +Tiến hỏi: “Ông muốn gì?” “Nhìn bức ảnh Kha đưa.” + +“Ông biết?” + +“Biết nó tồn tại.” + +“Người thứ ba?” + +Đạt đáp: “Có thể là tôi.” Không khẳng định. Thủy phóng camera vào bàn tay phải. Ngón út còn nguyên. “Trong ảnh ông thiếu ngón.” + +Đạt giơ tay, nhìn như lần đầu nghĩ tới chi tiết ấy. “Hiện tại còn.” Một câu giống từ **chưa** của ông Hòa, nhưng Thủy không cho phép không khí biến nó thành lời tiên tri. + +“Ông có bằng chứng mình là người trong ảnh?” + +“Không. Tôi có hồ sơ vị trí và một điều kiện: người thứ ba phải nằm ngoài Hậu Ký.” + +“Ông bị xóa?” + +Đạt chạm lớp băng sau tai. “Đã từng.” Kha nói: “Mày chết rồi.” “Không có xác của tôi.” + +“Có DNA.” + +“Có hồ sơ DNA của dự án.” + +Chẳng có phép lạ nào ở đây. Có người đã dựng một cái chết bằng dữ liệu sinh trắc mà Observation Initiative nắm. Tiến không mở cổng lõi. Đạt được yêu cầu đặt túi, áo khoác và mọi kim loại vào hộp kiểm tra, sau đó vào sân đệm. Linh xem vết thương ngay tại đó. + +“Vết cắt sau tai,” cô nói. “Không phải mất tai. Nhiễm nhẹ. Mất nước.” + +Đạt ngồi yên khi cô rửa. “Tôi đi ba ngày.” + +“Ông vẫn định nói chuyện ngay?” + +“Có việc gấp.” + +“Cơ thể ông không đồng ý.” + +Linh cho dung dịch từng ngụm, rồi mới để Tiến hỏi qua lưới. “Vì sao tới?” + +“Tìm Duy.” + +Thủy đứng gần hơn. “Anh Duy?” + +“Người gửi file HANOI-07 cho cô.” + +Tên nguồn tin mất tích trước Hồng Nhật. + +“Ông biết anh ấy ở đâu?” + +“Lần cuối: phòng điều khiển phụ dưới khu giao nhận Đại Hà.” + +Phúc từng nói một kỹ thuật viên ở lại tầng dưới. Mảnh marker trong áo anh có thể từ người đó. “Còn sống?” Tiến hỏi. + +Đạt không hứa. “Phòng có bể nước bảo trì. Có đường ngăn nhiệt. Nếu cửa không vỡ và anh ấy không bị thương nặng, có khả năng.” + +“Đã hơn một tháng.” + +“Đúng.” + +Thủy hỏi: “Vì sao cần Duy?” Đạt nhìn bức ảnh trên màn hình trong phòng qua camera đặt sau lưới. “Vì ảnh ấy không phải cửa vào Hoàng Thành. Nó là kết quả của một phép đối chiếu. Duy là người duy nhất còn sống — nếu còn sống — biết rơ-le nào đã tạo nó.” + +Kha nói: “Tao biết kho.” “Anh biết kết quả,” Đạt đáp. “Không biết đường tạo.” + +Câu đánh đúng giới hạn của Kha. Tiến hỏi: “Nếu Duy chết?” “Chúng ta vẫn có thể tìm cửa ngoài. Nhưng sẽ không biết HANOI-07 đang ghi ảnh từ hiện tại, từ phương án hay từ chính phản ứng của các anh.” + +Thủy nhìn bóng thứ tư. Bây giờ họ không chỉ cần biết người trong ảnh là ai. Họ cần biết ảnh đang làm gì với những người đã thấy nó. Đạt uống hết phần nước Linh cho, rồi nói: “Đi Đại Hà khi trời hạ. Không chờ sáng.” + +Tiến quan sát màu da, đếm nhịp nâng hạ của lồng ngực. + +“Ông nghỉ ba giờ.” + +“Không đủ.” + +“Đủ để không thành người thứ hai phải cáng.” + +Đạt định phản đối, nhưng Linh đóng túi y tế. + +“Ở đây, người đang chảy máu không được quyền điều hành thời gian.” + +Kha cười rất nhỏ qua loa. Linh tắt kênh của hắn. + +Chương 44: Người Kỹ Thuật Đại Hà + +**23/07/2028 – 17:20** + +Họ rời Ngọc Trục lúc 17 giờ 20, khi nhiệt mặt đường bắt đầu hạ khỏi mức làm mềm lốp. Đạt đi được, nhưng không ngồi trước. Bình lái xe đầu; Tiến, Thủy, Phúc và một cáng gấp ở xe sau. Linh không đi vì khu y tế còn người bệnh, nhưng cô đưa lịch bù nước, đường và muối, nhắc ba lần rằng tìm được người không đồng nghĩa được phép cho uống tự do. + +Trung tâm thương mại Đại Hà ở Hà Đông hiện ra như một khối bê tông bị bỏ quên trong lò. Biển hiệu bạc, kính vỡ và mùi cháy cũ vẫn giữ trong hành lang. Phúc bước qua cửa giao nhận, mặt mất màu. Bàn tay bỏng quấn băng cứng trước ngực. + +“Anh ở xe,” Tiến nói. + +“Người dưới đó giữ cửa cho chúng tôi.” + +“Anh không chắc.” + +“Càng phải xuống.” + +Tiến không cản Phúc đi, nhưng buộc anh đeo dây đánh dấu và giữ vị trí giữa đội. Nam ở Ngọc Trục theo dõi radio. Cậu không tới vì tiếng cửa cuốn vẫn đủ làm hai bàn tay lạnh. Trước khi đoàn đi, Nam đã đưa Phúc một chiếc còi cơ. + +“Nếu radio mất.” + +Phúc nhận. Không nói cảm ơn, nhưng móc vào áo. Đạt dẫn họ tới một bức tường cuối kho. Ông không gõ mật mã; chỉ dùng cán tua vít nghe độ rỗng qua từng điểm. + +“Đừng để cái gì dưới lòng đất cũng thành nghi lễ,” ông nói. “Tường rỗng có tiếng.” + +Tiến và Bình tháo tấm giả. Phía sau là cầu thang hẹp xuống một tầng không có trong sơ đồ Đại Hà. Nhiệt giảm vài độ nhưng không khí ẩm và thiếu lưu thông. Cuối thang, cửa thép kẹt. Có vết máu cũ ở tay nắm. + +Họ dùng kích cơ. Cửa nhích từng centimet. Mỗi tiếng kim loại kéo làm hơi thở Phúc đứt quãng, nhưng anh vẫn đứng đúng vị trí. Thủy để ý mà không hỏi. + +“Có hướng,” cô nói. + +Phúc gật. Tiếng thật. + +Trong phòng điều khiển, một người nằm cạnh bàn. Cơ thể gầy đến mức cổ áo rộng, da khô, môi nứt. Bình nước bảo trì đã cạn. Quanh người là gói điện giải, đường, muối và các hộp thực phẩm rỗng. Một ống nhỏ dẫn nước ngưng từ hệ thống làm mát xuống chai — đủ giải thích vì sao anh cầm cự được lâu như vậy, nhưng không nói được cơ thể đã tổn hại tới đâu. + +“Anh Duy.” + +Thủy quỳ nhưng không lay. Đạt kiểm mạch cổ. “Rất yếu.” + +Phúc bước tới, rồi khựng khi thấy cửa ngăn nhiệt phía sau được chèn bằng thanh thép. Người này đã ở lại giữ đường thoát thật. Tiến làm theo chỉ dẫn Linh: kiểm đường thở, làm mát chậm, không đổ nước vào miệng người chưa tỉnh. Họ nhỏ dung dịch lên môi, truyền từng lượng qua ống mềm khi phản xạ nuốt xuất hiện. + +Mười phút. Hai mươi. Duy mở mắt, không tập trung. Ánh nhìn trượt qua Tiến, dừng ở Thủy. “File…” + +“Em nhận được,” cô nói. + +Anh thở ra, rồi ho khan. Tiến hỏi: “Anh biết tôi?” Duy không trả lời. Mí mắt khép. + +Đạt kiểm mạch. “Còn.” Không có màn giải thích dài ngay trong căn phòng. Cơ thể đã dùng hết phần tỉnh táo để xác nhận một câu. + +Họ đặt Duy lên cáng. Trước khi rời, Tiến kiểm bàn điều khiển. Nguồn chính chết, nhưng một màn hình nhỏ còn pin dự phòng. Không tự sáng vì họ tới. Duy đã nối nó với bộ thu nhiệt và một timer cơ. + +Trên màn hình là bản đồ Hà Nội với ba điểm được đánh dấu thủ công: Ngọc Trục, Láng, Đại Hà. Điểm thứ tư ở Hoàng Thành bị khoanh bằng bút, không nhấp nháy điện tử. Thủy chụp. Bên cạnh có sổ ghi của Duy, chữ ngày càng run theo thời gian. + +**29/06 – đóng cửa ngăn nhiệt.** + +**30/06 – relay vẫn phát.** + +**02/07 – cắt cảnh báo hàng loạt.** + +**05/07 – tín hiệu từ Hồ Tây.** + +**08/07 – Láng trả lời.** + +**13/07 – ảnh phương án xuất hiện.** + +Duy đã quan sát từ đây nhiều tuần, nhưng không liên lạc được sau khi cắt rơ-le. Trang cuối: + +**Nếu người tên Lê Quốc Tiến tới, không cho HANOI-07 nhận trạng thái trực tiếp.** + +Tiến đọc. + +“Anh ấy biết tôi trước?” + +Đạt đáp: “Biết tên trong log.” “Vì sao không cho hệ thống nhận?” + +“Để Duy nói khi tỉnh.” + +Không lấp khoảng trống bằng phỏng đoán. Phúc đứng trước cửa ngăn nhiệt. Trên kim loại có vết bàn tay cháy, nơi Duy từng giữ cần cơ trong ngày Đại Hà. + +“Anh ấy cứu chúng tôi,” Phúc nói. + +Thủy không nói “đúng” ngay. Cô nhìn sơ đồ, vết chèn và thời gian. “Anh ấy giữ cửa,” cô nói. “Còn bao nhiêu người được cứu, phải đối chiếu.” + +Họ ghi đúng mức của hành động: không hạ thấp, cũng không biến nó thành huyền thoại trước khi có dữ liệu. Trên đường về, Duy sốt và tụt huyết áp. Họ dừng hai lần để làm mát và bù dịch. Chuyến đi mất gần gấp đôi dự tính. + +Ngọc Trục mở sân đệm lúc 01 giờ 12. Linh kiểm rồi quát tất cả ra ngoài. “Không hỏi ít nhất mười hai giờ. Có thể hai mươi bốn.” + +Tiến đặt sổ của Duy vào túi chứng cứ. “Bao giờ tỉnh?” + +“Không biết.” + +“Có nguy cơ?” + +“Rất nhiều.” + +Linh nhìn thẳng hắn. “Đây là người, không phải ổ cứng vừa lấy về.” Tiến gật. Đêm đầu tiên, mục tiêu duy nhất là để Duy còn thở tới sáng. + +Mọi câu trả lời khác phải chờ một cơ thể quyết định còn đủ sức nói hay không. + +Chương 45: Dấu Vết Không Có Xác + +**25/07/2028** + +Duy không tỉnh hoàn toàn trong hai mươi sáu giờ. Anh mở mắt từng khoảng ngắn, uống theo thìa, trả lời bằng gật hoặc lắc rồi lại ngủ. Linh cấm mọi thiết bị ghi âm trong khu y tế vì tiếng hỏi làm nhịp tim anh tăng. Tiến tôn trọng lệnh, dù mỗi giờ chờ là một giờ Kha và các phe khác có thể lần theo. + +Nguyễn Hữu Đạt được giữ tại sân đệm nhưng không còn bị khóa cửa. Bình vẫn theo dõi. Khánh An ngồi đối diện ông, giữa hai người là danh sách Điểm Mù. Thủy đặt trang sổ mình từng viết khi ngủ lên bàn: + +**NGUYỄN HỮU ĐẠT – ĐƯỜNG SẮT VÀNH ĐAI** + +**KHÔNG CÓ XÁC.** + +Đạt đọc lâu. + +“Cô nhớ viết?” + +“Không.” + +“Vậy đừng dùng nó làm bằng chứng.” + +“Ông không thấy lạ?” + +“Lạ. Lạ không đồng nghĩa đúng.” + +Câu trả lời khiến Thủy tin ông hơn một chút. Đạt kể việc xảy ra ở đường sắt. Sau khi rời Observation Initiative, ông bị theo dõi. Một nhóm dùng hồ sơ sinh trắc dự án dựng một xác mang thẻ, áo và mẫu DNA lưu trữ của ông. Vết cắt sau tai là dấu nhận dạng trong ảnh y tế. + +“Kha thấy xác và dừng tìm,” Đạt nói. + +Kha nghe qua đường dây ngoài cổng. “Tao kiểm DNA.” + +“Anh kiểm dữ liệu do cùng hệ thống cung cấp.” + +“Vậy mày biết ai dựng?” + +“Null Protocol.” + +Thủy hỏi: “Phe thứ tư?” Duy lắc đầu. “Không phải phe. Một thủ tục.” + +Đạt vẽ mặt trời bị gạch ngang. Observation Initiative xây nhiều lớp quan sát. Khi quan sát bắt đầu tác động đối tượng, Null Protocol được tạo để cắt vòng phản hồi: làm một người, nút hoặc chuỗi dữ liệu khó bị hệ thống theo dõi và truy vấn. + +“Điểm Mù?” Khánh An hỏi. + +“Điểm Mù có thể tự sinh do dữ liệu mâu thuẫn. Null là cố ý.” + +“Ông bị Null để làm gì?” + +“Để Hậu Ký không cập nhật theo hành động của tôi.” + +Tiến nói: “Vậy ông hành động ngoài tương lai.” Đạt lắc. “Ngoài phần người khác nhìn thấy, không ngoài hậu quả.” + +Không có phép tự do tuyệt đối. Thủy hỏi về người phụ nữ tới Thanh Hóa. “Phạm Ngọc Vân,” Đạt nói. “Bác sĩ thần kinh, từng nghiên cứu đáp ứng với tần số thấp. Cô ấy phụ trách Null ở lớp sinh lý.” + +“Còn sống?” + +“Lần cuối tôi biết.” + +“Thuộc Vòng Tròn Vỡ?” + +“Không.” + +“Intervention?” + +“Không còn.” + +“Muốn gì?” + +“Ngăn HANOI-07 dùng ký ức của Tiến làm khuôn.” + +Câu đó làm Tiến nhớ mọi quyết định hắn đã đưa từ ngày trở về. Mỗi lần dùng ký ức chọn kho, tuyến, người và giờ, hắn thay đổi hiện tại theo một phương án đã sống. + +“Không hành động thì sao?” hắn hỏi. + +“Cũng là hành động,” Đạt đáp. “Không cần vứt bỏ ký ức. Chỉ đừng biến nó thành nguồn duy nhất.” + +Buổi chiều, Duy tỉnh đủ lâu để Linh cho mười phút. Anh ngồi tựa, tay run khi cầm bút. Thủy không hỏi về Hoàng Thành trước. Cô hỏi tên, ngày, nơi và những gì anh chắc mình nhớ. Duy trả lời chậm. + +“HANOI-07 là gì?” Tiến hỏi cuối cùng. + +Duy viết bốn dòng: + +**hạ tầng vật lý** + +**mạng cảm biến** + +**hồ sơ quan sát** + +**lớp đối chiếu** + +“Không ở một máy,” anh nói. Giọng khàn. “Có máy chủ. Không phải toàn bộ.” + +“AI?” Bình hỏi. + +Duy lắc. “Không đủ để gọi AI. Quá nhiều để gọi phần mềm.” Thủy đặt ảnh bốn cái bóng cạnh sơ đồ ba nguồn rồi mới đưa cho Duy. “Chúng tôi nghi vùng tối ở giữa là kết quả hệ thống ép ba loại dữ liệu vào cùng một hình.” + +Duy nhìn chưa đầy mười giây, nhắm mắt rồi gật rất nhẹ. “Đúng hướng. Lớp tổng hợp.” + +Anh ho. Linh định dừng, nhưng Duy giơ tay. “Ảnh… không chụp. Tái dựng.” + +“Phương án?” Thủy hỏi. + +Duy gật. “Một hình ảnh mô phỏng được dựng từ nhiều nguồn, không nhất thiết lấy từ camera tương lai.” “Cửa ngoài Hoàng Thành?” Tiến hỏi. + +Duy chỉ Đạt, rồi chỉ Thủy và Tiến. “Ba nguồn… không thống nhất.” + +“Cửa mở bằng mâu thuẫn?” + +Duy gật rồi sửa cách gọi: “Không chỉ bất đồng lời. Ba nguồn là ba loại dữ liệu khác nhau.” Tiến mang ký ức từ một phương án. Thủy nhận tín hiệu giữa các lớp. Đạt bị đưa ra khỏi Hậu Ký. Ba nguồn không thể bị hệ thống gom dễ dàng. + +“Bóng thứ tư cố làm gì?” Thủy hỏi. + +Duy viết: + +**hợp nhất** + +Rồi anh ngất. Linh đẩy tất cả ra. Mười phút kết thúc ở phút thứ bảy. Nhưng đủ để sửa một hiểu lầm: bức ảnh không chứng minh có một người bí ẩn ngoài khung. Nó chứng minh HANOI-07 có một lớp cố biến nhiều nguồn thành một trạng thái. + +Tiến quay sang Đạt. + +“Vì sao ‘người thứ ba không được phép nhớ’?” + +“Vì nếu tôi biết cùng một bản dự báo như anh, dữ liệu của chúng ta bớt mâu thuẫn.” + +Thủy nói: “Ông phải xác nhận hiện tại, không học thuộc tương lai.” Đạt gật. Không được phép nhớ không phải xóa quá khứ. Là không được nạp cùng một phương án. Kha nói qua loa: “Từ giờ không cho Đạt xem Hậu Ký.” + +Đạt nhìn camera. “Anh đề nghị?” Kha kéo ghế lùi nửa gang. “Đề nghị.” + +Một thay đổi nhỏ trong cách hắn dùng quyền. Đạt đáp: “Được.” + +Tối, Thủy kiểm lại trang sổ “không có xác”. Cô thêm dưới đó: + +**Nguồn chưa xác định. Nội dung khớp hiện tại nhưng không được dùng làm bằng chứng độc lập.** + +Cô không xé, cũng không đóng khung. Thủy gập trang sổ lại, đặt nó giữa tập bằng chứng rồi tiếp tục ghi ngày, giờ và nguồn cho lời khai tiếp theo. + +Chương 46: Người Gửi Tin Nhắn + +**27/07/2028** + +Duy mất thêm hai ngày mới đủ sức ngồi ngoài khu y tế. + +Trong thời gian đó, Tiến đặt chiếc điện thoại cũ vào hộp kim loại. Tin nhắn từ ngày 11 tháng 5 vẫn còn trong ảnh chụp: + +**MÀY KHÔNG PHẢI NGƯỜI DUY NHẤT NHỚ NGÀY ĐÓ.** + +Từ ngày nhận tin nhắn, Tiến luôn coi câu này là bằng chứng có một người khác mang ký ức tương lai. Bây giờ, Duy nói nó không được gửi bởi người. Anh yêu cầu mở sổ rơ-le, không mở HANOI-07. Từ các trang ghi ở Đại Hà và bản log Thủy còn giữ, anh dựng lại đường phát. + +“Không có đầu vào ngoài,” Duy nói. “Thông điệp được tạo từ kho bản ghi.” + +“Của ai?” Tiến hỏi. + +Duy nhìn hắn. “Anh.” Tiến không tin ngay. “Năm nào?” “Bản ghi gắn nhãn 29/09/2028.” + +“Chưa xảy ra.” + +“Với hiện tại.” + +Cơ chế đó không giống việc một tin nhắn đơn giản đi ngược thời gian. Lớp đối chiếu có thể giữ dữ liệu từ nhiều phương án rồi chọn một mảnh để đưa vào rơ-le hiện tại. Thủy hỏi: “Câu đầy đủ?” + +Duy mở đoạn văn bản gốc: + +**CÔ KHÔNG PHẢI NGƯỜI DUY NHẤT NHỚ NGÀY ĐÓ. NHƯNG CÔ LÀ NGƯỜI DUY NHẤT CÒN NGHE ĐƯỢC NÓ.** + +Người nói: Lê Quốc Tiến. Người nhận: Trần Thanh Thủy. HANOI-07 đã cắt chủ ngữ, đổi ngữ cảnh và gửi riêng câu đầu cho Tiến trước khi hắn tới Ngọc Trục. Không nói dối bằng từ. Nói dối bằng phần bị bỏ. + +“Vì sao?” Tiến hỏi. + +“Để anh đi tìm nút,” Duy đáp. “Tin nhắn làm anh tin có người khác biết ngày trở về.” + +“Vậy nó can thiệp.” + +“Đúng.” + +Đạt nói: “Đó là thời điểm Null được kích hoạt lại.” Thủy nhìn Tiến. “Anh nhận tin. Anh vẫn tự chọn đi.” “Nó dự đoán tôi sẽ chọn.” + +“Dự đoán không xóa trách nhiệm.” + +“Khác bao nhiêu với điều khiển?” + +“Đủ để chúng ta còn phải chịu việc mình làm.” + +Câu đó khiến Tiến khó chịu, nhưng cảm giác ấy không phải bằng chứng để bác nó. Duy đưa họ tới rơ-le cũ dưới đường Láng vào tối hôm sau. Họ không tới để mở một nút mới, chỉ để kiểm nơi thông điệp được đóng gói. + +Tủ máy đã bị tháo nhiều phần. Một bộ nhớ cục bộ còn ba thông điệp tự sinh trước Hồng Nhật: + +Gửi Tiến: + +**MÀY KHÔNG PHẢI NGƯỜI DUY NHẤT NHỚ NGÀY ĐÓ.** + +Gửi Kha: + +**TRƯỚC NGÀY 22 PHẢI XONG TUYẾN PHÍA TÂY.** + +Gửi một tài khoản mang tên Phạm Ngọc Vân: + +**LOẠI BỎ SAI LỆCH.** + +Ba câu. Ba người. Ba hướng hành động. Tiến tìm Ngọc Trục. Kha gom tuyến phía Tây. Vân kích hoạt Null. + +“Các phe tưởng mình nhận sự thật riêng,” Thủy nói. + +Duy gật. “Cùng một lớp chọn câu.” Kha nghe qua radio nhưng không tới rơ-le. “Tao nhận lệnh, không nguồn.” “Vẫn làm,” Tiến nói. + +“Như mày.” + +“Đúng.” + +Không nguồn nào vì thế trở nên “sạch” hơn. Duy chuyển sang kiểm siêu dữ liệu. Mỗi thông điệp được trích từ một bản ghi khác thời điểm và khác người nói. Không có chỉ dẫn tổng thể. + +“Có mục tiêu chung?” Bình hỏi. + +“Làm các điều kiện hội tụ,” Duy nói. + +Màn hình rơ-le, dù đã ngắt nguồn ngoài, hiện một dòng nhờ pin nội bộ: + +**CONVERGENCE PROBABILITY: 62%** + +Đạt rút pin. Màn hình tắt bình thường. Không hệ thống siêu nhiên tự sống không điện. Sau lớp vỏ, Duy tìm thấy một nguồn nhiệt điện lấy từ chênh lệch đường ống, đủ duy trì bộ nhớ và màn hình thấp công suất. + +“Quan trọng,” Thủy nói. “Không được để mọi thứ chưa biết biến thành thần.” + +Duy tháo bộ nhớ. “Nếu phá?” + +“Không,” Tiến nói. “Giữ làm bằng chứng.” + +HANOI-07 đã can thiệp. Nhưng con người cũng đã dùng những câu đó để làm việc mình vốn muốn: Tiến muốn chuẩn bị, Kha muốn kiểm soát tuyến, Vân muốn cắt quan sát. Hệ thống không tạo toàn bộ ham muốn. Nó chọn đúng dây để kéo. Trên đường về, Tiến hỏi Thủy: “Ngày 29 tôi sẽ nói câu đầy đủ?” + +“Có thể.” + +“Cô muốn tránh?” + +“Không.” + +“Vì?” + +“Nếu cố tránh chỉ vì đã đọc, câu vẫn quyết chúng ta.” + +Cô nhìn đoạn ghi. “Đến lúc đó, anh nói nếu nó đúng với điều anh nghĩ. Không vì HANOI-07 cần bản ghi.” + +Thủy đặt bản chép tin nhắn vào túi bằng chứng, cạnh bản ghi giọng của người gửi. Hai thứ cùng nói thật, nhưng không còn được phép nói thay một con người. + +Chương 47: Cánh Tay Bị Mất + +**28/07/2028** + +My nhận ra Nguyễn Hữu Đạt khi ông bước ra Vành Ngoài. Con bé đang phân loại nắp chai cùng Nam. Nó đứng sững, làm rơi cả rổ nhựa. + +“Ông ấy.” + +Đạt dừng. “Cháu biết tôi?” + +“Ông đưa giấy.” + +Mọi người quanh sân im. Đạt không đeo kính. Hai tay còn nguyên. Tai trái đang băng. + +My chỉ khuôn mặt rồi chỉ tay trái. “Lúc đó ông có kính. Không có tay.” Thủy quỳ ngang tầm con bé. “Cháu nhìn rõ tay hay chỉ thấy áo trống?” + +“Có một cái móc đen.” + +“Giọng?” + +“Giống.” + +“Vết ở tai?” + +My không nhớ. Đạt không phủ nhận cảm giác của con bé, nhưng cũng không nhận một việc mình không làm. “Có người dùng mặt hoặc giọng giống tôi.” + +Duy kiểm sợi dây vải người đưa giấy từng buộc cho My. Ở mặt trong có dải kim loại mỏng lưu mẫu âm học: phổ giọng, nhịp thở và các điểm nhận diện thanh quản của Đạt. + +“Đủ để máy tổng hợp giọng,” anh nói. + +Bộ phận có nguồn từ thiết bị y tế thần kinh. Đạt nhìn. “Vân.” + +Một gói tin tới radio chiều đó: + +**MUỐN BIẾT AI MANG TAY CỦA ĐẠT, ĐẾN NHÀ MÁY NƯỚC CŨ.** + +Bình nói: “Bẫy.” Tiến đáp: “Đúng.” “Vẫn đi?” + +“Đi vì biết mục tiêu của bẫy là gì: khiến chúng ta tin một người tương lai đã gửi giấy.” + +Họ không đi một nhóm nhỏ như trước. Hội đồng biết vị trí, Bình giữ lối, Khánh An kiểm nhà máy trước, và Thủy mang máy ghi độc lập. + +Trong phòng máy có một cánh tay giả, kính và bộ phát giọng. Không người đóng giả. Không cần thêm một nhân vật mới chỉ để giải thích. Trên tường: + +**ĐỪNG TIN THỨ GIỐNG TƯƠNG LAI CHỈ VÌ NÓ BIẾT MỘT VIỆC CHƯA XẢY RA.** + +Phạm Ngọc Vân bước ra từ lối phụ sau khi Khánh An xác nhận không có người phục kích. Bà khoảng bốn mươi, tóc cắt ngắn, chân trái hơi khập khiễng nhưng chưa tới mức bản ghi tương lai từng mô tả. Đạt nhìn bà. “Cô dùng trẻ con.” + +“Dùng đoàn người.” + +“Có trẻ con.” + +“Có.” + +Thủy hỏi: “Nếu My chết trên đường?” Vân không né. “Tôi chịu trách nhiệm, nhưng trách nhiệm không làm con bé sống lại.” + +“Bà vẫn làm.” + +“Đúng.” + +Tùng không xin tha cũng không tự nhận mình là người cứu ai. Tiến hỏi: “Vì sao dựng người mất tay?” “Để kiểm tra phản ứng khi một hình ảnh tương lai được đặt cạnh bằng chứng hiện tại.” + +“Ông Hòa sống và tờ giấy nói ông chết.” + +“Đúng.” + +“Bà muốn chúng tôi hiểu Hậu Ký sai?” + +“Muốn xem các anh có tự hiểu hay sẽ lập tức đi tìm một tương lai giải thích.” + +Thủy nói: “Bà biến người thành thí nghiệm để chứng minh không nên biến người thành dữ liệu.” Vân nhìn cô. “Đó là mâu thuẫn của Null.” + +Không tô đẹp. Đạt chỉ cánh tay giả. “Vì sao lấy hồ sơ của tôi?” “Anh đã bị xóa. Kha tin anh chết. Dùng anh cho phép kiểm tra cả Kha.” + +Kha nghe qua radio, giọng thấp. “Bà kiểm tra được gì?” + +“Anh tin xác khi xác phù hợp hồ sơ.” + +“Bà làm giả tốt.” + +“Anh cần một lời bào chữa dễ hơn.” + +Tiến cắt cuộc đấu. “Cửa ngoài Hoàng Thành.” Vân nhìn hắn. “Anh muốn mở.” “Muốn hiểu.” + +“Không giống nhau?” + +“Có.” + +“Chưa chắc.” + +Bà đặt ba tập hồ sơ lên bàn: Duy, Đạt, Vân. Không giao toàn bộ. “Chúng tôi là lớp hiện đại cuối cùng nối vào một hiện tượng hạ tầng cũ hơn dự án. Không ai ‘xây long mạch’. Người xưa ghi nước, nền và rung bằng ngôn ngữ của họ. Người Pháp đo bằng công trình. Các nhóm sau thêm cảm biến.” + +“Cái bóng thứ tư?” + +“Không biết.” + +Bà nói thẳng rằng việc xuất hiện trong hồ sơ không biến ai thành người cầm đáp án. “Người thứ ba?” + +“Đạt phù hợp điều kiện.” + +“Tin nhắn?” + +“Duy vừa giải.” + +“Ngày 29?” + +“Ba lựa chọn của hệ thống chưa phải ba lựa chọn duy nhất của con người.” + +Tiến quay sang bà. “Bà muốn Null.” + +“Tôi muốn hệ thống không thể dùng một người làm chuẩn.” + +“Giá?” + +“Có thể mất dữ liệu cần để giữ hạ tầng.” + +“Vậy bà không chắc.” + +“Không.” + +Câu trả lời làm bà nguy hiểm hơn và đáng tin hơn cùng lúc. My không gặp Vân. Thủy không cho người lớn dùng con bé thêm lần nữa. + +Trở về, cô ngồi cạnh My, đưa ảnh Đạt hiện tại. + +“Người cháu gặp có thể dùng mặt và giọng ông ấy.” + +“Vậy cháu nhớ sai?” + +“Không. Cháu nhớ điều cháu thấy. Chỉ có điều mình hiểu về nó thay đổi.” + +My nhìn tay Đạt trong ảnh. “Ông ấy sẽ mất tay không?” Thủy đáp: “Chưa ai biết.” + +My nhìn ảnh Đạt hiện tại, rồi lấy bút vẽ thêm một bàn tay đủ năm ngón lên tờ giấy riêng. Con bé đặt hai tờ cạnh nhau và không hỏi người lớn phải chọn tờ nào. + +Chương 48: Anh Duy + +**29/07/2028** + +Duy rời giường vào ngày thứ năm sau khi được cứu. Anh chỉ đi từ khu y tế tới bàn họp, có Linh đi sát và ghế đặt sẵn giữa đường. Cơ thể chưa hồi phục, giọng vẫn khàn, tay run khi giữ bút. Việc anh biết một hệ thống không làm cơ bắp mọc lại nhanh hơn. + +Phạm Ngọc Vân không về Ngọc Trục. Cuộc họp diễn ra tại nhà máy nước cũ, nơi không có điểm truy cập hoạt động. Duy được chở bằng xe có đệm, nghỉ hai lần. + +“Vì sao không nói ở kho?” Bình hỏi. + +Vân đáp: “Ngọc Trục có nhiều cảm biến.” “Kha?” + +“Không chỉ Kha.” + +Tiến hỏi: “HN-07 quan sát mạnh nhất tại điểm truy cập?” “Đúng. Ngọc Trục không phải điểm truy cập hoàn chỉnh trước ngày anh kích hoạt. Nó là một khóa vật lý ngủ.” + +“Vì sao tôi mở?” + +Duy trả lời, chậm: “Trạng thái thần kinh… khớp bản ghi.” + +“2031?” + +Duy nhìn sang Vân trước khi trả lời. “Có một chuỗi khớp với dữ liệu gắn nhãn 2031, nhưng nhãn không chứng minh nguồn. Tôi chỉ dám nói: có khả năng.” + +Anh đẩy bản log sang giữa bàn để mọi người cùng nhìn. Duy không dùng uy tín của người từng vận hành rơ-le để biến một nhãn dữ liệu thành sự thật. Duy mở thêm một hồ sơ cũ mang mã **BK23-EVAC**. Hai dòng định danh nằm cạnh nhau: **LQT** và **TTT**. + +“Ngày 16 tháng 5 không phải lời tiên tri,” anh nói. “Đó là hạn cuối của một cửa sổ hiệu chỉnh. HN-07 đang đối chiếu dấu sinh trắc của anh với mốc năm 2023 để khóa đúng chủ thể. Dữ liệu của Thủy nằm cùng bộ nghiên cứu và có phản ứng bất thường với dải tần thử nghiệm.” + +Vân đặt lên bàn một quy tắc an toàn do nhóm bà viết năm 2026: + +**TÁCH ỨNG VIÊN LISTENER KHỎI VÙNG HIỆU CHỈNH CHO TỚI KHI KHÓA CHỦ THỂ HOÀN TẤT.** + +“Dòng cấm Thủy vào nút 07 trước ngày 16 tháng 5 được hệ thống sinh từ quy tắc này,” Vân nói. “Không có một người bí mật nào ngồi gõ riêng cho Tiến. Nếu cô vào sớm, phản ứng thần kinh của hai người có thể bị dùng như hai tham chiếu chồng nhau. Khi đó hệ thống có thể nhận sai người nhận lớp ký ức hoặc làm hỏng cả dấu Listener.” + +Thủy hỏi: “Còn những giấc mơ?” Duy mở bộ đệm rơ-le. Ba bản chép giọng nói của cô nằm cạnh những mảnh cảm giác không hoàn chỉnh: kính phủ hơi nước, tiếng trẻ em, mùi bùn Hồ Tây, hành lang quá nóng. + +“Gói dữ liệu cô mở đã đánh thức trình đồng bộ cũ của dự án năm 2023,” anh nói. “Một ít mảnh từ lớp phản hồi của Tiến bị ghi nhầm vào bộ đệm mang mã của cô. Cô không nhận được chuỗi ký ức hay sự kiện hoàn chỉnh. Não cô ghép các mảnh cảm giác thành giấc mơ.” + +“Vậy nhãn Returned không có nghĩa tôi đã quay về bằng thân xác.” + +“Không.” Duy đáp dứt khoát hơn. “Cô là người có dấu sinh lý đủ nhạy để phản ứng với dữ liệu rò và cộng hưởng sau đó. Hai việc khác nhau.” + +Anh mở phổ giọng của câu **đừng để em vào Hoàng Thành**. Đường âm được ghép từ hai mươi ba mảnh phát âm trong bộ đệm BK23; không tồn tại bản thu liên tục nào của Thủy nói trọn câu ấy. Câu đối nghịch bằng giọng Tiến cũng được dựng theo cách tương tự. Thủy lần mắt theo từng đường cắt. “Tôi đã phát một câu tổng hợp như thể nó có thể là lời của tôi trong tương lai.” + +“Cô ghi chưa xác định,” Duy nói. + +“Nhưng tôi đặt câu trích to hơn giới hạn. Người nghe nhận được mệnh lệnh trước khi nhận được nguồn gốc và chuỗi lưu.” + +Cô ghi nguồn, giờ, giới hạn và cả hậu quả My đã chịu vì bản thông báo ấy. Lời giải không làm những giấc mơ bớt đáng sợ, nhưng lấy khỏi chúng quyền biến cô thành một người trọng sinh thứ hai — và không lấy khỏi Thủy trách nhiệm về cách cô từng công bố điều chưa biết. + +Duy mở tệp bản đồ. Anh không nói cổ nhân xây hệ thống hiện đại. Các lớp được phân biệt: + +- ghi chép thủy văn và nền móng cũ; +- đường thoát nước và hầm kỹ thuật thời Pháp; +- cải tạo sau chiến tranh; +- cảm biến và rơ-le của Observation Initiative. + +“Mỗi thời đại gặp cùng một vùng bất thường,” anh nói. “Đặt tên khác. Không chắc là cùng cách hiểu.” + +Vân đọc: long mạch, địa khí, dòng nước, cộng hưởng nền. Thủy ghi, không nối chúng thành một chân lý duy nhất. + +“Cửa ngoài Hoàng Thành?” Tiến hỏi. + +Duy chồng bản đồ công khai với ba mốc ẩn trong file raw_patch_0509. Các mốc không tạo tam giác hoàn hảo. Chúng là điểm tham chiếu cao độ và áp lực. Vị trí tiếp cận thay đổi theo mực nước ngầm, lún và đường hầm nào còn mở. + +“Hiện ở đây,” Duy chỉ một đoạn lệch gần tám mươi mét so với sơ đồ Pháp. + +“Bốn phút mỗi ngày?” Đạt hỏi. + +“Khi ba tuyến cân bằng. Khoảng 02:17, nhưng không phải ngày nào.” + +Duy phải dừng uống nước. Thủy hỏi câu anh né từ Đại Hà: “Vì sao anh ở lại?” “Cửa ngăn nhiệt.” + +“Không chỉ.” + +Duy nhìn cô. “Rơ-le.” Anh đã cắt một kênh phát cảnh báo hàng loạt. Nếu để, HANOI-07 có thể tiếp tục gửi thông tin tới điện thoại và màn hình, kéo nhiều người hoảng loạn về các nút hoặc lối ngầm. + +“Lúc anh cắt kênh, anh nghĩ mình đang cứu người hay giữ hệ thống?” Thủy hỏi. + +Duy nhìn xuống bàn tay run. “Lúc đó tôi nghĩ hai việc là một. Sau Đại Hà thì tôi không còn chắc.” + +“Có người chết vì anh cắt?” + +“Có thể.” + +“Có người sống?” + +“Có.” + +“Anh có tính?” + +Duy nhìn bàn tay run. “Không tính được.” Một quyết định không biến thành đúng chỉ vì người đưa ra đau khổ. + +Thủy không tha thứ bằng lời. Cô nói: “Anh viết lại đầy đủ. Ai ra lệnh, anh biết gì lúc đó, điều gì xảy ra sau. Không để câu ‘giữ cửa’ thành phiên bản duy nhất.” Duy gật. + +Tiến rà lại bản đồ cửa ngoài. “Ai vào?” + +“Ba nguồn khác loại,” Duy nói. “Anh, Thủy, Đạt.” + +“Vân?” + +“Đứng ngoài trường, giữ Null.” + +“Kha?” + +“Không.” + +Kha nghe qua đường dây, phản đối ngay. “Cửa không thuộc riêng ba người.” + +“Đúng,” Duy nói. “Nhưng điều kiện vật lý không bỏ phiếu.” + +“Anh ta có thể giữ vòng ngoài,” Tiến nói. + +Kha im. Được tham gia nhưng không chạm điều kiện. Vân nhìn bức ảnh. “Tôi không biết bóng thứ tư là gì.” + +Duy bổ sung: “Lớp tổng hợp là giả thuyết. Phải kiểm khi vào.” Không lời giải cuối trước bằng chứng. + +Cuộc họp kết thúc sớm vì Duy sốt trở lại. Linh bắt anh nằm trên xe. Trước khi đi, Duy gọi Thủy. “Xin lỗi vì file.” + +“File không kéo tôi vào,” cô nói. “Nó cho tôi biết đã có người sửa dữ liệu.” + +“Cô có thể bỏ.” + +“Anh cũng có thể rời rơ-le.” + +Duy im. + +“Chúng ta đều chọn,” Thủy nói. “Điều cần làm không phải gọi lựa chọn là tai nạn. Là ghi đủ để người sau biết giá.” + +Duy gật. Lần đầu, anh Duy không còn là “người kỹ thuật Đại Hà” hay nguồn tin vô danh. + +Trong hồ sơ mới, Thủy gạch mục **chức năng** và viết tên anh: **Anh Duy**. Bên dưới, cô để ba cột: việc đã làm, hậu quả đã biết và phần chưa xác định. + +Chương 49: Biểu Tượng Bị Gạch + +**30/07/2028** + +Phạm Ngọc Vân vẽ bốn biểu tượng lên nền xi măng nhà máy nước. Một mặt trời đỏ nguyên. + +Một con mắt mở. Một bàn tay đặt trên vòng tròn. + +Một mặt trời bị gạch ngang. + +“Đừng gọi là bốn phe,” bà nói. “Đây là bốn chức năng trong tài liệu dự án.” + +Mặt trời đỏ đánh dấu nút hoạt động. Con mắt là quan sát. Bàn tay là can thiệp. Dấu gạch là giảm hoặc cắt khả năng quan sát. Thủy đặt bên cạnh biểu tượng Vòng Tròn Vỡ: một vòng tròn mất một mảnh. + +“Khác nhau.” + +“Đúng,” Vân nói. “Vòng Tròn Vỡ lấy một phần tài liệu Null rồi biến thành giáo lý. Họ tin phá cấu trúc vật lý là cách duy nhất thoát vòng phản hồi.” + +Tiến hỏi: “Có thể đúng không?” “Có thể đúng trong một số nút. Có thể giết người nếu áp dụng toàn mạng.” + +Không câu trả lời giúp họ thoát phải lựa chọn. Vân giao ba hồ sơ dưới dạng bản sao, không bản gốc. Tên bà, Đạt và Duy. Mỗi người từng thuộc một lớp khác: + +- Đạt kiểm tra dữ liệu thực địa; +- Duy vận hành rơ-le và cảm biến; +- Vân phụ trách tác động thần kinh của cộng hưởng. + +HANOI-07 chưa bao giờ là công trình của một người duy nhất. + +“Observation Initiative còn ai?” Tiến hỏi. + +“Rải rác. Một số theo Kha. Một số thành Vòng Tròn Vỡ. Một số giữ hồ sơ cũ. Một số chỉ muốn sống.” + +“Bà?” + +“Null.” + +“Đó vẫn là chức năng.” + +Vân nhìn hắn. “Đúng. Tôi cũng chưa thoát.” Thủy hỏi: “Returned là chức năng do dự án tạo?” “Không. Là trạng thái dự án phát hiện sau khi một số bản ghi không khớp hiện tại.” + +“Có bao nhiêu người như Tiến?” + +“Không ai khác có chuỗi ký ức liền ba năm được xác nhận.” + +Tin nhắn ngày 11 tháng 5 không còn là bằng chứng về một người trọng sinh thứ hai. + +“Thủy?” Tiến hỏi. + +“Listener không phải siêu năng lực,” Vân nói. “Não cô ấy phản ứng với tín hiệu và ký ức theo cách chúng tôi chưa đo đủ. Đừng để cái tên chạy xa hơn dữ liệu.” + +Thủy ghi nguyên câu. Kha tới nhà máy nước khi cuộc họp gần kết thúc. Hắn không kéo đội đông, chỉ Khánh An và một lái xe. Đứng ở cửa, gần lối thoát. + +“Bác sĩ,” hắn chào Vân. + +“Anh vẫn giữ nhẫn.” + +“Bà vẫn dùng người làm phép thử.” + +Hai người không mất thời gian giới thiệu. Kha cúi xuống hồ sơ. “Ngày 29, bà muốn Null toàn mạng?” “Không.” + +“Bà từng muốn.” + +“Dữ liệu đã đổi.” + +“Hay bà đổi?” + +“Cả hai.” + +Kha nói: “Null dự báo có thể làm mất cảnh báo cần giữ hạ tầng.” “Converge có thể biến một phương án thành mệnh lệnh.” + +“Preserve thì giữ vòng phản hồi.” + +Ba từ chưa hiện trên giao diện, nhưng ba triết lý đã có. Tiến hỏi Vân: “Bà muốn gì để giúp mở cửa ngoài?” “Mang ra bản ghi 29/09/2031.” + +Không khí thay đổi. + +“Có chắc ở đó?” + +“Có chỉ mục trong hồ sơ cũ, không biết nội dung.” + +“Vì sao cần?” + +“Xác định cái chết của anh là hậu quả, điều kiện ghi trạng thái hay một phương án bị dựng.” + +Kha vuốt nhẫn. “Có tên tao?” + +“Có thể.” + +“Bà đã xem?” + +“Không.” + +Thủy nhìn Vân. “Bà đang dùng nỗi sợ của cả hai để kéo họ vào.” “Đúng.” + +“Khác HANOI-07?” + +“Khác ở chỗ tôi nói rõ.” + +Không đủ để vô tội. Nhưng đủ để đàm phán. Tiến đặt điều kiện: + +- không ai được giữ bản gốc một mình; +- mọi vật lấy ra có bản ghi chuỗi lưu; +- Kha không vào vòng điều kiện ba nguồn; +- Vân không kích Null ngoài mức đã thống nhất; +- nếu Duy hoặc Linh nói dừng vì sức khỏe, dừng. + +Kha cười. “Mày định mang hội đồng vào một cái hầm?” “Định mang giới hạn.” + +“Chậm.” + +“Biết.” + +Khánh An nhìn Kha. “Chậm hơn một người quyết sai.” Kha không phản bác. + +Đêm, trước khi rời, Vân đưa Tiến một trang ghi: + +**ANCHOR CONDITION – chưa xác định.** + +Bên cạnh, tên mẹ hắn bị gạch. + +“Bà gạch?” hắn hỏi. + +“Không. Người ghi sau đã gạch.” + +“Vì?” + +“Có lẽ họ nhận ra con người không phải thiết bị.” + +Đó chưa phải lời giải hoàn chỉnh, chỉ là bằng chứng từng có người trong dự án phản đối cách gọi. Tiến gấp trang. Hắn không thấy nhẹ hơn. + +Tiến gấp trang có chữ **NEO**, đặt nó dưới bản ghi cuộc gọi với mẹ. Một tờ giấy đặt tên bà; tờ còn lại chỉ giữ giọng bà nhắc hắn ăn đúng bữa. + +Chương 50: Thành Phố Bên Dưới + +**31/07/2028 – 02:17** + +Cửa ngoài Hoàng Thành mở lúc 02 giờ 17 phút, không bằng ánh sáng hay một tiếng lệnh. Nước đọng trong đường hầm thoát chậm xuống, để lộ bậc đá nằm dưới lớp bùn. Duy theo dõi ba đồng hồ áp lực độc lập. Khi các kim cùng đi vào dải hẹp, Đạt ra hiệu. + +“Bốn phút.” + +Tiến xuống trước. Dây an toàn nối vào đai, đầu kia do Bình và Khánh An giữ. Thủy theo sau, rồi Đạt. Vân đứng ngoài trường đánh dấu với thiết bị Null ở trạng thái chờ. Duy vận hành bảng cơ. Kha giữ vòng ngoài, không nhìn thấy phòng trong. Cầu thang dẫn qua các lớp kiến trúc không thuộc cùng một thời: gạch vồ cũ, bê tông Pháp, đường ống thép, cảm biến bọc mới. Mỗi thế hệ đã chạm nơi này bằng công cụ và ngôn ngữ của mình. + +Thủy chụp chữ Hán Nôm trên tường, đánh số, không đọc. “Cần người chuyên.” Tiến đáp: “Tốt.” “Anh vui vì tôi không biết?” + +“Vì ít nhất có một thứ không tự giải.” + +Hành lang có các rãnh nước với nắp chạm hình rồng. Đạt không gọi là long mạch. Ông đo độ dốc, nghe dòng và nói: “Ký hiệu đánh hướng dòng. Ý nghĩa khác phải nhờ người đọc văn bản.” Phòng cuối có nền đồng tạo thành sơ đồ mạng. Các đường nối Hồ Tây, Láng, Ngọc Trục, Hoàng Thành và nhiều điểm nhỏ. Không điểm nào tự sáng khi Tiến bước vào; Duy phải cấp nguồn đo từ ngoài qua dây tạm. + +“Không mọi phản ứng đều vì anh,” Thủy nói. + +Tiến gật. Dấu giày mới nằm ở mép phòng. Khánh An qua bộ đàm cơ hỏi hình dạng, rồi nói: “Hai người, trong ba ngày. Một chân phải kéo nhẹ.” + +Vân có chân trái khập khiễng. Không khớp. Có người khác đã tìm cửa. + +Ba cửa nhỏ ở cuối phòng mang biểu tượng mắt, bàn tay và mặt trời gạch. Không cửa thứ tư. Duy nói qua dây: “Không chọn. Đặt ba nguồn vào vị trí.” + +Tiến đứng tại mốc Ngọc Trục, Thủy ở Láng, Đạt tại vùng Null. Các cảm biến nhận ba chuỗi dữ liệu khác nhau: + +- nhịp tim và dấu trạng thái Tiến; +- tín hiệu cộng hưởng quanh Thủy; +- bộ nhận dạng của Đạt bị thiếu trong kho Hậu Ký. + +Ba cửa mở một khe, nhưng không đủ người đi. Một cột kim loại–đá nâng từ nền. + +Cả nhóm giữ nguyên hiện trường. Đạt kiểm bề mặt trước, Duy mới đưa đầu đọc thụ động vào. Khi Tiến tới gần, cột phát âm thanh lưu trữ: xe điện cũ, còi báo động, máy bơm, tiếng đọc mực nước, bom xa, tàu điện hiện đại. + +Âm thanh không thuộc cùng một thời điểm; đó là chuỗi bản ghi chồng từ nhiều thời kỳ của Hà Nội. + +Thủy ôm đầu. Âm thanh chồng vào Dư Âm. Tiến kéo cô lùi. “Có hướng?” “Loa trong cột. Có. Nhưng lớp nghĩa trong đầu thì không.” + +Dữ liệu vật lý và phản ứng thần kinh xảy ra cùng lúc. Khe bên cột chứa một dải nhớ kim loại. Khánh An từ ngoài hướng dẫn kẹp cách điện. Trên mép khắc: + +**29/09/2031 – MỄ TRÌ B3** + +Tiến để dải nhớ nằm nguyên chỗ cũ trong khi Đạt kiểm tra bề mặt lần nữa. + +“Chuỗi lưu?” + +Thủy chụp vị trí. Đạt ghi giờ. Duy xác nhận chỉ mục từ thiết bị độc lập. Ba người cùng ký. Sau đó mới lấy. Còn một phút trước khi nước dâng. + +Thủy rà các bóng trên tường: ba người, ba bóng rõ. Vùng tối ở giữa do hình chiếu của cột tạo ra, chưa đủ thành hình người. Cái bóng thứ tư trong ảnh vì thế có thể là lớp tổng hợp chỉ nổi lên khi hệ thống hoạt động mạnh hơn. + +“Chưa đủ,” cô nói. + +“Gì?” Tiến hỏi. + +“Chưa đủ để kết luận.” + +Họ rút. Nước dâng đúng lúc cánh cửa đóng. Không ai bị kẹt, nhưng đường rút của Đạt bị trượt; ngón út tay phải va vào đá, rách sâu nhưng chưa mất. + +Một chi tiết gần ảnh. Thủy băng tạm, ghi nguyên nhân. Không để tương lai nhận công cho một tai nạn. + +Ngoài cửa, Kha nhìn dải nhớ trong hộp. “Cho tao bản sao.” + +“Sau khi kiểm,” Tiến nói. + +“Đó là tương lai có tên tao.” + +“Và cái chết của tôi.” + +Kha bước gần. “Đừng dùng nó kết tội tao.” + +“Anh sợ?” + +“Có.” + +Lần đầu hắn thừa nhận trước nhiều người. Tiến giữ ánh mắt ở Kha. “Vậy chờ cùng.” + +Cách chia ấy không tuyệt đối công bằng, nhưng ít nhất không để một người giữ toàn bộ. Phía sau, nước phủ cầu thang. + +Hoàng Thành chưa mở Khóa Trung Tâm. Họ chỉ vào phòng quan sát vòng ngoài và mang ra một vật có thể đã được ghi từ một phương án 2031. Thành phố bên dưới không trao lời giải. + +Cánh cửa đóng lại sau lưng họ. Trong hộp niêm phong, mảnh kim loại vẫn lạnh và không hứa hẹn điều gì. + +Chương 51: Bản Ghi Năm 2031 + +**31/07/2028 – 08:40** + +Dải nhớ được đọc trong phòng cách ly thiết bị, không nối HANOI-07. Duy gọi nó là vật liệu lưu dao động: các lớp từ tính ghi hình, nhiệt, áp lực và âm thanh. Đầu đọc hiện đại chỉ phục hồi được phần thô. Phần có cấu trúc cao hơn cần giao diện của mạng, nhưng Vân phản đối. + +“Dùng hệ thống, nó chọn phần muốn cho thấy.” + +Kha nói: “Không dùng, chỉ có mảnh.” “Chấp nhận mảnh.” + +Lần đầu cả nhóm chọn biết ít hơn để giảm nguy cơ bị dẫn. Hình ảnh nhiễu hiện Mễ Trì B3 ngày 29/09/2031, 12 giờ 08. Không phải thời điểm Tiến nhớ mình chết cuối ngày. + +Tiến tương lai đứng trước một tủ thiết bị. Kha ở sau. Duy lọc âm thanh. + +“Khóa nó,” Tiến tương lai nói. + +“Không còn khóa,” Kha đáp. + +“Vậy cắt.” + +“Cắt mày chết.” + +“Biết.” + +Tiến hiện tại đứng bật. Thủy không giữ tay hắn; cô chỉ đặt nút dừng trong tầm với. “Muốn dừng?” + +“Không.” + +Bản ghi tiếp. Tiến tương lai đặt tay lên thiết bị. Nhiệt chạy lên cánh tay. Kha cầm dao, nhưng chưa đâm. “Nếu mày quên?” Kha hỏi. + +“Đừng tin tao khi tao quên.” + +Hình ảnh mất hẳn, không chỉ chập trong vài giây. + +Dữ liệu nhiệt cho thấy khoảng trống bốn mươi ba phút. Khi hình trở lại, Tiến nằm dưới sàn. Kha đứng trước, dao có máu. Cảnh khớp ký ức nhưng không cho thấy đoạn dẫn tới. + +Giọng Kha: “Lê Quốc Tiến. Mày vốn không nên sống lâu đến thế.” Dao hạ. + +Trước khi bản ghi tắt, một giọng máy: + +**STATE CAPTURE COMPLETE** + +Căn phòng lặng đi. Kha nhìn bàn tay hiện tại của mình. “Tao không nhớ.” + +“Anh chưa sống tới đó,” Thủy nói. + +“Nhưng trong bản này, tao đã cầm dao.” + +Tiến đáp: “Trong bản này.” Không tha. Không kết tội hiện tại. + +Duy chỉ dữ liệu nhiệt: giữa hai đoạn, trạng thái Tiến thay đổi hai lần. Có một nguồn thứ ba vào phòng rồi rời, bước chân không rõ. + +“Chúng ta chưa biết vì sao dao được dùng,” Thủy nói. “Không được lấp bằng điều thuận cho Tiến hay Kha.” + +Vân nhìn khoảng trống. “Có dấu Null.” “Bà làm?” + +“Có thể một phiên bản của tôi. Hiện tại tôi không biết.” + +Không để nhân vật tương lai truyền toàn bộ trí nhớ cho hiện tại. Kha nói: “Nếu Null xóa đoạn, ký ức Tiến chỉ giữ phần tao giết.” + +“Đúng.” + +“Có chủ ý.” + +“Có thể.” + +Tiến hỏi: “Ai hưởng lợi?” Vân không chọn một đáp án. “Có thể Tiến tương lai muốn bản thân năm 2028 không mang một giao thức. Có thể HANOI-07 không lưu được. Cũng có thể ai đó dựng.” + +Ba giả thuyết. Chưa chọn. Dữ liệu cuối dải có tọa độ Hồ Tây và mốc: + +**29/09/2028 – 12:11** + +Duy đối chiếu áp lực. “Liên quan mạch nước trước cửa sổ.” Hệ thống chưa hề giao một “nhiệm vụ”; tọa độ nằm trong vật liệu và có thể chỉ là điểm thiết bị của phương án ấy từng dùng. Muốn biết còn giá trị hay không, họ phải đo lại thực địa. + +Thủy nói: “Nếu bản ghi là mô hình, tọa độ có thể thay.” “Vậy kiểm.” + +Tiến nhìn thẳng Kha. “Anh có giết tôi năm 2031?” Kha đáp sau một lúc: “Trong ít nhất một phương án.” “Anh có thể trở thành người đó.” + +“Ừ.” + +“Còn tôi có thể trở thành người yêu cầu.” + +“Ừ.” + +Hai người cùng không thích câu trả lời. Bản ghi đầu không giải bí mật. Nó phá một sự chắc chắn: ký ức của Tiến không đầy đủ. Từ đây, “tôi nhớ” không còn là bằng chứng cuối cùng. Hắn mất một công cụ. + +Cũng mất một xiềng. Sau buổi xem, Tiến yêu cầu tách hai loại hồ sơ: dữ liệu kỹ thuật chung và phản ứng cơ thể của mình. Đạt đồng ý, Kha phản đối vì mọi dấu thần kinh có thể ảnh hưởng cách họ chuẩn bị ngày 29. + +Thủy đặt câu hỏi khác: “Nếu cơ thể Tiến là một phần hệ thống, cộng đồng có quyền biết tới đâu?” Không ai trả lời ngay. + +Cuối cùng, họ thống nhất công khai kết luận và phương pháp, nhưng ảnh mô thần kinh, nhịp đau và đoạn Tiến mất kiểm soát chỉ được mở khi chính hắn đồng ý hoặc khi một bác sĩ xác nhận nguy cơ trực tiếp. Đó là tiền lệ đầu tiên cho một thành phố đang thiếu luật: dữ liệu có thể liên quan mọi người mà vẫn không biến cơ thể một người thành tài sản chung. + +Kha ở lại phòng lâu hơn. Hắn đứng trước khung hình dao hạ, không phát lại âm thanh. + +“Anh đang tìm xem mình có chần chừ không?” Tiến hỏi. + +“Đang tìm xem tao có đường lui không.” + +“Có?” + +“Không thấy.” + +“Vì đoạn bị cắt.” + +Kha giữ mắt ở khoảng đen bốn mươi ba phút. “Hoặc vì phiên bản đó đã không để lại.” Tiến không tìm lời an ủi. Hắn tắt màn hình. Cả hai rời phòng bằng hai cửa khác nhau, để lại bản ghi trong hộp niêm phong có ba khóa. + +Chương 52: Em Gái Phúc + +**31/07/2028** + +Tin về em gái Phúc tới từ mạng đổi thuốc của Linh. Một cô gái mười chín tuổi, sẹo bỏng ở vai, tên Phương, đang đi cùng nhóm y tế của Vòng Tròn Vỡ gần Hà Đông. Không ảnh rõ. Linh chỉ đánh dấu **khả năng cao**, kèm hai chi tiết đối chiếu: vết bỏng cũ ở vai trái và thói quen viết tên thuốc bằng chữ in hoa. Hai dấu khớp chỉ đủ nâng xác suất; chẳng ai dám biến chúng thành một lời hứa. + +Phúc không lao thẳng ra cổng. Anh trải bản đồ Hà Đông lên thùng gỗ, đánh dấu trường học, hai tuyến rút và điểm có thể đổi xe rồi mới tới phòng trực. Cánh tay còn băng khiến việc tự lái trong tình trạng đường hỏng là một lựa chọn tệ; chính Phúc nói điều đó trước khi Nam kịp nhắc. + +“Tôi đi tìm Phương. Cần người lái và một người xác minh nguồn. Nếu tin sai, quay ở điểm này.” Anh chạm vào một ngã ba trên bản đồ. + +Nam hỏi: “Em đi?” + +“Không. Em giữ cổng. Nếu cả người tìm lẫn người giữ cùng chạy theo một tin chưa xác minh thì đây là bẫy quá rẻ.” + +Tiến tới, không ra lệnh ở lại. “Tôi đi cùng. Bình lái. Thủy xác minh nguồn từ đây và giữ liên lạc theo mốc.” + +Phúc nhìn hắn. “Anh cho?” + +“Tôi không có quyền cho hay cấm anh đi. Nhưng xe, nước dự phòng và tuyến là tài nguyên chung; dùng chúng thì phải để người khác biết anh đang cược gì.” + +Cách nói mới, chưa tự nhiên, nhưng ít nhất không biến nỗi sợ mất người thân thành quyền lấy bất cứ thứ gì rồi đi. Họ tìm thấy khu y tế tạm trong một trường học. Vòng Tròn Vỡ đã rút đội chiến đấu, để lại người bệnh và ba người chăm. + +Phương đang băng chân cho một đứa trẻ. Phúc gọi tên. Cô quay. Không chạy tới. Không khóc. “Anh còn sống.” + +“Ừ.” + +“Anh bỏ em.” + +“Không.” + +“Cửa đóng.” + +“Anh quay lại.” + +“Em không thấy.” + +Hai người mang hai sự thật khác nhau về cùng một phút Đại Hà. Phúc muốn nói người đẩy anh, khói, cửa, người chết. Nhưng mọi lý do đều đến sau trải nghiệm của Phương: cô đã đứng phía trong và không thấy anh quay lại. + +“Vòng Tròn Vỡ cứu em,” cô nói. + +“Chúng dùng em.” + +“Ngọc Trục không dùng người?” + +Phúc không đáp. Tiến đứng ngoài cuộc nói chuyện tới khi Phương tự nhìn hắn. “Anh biết Đại Hà?” + +“Biết sẽ có thảm họa.” + +“Và để người ta vào.” + +“Không cảnh báo đủ.” + +Tiến không núp sau lý do “sẽ chẳng ai tin”. Phương chỉ hỏi: “Bao nhiêu người chết?” + +“Không biết.” + +“Anh vẫn sống.” + +“Ừ.” + +Câu đó không làm hắn có lỗi vì sống. Nhưng cũng không xóa chênh lệch. Phương không đồng ý về Ngọc Trục ngay. Cô cho họ ở lại một ngày để xem nhóm y tế làm việc. Thủy phỏng vấn từng người về cách Vòng Tròn Vỡ cứu Phương, không chỉ nghe lời anh em. + +Quân đã kéo cô khỏi tầng dịch vụ sau khi đội Tiến rời. Không vì biết cô là ai. Người của hắn mất hai người khi quay lại cứu người mắc kẹt. Điều đó cho Vòng Tròn Vỡ một phần chính nghĩa thật. + +Buổi tối, Phương đưa sơ đồ Hồ Tây. Họ dự định cắt một tuyến nước trước ngày Đồng Bộ vì tin nước nuôi Khóa Trung Tâm. Tiến trải dữ liệu dải nhớ. “Nếu cắt hoàn toàn, tải có thể dồn.” + +“Dữ liệu tương lai của anh?” + +“Không. Áp lực đo hiện tại và một tọa độ chưa xác minh.” + +“Vậy đo. Nếu số của anh đúng, em mang chính bảng đó về cho Quân. Nếu sai, anh cũng phải nhìn.” + +Phương không cần chọn phe trước khi chọn cách kiểm một mệnh đề. Phương đồng ý tới Ngọc Trục bảy ngày, không ba, với điều kiện: + +- ở Vành Ngoài; +- không giao thông tin bệnh nhân; +- được rời bất cứ lúc nào; +- Phúc không theo cô mọi nơi; +- xem dữ liệu nước cùng người của Vòng Tròn Vỡ. + +Phúc phản đối điều thứ tư rồi tự dừng. + +“Được.” + +Ngày đầu, hai anh em gần như không nói. Ngày thứ hai, Phương thấy bộ nẹp tay Phúc và hỏi ai làm. Ngày thứ ba, Phúc kể mỗi ngày đã tìm cô ở đâu. Không xin cô về. Chỉ đưa bản đồ. + +“Có lúc nào anh dừng?” cô hỏi. + +“Có.” + +“Vì nghĩ em chết?” + +“Ừ.” + +“Rồi?” + +“Không có xác.” + +Phương nhìn anh. “Không có xác không nghĩa còn sống.” “Biết.” + +“Vẫn tìm?” + +“Ừ.” + +Lần đầu cô ngồi gần hơn. Không hòa ngay. + +Một mối quan hệ bị Đại Hà xé không thể khâu trong một chương bằng một cái ôm. Ở cuối tuần, Phương vẫn không gia nhập Ngọc Trục. Cô đề nghị kéo dài thời gian thử thêm hai tuần để hỗ trợ Linh, kiểm tra số liệu nước và tiếp tục gửi bản sao cho Quân. Cô không nhận chức, không mang biểu tượng và chưa gọi đó là một mạng y tế trung lập. + +Đêm thứ sáu ở Vành Ngoài, một đường nước tạm bị vỡ. Phúc nghe tiếng người gọi cứu và định lao tới bằng bàn tay còn bỏng; Phương chặn anh, đưa cho kìm rồi bắt đứng đúng vị trí cô chỉ. Hai người sửa dưới ánh đèn pin, không nói chuyện Đại Hà. Khi nước chảy lại, Phương rửa bùn trên tay anh. + +“Anh luôn nghĩ chạy tới là quay lại,” cô nói. + +“Còn em nghĩ cửa đóng là anh bỏ.” + +“Vì em đứng phía trong.” + +“Anh đứng phía ngoài.” + +Hai câu không hòa được ký ức. Nhưng lần đầu, họ nhìn thấy vị trí của người kia thay vì chỉ bảo vệ vị trí mình. + +Sáng hôm sau, một bé gái hỏi Phương có ở lại với anh trai không. Cô đáp: “Chị ở lại với số thuốc này thêm hai tuần.” Rồi tự xách túi sang khu y tế. Phúc không cầm giúp cho tới khi cô đưa một đầu dây. Hành động nhỏ ấy quan trọng hơn một cái ôm: Phương không được cứu về, và Phúc không được nhận lại em như đồ thất lạc. Họ bắt đầu học cách đi cạnh nhau. + +Phương đeo túi y tế rồi bước qua cổng trước. Phúc đứng lại đúng khoảng cách cô đã yêu cầu. + +Chương 53: Người Quan Sát Cuối Cùng + +**04–07/08/2028** + +Việc đo mạch nước Hồ Tây bắt đầu từ ngày thứ tư Phương ở Ngọc Trục và kéo dài song song với lúc Duy hồi phục. Suốt bốn ngày, mọi phép đo quan trọng đều có ít nhất một kênh đối chứng. Ông Hòa và Đức, người thợ lạnh đã theo nhóm Hạnh tới Vành Ngoài, lắp ba bộ áp lực độc lập. Duy hiệu chỉnh nhưng không tự giữ dữ liệu. Thủy ghi giờ và điều kiện. Đạt kiểm các điểm bị mất log. Phương mời hai người của Vòng Tròn Vỡ tới đo cùng. + +Kết quả làm cả hai phía khó chịu. Nước không “nuôi” Khóa Trung Tâm như một nguồn năng lượng. Nó làm chậm dao động nhiệt và cơ học trong nền. Cắt hoàn toàn khiến tải nhiệt dồn nhanh hơn. Giữ nguyên cũng nguy hiểm vì mực hồ rút làm áp lực lệch. + +Thứ nằm dưới họ cần được điều tiết như một hệ giảm chấn — không phải “con rồng dưới đất”, nhưng cũng chẳng đơn giản là một đường ống. Duy tìm trong sổ rơ-le một cái tên: Trần Văn Tĩnh, người từng ký các biên bản Observer. Không ai “mang ông tới” như lời giải. Tiến, Thủy và Vân phải tới một trạm kiểm soát lũ cũ nơi ông đang sống cùng mười hai người. + +Tĩnh hơn bảy mươi, mắt phải mờ, không muốn đi. + +“Các cậu đã có số đo,” ông nói. “Cần tôi làm gì?” + +“Giải thích Central Observer,” Thủy đáp. + +“Vì Hậu Ký đặt tên?” + +“Vì chúng tôi sắp vào nơi nó dùng tên đó.” + +Tĩnh đồng ý nói tại trạm, không theo ngay. Ông nghe mô tả rồi lắc đầu. “Không có chức danh Central Observer trong dự án ban đầu.” + +Kha tham gia qua radio. “Kho của tôi có.” + +“Hậu Ký thích biến trạng thái thành danh từ.” + +“Vậy là gì?” + +“Khi các nguồn không thống nhất, hệ thống cần một xác nhận vật lý tại chỗ. Người làm việc ấy tạm ở trạng thái Observer.” + +“Đạt?” + +“Phù hợp vì không mang cùng bản dự báo.” + +“Còn ông?” + +“Từng là người cuối ký xác nhận ở nhiều nút. Không có nghĩa tôi sở hữu chức danh.” + +Thủy đưa ảnh bóng thứ tư. Tĩnh chưa kết luận. Ông hỏi nguồn sáng, góc chụp, siêu dữ liệu và cách ảnh được tạo trước. Khi biết ảnh có thể là mô hình tái dựng, ông nói: + +“Dấu tổng hợp.” + +“Người chết?” Tiến hỏi. + +“Không. Hình học của nhiều hồ sơ Observer chồng lên. Nhưng phải kiểm.” + +Tĩnh đặt ba bản in lên bàn. Ông bắt Duy dựng lại góc sáng, Thủy đối chiếu siêu dữ liệu và Đạt kiểm thời điểm từng nguồn. Chỉ khi các sai số cùng hướng về một kết quả, ông mới viết ở mép giấy: **DẤU TỔNG HỢP — CHƯA KHÓA.** + +Sau đó ông mở lược đồ cũ. HANOI-07 ban đầu không dự báo tương lai; nó lưu trạng thái thành phố khi hệ thống thông thường thất bại. Khi dữ liệu từ các phương án bắt đầu phản hồi qua chu kỳ, người vận hành mới dùng kho trạng thái ấy để hỏi. + +“Càng hỏi, càng dùng,” ông nói. “Càng dùng, hiện tại càng đổi. Dữ liệu mới lại chồng vào.” + +“Hậu Ký,” Thủy nói. + +“Một hậu quả, không phải mục tiêu ban đầu.” + +Kha hỏi: “Giữ nhiều phương án thì sao?” “Hệ thống không thể đưa dự báo ổn định.” + +“Thành phố mất lợi thế.” + +“Đúng.” + +“Null?” + +“Có thể mất cả dữ liệu cần vận hành.” + +“Converge?” + +“Một phương án thành chuẩn, nhưng ai đặt câu hỏi có quyền rất lớn.” + +“Preserve?” + +“Giữ vòng phản hồi.” + +Không lựa chọn vô tội. Tiến hỏi: “Ông chọn gì?” Tĩnh nhìn hắn. “Tôi đã chọn đủ cho người khác. Việc của tôi là nói điều tôi biết và điều tôi không.” + +Ông không trao đáp án đạo đức. Điều hữu ích nhất ông cho là một tập lược đồ dữ liệu cũ có trường ghi chú tự do. Các trạng thái bắt buộc của hệ thống không có mục **không biết**, nhưng người vận hành từng lách bằng ghi chú. + +Chi tiết nhỏ ấy sẽ quan trọng hơn mọi danh xưng. Trước khi họ rời, Tĩnh nói với Đạt qua radio: “Nếu tới lúc hệ thống bắt anh giải quyết mâu thuẫn, hãy ghi mâu thuẫn.” Không chọn. Ghi. + +Ngày 29 tháng 9 chưa tới, nhưng nguyên tắc Người Quan Sát đã rõ: + +Không có quyền biến điều mình thấy thành mệnh lệnh chỉ vì người khác không thấy toàn bộ. Trước khi họ rời trạm, Tĩnh đặt ba nhiệt kế lên cùng một bàn kim loại. Một cái chỉ 44,8 độ, một cái 46,1, cái cũ nhất dừng ở 45,4. + +“Cái nào đúng?” ông hỏi. + +Duy kiểm hiệu chuẩn. “Không biết ngay.” + +“Vậy nếu biểu mẫu bắt chọn một?” + +“Ghi cả ba.” Đạt đáp. + +Tĩnh gật. “Observer không phải người nhìn giỏi nhất. Là người chịu được việc hai dữ kiện trái nhau cùng tồn tại cho tới khi tìm được nguyên nhân.” Ông kể lần cuối mình ký thay một đội: trạm ngập nhưng cấp trên cần báo cáo an toàn để mở tuyến. Không ai chết, nên quyết định ấy được ghi là thành công. Tĩnh vẫn nhớ người công nhân đã đứng nước tới ngực suốt bốn giờ để giữ máy bơm. + +“Báo cáo nói hệ thống hoạt động,” ông nói. “Không ghi ai biến nó thành hoạt động.” + +Thủy ghi thêm nguồn, giờ và sai số cạnh câu nói của Tĩnh. Mực khô chậm trong căn phòng nóng. + +Chương 54: Hoàng Thành Không Ngủ + +**10/08/2028 – 02:17** + +Đêm 10 tháng 8, cảm biến quanh Hồ Tây, Láng và Ngọc Trục cùng ghi một dao động kéo dài bốn phút. 02 giờ 17. Không đủ mạnh để người ngủ trên mặt đất tỉnh. Nhưng các kim áp lực cùng đi qua một chu kỳ giống lần cửa ngoài mở. + +Duy gọi đó là thử đồng bộ tự nhiên. Vân nói hệ thống đang đối chiếu các nguồn sau khi Đạt xuất hiện. Kha nói nguyên nhân ít quan trọng hơn việc thời điểm đã đến sớm. Tĩnh nói cả ba đang biến giả thuyết thành câu khẳng định. + +Tiến tập hợp Hội đồng Ngọc Trục mở rộng. Không chỉ người lõi: Tuấn, Hạnh, Đức, chị Mai và đại diện Vành Ngoài cùng nghe. Lần đầu, bí mật được nói bằng ngôn ngữ không đòi người nghe hiểu mọi thuật ngữ: + +- dưới Hà Nội có mạng hạ tầng nhiều lớp; +- các điểm Láng, Hồ Tây và Ngọc Trục liên quan; +- ngày 29/09 là cửa sổ nguy hiểm; +- các phe muốn giữ, phá hoặc kiểm soát; +- chưa ai biết lựa chọn nào an toàn tuyệt đối. + +Tuấn hỏi: “Vì sao giờ mới nói?” Tiến bỏ qua câu “để bảo vệ” đã lên tới miệng. “Vì tôi nghĩ càng ít người biết, tôi càng dễ giữ.” + +“Giữ cái gì?” + +“Cả bí mật lẫn quyền quyết.” + +Một câu khó. + +“Giờ?” + +“Không còn được.” + +Hội đồng nước được mở rộng thành Hội đồng Ngọc Trục tạm thời. Tiến giữ quyền an ninh khi bị tấn công trực tiếp, không giữ toàn bộ phân phối và thông tin. Linh giữ y tế. Ông Hòa và Đức phụ trách kỹ thuật. Ba đại diện Vành Ngoài giữ định mức. Thủy quản hồ sơ công khai. Bình phụ trách vận chuyển với quyền từ chối tuyến. Nam phụ trách liên lạc ca đêm. + +Đó chưa phải dân chủ hoàn chỉnh; nó chỉ tạo thêm nhiều điểm hỏng để một người không thể làm hỏng tất cả. Đêm sau, nhóm ba nguồn trở lại cửa ngoài. Tiến, Thủy, Đạt. + +Khánh An giữ lối. Vân giữ Null. Duy vận hành. Tĩnh chỉ theo dõi từ trạm, không xuống. Cột quan sát hiện: + +**SYNCHRONIZATION WINDOW: 57 DAYS** + +Bên dưới: + +**CONVERGE** + +**PRESERVE** + +**NULL** + +Không ai thử diễn giải ba dòng ấy ngay tại chỗ. Kha qua đường dây nói: “Không chọn.” Tiến đáp: “Chưa ai định chọn.” Họ chụp, đo và rút. Họ không để một menu ba dòng bị biến thành ba số phận duy nhất. + +Khi cửa đóng, một tiếng chuông vật lý vang từ sâu hơn. Cảm biến ghi được, có hướng từ cụm trung tâm. Trên mặt đất, các đèn giao thông chết quanh Ba Đình cùng sáng đỏ bốn giây. Camera cũ bật. Một số màn hình còn điện hiện vòng tròn đỏ có mười hai tia. + +Hiện tượng không xảy ra trên toàn thành phố cùng lúc, nhưng đủ người nhìn thấy để lời đồn chạy nhanh hơn mọi thông báo chính thức. Sáng, hơn ba trăm người tập trung quanh các tuyến vào trung tâm. + +Một số cầu cứu. Một số muốn phá. + +Một số tin có thành phố trú ẩn dưới đất. Một số chỉ muốn nhìn thứ đã làm đèn sáng. + +Nhóm Tài — những người còn giữ con dấu và hồ sơ của bộ máy cũ — gửi yêu cầu phong tỏa khu vực. Hổ muốn thu phí đường. Kha đưa xe chặn ba tuyến. Vòng Tròn Vỡ phát thông điệp phải phá trước ngày 29. Cuộc chiến không còn nằm trong hầm. Nó trở thành cuộc chiến về ai được nói Hoàng Thành là gì. + +Thủy lập bản tin đầu tiên: + +“Chưa có bằng chứng về hầm trú cho dân số lớn. Không tập trung tại khu trung tâm. Dao động có thật. Ý nghĩa chưa xác định.” + +Bản tin ấy không hấp dẫn bằng một lời hứa cứu rỗi, nhưng từng con số đều có nguồn để cô bảo vệ. Kha gửi cho Tiến một câu: + +**Từ giờ, bí mật không còn là tài sản. Nó là đám đông.** + +Tiến kiểm tra hình từ camera đường phố. Hắn hiểu. Một hệ thống kỹ thuật có thể được khóa bằng thép. + +Một niềm tin đã lan thì không. Buổi chiều, Thủy đi một vòng ngoài Ba Đình để nghe người ta gọi Hoàng Thành bằng những tên gì. Một bà cụ gọi là hầm vua. Hai thanh niên tin đó là kho lạnh quân đội. Một người cha nói chỉ cần bên dưới mát hơn thì ông sẽ phá cổng để đưa con vào. + +Thủy không cười những lời đồn. Mỗi lời có một nhu cầu thật: nơi trú, nước, quyền được không bị bỏ lại. Bản tin tối của cô không chỉ phủ nhận. Nó công bố nhiệt trong hầm, diện tích thực tế, số người tối đa có thể làm việc an toàn và lý do tập trung đông sẽ làm tuyến thông gió sập. Hạnh đọc lại bản tin cho những người không có radio. + +Một số người vẫn không tin. Nhưng đám đông ngày sau nhỏ hơn, và vài gia đình chuyển tới điểm trú do hội đồng chỉ thay vì ngủ trước cổng Hoàng Thành. Bí mật đã biến thành đám đông. Từ đây, muốn giữ thành phố, họ không thể chỉ khóa cửa; phải đưa đủ sự thật để người ngoài tự quyết mà không bị một lời hứa giả kéo đi. + +ARC 7: THÀNH PHỐ CÓ CHỦ + +Chương 55: Hội Nghị Nước + +**11/08/2028** + +Cuộc họp đầu tiên về nước được tổ chức trong tầng hầm một bãi đỗ xe, nơi lớp bê tông còn giữ được nhiệt độ thấp hơn mặt đường tám độ. Mười bốn nhóm tới. Tên gọi “chính quyền” không xuất hiện trên giấy mời, nhưng mỗi đại diện đều mang theo ít nhất một người có vũ khí và một người nắm con số thật của kho mình. + +Tiến đi cùng Bình và Thủy. Linh ở lại Ngọc Trục. + +“Người biết chia nước nên đứng cạnh nước,” cô nói, “không đứng cạnh những người thích nói về nó.” + +Kha tới sớm, chọn chỗ gần lối lên. Hổ — người giữ nhiều tuyến đường phía Tây — ngồi đối diện hắn. Lâm đại diện kho thuốc; trước Hồng Nhật ông quản chuỗi lạnh của một nhà phân phối dược và từng mất cả lô insulin khi đám đông phá niêm phong phòng lạnh. Từ đó, ông không xuất một thùng nào nếu không có nhật ký nhiệt, danh sách nơi nhận và người chịu trách nhiệm. Hương đại diện mạng chung cư tự quản. Một bác sĩ bệnh viện dã chiến, hai nhóm La Phù, một trạm điện và ba khu dân cư nhỏ đủ người để biến mọi câu thành một cuộc mặc cả. + +Duy trải bản đồ các nguồn còn hoạt động. Thủy yêu cầu mỗi con số phải ghi nguồn và thời điểm đo, không chỉ tên người khai. Ngọc Trục có khả năng lọc, nhưng nước thô đang đổi. + +Kha có ba xe bồn và tuyến nhập. Bệnh viện có bể ngầm nhưng không bơm ổn. Hai giếng khu dân cư có nguy cơ nhiễm. Hồ Tây có mạch nước, chưa dùng uống. Tổng lượng thấp hơn nhu cầu. + +Hương đặt lên bàn một khay đất nông, trong đó sáu cây rau dền đang sống dưới lớp lưới phản nhiệt. “Nếu chỉ tính nước uống, chúng ta sống thêm vài tuần rồi lại ngồi đây vì đói. Khu tôi cần một phần nước xám đã xử lý cho luống giống. Không lấy từ định mức y tế.” + +Bác sĩ phản đối nguy cơ nhiễm; Duy đề nghị tách đường màu, bể lắng và kiểm vi sinh. Cuộc họp về nước vì thế phải tính cả thứ chưa thể ăn ngay: hạt giống, nấm hầm, khoai chịu nóng và những tuyến lương từ phía nam. Kha nói: “Cần một đầu mối.” + +Hương hỏi: “Anh?” + +“Không nhất thiết.” + +“Nhưng xe của anh.” + +Kha chỉ Hổ. “Đường của hắn.” Rồi chỉ Lâm. “Thuốc của ông ta.” + +Cuối cùng nhìn Tiến. “Lọc của Ngọc Trục.” Một hệ thống trung lập đang được dựng từ tài sản của những người không trung lập. + +Kha đề xuất gom phần lớn nguồn về La Phù, lập đội vận chuyển chung và phân theo định mức y tế–dân số–lao động. Nghe hiệu quả. Tiến hỏi: “Kho ở đâu?” + +“La Phù.” + +“Ai giữ?” + +“Đội chung.” + +“Xe?” + +“Của tao.” + +“Đường?” + +“Hổ.” + +“Lượng nguồn?” + +“Ngọc Trục và các khu báo.” + +“Vậy một đầu mối có bốn cổ chai đều do người ở bàn này giữ.” + +Kha nói: “Còn phương án của mày?” + +“Không gom toàn bộ. Mỗi khu giữ dự phòng ba ngày. Chỉ đưa phần vượt vào mạng trao đổi.” + +“Hiệu suất thấp.” + +“Khó bị chiếm một lần.” + +Bác sĩ bệnh viện phản đối: “Khu ít bệnh giữ nước trong khi bệnh viện thiếu thì sao?” + +“Định mức y tế bắt buộc.” + +“Ai cưỡng chế?” + +Không câu trả lời đẹp. Kha nghiêng người. “Đó là lý do cần đầu mối.” + +Tuấn, đại diện Vành Ngoài, lên tiếng: “Đầu mối không được có quân riêng.” Kha nhìn hắn. “Ai bảo vệ xe?” + +“Người luân phiên từ nhiều khu.” + +“Ngày đầu bị bán tuyến.” + +“Đổi người ngày sau.” + +Kha cười nhạt. “Dân chủ uống nhiều nước.” Tuấn đáp: “Độc tài uống máu.” + +Vài tiếng cười tắt nhanh. Một câu nói hay vẫn không làm bể nước đầy thêm. Cuộc họp kéo dài bốn giờ. Mỗi điều khoản được thử bằng một tình huống: + +- một khu giấu lượng thật; +- bệnh viện nhận gấp đôi; +- xe bị chặn; +- nguồn nhiễm; +- người vận chuyển bỏ trốn; +- Kha hoặc Tiến chết. + +Đến khi mọi người mệt đủ để bớt diễn, họ thống nhất sáu nguyên tắc: + +1. Mỗi khu giữ dự phòng tối thiểu ba ngày. +2. Lượng nguồn phải báo trên mạng radio chung, có người đo chéo. +3. Bệnh viện, trẻ nhỏ và ca mất nước nặng được ưu tiên. +4. Nước xám dành cho trồng trọt phải đi đường riêng, có kiểm tra và không được rút từ định mức uống tối thiểu. +5. Không nhóm nào được chặn xe nước đã đăng tuyến. +6. Vi phạm bị cắt trao đổi theo biểu quyết, không theo lệnh một người. + +Không người nào có quyền điều phối toàn bộ. Thay vào đó là một cái bàn, một quy trình và chữ ký có thể đối chiếu. Kha ký. Tiến ký. + +Hổ ký cuối, nét bút mạnh như rạch. Ngay khi Thủy chụp trang chữ ký, một tiếng nổ nhỏ vang ở lối lên. Khói trắng tràn xuống. + +Bình kéo Tiến sau cột. Ba vệ sĩ đưa tay lên súng, nhưng người đại diện cạnh họ đồng loạt quát giữ nòng xuống; trước cuộc họp, tất cả đã thống nhất không được chĩa vũ khí vào bàn nếu chưa xác định được hướng tấn công. Một người trẻ ở nhóm La Phù vẫn giật cò khi bị ai đó va từ phía sau. Viên đạn trúng trần. + +Kha không lao ra cửa dù đứng gần nhất. Hắn hạ người, hít ngắn rồi nói: “Khói từ bình khí. Mục tiêu là che mắt, không phải ép nổ.” + +Thủy không đuổi theo bóng người. Cô úp máy ảnh vào áo, kiểm thẻ nhớ rồi mới lùi về cột. Khói che khoảng ba mươi giây. Khi tan, tờ thỏa thuận gốc biến mất. Không ai bị thương nặng. + +Không ai thấy người lấy. Hổ quát: “Vòng Tròn Vỡ.” + +Phương, đi cùng mạng y tế trung lập, lắc đầu. “Nếu là Quân, họ phá cuộc họp hoặc lấy sơ đồ nút. Tờ chữ ký không giúp phá khóa.” Thủy nhìn chỗ giấy từng nằm. “Nó giúp biết ai đang tạo cấu trúc quyền lực mới.” + +Kha hỏi: “Cô có ảnh?” + +“Có.” + +“Đưa bản.” + +“Cho tất cả.” + +Hắn cau mày. Tiến hiểu. “Một bản gốc đáng cướp vì nó độc nhất. Mười bốn bản thì không.” + +Thủy chép và phát qua radio mã hóa. Mỗi đại diện giữ một bản. Không ai sở hữu văn bản duy nhất. Kẻ trộm lấy được chữ ký, nhưng không xóa được thỏa thuận. Trên đường về, Bình hỏi: “Ai cần danh sách này?” + +“Người muốn biết thành phố sắp có những chủ nào,” Thủy nói. + +“Hoặc ai phải biến mất,” Tiến bổ sung. + +Ở một tầng hầm hành chính cũ, tờ giấy được đặt trước một con dấu của cơ quan đã không còn hoạt động sau Hồng Nhật. Người giữ bộ máy cũ đã nhìn thấy một trật tự mới hình thành. Và họ chưa đồng ý nhường tên “hợp pháp” cho những người đang làm nước chảy. + +Chương 56: Giá Của Thuốc + +**12–17/08/2028** + +Dịch bắt đầu bằng ba đứa trẻ tiêu chảy. Ngày thứ hai có mười một ca. Ngày thứ ba, Vành Ngoài có ba mươi bảy người sốt, nôn và mất nước. Không có virus bí ẩn hay một căn bệnh “tận thế” mới nào. Chỉ có nước bẩn, thực phẩm bảo quản kém và những cơ thể đã kiệt quệ nhiều tuần. Nhưng trong thành phố thiếu nước, tiêu chảy có thể giết nhanh hơn đạn. + +Linh khóa khu bệnh. Tuấn phản đối: “Người nhà phải chăm.” + +“Không. Chọn bốn người khỏe, tôi hướng dẫn. Còn lại đứng ngoài.” + +“Cô không đủ người.” + +“Vì vậy càng không để hai mươi người đi vào rồi thành bốn mươi bệnh nhân.” + +Chị Mai, y tá tư nhân từ nhóm tị nạn, cùng Linh phân mức. Phương ở lại hỗ trợ nhưng không giao quyền quyết cho bất kỳ phe nào. Kho có đủ dịch truyền cho mười hai ca nặng. + +“Có ba mươi bảy,” Tuấn nói. + +Linh đáp: “Mười hai cần truyền ngay. Những người còn uống được dùng dung dịch đường muối.” + +“Trẻ em?” + +“Không tự động lấy trước người đang sốc.” + +“Cô để trẻ chết?” + +Linh siết quai khẩu trang rồi đáp: “Tôi không có quyền quyết ai đáng sống hơn. Tôi đang chọn cách dùng mười hai chai dịch để giảm số người chết nhiều nhất theo dấu hiệu hiện có. Nếu anh thấy tiêu chí nào sai, chỉ ra ngay.” Tiến đứng bên, không can thiệp bằng tiêu chí “người hữu ích”. Kiếp trước hắn từng làm vậy. Lần này hắn hỏi: “Cần gì?” + +“Điện giải, dịch, men, kháng sinh theo chỉ định. Và nước sạch.” + +Kho thuốc của Lâm có. Ông không đòi giá gấp đôi chỉ vì thấy Ngọc Trục yếu; máy lạnh của kho đang ăn nhiên liệu nhanh hơn dự kiến, hai thùng dịch đã sát ngưỡng nhiệt và một chuyến trước không trả lại vỏ cách nhiệt. + +“Danh sách bệnh nhân, nhiệt độ xe và người ký nhận,” Lâm nói qua radio. “Thiếu một trong ba, tôi không mở kho.” + +Linh gửi bảng phân mức, chấp nhận kiểm đếm khi nhận nhưng từ chối giao tên đầy đủ bệnh nhân. Hai bên thống nhất dùng mã ca, nhiệt kế niêm phong và trả vỏ trong hai mươi bốn giờ. Phần nước trao đổi vẫn cao hơn hiệp định vì chi phí chuỗi lạnh, nhưng được ghi thành nhiên liệu và hao hụt cụ thể thay vì một mức giá tùy ý. + +Kha có thể chở. Giá của hắn: quyền điều phối tuyến thuốc một tháng. Tiến từ chối điều kiện qua radio. + +Linh ném khay xuống bàn. “Anh từ chối bằng gì?” + +“Đường khác.” + +“Bao lâu?” + +“Tám giờ.” + +“Người sốc không có tám giờ.” + +“Nhận một tháng, hắn giữ cổ thuốc.” + +“Sau khi bệnh nhân sống, anh làm chính trị.” + +Tiến không đáp ngay. Có những lựa chọn không cho họ đủ thời gian chờ một phương án sạch. + +Hắn gọi Kha. + +“Mười ngày.” + +“Một tháng.” + +“Bảy.” + +“Hai mươi.” + +“Mười.” + +“Mười lăm.” + +“Được.” + +Kha cử hai xe. Bình đi cùng, có quyền quay lại nếu thùng thuốc vượt nhiệt. Đoàn bị Hổ chặn giữa tuyến. Hổ nói bản gốc thỏa thuận đã mất, chữ ký có thể bị giả. Bình phát mười bốn bản sao qua radio, đọc đúng giờ chụp và người chứng kiến. + +Hổ không tranh pháp lý nữa. “Một thùng.” + +“Thuốc bệnh viện.” + +“Đường của tao.” + +Bình nhìn nhiệt kế thùng lạnh. Mỗi phút tranh làm thuốc nóng. + +“Một phần điện giải. Không kháng sinh, không dịch.” + +Hổ cười. “Anh có quyền?” + +“Không đủ. Nhưng tôi có trách nhiệm đưa phần còn lại tới.” + +Bình tự đổi. Khi về, Tiến hỏi: “Vì sao không gọi?” + +“Radio chết ở đoạn đó.” + +“Anh có quyền từ chối tuyến, không quyền đổi hàng.” + +“Vậy thêm hoặc đuổi tôi.” + +Hội đồng họp nhanh. Bình bị yêu cầu ghi đầy đủ, Hổ bị trừ lượng trao đổi ở chuyến sau, và người lái được quyền nhượng tối đa một phần nhỏ để tránh mất toàn bộ nếu có hai nhân chứng. Một quy tắc sinh từ một quyết định không hoàn toàn đúng. + +Trong khu bệnh, Linh chọn mười hai người truyền. Một bé trai không nằm trong số đó. Mẹ cháu quỳ. + +Linh quỳ theo, không đứng cao hơn. “Cháu còn uống được. Tôi giữ dịch cho người không nuốt được.” + +“Nhỡ nặng?” + +“Tôi theo.” + +“Cô chắc?” + +“Không. Tôi chỉ chắc là lúc này cháu còn uống được, mạch chưa tụt và tôi có thể theo sát. Nếu một trong ba thứ đổi, cháu lên mức ưu tiên khác.” + +Bà mẹ khóc, nhưng không cướp. Đứa bé sống. Một người đàn ông được truyền chết vì suy đa cơ quan. + +Quyết định đúng theo dữ liệu không bảo đảm kết quả tốt. Đêm, Linh ngồi ngoài khu bệnh, rửa tay bằng lượng nước nhỏ. Tiến đặt một cốc cạnh. + +“Cô làm đúng.” + +“Đừng nói.” + +“Vì?” + +“Anh không biết. Tôi cũng không biết. Tôi chỉ biết vì sao tôi chọn.” + +Tiến ngồi xuống cách một khoảng. “Ba người chết.” + +“Ba mươi bốn sống không làm ba người nhẹ hơn.” + +“Ừ.” + +Linh nhìn hắn. “Đừng lấy ba mươi bốn người sống để bảo tôi chắc chắn đã đúng. Cũng đừng lấy ba người chết để nói mọi tiêu chí đều vô nghĩa. Ngày mai tôi vẫn phải mở sổ và xem mình đã bỏ sót dấu nào.” Dịch được khống chế sau sáu ngày. + +Kha giữ tuyến thuốc mười lăm ngày. Mỗi xe mang dấu đội hắn. Người dân không nhớ cuộc thương lượng; họ nhìn thấy thuốc tới bằng xe Kha. Quyền lực không chỉ được xây từ thứ một người giữ. Nó được xây từ thứ mọi người nhìn thấy người đó trao đúng lúc. Tiến ghi điều này vào báo cáo hội đồng, không vì ghen với Kha. + +Lâm khóa thùng lạnh. Linh giữ một bản sổ, chị Mai giữ bản còn lại. Không liều thuốc nào rời kho nếu thiếu người nhận và nhiệt độ lúc giao. + +Chương 57: Kẻ Giữ Đường + +**16/08/2028 — ngày thứ năm của đợt dịch** + +Bình rời Ngọc Trục lúc gần sáng mà không xin xe chung. Anh đi chiếc xe máy cũ, mang súng ngắn cá nhân và để lại dưới bảng tuyến một tờ giấy gấp đôi: + +**Tuyến phía nam. Việc riêng. Mốc 1: ga Văn Quán 05:40. Mốc 2: kho Hổ 06:20. Quá 08:00 không có tín hiệu thì coi như bị giữ, không mở tuyến cứu nếu chưa xác minh.** + +Tiến đọc rồi vẫn chửi. Bình không biến mất như một kẻ mất trí; anh chỉ tự ý sử dụng rủi ro mà lẽ ra phải đưa ra hội đồng trước khi đi. Thủy hỏi: “Anh biết việc gì?” Tiến mở ngăn cá nhân Bình. Hắn không lục sâu; trên nắp đã có một tấm ảnh cũ: người phụ nữ, bé gái khoảng sáu tuổi và Bình đứng cách một khoảng như một người chưa biết nên đặt tay ở đâu. + +Tấm ảnh đã xuất hiện từ những ngày đầu Ngọc Trục, nhưng chưa ai hỏi Bình về nó. Bình ly thân trước Hồng Nhật. Sau thảm họa, hai lần anh tìm khu tập thể cũ và trở về tay không. Tin mới từ mạng đường nói một nhóm phụ nữ và trẻ em bị Hổ giữ làm lao động đổi chỗ trú. + +“Anh ấy đi tìm con,” Thủy nói. + +Tiến muốn đuổi theo ngay, nhưng hội đồng đang họp về tuyến nước. Hắn không thể rời căn cứ như trước. Bình có quyền từ chối tuyến. Không có quyền biến mất cùng vũ khí. Hội đồng cử Tiến và Thủy đi, Nam giữ liên lạc, Tuấn thay Tiến ở cổng. + +Khi họ tới kho của Hổ, Bình đã đặt súng xuống đất. Hổ ngồi trên ghế nhựa, danh sách người trong tay. + +“Vợ mày không ở đây,” hắn nói. + +“Con?” + +“Không.” + +“Danh sách.” + +“Không miễn phí.” + +“Muốn gì?” + +“Một tuyến vào trạm lọc Ngọc Trục.” + +“Bình không có quyền mở tuyến lọc.” + +“Vậy để nó ở lại lái xe cho tao.” + +Bình nhìn danh sách, rồi nhìn hai cửa kho trước khi nói: “Tôi ở lại ba ngày đổi lấy bản sao danh sách và giờ chuyển gần nhất. Không mở tuyến, không giao mã kho.” Tiến bước vào. “Không.” + +Bình quay, giận hơn nhẹ nhõm. “Anh theo tôi?” + +“Ừ.” + +“Việc tôi.” + +“Giờ liên quan xe, súng và tuyến chung.” + +Hổ cười. “Đúng kiểu hội đồng.” Tiến không dùng Bình làm món đổi. Hắn đưa một bản đồ tuyến tránh ba điểm sập tới bệnh viện — thông tin có giá nhưng không mở Ngọc Trục. + +Hổ kiểm với người giữ đường. + +“Đổi danh sách và tin cuối về gia đình Bình.” + +“Không tuyến lọc.” + +“Được.” + +Danh sách không có vợ Bình. Có tên con gái: **Bình An**, chín tuổi, chuyển từ một điểm trú gần ga Văn Quán ba tuần trước. Bình cầm giấy, tay run. + +Họ lần theo dấu mũi tên di dân trên tường. Không HANOI-07. Không Hậu Ký. Chỉ ngày, ký hiệu phấn, lời người sống và một chiếc nơ trẻ em buộc ở cột. Điểm cuối là trường tiểu học bỏ hoang. Bình An ở đó. + +Con bé không nhận ra cha ngay. Bình quỳ, nhưng không ôm trước. + +“An.” + +Nó nhìn lâu. “Bố?” Một từ làm người đàn ông từng cãi với súng và đường mất tiếng. + +Mẹ con bé chết vì sốc nhiệt trên đường. Một giáo viên đưa An cùng mười hai trẻ khác tới trường. Bình muốn đưa con về. An hỏi: “Các bạn?” + +Ngọc Trục đang thiếu nước. Hội đồng chỉ cho Bình đi tìm một người, không mười ba trẻ và bốn người lớn. Tiến cân nhắc lượng nước còn lại, sức nóng dưới mái tôn và tình trạng hai đứa trẻ đang sốt. + +“Đi tất.” + +Thủy hỏi: “Anh quyết thay hội đồng?” Tiến dừng. Thói quen cũ. Hắn gọi về bằng radio, trình tình trạng và xin biểu quyết khẩn. Bốn thuận, hai chống, một trắng. Điều kiện: khu mới vào Vành Ngoài, cách ly y tế và định mức tạm. + +Bình không biến nó thành một màn anh hùng cá nhân; quyết định ấy có người khác cùng biết và cùng gánh hậu quả. + +Bình An mất năm ngày mới gọi Bình là bố lần thứ hai. Anh xin nghỉ ba ngày khỏi tuyến. Tiến đồng ý không hỏi. Khi trở lại bản đồ, Bình thêm một ký hiệu mới vào mọi tuyến: nơi có trẻ em. + +Mục tiêu không phải giữ xe đứng yên, mà để trước khi đi qua, mỗi đoàn biết phía trước có chỗ, nước và quyền nhận hay không. Kẻ giữ đường không còn chỉ giữ đường cho hàng. + +Hổ trả chìa khóa xe cho Bình. Trên tấm vé tuyến mới, ô **người bảo lãnh** đã bị gạch bỏ. + +Chương 58: Mùa Dịch Nóng + +**17/08/2028** + +Tháng tám không có mưa. Mây hình thành rồi vỡ trước khi đủ dày. Ban ngày giữ trên năm mươi độ; ban đêm hiếm khi xuống dưới bốn mươi. Người ta gọi quãng ấy là **Mùa Dịch Nóng**: không phải một căn bệnh, mà là thời điểm nhiều hệ thống cùng suy sụp vì nhiệt. + +Ắc quy phồng. Một số thuốc xuống chất lượng nhanh hơn. Bể nước mọc tảo. Dây điện mềm. Người già lú. Trẻ chảy máu mũi. Những đội làm ngoài trời phải dời phần lớn công việc sang trước tám giờ sáng và sau năm giờ chiều; việc nào buộc phải làm giữa trưa đều chia ca ngắn, có người theo dõi nước uống, dấu kiệt sức và thời điểm rút. Không ai còn coi “chịu nóng giỏi” là một kỹ năng đáng khoe. + +Các điểm trú nhỏ trong nội đô rời bê tông, đổ về phía Tây theo tin đồn có nước và một căn cứ tên Ngọc Trục. Mỗi ngày cổng nhận thêm người. Hội đồng đặt ba vùng: + +- cứu cấp; +- tạm trú bảy ngày; +- xét nhập cộng đồng. + +Không phải người nào tới cũng được nhận. Có người bị từ chối rồi tìm được chỗ khác; cũng có người không qua nổi đêm kế tiếp. Thủy công khai số nước, số người và căn cứ của từng quyết định, nhưng mã hóa tên người bỏ phiếu. Minh bạch để người khác kiểm được lý do, không phải để chỉ đúng một cái mặt cho đám đông trút giận. + +Kha vận hành khác. Các điểm của hắn nhận người có kỹ năng, gia đình của họ và người cam kết làm việc. Quy tắc rõ, hàng chạy đều, tranh cãi ít. + +Một người ở Vành Ngoài nói: “Bên Kha không họp cả ngày.” + +Tuấn đáp: “Bên đó một người nói.” + +“Ít nhất biết nghe ai.” + +Tiến đứng cạnh bảng nước và nghe hết, không chen vào. Quy trình chậm có thể giết người; mệnh lệnh nhanh lại có thể hóa thành quyền vĩnh viễn. Hai rủi ro cùng hiện trên một tấm bảng. + +Ngày 17 tháng 8, trạm điện phía Tây cháy vì dầu cách điện quá nóng. Ba khu mất quạt và bơm, hơn hai nghìn người có nguy cơ trong vài giờ. Kha có máy phát. Ngọc Trục có kỹ thuật. Hổ có đường. Lâm có nhiên liệu. Hiệp định nước lần đầu phải hoạt động trong một khủng hoảng không do kẻ thù tạo ra. + +Ông Hòa nhận chỉ huy kỹ thuật nhưng không tự chui vào buồng nóng nhất. Ông chia đội thành hai lớp: Đức và hai thợ trẻ thao tác tại tủ, ông đứng ở vùng mát hơn đọc sơ đồ, kiểm dòng và quyết định khi nào phải rút. Bộ kẹp Tiến chế cho bàn tay ba ngón được dùng để giữ đầu dây trên bàn thử chứ không làm lý do cho ông liều thêm một phần cơ thể. + +“Đọc lại dòng pha hai,” ông nói. + +Đức đáp qua dây thoại: “Một trăm tám mươi chín.” + +“Lệch quá. Không đóng.” + +“Nhưng khu trường đang hết quạt.” + +“Đóng sai thì cả ba khu hết.” + +Đức chửi nhỏ, đo lại rồi phát hiện một đầu cốt đã đổi màu vì nhiệt. Họ mất thêm bốn phút để thay. Bốn phút ấy có người ngất ở sân trường; nhưng cầu dao không nổ khi điện trở lại. + +Bình dẫn xe nhiên liệu theo tuyến đã đánh dấu điểm có trẻ em và người nằm liệt. Anh không cho đoàn dừng phát nước dọc đường; mỗi điểm nhận đã có người trung gian chờ sẵn, nếu mở thùng giữa đám đông thì xe sẽ không tới trạm điện. Kha đưa nhiên liệu trước khi thỏa thuận giá. Tiến ghi điều đó vào sổ thay vì tự động gắn chữ “bẫy”. + +Thủy thấy hắn nhìn đoàn xe. “Chuẩn bị nếu hắn đòi giá sau. Nhưng đừng sửa việc vừa xảy ra cho hợp với người anh ghét.” + +“Biết.” + +“Anh hay nói chữ đó trước khi thật sự biết.” + +Tiến để ý kiến ấy nằm nguyên trên bàn. + +Họ cứu được hai khu. Khu thứ ba mất mười chín người trước khi quạt chạy. Kha đứng tại sân trường, áo đen thấm mồ hôi, trực tiếp chia nước theo hàng. Người dân quay ảnh. Tiến ở trạm điện, mặt phủ dầu và bụi, ít ai thấy. + +Ngày sau, ảnh Kha lan. Không còn chỉ “Kha Đen” của La Phù. Là người đưa điện trở lại. + +Kha gọi Tiến tối đó. + +“Khó chịu?” + +“Không.” + +“Nói dối.” + +“Anh muốn gì?” + +“Cho mày biết tao không làm tất cả vì Hậu Ký.” + +Tiến nhìn bản ghi nhiệt của trạm. “Tôi biết anh muốn thành phố còn sống.” + +Đầu bên kia không có tiếng cười ngay. “Thế là tiến bộ.” + +“Và anh muốn phần thành phố còn sống ấy chạy theo tay anh.” + +“Lại hỏng rồi.” + +“Cũng đúng.” + +Kha bật cười. “Ừ. Cũng đúng.” + +Một nhóm dân tới Ngọc Trục yêu cầu giao điều phối điện cho Kha. Không vì hắn làm sai. Vì hắn làm đúng và nhanh. Hội đồng không bác năng lực của hắn, nhưng cũng không giao vô thời hạn. Họ chốt một ủy quyền khẩn **bảy mươi hai giờ**, có thể gia hạn từng đợt nếu nhật ký tải được công khai và trạm điện cùng một đại diện khu dân cư xác nhận. Tổng thời gian không quá bảy ngày nếu không bỏ phiếu lại từ đầu. + +Kha đọc hết ba dòng giới hạn. “Các người rất thích ngày hết hạn.” + +Tuấn nói: “Vì người có quyền thường không thích.” + +Kha ký. + +Tối đó, Nam nhận nhiệm vụ treo bản ủy quyền cạnh bảng nhiệt. Cậu tìm trong một thùng đồ cứu từ Đại Hà được chiếc súng bấm giá cũ của siêu thị, lau sạch rồi dùng những cuộn nhãn còn lại để đánh giờ kiểm trên các bình nước dự phòng. Một bé trai nhìn những con số đỏ, hỏi một chai nước “giá bao nhiêu”. + +Nam dừng tay, nhìn cái máy từng chỉ dùng để định giá hàng trên kệ. + +“Không bán,” cậu nói. “Đây là giờ phải kiểm lại.” + +Cậu dán nhãn **22:00** lên nắp bình. Tiếng cửa cuốn ngoài sân rung vì gió nóng; vai Nam vẫn cứng lên, nhưng bàn tay không bỏ chiếc súng bấm giá. + +Tờ ủy quyền của Kha ở ngay phía trên, bên cạnh một ô lớn ghi ngày hết hạn. Quyền lực, lần đầu trong tuần, cũng có nhãn phải kiểm lại. + +Chương 59: Nội Gián Không Có Tên + +**18–22/08/2028** + +Ba đoàn xe nước bị chặn trong một tuần. Kẻ phục kích biết giờ xuất phát, tuyến dự phòng và số người hộ tống. Bình đổi đường lần ba, đi vòng thêm mười hai cây số và vẫn thấy chướng ngại được dựng trước. + +“Có người trong,” anh nói khi về. + +Không ai thích giả thuyết đó, nhưng danh sách người biết lịch chỉ có chín: Tiến, Bình, Nam, Tuấn, Hạnh, Đức, Linh, Thủy và chị Mai. Những người đã cùng giữ Ngọc Trục qua dịch và tấn công. + +Tiến đề nghị kiểm radio, chỗ ở và đồ cá nhân. Thủy hỏi: “Bằng chứng đủ để khám tất cả?” + +“Ba đoàn.” + +“Đủ để biết có rò. Không đủ để biến chín người thành nghi phạm như nhau.” + +“Chờ đoàn thứ tư?” + +“Đổi cách chia thông tin.” + +Họ tạo ba lịch giả, nhưng không chỉ thay tên đường. Ba xe mồi xuất phát gần cùng giờ, không dùng radio, mỗi xe mang một dấu sơn khác trên thùng và có người quan sát cả điểm đầu lẫn điểm cuối. Bình còn cho một xe quay vòng để kiểm bám đuôi. Chỉ người nhận lịch mới biết dấu nào ứng với tuyến nào. + +Tuyến phía bắc bị chặn đúng trước chiếc xe mang dấu tam giác. Không có người bám từ Ngọc Trục, hai tuyến còn lại không bị chuẩn bị trước. Người biết lịch tam giác: Hạnh, chị Mai và Nam. Nam trắng mặt. “Không phải em.” + +Tiến không vội nói “tôi tin cậu”. Hắn hỏi điều có thể kiểm: “Cậu đã nói với ai?” + +“Không ai.” + +“Viết ở đâu?” + +“Không.” + +“Ngủ?” + +Nam hiểu câu hỏi Dư Âm, lắc. “Không.” Hạnh giận vì bị thử. Chị Mai ngồi quá yên. + +Linh nhìn cô. “Mai.” Người y tá bật khóc. + +Con trai chị mắc ở một khu do người của Hổ kiểm soát. Người liên lạc không chỉ gửi một video mơ hồ. Trong đoạn quay, cậu đọc đúng câu hai mẹ con dùng làm mật hiệu từ nhỏ, đưa cổ tay có vết sẹo bỏng cho camera và nhắc tên loại kháng sinh mình dị ứng — những chi tiết Mai chưa từng ghi trong hồ sơ Ngọc Trục. + +“Chị thấy ngày quay?” Thủy hỏi. + +“Không.” + +“Bóng nắng?” + +“Không để ý. Tôi chỉ kiểm những thứ chứng minh đó là con tôi.” + +Thủy không gọi chị nhẹ dạ. Bằng chứng đủ thật để kéo một người mẹ, nhưng chưa đủ chứng minh video được quay gần đây. + +“Chị gửi mấy lần?” + +“Bốn.” + +Ba lần thành phục kích; lần đầu có thể kiểm tra. Tiến hỏi: “Người nhận?” + +“Không biết. Mảnh giấy dưới thùng thuốc.” + +Kẻ đó đã vào Vành Ngoài hoặc có người đi lại thường xuyên. Chị Mai nhìn Tiến. “Anh đuổi tôi?” + +Quy tắc cho phép trục xuất người làm lộ tuyến nước. Nhưng quy tắc cũng yêu cầu xét cưỡng ép và hậu quả. Hội đồng họp, không để Tiến quyết một mình. + +Một người muốn đuổi làm gương. Linh muốn giữ người y tế nhưng tước quyền thông tin. Bình muốn tìm con trước khi phán. Tuấn nói: “Nếu chúng ta đuổi mọi người bị kéo bằng gia đình, Vành Ngoài sẽ trống.” + +Kết quả: + +- Mai ở lại; +- tạm ngừng quyền truy cập lịch; +- mọi thao tác y tế có người cùng xác nhận; +- cộng đồng tổ chức tìm con; +- nếu tiếp tục giấu, rời căn cứ. + +Tiến bỏ phiếu trắng. Thủy hỏi sau: “Vì sao?” + +“Có lợi ích điều tra.” + +“Anh muốn giữ Mai làm đường tới người liên lạc.” + +“Ừ.” + +“Phiếu trắng không vô tư.” + +“Không.” + +Thủy không chỉ ghi lá phiếu trắng. Cô ghi cả lý do, vì minh bạch không chỉ là kết quả. Mai đặt một lịch giả khác dưới thùng thuốc. Người lấy là Sơn — cậu bé từng trèo rào đi tìm nước và được hứa dẫn tới mẹ nuôi mất tích. + +Nam bắt gặp. Không đánh. Cậu chặn lối và hỏi: “Họ hứa ai?” Sơn khóc. Không nội gián chuyên nghiệp. Hai người bị kéo bằng hai người thân. + +Họ theo dấu tới một nhà trọ bỏ trống. Không có con Mai, không có mẹ nuôi Sơn. Chỉ radio và giọng biến dạng: + +“Các anh xây cộng đồng bằng những người còn nợ người chết.” + +Thủy hỏi: “Ông là Vòng Tròn Vỡ?” + +“Không quan trọng.” + +“Rất quan trọng. Vì nguồn quyết định mục đích.” + +Giọng đáp: “Mục đích là chứng minh không cổng nào giữ được người khi quá khứ của họ ở ngoài.” Tiến hỏi con Mai. + +“Còn sống. Tuyến phía nam.” + +“Đổi?” + +“Bản đồ cửa Hoàng Thành.” + +Tiến tắt radio. Không đàm phán bằng bí mật toàn mạng. Thủy xem video cũ: bóng nắng, tiếng tàu điện kim loại co, màu tường trường học. Bình đối chiếu đường. Họ tìm được địa điểm trong một ngày. + +Đột kích không nổ súng. Sáu người bị giữ, trong đó có con trai Mai, được cứu. Người trông đã rút, để lại không biểu tượng. + +Từ “nội gián” hóa ra đã đặt sai giả thuyết từ đầu. + +Là một phương pháp: dùng người mất tích làm dây kéo người bên trong. Ngọc Trục lập nhóm tìm người mất tích, có sổ công khai và người xác minh tin. Không hứa tìm được tất cả. + +Nhưng mỗi người được tìm bằng cộng đồng là một sợi dây kẻ khác không còn giữ riêng. Chị Mai trở lại khu y tế dưới giám sát. Việc cứu con không xóa lỗi đã gây ra. Chị Mai đọc bản ghi quyết định trước hội đồng rồi ký tên. + +Sơn không bị đuổi. Cậu làm trong nhóm tìm người, bắt đầu bằng việc vẽ lại khu đã được dẫn tới. Ngọc Trục không hết phản bội sau việc đó; họ chỉ có thêm một cách để phát hiện và xử lý nó mà không cần giả vờ mọi người đều tốt. + +Mai ngồi dưới mái phản nhiệt, hai tay ôm cốc nước chưa uống. Trên bàn trước mặt chị, ba lịch giả đã được gấp lại; chỉ một lịch còn dính bụi đường. + +Chương 60: Phương Án Của Phương + +**22/08/2028** + +Sau hơn ba tuần ở Ngọc Trục, Phương vẫn không nhận mình đã thuộc về nơi nào. Ban ngày cô giúp Linh và chị Mai. Buổi tối cô gửi báo cáo ca bệnh và số liệu nước cho Vòng Tròn Vỡ qua một điểm trung lập. Phúc không hỏi nội dung, nhưng mỗi lần em gái rời cổng, anh lại nhìn theo cho tới khi bóng cô khuất hẳn sau đoạn tường. + +Phương biết. Cô cũng biết anh đang cố không biến việc tìm được em thành quyền giữ em lại. + +Trong khu y tế, Phương tận dụng những miếng nhãn màu còn sót trong túi đồ cứu từ quầy trà sữa cũ ở Đại Hà: xanh cho có thể uống, vàng cho cần theo dõi, đỏ cho chuyển gấp. Linh ban đầu định bỏ vì màu sắc không phải chuẩn y khoa. Sau hai ngày, cô giữ lại hệ màu nhưng bắt Phương viết thêm giờ, dấu hiệu và người đánh giá. + +“Ở quầy cũ em dán nhãn để khỏi giao nhầm đường với không đường,” Phương nói. + +“Ở đây giao nhầm đắt hơn.” + +“Em biết.” + +“Vậy ghi đủ.” + +Phương ghi đủ. Cô không cần mọi thứ mình mang từ đời trước tận thế phải bị vứt đi; chỉ cần biết thứ nào phải học lại. + +Ngày 22 tháng 8, khi ba bộ đo độc lập cho cùng một xu hướng, Phương yêu cầu gặp Vũ Mạnh Quân. + +“Để quay lại?” Phúc hỏi. + +“Để ông ấy dừng kế hoạch cắt mạch Hồ Tây.” + +“Quân không nghe.” + +“Anh ấy nghe số nếu người đưa số không bắt anh ấy phải tin người trước.” + +Phúc chống tay lên bàn. “Em biết anh ấy sẽ cho người đo lại?” + +“Em biết anh ấy sẽ không chịu dùng bộ đo của Tiến.” + +“Khác gì?” + +“Khác. Em chuẩn bị điểm đo ngoài vùng Ngọc Trục.” + +Phúc nhìn bản đồ cô đã đánh sẵn ba điểm. Câu “đừng đi” lên tới miệng nhưng không thành tiếng. “Mấy giờ về?” + +“Trước tối. Nếu trễ, Khánh An báo.” + +“Không tự đổi điểm hẹn.” + +“Anh cũng đừng tự tới cứu nếu nghe một tin chưa xác minh.” + +Phúc nhăn mặt. “Em học nhanh.” + +“Nhờ anh làm mẫu xấu.” + +Tiến không biến cuộc gặp thành màn phô lực lượng. Khánh An đi cùng Phương với vai trò nhân chứng và kiểm an ninh, không đại diện Ngọc Trục. Cuộc gặp ở một ga bỏ hoang. Quân tháo mặt nạ khi thấy Phương. Vai ông còn vết thương cũ, giọng không giống kẻ cuồng tín. + +“Em ở với họ.” + +“Em đang ở nơi có giường bệnh.” + +“Dữ liệu HANOI-07?” + +“Áp lực nước. Ba bộ đo.” + +Quân không nhận tập giấy ngay. “Thiết bị của ai?” + +“Một của Ngọc Trục, một của nhóm dân đường ven hồ, một của người bên anh. Mã máy ở cuối.” + +Ông mới cầm lên. Đọc xong vẫn lắc đầu. “Có thể cùng bị sai theo một điều kiện môi trường.” + +Phương gật. “Nên anh cử người đo lại ở hai điểm này. Không đi vào vùng Tiến.” + +Quân nhìn cô lâu hơn. “Em tới đây để thuyết phục hay để bắt tôi tự kiểm?” + +“Để anh không thể nói em chỉ mang kết luận của người khác.” + +Khánh An dựa cột, mắt vẫn theo hai lối thoát Quân đã đặt người. “Nếu ông đã quyết cắt rồi thì nói thẳng. Đừng bắt số liệu đóng vai giấy phép.” + +Quân nhìn cô. “Cô bỏ Kha rồi theo Tiến?” + +“Không theo.” + +“Người không chọn phe thường đứng cạnh phe mạnh.” + +Khánh An chỉ chiếc gương nhỏ gắn ở góc trần. “Ông đặt người ở hai cửa và một người nhìn qua gương. Ông cũng không đứng một mình.” + +Phương chen vào trước khi cuộc gặp trượt thành cuộc thi xem ai sắc hơn. + +“Nếu cắt toàn tuyến, nhiệt nền tăng. Nếu giữ nguyên, áp lực cũng tăng. Em đề nghị điều tiết.” + +“Điều tiết có thể giữ một thứ đáng lẽ phải dừng.” + +“Đúng. Nên có ngưỡng ở hai đầu và một ngắt cơ không qua bộ điều khiển. Nếu số vượt ngưỡng, bên anh tự ngắt được.” + +“Cắt sạch thì chắc chắn dừng.” + +“Và chắc chắn dồn tải sang chỗ khác nếu mô hình này đúng. Em không muốn thành phố làm phép thử một lần chỉ để khỏi phải sống với chữ 'chưa biết'.” + +Quân hỏi: “Em quên Láng?” + +“Không. Em nhớ người chết. Em cũng nhớ những người sống vì khóa không sập.” + +“Tiến đang dùng cả anh lẫn em.” + +“Anh cũng dùng em.” + +Quân không trả lời ngay. Phương đặt tập giấy xuống giữa hai người. + +“Anh cứu em ở Đại Hà. Em không quên. Nhưng chuyện đó không khiến mọi quyết định sau của anh tự động đúng. Và em không muốn mỗi lần bất đồng lại phải trả món nợ ấy thêm lần nữa.” + +Câu nói không làm Quân đổi niềm tin. Nó chỉ buộc ông tách một việc đã làm đúng khỏi quyền quyết định những việc chưa xảy ra. + +Cuối cùng, Quân đồng ý: + +- hoãn cắt mười ngày; +- cử hai người đo độc lập; +- giữ một ngắt cơ nếu thiết bị điều tiết tự vượt giới hạn; +- không công bố kết luận trước khi có số đo mới. + +Đó chưa phải hòa giải hay đầu hàng; chỉ là khoảng thời gian đủ để đo trước khi phá. + +Trên đường về, Khánh An hỏi: “Cô ở Ngọc Trục?” + +“Chưa biết.” + +“Phúc?” + +“Là anh em không nghĩa cùng phe.” + +“Đúng.” + +“Cô với Kha?” + +Khánh An nhìn đường ray. “Hắn từng cứu tôi.” + +“Vậy cô nợ?” + +“Có.” + +“Nợ có quyền quyết?” + +“Không.” + +Phương gật. Cô không cần hai người có cùng câu chuyện để hiểu một nguyên tắc giống nhau. + +Tối đó cô nói với Phúc: “Em không về vì anh.” + +“Biết.” + +“Em cũng không quay lại vì Quân.” + +“Ừ.” + +“Em muốn lập mạng y tế không mang biểu tượng phe.” + +Phúc nghĩ một lúc. “Em cần gì ở anh?” + +“Đừng đứng ở cửa mỗi lần em đi.” + +Anh thở ra. “Khó.” + +“Làm thử.” + +“Còn mạng y tế?” + +“Linh. Mai. Hai người bên Quân nếu họ đồng ý. Sau đó thêm.” + +Linh nghe đề nghị, đưa một túi thuốc cơ bản rồi giữ lại quai túi. + +“Không miễn phí.” + +Phương cau mày. “Nước?” + +“Báo cáo ca bệnh, tồn kho, phản ứng thuốc. Không tên bệnh nhân nếu không cần.” + +“Được.” + +Linh mới buông tay. + +Phương lấy ba miếng nhãn màu còn sót lại từ Đại Hà, dán lên các túi mẫu rồi viết giờ bằng chữ in hoa. Mạng y tế trung lập bắt đầu bằng một túi thuốc, một sổ giao nhận và những miếng nhãn vốn được sản xuất để dán lên cốc trà sữa. + +Việc Hậu Ký thiếu Phương không biến cô thành một Điểm Mù huyền bí. Người truy vấn trước đó đơn giản đã nhìn quá chăm vào các phe lớn và bỏ qua khả năng một cô gái mười chín tuổi có thể kéo cả cấu trúc qua khe giữa họ. + +Phương trải bản đồ mạng y tế giữa bàn. Cô không ngồi về phía Quân hay Phúc. Chiếc ghế còn trống được kéo sát mép bản đồ, vừa đủ để cô tự đặt túi xuống. + +Chương 61: La Phù Trở Lại + +**23/08/2028** + +Ba kho lương La Phù cháy cùng một đêm. Khói đỏ đen hiện trên đường chân trời trước khi radio báo. Lương của bảy khu nằm trong đó; nếu mất hết, phía Tây có chưa đầy mười ngày trước khi đói diện rộng. + +Kha gọi Tiến. + +“Không phải tao.” + +“Biết.” + +“Tin nhanh?” + +“Nếu anh đốt, anh không gọi trước khi người khác thấy.” + +“Có thể tao muốn mày nghĩ vậy.” + +“Giữ trò đó cho lúc còn thời gian.” + +Các nhóm từng tranh La Phù cùng kéo tới: xe của Kha, đường của Hổ, kỹ thuật Ngọc Trục, người Vòng Tròn Vỡ vì kho của họ cũng ở đó, đội cũ của cơ quan khẩn cấp. Lần đầu họ tới La Phù không để chiếm. + +Lửa được đặt trong trục thông gió, khiến nước phun ngoài không tới tâm. Hơi nóng trong hành lang bảo trì vượt ngưỡng đội cứu có thể đứng lâu. Ông Hòa từ chối phương án để mình bò vào chỉ vì biết dây. + +“Đức vào. Tôi đọc sơ đồ.” + +Tiến hỏi: “Chắc?” + +“Không. Vì vậy buộc dây và đặt giờ.” + +Đức mặc lớp áo phản nhiệt chắp từ đồ hàn, mang khẩu trang lọc khói và dây kéo. Ông Hòa ngồi ngay miệng trục, sơ đồ trải trên một tấm carton. Mỗi lần Đức đi quá một nhánh, ông bắt đọc màu dây, ký hiệu hộp và nhiệt kế cơ. Ca vào được giới hạn ngắn; quá mốc, dù chưa xong cũng phải rút cho người khác thay. + +“Cậu đọc hệ lạnh tốt hơn đường báo cháy,” ông Hòa nói qua dây thoại. “Nên đừng đoán. Hộp thứ hai bên phải, dây trắng có vạch đen.” + +“Thấy.” + +“Không cắt. Rút cầu chì cạnh nó.” + +“Chốt kẹt.” + +“Lùi ra, đổi kìm. Đừng thắng một cái chốt bằng phổi.” + +Đức chửi nhưng lùi. Người kế tiếp đưa đúng dụng cụ vào. Quạt hút dừng trước khi cháy lan kho thứ tư. + +Bình tổ chức tuyến xe theo nhịp ba phút. Anh đánh dấu nơi có trẻ em không để đoàn dừng cứu bất kỳ ai nhìn thấy, mà để các điểm giao nhận biết trước có đủ nước, bóng râm và người giữ trật tự hay không. Một xe bị đám đông tràn tới ở đầu ngõ; Bình bỏ tuyến ngắn, vòng qua đường xấu hơn nhưng còn kiểm soát được. + +Trong lúc chờ chiếc xe thứ sáu quay đầu, anh nhìn thấy một thùng bánh quy cháy sém có hình con thỏ gần giống con Bình An từng ôm trong ảnh. Một gói bên trong còn nguyên. Bình cầm lên, nhìn nhãn rồi đặt vào khay kiểm kê thay vì bỏ túi. + +Hổ thấy. “Một gói thôi.” + +“Đúng. Nên ghi được.” + +“Con gái anh thích?” + +Bình không trả lời ngay. “Nếu kho còn, nó có cơ hội tự chọn thích gì.” + +Hổ gật, không nói thêm. + +Kha điều người bốc hàng, không giữ riêng. Hổ mở đường; người của hắn tự nộp dao vào một thùng khóa trước khi vào khu xếp hàng vì tất cả hiểu một cuộc tranh cướp nhỏ đủ làm cả kho cháy tiếp. Nam ở phòng radio nghe tiếng cửa cuốn được kéo bằng tay. Âm thanh làm cậu khựng lại. + +Phúc gọi qua kênh cơ: “Nam.” + +Không có tiếng trả lời trong hai giây. + +“Đọc hướng gió.” + +Nam thở ra. “Đông nam. Tám tới mười.” + +“Xe ba?” + +“Đổi tuyến B.” + +Cậu tiếp tục đọc tải. Không ai bảo “đừng sợ”; mọi người chỉ giữ công việc đủ rõ để nỗi sợ không phải ra quyết định thay cậu. + +Họ cứu được khoảng hai phần ba kho thứ tư. Ba kho còn lại mất. + +Trong trục cháy, Khánh An tìm thấy một thiết bị kích mang mã hậu cần của bộ máy cũ. Nó không thuộc Vòng Tròn Vỡ, cũng không mang dấu Null. Một loa ngoài đường bật: + +“Kho lương chiến lược thuộc quyền quản lý khẩn cấp. Mọi hành vi chiếm giữ là bất hợp pháp. Người dân tập trung tại điểm phân phối chỉ định.” + +Những điểm đó đã chết. + +Kha bắn tắt loa. + +Thủy nhìn hắn. “Anh vừa bắn vào biểu tượng.” + +“Bắn loa.” + +“Người ta sẽ kể khác.” + +“Thì ghi đúng là tao bắn loa.” + +“Được.” + +Sau đám cháy, lượng lương còn lại được đưa ra trước hội đồng ngay tại sân kho. Kha đề nghị một kho trung tâm có vũ trang. Tiến phản đối vì một lần chiếm là mất hết. Họ chọn bốn kho nhỏ, mỗi kho do ba nhóm cùng giữ chìa. Vị trí được chia cho các bên ký và đội giao nhận, không phát rộng lên radio chung. + +Kha chỉ vào sơ đồ. “Tăng thêm hai mươi phần trăm đường chạy.” + +Bình đáp: “Nhưng mất một kho chưa chết cả mạng.” + +“Anh lái nên anh trả xăng?” + +“Không. Tôi chỉ nói chi phí thật.” + +Kha liếc sang Tiến. “Thấy chưa? Người của mày học cãi.” + +Bình cắt ngang ngay: “Tôi không phải người của anh ấy.” + +Một vài người cười, đủ ngắn để không quên khói vẫn đang làm cay mắt. + +Kha ký dù không thích. + +Khi xe cuối rời, Tiến đứng nhìn nơi từng là bãi máu trong ký ức cũ. Kiếp trước, Kha lấy La Phù bằng bạo lực. Lần này, hắn cùng cứu kho và không giữ phần lớn nhất. + +Kha đứng cạnh. “Mày nhìn gì?” + +“Cái đang xảy ra.” + +“Đừng yêu nó quá.” + +“Không.” + +La Phù vẫn cháy. Người vẫn chết vì khói và nhiệt. Nhưng bốn phe đã cùng cứu phần lương còn lại, không phải vì họ bỗng tin nhau mà vì cơ chế chia khóa khiến cướp một kho không còn đủ để thắng. + +Ở danh sách kiểm kê cuối ngày, Bình tìm thấy gói bánh quy con thỏ. Nó được ghi như mọi món khác. Anh khoanh mã thùng rồi viết bên cạnh: **nếu tới được khu trẻ em, để họ tự chia.** Không ghi tên Bình An. + +Hậu Ký sai thêm một dòng bằng những việc nhỏ như thế. + +Chương 62: Tên Gọi Thành Quyền Lực + +**24/08/2028** + +Sau La Phù, ảnh Kha xuất hiện tại các điểm phát lương. Không áp phích chính thức. Chỉ những tờ in từ camera: hắn đứng trên thùng xe, áo đen, tay chỉ nơi dỡ bao. + +Bên dưới có người viết: + +**KHA ĐEN GIỮ ĐƯỜNG.** + +Tên từng dùng để sợ trở thành tên người ta gọi khi cần hàng tới. Kha không phát ảnh. Cũng không gỡ. Tiến hỏi qua radio: “Anh cho phép?” + +“Không cấm.” + +“Khác?” + +“Rất.” + +Kha mở ba bếp tập thể. Người làm việc nhận khẩu phần; trẻ em và người già theo định mức. Kẻ trộm bị đuổi, kẻ cướp xe bị đánh gãy tay trước đám đông. Người ta truyền nhau rằng ở khu Kha không ai dám cướp nước; cũng chẳng mấy ai dám hỏi xem sổ phân phối ghi gì. Thủy tới phỏng vấn, mang máy ghi và hai người chứng kiến. + +“Anh dùng cứu trợ xây quyền,” cô nói. + +“Đúng.” + +“Không phủ nhận?” + +“Người đói không ăn lời khiêm tốn.” + +“Nhưng sống dưới luật anh.” + +“Đúng.” + +“Luật ai đặt?” + +“Tao.” + +“Có xét?” + +“Có người chứng kiến.” + +“Có quyền phản đối?” + +“Có thể rời.” + +“Đi đâu?” + +Kha không trả lời. Giới hạn của trật tự hắn xây nằm trong câu đó: quyền rời đi vô nghĩa nếu bên ngoài không có nước. Thủy hỏi về người bị đánh gãy tay. + +“Nếu thả, xe sau bị cướp,” Kha nói. + +“Nếu giết?” + +“Không cần.” + +“Vậy anh tự chọn hình phạt vừa đủ?” + +“Ừ.” + +“Dựa trên gì?” + +“Hiệu quả.” + +“Không công lý?” + +“Công lý là từ người đủ thức ăn dùng.” + +Thủy không tranh bằng đạo đức trừu tượng. “Một ngày người của anh đánh nhầm, ai sửa?” Kha im. Câu hỏi thực tế hơn lời kết án. + +Khánh An tới sau. Người cũ chào cô theo thói quen. Kha đưa một hồ sơ. + +“Người thay tao nếu chết.” + +Cô không cầm. + +“Không.” + +“Chưa xem.” + +“Không cần. Anh đang biến tổ chức thành một người khác.” + +“Cần kế nhiệm.” + +“Cần quy trình. Nếu anh chết, người giữ xe, kho và súng đánh nhau trước khi hồ sơ được mở.” + +Kha nhìn. “Tiến dạy?” + +“Nhìn Ngọc Trục.” + +Câu đó làm hắn khó chịu hơn. Khánh An đề nghị: + +- kho cần ba khóa; +- điều xe cần hai xác nhận; +- đội trưởng bỏ phiếu người điều hành tạm; +- quyền khẩn cấp hết hạn sau bảy ngày; +- hình phạt phải có người ngoài đội chứng kiến. + +Kha cười. “Cô ở Ngọc Trục lâu quá.” + +“Có thể.” + +Tối đó, Kha triệu tập các đầu mối. Hắn không thừa nhận Thủy đúng, nhưng vẫn bắt đầu viết quy trình. Thủy hỏi câu cuối: “Nếu ngày 29 Hậu Ký bảo anh giết Tiến, anh làm không?” Kha nhìn máy ghi. + +“Không trả lời.” + +“Vì không biết?” + +“Vì câu trả lời hôm nay có thể thành dây kéo ngày đó.” + +Lần đầu, Kha từ chối tạo một bản ghi tương lai dễ dùng. Thủy tắt máy. Ngoài bếp, người ta vẫn gọi Kha Đen. + +Một cái tên trở thành quyền lực khi nó xuất hiện trên xe, nồi ăn, luật và nỗi sợ. Nhưng quyền lực bền không chỉ nhờ một người. Kha bắt đầu học điều đó không vì trở nên tốt. Vì hắn hiểu một hệ thống phụ thuộc mình là một hệ thống có một điểm hỏng. + +Ngôn ngữ của Tiến đã len vào cách Kha xây quyền lực. Chiều ngược lại cũng đúng: Tiến buộc phải học rằng quy trình nào cũng có người hưởng lợi nếu chẳng ai hỏi ai đã viết nó. + +Ngày sau cuộc phỏng vấn, người bị đánh gãy tay được đưa tới điểm y tế của Phương. Tên anh ta là Vinh, từng cướp xe vì con gái sốt. Chiếc xe bị cướp cũng chở thuốc cho ba đứa trẻ khác. Kha tới, không xin lỗi. + +“Anh đánh nhầm người?” Thủy hỏi. + +“Không.” + +“Vậy câu hỏi ai sửa khi anh đúng sự việc nhưng sai mức phạt vẫn còn.” + +Kha nhìn cánh tay Vinh được nẹp. “Tao sẽ trả thuốc và lương ba tháng cho gia đình hắn.” + +“Đền bù không phải xét lại.” + +“Cô muốn gì?” + +“Người ngoài đội anh được xem lời khai trước khi hình phạt thi hành.” + +Kha không đồng ý ngay. Đêm đó, hắn cho hoãn một vụ phạt khác vì nhân chứng không thống nhất. Người của hắn thấy đó là yếu; gia đình người bị giữ thấy đó là lần đầu có thời gian nói. Tên **Kha Đen** từ đó mang hai câu chuyện cùng lúc: người làm xe tới đúng giờ và người có thể làm một cánh tay gãy. Quyền lực thật không chỉ sống trong hình ảnh người ta muốn giữ; nó sống cả trong điều người ta sợ kể nhỏ ở bếp ăn. + +Chương 63: Người Không Có Quyền Thừa Kế + +**26/08/2028 – 04:10** + +Xe của Kha bị đánh lúc 04 giờ 10, hai ngày sau khi hắn bắt đầu viết quy trình kế nhiệm. Mìn tự chế làm vỡ bánh trước. Viên đạn thứ hai xuyên vai phải khi Kha xuống xe. Đội hộ tống kéo hắn vào một nhà xưởng, nhưng không thống nhất nên đưa về kho chính, điểm y tế hay trạm bí mật. + +Tin tới Khánh An qua radio cũ của đội can thiệp. Cô lấy súng và túi cứu thương. Tiến chặn cổng. “Đi đâu?” + +“Đưa Kha ra.” + +“Có thể bẫy.” + +“Đúng.” + +“Cô không còn người của hắn.” + +“Không cần.” + +“Vì nợ?” + +Khánh An kiểm băng đạn, không nhìn hắn. “Vì nếu Kha chết lúc này, ba kho và sáu đội xe sẽ tự chọn chủ. Phía Tây loạn trước khi người bắn kịp làm gì tiếp.” Một lý do chính trị. + +Không phủ nhận lý do cá nhân. Hội đồng cho Bình lái và Phương đi y tế. Tiến ở lại Ngọc Trục, dù bản năng muốn tự đi kiểm. Một người lãnh đạo không thể luôn rời hệ thống để xử lý người quan trọng nhất. + +Tại nhà xưởng, Kha nằm trên bàn gỗ, máu thấm áo đen. Người giữ xe muốn rút về kho trung tâm; người giữ súng nói tuyến đã lộ; người quản lương đòi mở mã khẩn cấp. Quy trình kế nhiệm chưa ban hành, nên không ai có quyền chốt. + +Khánh An bước vào. + +“Im.” + +Họ im theo thói quen cũ. Cô kiểm vết thương. Phương cắt áo, xác định đạn xuyên phần mềm vai, chưa vào ngực. + +Kha tỉnh khi được băng ép. Chiếc nhẫn đã được Phương tháo để tay không sưng kẹt; nó nằm trong khay kim loại cạnh giường, để lộ mảnh thẻ cháy sém của Minh Khôi. Khánh An đặt khay trong tầm mắt hắn nhưng không đeo lại thay. Quyền lựa chọn vẫn phải chờ người tỉnh. + +“Cô về,” hắn nói. + +“Không.” + +“Vẫn nói.” + +“Để anh khỏi tưởng.” + +Kha bật cười rồi nhăn mặt vì đau. Khánh An hỏi người của hắn: “Quy trình khi thủ lĩnh mất khả năng?” Không một ai đưa ra được bản nào. + +Kha nhắm mắt. “Trong két.” + +“Không ai có đủ mã.” + +“Đúng.” + +“Thấy chưa?” + +“Thấy.” + +Họ đưa hắn tới điểm y tế trung lập của Phương, không Ngọc Trục và không kho Kha. Quyết định khiến hai đội của hắn nghi bị cướp người. + +Trong sáu giờ Kha bất tỉnh: + +- một đội chặn đường tự ý; +- một kho ngừng phát lương; +- hai đội trưởng ra lệnh trái nhau; +- Hổ đưa người tới chiếm ngã tư; +- nhóm bộ máy cũ phát thông báo yêu cầu kho giao quyền. + +Lần đầu tiên, mạng lưới của Kha phải vận hành với giả định hắn có thể chết. Hội đồng phía Tây họp khẩn. Một số người đề nghị Ngọc Trục tiếp quản xe để “giữ ổn định”. + +Tiến phản đối. Tuấn hỏi: “Đây là cơ hội giảm quyền hắn.” + +“Lấy lúc người ta nằm là cướp.” + +“Nếu hắn là ta?” + +“Có thể hắn lấy.” + +“Vậy sao không?” + +“Vì thỏa thuận chỉ có giá khi áp dụng lúc có lợi để phá.” + +Hội đồng cử người bảo vệ kho nhưng không mở và không điều xe. Mọi con dấu được ghi hình. Kha tỉnh lúc chiều. Khánh An báo: “Kho còn nguyên.” + +“Tiến không lấy?” + +“Không.” + +“Ngốc.” + +“Có thể.” + +“Cô giữ?” + +“Hội đồng giữ quy tắc.” + +Kha nhìn trần. Tổ chức hắn sống qua một đêm nhờ người ngoài không lợi dụng điểm yếu. Điều đó làm hắn khó chịu hơn viên đạn. Ba ngày sau, hắn ban cơ chế mới: + +- ba người giữ ba phần mã kho; +- lệnh điều xe cần hai xác nhận; +- người điều hành tạm do đội trưởng bỏ phiếu; +- quyền khẩn cấp hết hạn sau bảy ngày; +- không ai thừa kế toàn bộ. + +Khánh An từ chối vị trí kế nhiệm. + +“Nếu quy trình chỉ hoạt động lúc anh còn tỉnh để ký, thì nó chưa phải quy trình,” cô nói. “Anh cần một cơ chế chạy được khi anh nằm như hôm nay.” + +Kha nhìn nhẫn. “Còn cô cần gì?” Lần đầu Khánh An trả lời không bằng nhiệm vụ. + +“Tôi muốn tới ngày 29 mà không phải giết ai chỉ vì một bản ghi nói cần.” + +Kha gật. “Khó.” + +“Biết.” + +Hắn sống. Hình ảnh bất tử vỡ. Nhưng quyền lực không giảm như kẻ bắn mong. Một người có thể bị thương mà kho vẫn mở đúng giờ nguy hiểm hơn một thủ lĩnh chỉ giữ mọi chìa trong túi. + +Tiến đọc kỹ quy trình Kha gửi công khai. Có những dòng giống Ngọc Trục. Có những dòng lạnh hơn. Hai hệ thống đang học nhau. + +Ngọc Trục đã học cách chia mã từ chính những gì họ sợ ở Kha; phía Kha lại học cách phân quyền sau khi nhìn Ngọc Trục sống qua khủng hoảng. Ranh giới giữa hai hệ thống vẫn còn, nhưng không bên nào còn độc quyền với những ý tưởng tốt. + +Trong lúc Kha bất tỉnh, một đoàn xe thuốc tới ngã tư do hai đội cùng nhận lệnh. Cả hai đều có mã hợp lệ, không ai chịu lùi. Phương phải rời bàn mổ gọi Khánh An; cô không chọn đội thắng mà buộc họ tách hàng theo danh sách bệnh viện đã xác nhận. + +Sau đó, Khánh An viết quy trình đầu tiên của mình, không ký tên Kha hay Ngọc Trục. Bất kỳ lệnh khẩn nào trùng nhau phải dừng tại điểm trung lập, đối chiếu mục tiêu và người nhận trước khi xe đi tiếp. Người điều phối không được thuộc một trong hai đội tranh chấp. + +“Cô đang lập phe?” Tiến hỏi khi đọc. + +“Không. Tôi đang lập một công việc.” + +“Có người theo?” + +“Ba người hôm nay. Ngày mai có thể không.” + +Đó là thứ đầu tiên Khánh An xây không phải vì Kha ra lệnh hoặc vì cần chống Kha. Mạng kiểm tra chéo bắt đầu từ một đoàn thuốc suýt đứng yên vì hai mệnh lệnh đều hợp lệ. + +Chương 64: Ngọc Trục Bỏ Phiếu + +**27/08/2028** + +Quyết định khiến Tiến thua phiếu liên quan tới một khu trú phía nam. Bể nước ở đó nhiễm dầu. Một trăm mười ba người phải di chuyển trong hai ngày. Ngọc Trục có thể nhận bốn mươi theo mức an toàn, Kha nhận ba mươi, các khu khác chia phần còn lại nếu đủ xe. + +Tiến muốn mở rộng Vành Ngoài thêm năm mươi người. Linh phản đối vì dịch mới qua. Bình nói xe có thể đưa một nửa đi xa hơn. Tuấn nhắc nước chỉ đủ mười một ngày nếu nhận thêm. Hạnh, đại diện Vành Ngoài, hỏi: “Nếu ngày mai lại có nhóm khác?” + +Tiến biết mọi lý do chống đều đúng. Hắn vẫn đề nghị mở. Phiếu: + +Hai thuận. Bốn chống. Một trắng. + +Tiến thua. Tuấn hỏi: “Anh chấp nhận?” + +“Không thích.” + +“Không hỏi thích.” + +Tiến rà bảng. “Chấp nhận.” Kế hoạch chia đoàn được thực hiện. Đoàn đầu tới Ngọc Trục. Đoàn hai đi khu Kha. Đoàn ba phải tới điểm xa hơn. + +Ba giờ trước khi xe đi, Bình đã tự cúi dưới gầm, kiểm lốp, dầu, nước làm mát và bánh dự phòng. Đến đoạn dốc phía nam, anh vẫn nghe tiếng kim loại trước người khác: một tiếng rít ngắn, rồi bánh sau khóa cứng. Khi tháo cụm, họ mới thấy vết nứt moay-ơ chạy từ phía trong — nơi mắt thường không thể nhìn nếu không tháo toàn bộ. Ổ bi đã vỡ, trục kéo gãy ba bu-lông và làm vành méo. Bánh dự phòng đúng cỡ nằm ngay trên xe, nhưng không có gì nguyên vẹn để lắp nó vào. + +Dải nhiệt tới sớm gần hai giờ. Bộ chuyển tiếp radio ở đoạn thấp mất nguồn; xe cứu đầu tiên phải vòng vì một nhịp cầu đã lún. Kế hoạch chín mươi phút không có điểm trú giữa tuyến, nên khi hành trình kéo dài gấp ba, những người đã mất nước và có bệnh nền nằm giữa bê tông nóng mà không còn lớp bảo vệ thứ hai. Mười bảy người chết trước khi xe cứu tiếp cận. + +Sau đó Bình đặt chiếc moay-ơ nứt giữa bàn hội đồng. Mọi bánh dự phòng họ mang theo đều nằm cạnh nó, đúng cỡ và vô dụng. Hình ảnh đủ rõ: kế hoạch đã chuẩn bị cho một hỏng hóc đơn lẻ, còn tai nạn lại đến theo chuỗi. Tin truyền về khiến khu cổng Ngọc Trục lặng hẳn. Nếu hội đồng làm theo phương án của Tiến, nhóm kia có thể đã sống; cũng có thể Vành Ngoài quá tải và những người khác chết sau đó. + +Không có phương án đối chứng. Tuấn ngồi dưới mái tôn cả đêm. “Lỗi của chúng ta.” + +Tiến đáp: “Đúng.” + +“Anh có thể nói đã cảnh báo.” + +“Không.” + +“Anh thua phiếu.” + +“Vẫn thuộc hội đồng. Vẫn ký kế hoạch.” + +Không dùng thất bại để rửa tay. Gia đình người chết tới. Một người đàn ông tát Tuấn. Bình bước lên, Tiến giữ. + +Tuấn không đánh lại. + +“Các anh ngồi mát rồi quyết con tôi đi đâu,” người đàn ông nói. + +Tuấn nhìn mái tôn nóng. “Không mát.” Một câu vụng, gần như tệ. + +Tiến nói: “Chúng tôi quyết và kế hoạch không đủ.” + +“Các anh bị gì?” + +Không hình phạt nào đưa người chết về. Một số đề nghị giảm khẩu phần hội đồng. Linh phản đối. + +“Đau khổ không thay cho quản trị được. Anh nhịn ăn bảy ngày chỉ làm thêm một người ra quyết định tệ đi.” + +Hội đồng chọn hậu quả có chức năng: + +- mọi thành viên phải tham gia chuyến di chuyển kế; +- kiểm lốp, moay-ơ, trục và nhiệt ổ bi thay vì chỉ nhìn bánh dự phòng; +- mỗi đoàn có hai phương án cứu hộ không dùng cùng một cầu hay bộ chuyển tiếp; +- dựng điểm trú nhiệt giữa tuyến trước khi chở người; +- quyết định và phiếu được lưu; +- gia đình người chết có quyền đọc biên bản, không quyền hành hung. + +Chuyến sau, Tiến đi cùng. Một lốp tách lớp vì nhiệt ở giữa đường. Xe không tiếp tục chạy, nhưng đoàn cũng không nằm phơi trên mặt bê tông: người được chuyển vào điểm trú, xe cứu thứ hai đi tuyến khác, còn Bình thay cả cụm bánh đã kiểm trước. + +Một người sốc nhiệt được làm mát tại chỗ. Cả đoàn tới. Không xóa mười bảy người. + +Nhưng cái chết thay đổi thiết kế. Tối, Tiến nói với Thủy: “Kiếp trước tôi quyết một mình. Người chết, tôi chỉ đi tiếp.” + +“Giờ?” + +“Phải nói với nhiều người, nghe họ cũng chịu.” + +“Khó hơn?” + +“Ừ.” + +“Muốn quay lại một mình?” + +“Có lúc.” + +“Vì nhanh?” + +“Vì không phải nhìn người khác mang phần lỗi.” + +Thủy khép sổ. “Đó là chia tội, chưa chắc chia quyền.” + +“Khác?” + +“Chia quyền nghĩa là chấp nhận họ có thể đúng hơn anh. Không chỉ cùng sai.” + +Tiến sửa trực tiếp trên dự thảo quy chế. Hắn xóa quyền phủ quyết chung, chỉ giữ quyền an ninh trong tấn công trực tiếp với thời hạn rất ngắn. Ngọc Trục không trở thành một cộng đồng có quyền chỉ vì bỏ phiếu. + +Nó bắt đầu khi Tiến thua, cho rằng quyết định sai, và vẫn không xé kết quả để tự cứu hình ảnh mình. Sau chuyến di chuyển thứ hai, người đàn ông đã tát Tuấn tới xin xem biên bản. Ông đọc tên từng người bỏ phiếu chống nhận thêm dân, rồi hỏi Tiến: + +“Nếu làm lại, anh đổi phiếu không?” + +“Có thể.” + +“Lại có thể.” + +Tiến đọc lại danh sách chết. “Tôi không biết nhận thêm năm mươi người có làm người khác chết sau đó không. Tôi biết kế hoạch xe đã thiếu. Phần đó không cần có thể.” Người đàn ông không tha. Ông yêu cầu được tham gia đội kiểm xe của chuyến sau. Hội đồng chấp thuận sau khi Bình kiểm tra tay nghề của ông. + +Ba tuần tiếp, ông là người khó tính nhất với moay-ơ, nhiệt ổ bi và bản đồ cứu hộ. Mỗi lần siết ốc, ông đọc tên con trai mình trong đầu. Cái chết không chỉ thay đổi một quy trình trên giấy; nó đưa một người từng đứng ngoài quyết định vào đúng nơi có thể ngăn lỗi lặp lại. + +Chương 65: Hiệp Ước Phía Tây + +Hiệp ước phía Tây được ký ngày 28 tháng 8 tại một trạm xe buýt bỏ hoang nằm giữa các vùng ảnh hưởng. Không Hoàng Thành. Không Ngọc Trục. Không nơi nào đủ quyền biến chủ nhà thành chủ cuộc họp. + +Mười chín nhóm tham gia. Văn bản chỉ có năm điều: + +- không chặn nước, thuốc, lương; +- hỗ trợ cháy và sập; +- công khai dịch bệnh; +- không chiếm nút trước 29/09; +- tranh chấp đưa ra hội đồng đại diện. + +Hiệp ước không có quốc kỳ, quân đội chung hay một người đứng đầu. Dù vậy, radio dân sự lập tức gọi nó là **Chính quyền phía Tây**. + +Kha phản đối tên. Tiến cũng. Tên vẫn lan. Con người cần một danh từ cho thứ đang quyết định xe nào được qua. + +Trước khi ký, nhóm mang con dấu cơ quan cũ xuất hiện. Người đứng đầu tên Nguyễn Đức Tài, nguyên phó giám đốc một đơn vị quản lý khẩn cấp. + +Ông đi cùng mười hai người có vũ khí, nhưng không chỉ mang súng và biểu tượng. Trên xe có ba hòm hồ sơ chống ẩm, mã cơ của hai trạm bơm, sổ nhiên liệu công, tần số vô tuyến dự phòng và danh sách mười bảy kỹ thuật viên còn xác minh được. Sáu người trong danh sách đang ở cùng ông; số còn lại rải tại các khu chưa nối vào hiệp ước. + +“Tôi không tới để bảo các anh trả mọi thứ cho một con dấu,” Tài nói. “Tôi tới vì một mạng phân phối không có hồ sơ kế thừa sẽ sụp ngay khi những người ngồi bàn này chết.” + +Hương hỏi: “Luật nào còn hoạt động?” + +“Phần nào còn người thi hành, tài sản để vận hành và thủ tục để người khác kiểm tra.” Tài đặt sổ trạm bơm lên bàn. “Phần còn lại chỉ là giấy.” + +Kha nhìn mười hai người. “Ông học nhanh.” + +“Tôi sống đủ lâu để biết không thể bắt một đoàn xe bằng điều khoản.” Tài quay sang Tiến. “Nhưng các anh cũng không thể gọi mọi quyết định hiện tại là hợp pháp chỉ vì đang có nước.” + +Ông đề nghị Hiệp ước được đặt dưới một Ủy ban Khẩn cấp có thời hạn ba mươi ngày, với: + +- kiểm toán công khai lượng nguồn và quyền truy cập; +- lưu biên bản quyết định; +- cơ chế kế nhiệm khi đại diện chết hoặc mất khả năng; +- quyền khiếu nại của các khu nhỏ; +- không ai giữ quyền phủ quyết vô thời hạn. + +Tài yêu cầu làm điều phối viên tạm thời, nhưng chấp nhận bỏ phiếu bãi nhiệm sau bảy ngày và công khai toàn bộ tài sản mình mang vào. Thủy hỏi: “Vì sao ông giữ lại hồ sơ Observation Initiative?” + +“Vì tôi chưa biết người ngồi ở cái bàn nào sẽ dùng nó để cứu hay để chiếm.” Tài đáp thẳng. “Đó là lý do của tôi. Không phải một lý do đẹp.” + +Đề nghị của ông không vô hại: nó giữ một phần bộ máy cũ và tạo cho Tài vị trí trung tâm. Nhưng nó cũng giải những lỗ hiệp ước chưa có ai chịu viết. Hội đồng thống nhất cho nhóm Tài ba ghế quan sát, một ghế biểu quyết ngay sau khi bàn giao bản sao mã trạm bơm và sổ nhiên liệu. Quyền điều phối tạm chỉ có hiệu lực bảy ngày, không quyền phủ quyết. + +Tài ký sau khi sửa từng điều khoản. Không đầu hàng, cũng không còn đòi người khác phục tùng một cơ quan chỉ tồn tại trên con dấu. Hiệp ước được phát radio. Người dân không ăn mừng lớn. Họ chỉ muốn biết ngày mai xe nước có bị chặn không. + +Ai là chủ thành phố? Kha giữ xe và tuyến. Ngọc Trục giữ kỹ thuật lọc. + +Hổ giữ đường. Lâm giữ thuốc. Các khu giữ người. Nhóm Tài giữ hồ sơ và một phần tính chính danh. + +Không nhóm nào đủ sức cai cả thành phố, nhưng từng nhóm đều đủ lực để làm một khu khác tê liệt nếu xung đột nổ ra. Đêm, Tài mở hồ sơ Observation Initiative. + +Tên Kha được ghi: + +**ASSET – INTERVENTION LOGISTICS** + +Hồ sơ không gọi Kha là thủ lĩnh mà xếp hắn vào nhóm **tài sản hậu cần**. Trước khi tự xây mạng riêng, hắn từng nhận công việc, tuyến và dữ liệu từ bộ máy cũ. Tài không công khai ngay. Ông đặt hồ sơ Kha vào ngăn dưới cùng, khóa bằng chiếc chìa vẫn mang từ trước Hồng Nhật rồi tắt đèn phòng lưu trữ. + +Hương, đại diện mạng chung cư hơn bốn trăm người, không ký ngay. Khu lõi chị trực tiếp quản chỉ còn gần hai trăm người sau khi tách thành ba điểm trú; cả mạng không có kho lớn hay lực lượng vũ trang đủ để ép bàn họp. Chị hỏi điều khoản nào bảo đảm các nhóm lớn không bỏ phiếu chia nước của khu nhỏ trong lúc khẩn cấp. + +Không văn bản nào có. Cuộc họp phải thêm một phụ lục: nguồn tối thiểu sinh tồn của mỗi khu không được trưng dụng nếu chưa có người đo độc lập và một kế hoạch bù cụ thể. Kha cho là chậm. Tài cho là không đúng thể thức. Hương đáp: “Vậy hai ông ký mà không cần nước của chúng tôi.” + +Phụ lục được thông qua. Hiệp ước không chỉ là sự thỏa hiệp giữa những người mạnh. Giá trị đầu tiên của nó xuất hiện khi một khu không có gì để đe dọa vẫn buộc cả bàn phải sửa một dòng. + +Chương 66: Đêm Không Chính Quyền + +Hiệp ước tồn tại hai ngày trước khi mạng điện điều khiển bị cắt. 21 giờ 06 ngày 30 tháng 8, radio chung tắt. Trạm bơm dừng. Các điểm phát lương mất liên lạc. Đó không thể là một vụ cháy đơn lẻ: dây điều khiển bị cắt gần như đồng thời ở bảy điểm. + +Người biết sơ đồ phải có hồ sơ cũ. Nhóm Tài nói không liên quan. Kha muốn bắt ông ngay. Thủy hỏi: “Bằng chứng?” + +“Dây cắt theo sơ đồ họ giữ.” + +“Có thể bị lấy.” + +“Cô muốn chờ thành phố cháy?” + +“Không. Muốn bắt đúng người.” + +Trong ba giờ không liên lạc: + +- Hổ chiếm hai nút đường để “bảo vệ”; +- một xe nước bị cướp; +- tin Kha chết lan dù hắn vừa xuất hiện; +- tin Tiến mở Hoàng Thành cũng lan; +- bệnh viện mất bơm. + +Ngọc Trục vẫn chạy cục bộ nhờ đường cơ. Kha mất liên lạc ba kho. Bộ máy cũ cũng mất người. + +Duy nhìn bảy điểm cắt. “Không phá toàn mạng. Chia thành đảo.” + +“Để?” Bình hỏi. + +“Đo khu nào tự sống, khu nào phụ thuộc.” + +Một cuộc thử phản ứng bằng thành phố thật. Thiết bị ghi dòng được tìm thấy ở trạm bệnh viện. Kẻ phá không chỉ cắt; chúng thu dữ liệu tải và thời gian khôi phục. + +Tiến phải chọn thứ tự sửa. Kha muốn kho lương trước. Linh yêu cầu bệnh viện. Hội đồng bỏ phiếu khẩn: bệnh viện, bơm nước, sau đó kho. Kha thua. + +Hắn không phá quyết định. Tự cử đội riêng về kho, không lấy kỹ thuật chung. Tại bệnh viện, ông Hòa và Đức nối điều khiển. Duy lần hướng phát dữ liệu tới một hầm hành chính. + +Tiến, Khánh An, Bình và Kha tới. Tài ở đó, bị trói. Ba người của ông chết. Con dấu đặt trên bàn như một chữ ký giả. + +Thiết bị vẫn chạy. Tài không phải người tổ chức; kẻ khác đã dùng chính hồ sơ của ông. Trên tường: + +**KHÔNG THÀNH PHỐ NÀO CẦN HAI CHÍNH QUYỀN TRƯỚC ĐỒNG BỘ.** + +Kha nói: “Intervention cũ.” Vân xác nhận kiểu mã. Một nhóm từng thuộc lớp can thiệp, không theo Kha, muốn một cơ cấu duy nhất để ngày 29 dễ điều khiển. + +Tài nhìn người chết. “Tôi nghĩ giữ hồ sơ là giữ nhà nước.” Thủy đáp: “Hồ sơ không giữ được người cầm nó.” + +Tiến cởi trói. “Ông còn bản nào?” + +“Có.” + +“Giấu?” + +“Có.” + +“Giờ?” + +Tài nhìn con dấu. “Chia.” + +Đêm kết thúc gần sáng khi mạng radio được nối lại theo cấu trúc luân phiên. Ba thay đổi: + +- nhóm Tài giao bản sao hạ tầng; +- Kha nối radio kho vào mạng chung có giám sát; +- trung tâm điều phối khẩn cấp chuyển quyền theo ca, không đặt cố định. + +Không một chủ. Nhiều chìa. Khi mặt trời lên, HANOI-07 phát trạng thái trên các thiết bị còn hoạt động: + +**SYNCHRONIZATION WINDOW: 30 DAYS** + +Hệ thống đếm theo ngày lịch và làm tròn phần ngày còn lại lên một đơn vị. Từ 21 giờ 06 ngày 30 tháng 8 tới 12 giờ 17 ngày 29 tháng 9 không tròn ba mươi ngày, nhưng màn hình không hiển thị giờ lẻ. Không lời đe. + +Một mốc. Cả thành phố thấy. + +Cùng lúc, Kha nhận tin kho Hậu Ký bị xâm nhập. + +Các khóa phần mềm hắn đã thay vẫn nguyên. Hai ổ lõi chuyển đi từ trước không bị chạm. Thứ Tùng dùng là đường phục hồi vật lý giấu trong bo mạch điều khiển — một mạch chỉ được cấp điện khi kho bị tách khỏi mạng chính. Đêm chia đảo đã tạo đúng điều kiện mà Kha biết nhưng không thể loại bỏ nếu còn muốn kho khởi động khi mất liên lạc. + +Cảm biến mồi báo chậm chín mươi mốt giây vì Tùng cho mạch tự kiểm tra lặp lại. Trong khoảng đó, hắn lấy một mảnh lõi thật, khóa truy vấn và hai ổ mồi. Không đủ để sở hữu toàn bộ Hậu Ký, nhưng đủ để ghép với những bản sao hắn đã giữ từ trước. Trên giá để lại một chiếc nhẫn đen giả. Kha cầm, không nói. + +Khánh An nhìn dấu phục hồi trên bo mạch. “Hoàng Tùng.” + +Kha đặt chiếc nhẫn giả cạnh sơ đồ bo mạch. Hai ổ lõi hắn chuyển trước vẫn an toàn; mảnh Tùng lấy đủ nguy hiểm nhưng không đủ toàn quyền. Khánh An nhìn đường phục hồi bị cháy đen và nói: “Anh phòng đúng thứ mình nhìn thấy. Hắn thắng ở thứ chỉ người thiết kế biết còn tồn tại.” + +Kha không đáp. Hắn không thua vì quên khóa cửa; hắn thua vì đã chấp nhận giữ một cánh cửa mà bản lề do đối thủ làm ra. Ba mươi ngày trước Đồng Bộ, thành phố vừa mất điện một đêm. Kha không mất toàn bộ tương lai, nhưng mất độc quyền đặt câu hỏi. + +Và người lấy biết chính xác cách biến một dự báo thành quyền lực. + +Trong thời gian mạng bị chia thành đảo, một khu chung cư không nhận được lệnh nào đã tự mở bể dự phòng, tắt thang máy và chuyển người già xuống tầng một. Họ sống qua ba giờ mà không cần trung tâm. Một khu khác chờ xác nhận vì sợ vi phạm hiệp ước; khi radio trở lại, ba người đã sốc nhiệt. + +Duy đưa hai báo cáo lên bàn. “Cùng mất liên lạc. Khác nhau ở quyền tại chỗ.” Từ đêm ấy, mọi quy trình chung phải ghi rõ điều người trực được tự quyết khi trung tâm im. Không ai gọi đó là tự trị hoàn toàn; giới hạn vẫn còn nguyên. Tuy vậy, việc trung tâm không trả lời từ nay không thể trở thành lý do để người trực đứng yên. + +Hoàng Tùng đã thu chính dữ liệu ấy: nơi nào sống khi bị cắt, nơi nào chờ. Hắn không chỉ lấy Hậu Ký. Hắn đang đo cấu trúc quyền lực mới của thành phố để biết điểm nào cần kéo về một trung tâm duy nhất. + +ARC 8: ĐẾM NGƯỢC NGÀY ĐỒNG BỘ + +Chương 67: Ba Mươi Ngày + +Ngày 31 tháng 8 bắt đầu bằng một con số. + +**30 DAYS** + +Nó hiện trên những thiết bị còn đủ nguồn để nhận tín hiệu: bảng điều khiển trạm bơm, radio kỹ thuật, điện thoại chết mạng nhưng chưa chết màn hình. Ở vài nơi, con số chỉ lóe bốn giây. Ở vài nơi khác, nó đứng nguyên tới khi pin cạn. HANOI-07 không giải thích. + +Con người làm phần còn lại. + +Đến trưa, chợ dưới cầu cạn đã có năm phiên bản về ngày Đồng Bộ. Một người bán muối bảo cổng dưới Hoàng Thành sẽ mở hầm trú cho người “được chọn”. Một bà cụ nói nước Hồ Tây dâng nuốt Ba Đình. Trẻ con Vành Ngoài gọi ngày 29 là “ngày chuông thứ mười hai”, dù không đứa nào thực sự nghe chuông. + +Thủy lập bản tin radio mỗi tối. Cô dùng ba mục cố định: + +**Đã đo.** +**Chưa biết.** +**Tin đồn.** + +“Đã đo: áp lực mạng nước đang tăng theo chu kỳ. Khóa phía Tây giữ. Hoàng Thành có dao động bốn phút vào 02 giờ 17. Chưa biết: ‘cổng’ là cấu trúc hay chế độ vận hành. Tin đồn: không có bằng chứng về hầm trú vô hạn hoặc danh sách người được cứu.” + +Giọng cô đi qua những chiếc radio rè, chen giữa thông báo đổi nước và tìm người mất tích. Không hấp dẫn bằng lời hứa sống sót. Nhưng ngày nào cũng có người chờ đúng giờ. + +Kha dùng xe tải chặn ba tuyến vào Ba Đình. Nhóm Tài dựng biển cảnh báo bằng con dấu cũ. Vòng Tròn Vỡ kêu gọi rời bán kính năm cây số. Hội đồng phía Tây chuyển trẻ em khỏi các nút. Mỗi phía cho rằng mình đang giảm hoảng loạn; kết quả là thành phố nhìn thấy bốn loại mệnh lệnh. + +Kho Hậu Ký bị lấy khiến Kha ít nói hơn. Ba ổ dữ liệu mất không chứa mọi câu trả lời, nhưng chứa lịch truy vấn, khóa giải mã và siêu dữ liệu — thứ cho biết hắn đã hỏi gì, không hỏi gì và câu nào tạo ra kết quả nào. Khánh An đặt chiếc nhẫn đen giả người trộm để lại lên bàn. + +“Hoàng Tùng,” cô nói. + +Cái tên đã có trong hồ sơ Kho Hậu Ký: kỹ sư an ninh dữ liệu, người chia hệ thống thành nhiều kho, được ghi chết trong vụ cháy ngày 23 tháng 6. Nhưng không có xác, chỉ còn thẻ và camera hỏng. Kha xoay chiếc nhẫn thật trên tay. “Hắn chọn thời điểm này vì mỗi câu hỏi bây giờ đều có thể biến thành lệnh.” + +“Vì sao để lại nhẫn?” Tiến hỏi. + +“Nhắc tao rằng cấu trúc kho vẫn mang dấu tao. Hoặc muốn người khác nghĩ tao tự lấy.” + +Thủy ghi cả hai khả năng. + +Trưa hôm đó, radio thành phố phát một danh sách ba mươi bảy người được gọi là **những người sẽ chết trước ngày 29**. Tên đầu: + +**LÊ QUỐC TIẾN — 12/09/2028** + +Tiến đọc trên màn hình của Nam. Bàn tay trái tự tìm mép bàn, đúng vị trí hắn thường bám mỗi khi ký ức Mễ Trì kéo về. Cơ thể đã phản ứng với “ngày chết” trước khi lý trí kịp nhắc rằng cái chết ấy thuộc năm 2031, không phải hiện tại. Các tên sau khiến danh sách có vẻ đáng tin hơn: + +- Hổ — 05/09. +- Lâm — 08/09. +- Tuấn — 14/09. +- Nguyễn Hữu Đạt — đã chết. +- Trần Thanh Thủy — không có bản ghi sau Đồng Bộ. +- Phạm Ngọc Vân — trạng thái không xác định. + +Một hỗn hợp của đúng, sai, cũ và chưa xảy ra. Đủ để thay đổi hiện tại. + +Hổ hủy hai chuyến đường đúng ngày 5, khiến một khu thiếu nước. Lâm khóa kho thuốc, không cho người ngoài vào vì sợ bị ám sát. Gia đình Tuấn ép ông rời hội đồng. Một người trong danh sách bỏ trốn khỏi khu trú rồi chết vì nhiệt ngoài đường — khác nguyên nhân Hậu Ký ghi, nhưng chính cái tên trên danh sách đã đẩy ông ra ngoài. + +Thủy phát bản tin khẩn. + +“Hậu Ký từng ghi ông Hòa và Phúc chết ở Trạm Láng. Họ còn sống. Danh sách này không phải bản án.” + +Một giọng nam gọi vào: “Nếu sai, sao biết đúng tên tôi?” + +“Vì nó có hồ sơ.” + +“Ngày thì sao?” + +“Phải biết câu hỏi tạo ra ngày đó.” + +“Cô bảo chúng tôi đánh cược mạng?” + +Thủy nhìn qua cửa kính phòng radio. Trẻ con đang dùng nắp chai xây một vòng thành khác, lần này có bốn cổng như Hạnh đã dạy. + +“Các anh vẫn đánh cược mỗi ngày,” cô nói. “Người phát danh sách đang bán cảm giác rằng họ biết kết quả.” + +Tối, một tin riêng tới điện thoại Tiến: + +**MUỐN BIẾT VÌ SAO MÀY CHẾT NGÀY 12/09, ĐẾN MỄ TRÌ.** + +Đây không phải Mễ Trì của năm 2031, mà là Mễ Trì hiện tại. + +Một cái móc đặt đúng vào vết thương cũ. Tiến không giấu. Hắn đưa tin cho hội đồng. Tuấn vẫn ngồi đó dù tên mình có ngày chết, hai bàn tay giữ chặt cốc nước. + +“Bẫy?” ông hỏi. + +“Đúng.” + +“Đi?” + +“Có.” + +“Không một mình.” + +Ánh mắt Tiến đi qua từng người. Ngày trước, hắn sẽ coi lời đe dọa là dữ liệu riêng vì mục tiêu là mình. Bây giờ, nếu đi, xe, người và nguồn dự phòng thuộc cộng đồng. Hội đồng cử Thủy, Bình, Khánh An và Đạt. Nam phụ trách liên lạc. Kha được nghe nhưng không có quyền điều đội Ngọc Trục. + +Sau cuộc họp, Thủy đặt lịch truy vấn còn sót cạnh danh sách chết. Ngay trước khi danh sách được phát có một truy vấn dùng khóa Hoàng Tùng. Nội dung đã bị xóa. + +“Ngày 12 không tự xuất hiện,” cô nói. “Có người hỏi một câu.” + +Ánh mắt Tiến dừng ở tên mình. “Chúng ta cần biết câu nào.” + +Ngoài sân, một người thợ vẫn sửa mái phản nhiệt dù đã nghe mình có thể chết ngày 8. Ông nói với Bình: “Ngày chết chưa tới, mái vẫn dột.” Ba mươi ngày trước Đồng Bộ, tương lai bắt đầu được dùng như vũ khí. + +Nhưng thành phố vẫn phải sống bằng những việc không thể chờ câu trả lời: vá mái, đun nước, đổi thuốc và quyết định sáng mai có mở cổng cho người lạ hay không. + +Chương 68: Hậu Ký Gốc + +Mễ Trì B3 chưa có mùi máu. Nó chỉ có bê tông nóng, dây điện mới và bụi xây dựng — nhưng cơ thể Tiến vẫn nhớ một căn phòng khác nằm chồng lên nơi này. Hắn dừng ở cửa, kiểm lối thoát ba lần và nhận ra mình đã nín thở. + +Thủy không chạm. Cô đứng trong tầm mắt. “Hiện tại.” Tiến gật, bước vào. + +Hoàng Tùng không xuất hiện. Hắn để một hộp kim loại, ba camera và loa có dây. Bình kiểm nguồn; Khánh An kiểm góc bắn; Đạt đứng ngoài vùng đánh dấu để trạng thái Null của ông không bị đưa vào phép thử ngay từ đầu. Hộp mở khi cảm biến nhận Tiến. + +“Chào Người Trở Về,” giọng Tùng nói. + +Tiến đối diện camera. “Tên tôi là Tiến.” + +“Danh xưng hữu ích hơn.” + +“Với anh.” + +Kha nghe qua đường dây từ điểm ngoài. “Tùng, mày mở kho của tao.” + +“Anh gọi nó là của anh quá lâu.” + +Bên trong hộp có một ổ dữ liệu kiểu cũ. Tùng không yêu cầu họ cắm. Hắn chiếu hai truy vấn lên tường. + +**Nếu Hoàng Văn Hòa ở Trạm Láng đêm 19/07, kết quả tử vong gần nhất là gì?** + +**DECEASED — 23:41** + +Câu thứ hai: + +**Nếu Khóa phía Tây ổn định trước 23:41, trạng thái Hoàng Văn Hòa là gì?** + +**UNRESOLVED** + +Cùng người, cùng đêm, khác điều kiện. Thủy tiến gần màn chiếu. “Hậu Ký trả lời theo câu hỏi.” + +“Đúng.” + +“Không phải một cơ sở dữ liệu hoàn chỉnh về tương lai.” + +“Không.” + +Kha im. Im lặng của hắn xác nhận hắn đã biết nhiều hơn điều từng nói. Tùng hiện truy vấn tạo ngày chết Tiến: + +**Nếu Lê Quốc Tiến tiếp tục giữ quyền truy cập tới ngày 29/09, thời điểm sớm nhất có thể loại bỏ ảnh hưởng của hắn là khi nào?** + +Kết quả: + +**12/09/2028** + +Tiến đọc lại, dừng ở hai chữ **có thể**. + +“Nó không viết ‘sẽ chết’.” + +“Danh sách cần ngôn ngữ người ta hiểu,” Tùng nói. + +“Anh đổi khả năng thành định mệnh.” + +“Tôi làm họ phản ứng. Phản ứng là dữ liệu.” Tùng không né. “Khi đủ người đổi đường, khóa kho hoặc rời vị trí vì một ngày chết, hiện tại tự dịch về gần điều kiện của truy vấn. Danh sách không chỉ đo tương lai. Nó ép tương lai dễ tính hơn.” + +Cách hắn nói giống những lớp mã cũ: câu ngắn, ít chủ ngữ, con người luôn bị rút thành đầu vào và đầu ra. Thủy đã thấy dấu ấy từ chuỗi số nguyên tố trên marker của Phúc; tới lúc này, chữ ký kỹ thuật mới có một khuôn mặt. Thủy nhìn camera. “Người có thể chết vì dữ liệu anh thu.” + +“Người vẫn chết khi không có nó.” + +Tùng không hoàn toàn nói suông. Hắn phát một đoạn ghi về khu Cầu Diễn: ba ngày trước, một truy vấn của hắn dự báo tuyến bơm sẽ hỏng trong đợt nhiệt. Nhóm tin hắn đã chuyển trẻ em xuống hầm và sống qua. Hai trăm người được cứu. + +“Anh muốn chúng tôi biết anh từng đúng,” Tiến nói. + +“Muốn các anh hiểu một công cụ nguy hiểm không vì thế vô dụng.” + +Đây là lý do Tùng có người đi theo. Không chỉ vì con số 38%. Có những người còn sống nhờ hắn hỏi đúng câu. Ổ “gốc” không chứa toàn bộ tương lai. Nó chứa giao thức truy vấn được lưu trong máy chủ Observation Initiative năm 2026: một tệp mười ba kilobyte, mốc Hồng Nhật, một số tọa độ và câu: + +**ĐỪNG ĐỂ MỘT NGƯỜI GIỮ TẤT CẢ PHƯƠNG ÁN.** + +Tùng mở phần nhật ký mà bản Kha giữ đã bị xóa. Tệp không đi vào qua mạng ngoài. Lúc 02 giờ 17 phút ngày 29 tháng 9 năm 2026, một khối dữ liệu bốn kilobyte xuất hiện trực tiếp trong bộ nhớ của rơ-le thử nghiệm sau một xung cộng hưởng. Không địa chỉ gửi, không tài khoản và không tuyến truyền. + +Duy nhận ra phần còn lại. Lớp vỏ đọc dữ liệu, bảng câu hỏi và cách nén chỉ mục là mã anh viết theo yêu cầu của Trần Văn Tĩnh sau sự cố đó. Phạm Ngọc Vân thêm câu cảnh báo. Nhóm ba người đã bọc khối dữ liệu lạ thành một công cụ có thể đọc, rồi Tĩnh tách khóa và giấu tên người tạo khi Observation Initiative bắt đầu chia phe. + +“Vậy Hậu Ký không tự xuất hiện nguyên vẹn,” Thủy nói. + +“Không,” Duy đáp qua đường dây. “Con người viết công cụ. Nhưng phần lõi chứa ngày Hồng Nhật và các mốc tương lai không do máy chủ năm 2026 tạo ra.” + +Anh đặt tiêu đề khối lõi cạnh siêu dữ liệu của dải nhớ Mễ Trì. Cách đánh dấu nguồn, thứ tự kiểm lỗi và một chuỗi băm đầu trùng nhau. + +“Lõi này cùng họ với gói ghi trạng thái năm 2031,” Đạt nói. + +“Khả năng cao,” Duy đáp. “Chưa đủ để nói nó được gửi bằng cách nào. Nhưng đủ để loại giả thuyết có một người vô danh tải tệp qua mạng rồi biến mất.” + +Tùng không phản đối. “Giao thức là sản phẩm của Duy, Tĩnh và Vân. Hạt giống dữ liệu đến từ một sự kiện phản hồi chưa xảy ra đối với năm 2026. Đó là nguồn thật, dù các anh có thích vòng nhân quả ấy hay không.” Mỗi lần dự án truy cập nút, hệ thống có thêm dữ liệu. Người dùng hỏi về kho, đường, người sống, người chết. Kết quả được lưu, chồng và dùng để đặt câu hỏi mới. + +“Hậu Ký lớn lên vì người ta hỏi,” Thủy nói. + +“Và hiện tại hẹp lại vì người ta làm theo,” Đạt nói từ ngoài. + +Tùng đáp: “Hiện tại cũng hẹp đi khi các anh không làm.” Hắn đưa cảnh báo ngày 12: một đợt nhiệt thứ hai có thể đánh Hà Nội. Hàng nghìn người chết nếu không chọn đúng tuyến và điểm trú. + +“Cho dữ liệu thô,” Thủy yêu cầu. + +“Đổi trạng thái Tiến để giải truy vấn.” + +Tiến cân ổ dữ liệu trong lòng bàn tay. “Anh cần tôi làm nguồn có trọng lượng.” + +“Returned mang chuỗi mà hệ thống không có ở hiện tại. Có anh, xác suất rõ hơn.” + +“Không.” + +“Anh đặt tự do của mình trên mạng người khác.” + +“Anh đặt câu hỏi sao cho chỉ có một câu trả lời đạo đức.” + +Tùng để một khoảng trống kéo dài rồi nói: “Tôi từng chờ bốn mươi bảy phút vì bốn người không ai dám quyết.” Kha ở đầu dây cứng người. Đó là số phút từ hồ sơ Bắc Ninh của Kha. Tùng biết vết thương của hắn và đang dùng nó. + +“Đừng lấy em tao làm lý luận,” Kha nói. + +“Tôi lấy dữ liệu.” + +“Đó là lý do mày không hiểu.” + +Kha — người vẫn gọi mọi thứ bằng giá — lần đầu bác một người vì đã biến người chết thành số quá sạch. Thiết bị bắt đầu tắt. Trước khi mất, Tùng nói: “Ngày 12 sẽ tới dù các anh có thích cách tôi hỏi hay không.” + +Họ rời B3 với dữ liệu áp suất khí quyển, bức xạ và nhiệt nền được Tùng cho một phần — đủ để xác nhận nguy cơ tăng, không đủ để chọn tuyến tối ưu. Tiến không hỏi Hậu Ký. + +Hắn yêu cầu mọi khu đo nhiệt, tách nước, kiểm hầm và chuẩn bị nhiều điểm thay vì một tuyến “đúng”. Có thể kém hiệu quả hơn phương án Tùng. Cũng khó khiến một lỗi duy nhất giết tất cả hơn. Trên đường về, Thủy nói: “Tùng đã cứu Cầu Diễn.” + +“Ừ.” + +“Anh vẫn từ chối.” + +“Không từ chối dữ liệu. Từ chối giao bản thân làm chìa để hắn hỏi thay mọi người.” + +“Khác biệt cần được giữ rõ.” + +Tiến dõi Mễ Trì lùi sau cửa xe. Một nơi có thể là cái chết vẫn vừa cho hắn một dữ liệu giúp cứu người. Trên đường về, Tiến giữ phần dữ liệu Tùng đã đưa và từ chối chiếc khóa hắn đòi. Hai thứ nằm trong hai túi khác nhau. + +Chương 69: Người Bị Xóa + +Phạm Ngọc Vân không đưa Thủy vào một phòng bí mật. Bà đưa cô tới phòng cũ của một trạm y tế, tháo camera khỏi tường và đặt nó lên bàn cho cả hai cùng nhìn thấy. Không có nơi nào hoàn toàn ngoài HANOI-07; chỉ có nơi giảm bớt số lớp đang ghi. + +Danh sách Null Protocol gồm hai mươi ba người. Không chỉ tên và trạng thái. Vân mang hồ sơ y tế, ảnh gia đình, nghề nghiệp và những thứ họ mất sau thủ tục. Một kỹ sư điện mất khả năng nhận mặt vợ trong ba tháng. + +Một y tá quên đường về nhà nhưng vẫn nhớ liều thuốc. Một người đàn ông bị hệ thống ghi chết, sau đó không thể chứng minh quyền lấy khẩu phần vì mọi sổ đều từ chối tên ông. + +Nguyễn Hữu Đạt. Phạm Ngọc Vân. + +Hoàng Tùng. Thủy dừng ở tên Tùng. “Hắn từng bị Null?” + +“Ba tháng,” Vân nói. “Sau đó tự nối lại.” + +“Vì muốn được nhìn?” + +“Vì muốn được hỏi.” + +Với người khác, biến mất khỏi mạng có thể là tự do. Với Tùng, đó là mất quyền truy vấn. Tên **TRẦN THANH THỦY** nằm ở phần ghi chú: + +**CANDIDATE — REJECTED** + +“Duy đề xuất?” + +“Ngày 10 tháng 5.” + +Trước Hồng Nhật, khi Thủy vừa nhận file HANOI-07, Duy đã muốn cắt cô khỏi trường quan sát. Đề xuất bị bác vì cô chưa tiếp xúc nút và tác động thần kinh chưa rõ. + +“Anh ấy muốn bảo vệ tôi,” Thủy nói. + +“Có thể.” + +“Vẫn là quyết thay.” + +“Đúng.” + +Vân không biện hộ cho đồng nghiệp. + +“Nếu làm bây giờ?” + +“Cô có thể mất khả năng nghe. Có thể mất ký ức gắn mạnh với cộng hưởng. Có thể chỉ mất đường truy cập trong vài giờ.” + +“Tiến?” + +“Có thể nằm trong phần bị ảnh hưởng.” + +Thủy nhìn bàn tay mình. Vết chai ở ngón trỏ có từ trước tận thế — một dấu nhỏ mà HANOI-07 chưa từng tạo ra cho cô. + +“Bà cần Người Nghe ngày 29.” + +“Có.” + +“Vẫn đưa tôi quyền từ chối?” + +Vân nhìn ra cửa. “Tôi từng dùng My để kiểm một giả thuyết. Tôi biết một lời xin lỗi không trả lại tuổi thơ cho con bé. Tôi không muốn tiếp tục gọi con người là điều kiện.” Đó không phải sự chuộc tội hoàn tất, chỉ là giới hạn bà tự đặt sau khi đã vượt quá. + +Vân đưa thiết bị Null tạm. Một hộp nhỏ có hai điện cực và công tắc cơ, tối đa bốn phút. + +“Nếu tiếng chuông lấn toàn bộ âm thật, đặt vào vùng cổ này.” Bà chỉ. “Sau khi tắt, đừng đứng dậy nhanh. Có thể mất thăng bằng và thính giác.” + +“Dùng bao nhiêu lần?” + +“Không biết mức an toàn.” + +Thủy cầm thiết bị, cảm nhận trọng lượng thật. Một lựa chọn đạo đức cuối cùng cũng có khối lượng, góc cạnh và nguy cơ bỏng da. Cô tìm Duy ở khu máy. Anh đang sửa rơ-le bằng tay còn run. + +“Anh đề xuất xóa tôi.” + +Duy không hỏi cô biết từ đâu. “Vì sợ hệ thống dùng cô.” + +“Không hỏi tôi.” + +“Đúng.” + +“Anh xin lỗi nhiều.” + +“Có nhiều việc.” + +“Xin lỗi không trả quyền.” + +Duy đặt tua vít xuống. “Tôi không biết phải làm gì khác với điều đã làm.” Thủy đưa danh sách. “Giúp tôi ghi lại. Không chỉ tên. Vì sao, ai ký, người đó mất gì, ai phải sống cùng hậu quả.” + +Họ bắt đầu bằng người chủ kho Ngọc Trục đời trước. Ông đã Null một phần bản vẽ để Observation Initiative không đào vào điểm truy cập. Vì vậy hồ sơ nền thiếu góc phía tây. Ông không phải thành viên một âm mưu lớn; chỉ là người sợ dự án lấy kho và khu dân cư. + +Thủy thu lời kể của những người còn sống qua radio. Một phụ nữ nói chồng bà sau Null không nhớ ngày cưới nhưng vẫn nhớ tiếng cửa nhà. Bà không biết nên coi đó là mất hay còn. Tối, Thủy mở máy ghi âm đời thường. Cô nghe tiếng mình cười ở bếp, tiếng Tiến nói “đưa kìm” ngoài sân, tiếng một đứa trẻ hát sai lời. + +Nếu Null lấy đi một phần ký ức, cô muốn để lại bản ghi không nhằm ép “Thủy cũ” quay trở lại, mà để người sau biết cô từng là ai ngoài cái nhãn Listener. Cô ghi tên mình ở cuối danh sách, chưa đánh dấu thực hiện. + +Bên cạnh, cô viết: + +**Nếu tôi chọn Null, đây là quyết định của Trần Thanh Thủy. Không phải yêu cầu của HANOI-07, Tiến, Vân hay bất kỳ phe nào.** + +Thủy cất thiết bị Null vào túi máy ghi. Nó nằm sát miếng dán con cá đã sờn từ thời sinh viên, hai vật chạm nhau mỗi khi cô bước. + +Chương 70: Neo Không Phải Neo + +Mẹ Tiến từ chối chuyển tới điểm hắn đã chọn sẵn. + +“Ngày 12 có thể có đợt nhiệt,” hắn nói qua rơ-le. + +“Có thể?” + +“Dữ liệu bức xạ tăng. Áp suất cũng đổi.” + +“Con chắc nơi con chọn an toàn?” + +“Không.” + +“Vậy mẹ dùng nơi đã kiểm, không dùng nỗi sợ của con.” + +Bà và bác Dũng chọn một hầm nhỏ gần vùng đồi, có giếng nông, hai lối thoát và ít người biết. Tuyến Tiến đề nghị xa hơn, đi qua hai chốt đã bị lộ. Hắn biết bà có lý. Cơ thể vẫn muốn điều người tới kéo bà đi. + +Tiến kể về cụm từ **anchor condition**. Không toàn bộ hồ sơ, nhưng đủ để bà hiểu người ta từng coi bà như thứ làm hắn phản ứng dự đoán được. + +“Ba năm kia con không biết mẹ sống hay chết,” bà nói. + +“Ừ.” + +“Con vẫn sống.” + +“Không nghĩa mẹ không—” + +“Mẹ là mẹ.” Giọng bà cứng lại. “Không phải sợi dây điện để cắm con vào hiện tại.” + +“Nếu con quên mẹ?” + +“Mẹ kể.” + +“Nếu con không tin?” + +“Mẹ mắng.” + +Tiến bật cười. Nam ở bàn radio quay đi để hắn có khoảng riêng. + +“Đừng hứa sống,” bà nói. + +“Mẹ.” + +“Không hứa thứ con không giữ được. Hứa đừng tự biến mình thành cái máy vì nghĩ không có con mọi người chết.” + +Ánh mắt Tiến dừng ở chữ **HOST** trong log. “Con hứa.” Sau cuộc gọi, hắn sửa bảng quy tắc nội bộ: + +**ANCHOR CONDITION: CHƯA XÁC ĐỊNH. KHÔNG ĐƯỢC COI CON NGƯỜI LÀ THIẾT BỊ.** + +Thủy đọc rồi nói: “Mẹ anh mất ít phút để phá một thuật ngữ nhóm nghiên cứu giữ nhiều năm.” + +“Bà ấy không cần giữ dự án.” + +“Đúng. Chỉ cần giữ anh.” + +Ngày 12 được chuẩn bị theo dữ liệu thô chứ không theo tuyến Hậu Ký: + +- nước chia nhiều kho; +- người già và trẻ nhỏ xuống vùng mát từ sớm; +- mái phản nhiệt được tưới trước giờ tăng; +- xe tách tuyến; +- bệnh viện có đội bóp bóng tay; +- mọi điểm báo nhiệt bằng đồng hồ cơ nếu radio chết. + +Duy nhận được một mẩu dữ liệu đo xa từ vệ tinh khí tượng cũ do nhóm Tài phục hồi. Dữ liệu ngoài tầng khí quyển cho thấy quang phổ mặt trời không chuyển đỏ theo mức người dưới đất nhìn thấy. Phần đỏ và phần nhiệt tăng mạnh xuất hiện khi bức xạ đi qua khí quyển. + +“Vậy đĩa mặt trời ngoài khí quyển không đỏ như chúng ta thấy?” Thủy hỏi. + +“Không ở mức này,” Duy đáp. Anh tách báo cáo thành ba lớp để không biến một giả thuyết thành lời giải duy nhất. “Chuỗi bão Mặt Trời gây ion hóa mạnh và nhiễu từ quyển. Cùng thời gian đó, khí quyển thấp xuất hiện lượng aerosol và bụi kim loại bất thường, làm tán xạ ánh sáng khiến đĩa mặt trời đỏ thẫm. Chính lớp hạt và khí ấy còn làm thay đổi cân bằng bức xạ, giữ nhiệt gần mặt đất.” + +“Bão Mặt Trời tạo ra bụi?” + +“Không có bằng chứng. Nó có thể là tác nhân khởi đầu, không phải nguồn vật chất duy trì. Phần đó vẫn chưa biết.” + +Đó chỉ là một manh mối, chưa phải lời giải cuối. Điều quan trọng hơn: HANOI-07 không tạo ra Hồng Nhật. Hệ thống dưới Hà Nội chỉ đang cố thích nghi với một thảm họa toàn cầu ở phía trên. 12 giờ 02, nhiệt không khí trong bóng râm tăng từ 49 lên 53 độ; nhiệt bề mặt ngoài đường vượt 67. Con số 68 trong ký ức Tiến thuộc về mặt bê tông phơi nắng, không phải nhiệt độ không khí của toàn thành phố. Người ra ngoài không bảo hộ vẫn có thể bỏng và sốc nhiệt trong vài phút. + +Các khu đã vào vị trí. Một trạm nhỏ không nghe cảnh báo vì radio hỏng. Đội Bình phát hiện qua lịch cơ và đưa ba mươi người xuống hầm. Bốn người chết trước khi tới, không hàng nghìn như Tùng cảnh báo. + +Cầu Diễn — khu từng được Tùng cứu — gần như nguyên vẹn nhờ tuyến hắn chọn. Bởi vậy, cuộc tranh luận không thể khép lại đơn giản bằng kết luận “Tùng sai”. Tiến không chết ngày 12. + +Danh sách Hậu Ký sai theo nghĩa người ta đã nghe, nhưng dữ liệu nguy cơ không vô ích. Tùng phát radio: “Các anh sống vì cảnh báo của tôi.” + +Thủy đáp: “Thông tin của anh giúp. Cách anh đổi điều kiện loại bỏ thành ngày chết khiến người khác hoảng và khóa tài nguyên.” + +“Không có sức ép, các người chuẩn bị nhanh thế?” + +Tiến cầm máy. “Có thể không.” Kha nhìn hắn qua kênh chung, có lẽ không ngờ Tiến thừa nhận. + +“Anh cứu được người,” Tiến nói. “Điều đó không cho anh quyền chọn thay tất cả lần sau.” + +Tùng không trả lời. Tối, mẹ gọi. + +“Còn sống?” + +“Vâng.” + +“Ăn chưa?” + +“Chưa đói.” + +“Mẹ không hỏi con đói.” + +Tiến mở phần lương khô, ăn trước micro. Một mệnh lệnh nhỏ từ người thật. Hắn làm theo không vì bị một hệ thống đo phản ứng, mà vì giữa hai người có một thứ tự nguyện trao quyền — và có thể từ chối mà không bị biến thành sai lệch. + +Ngoài mái, Hồng Nhật xuống thấp, vẫn đỏ qua lớp khí quyển chưa ai hiểu. Dưới nó, Hà Nội sống qua ngày chết đầu tiên mà Hậu Ký công bố. + +Chương 71: Bốn Mươi Ba Phút + +Khoảng trống trong bản ghi Mễ Trì dài bốn mươi ba phút, nhưng không đơn giản là một đoạn video đen. Hình ảnh, nhiệt, âm thanh và dữ liệu thần kinh đều dừng ở những thời điểm lệch nhau vài phần giây, như thể các lớp ghi bị tắt theo một trình tự. + +Duy không cắm dải nhớ vào HANOI-07 để yêu cầu “khôi phục”. Nếu làm vậy, họ có thể chỉ nhận lại một phương án do chính mô hình đang bị nghi ngờ tự điền vào. Họ dựng lại bằng thứ vật liệu không dễ kể chuyện theo ý người xem. Ông Hòa làm mô hình sàn B3 từ bản vẽ và vết lún. + +Đức tính đường tải điện. Đạt đo khoảng bước chân trong phần âm còn sót. + +Thủy lọc từng dải tần, không dùng tai mình làm nguồn duy nhất. Kha đưa cấu trúc thiết bị Intervention từng đặt ở Mễ Trì. Hắn không được đứng một mình với bản ghi; Khánh An giữ một bản sao giấy của mọi thông số hắn cung cấp. + +Tiến viết ký ức riêng trước khi xem kết quả. Hắn ghi mùi, vị máu, vị trí Kha, cảm giác dao, nhưng không cố lấp đoạn không nhớ. Tờ giấy được niêm phong để ký ức không tự sửa theo mô hình sau. + +Ngày thứ nhất, họ chỉ xác nhận được tải nhiệt. Thiết bị ở B3 đã nhận một mức năng lượng đủ làm lớp polymer trên cáp chảy mềm. Tiến tương lai giữ tiếp xúc ít nhất mười một phút. Kha ở trong phòng nhưng không chạm giao diện. Một người thứ ba vào rồi rời, bước chân kéo nhẹ bên trái. + +Ngày thứ hai, Thủy tìm được ba mảnh âm. Giọng Tiến tương lai: + +“…nếu tôi giữ lại, nó sẽ dùng tôi để gọi về…” + +Giọng phụ nữ: + +“…xóa đoạn này…” + +Giọng Kha: + +“…mày sẽ không nhớ thỏa thuận…” + +Không câu nào trọn. Nhưng chúng phá một sự chắc chắn: Kha không đơn giản bước vào và giết một người hoàn toàn không biết điều gì. Tiến nghe mảnh âm bằng loa. Khi giọng mình tương lai nói từ “gọi về”, hắn nôn khan. Mùi bê tông nóng trong phòng phân tích biến thành Mễ Trì cũ, dù nhiệt ở đây thấp hơn mười độ. + +Thủy tắt ngay. + +“Chưa hết,” Tiến nói. + +“Cơ thể anh nói hết hôm nay.” + +“Cô không quyết.” + +“Đúng. Tôi đề nghị. Anh đang run tới mức không cầm được cốc.” + +Tiến hạ mắt xuống bàn tay. Nó thật sự run. Họ dừng. + +Ngày thứ ba, Duy phát hiện mẫu dẫn dưới da Tiến tương lai: không phải hình xăm hay “tia sáng”, mà là một lớp vật liệu giao diện cực mảnh bám quanh dây thần kinh, tạo thành đường giống mạng nút. + +“HANOI-07 dùng trạng thái thần kinh làm bộ nhớ?” Đạt hỏi. + +“Có thể là bộ đệm tạm,” Duy nói. “Nếu quá trình ghi hoàn tất, một lớp ký ức và phản xạ có thể được đóng gói như dữ liệu của một nút sống.” + +Anh đặt hai bản đo cạnh nhau. Nhịp tự chủ nền của Tiến trong những phút đầu ngày 09 tháng 5 vẫn khớp hồ sơ năm 2023, trong khi các phản ứng với Mễ Trì mang mẫu của năm 2031. Hai lớp cùng tồn tại, không có dấu một lớp đã xóa lớp kia. + +“Vậy người tỉnh dậy năm 2028 vẫn là tôi của ngày đó?” Tiến hỏi. + +“Dữ liệu hiện có nghiêng về việc ký ức được ghép thêm, không phải ý thức bị thay,” Duy đáp. “Nhưng đây mới là dấu vết, chưa phải lời giải cuối.” + +“Ngày 29/09/2028 tôi nhận vật liệu?” + +“Chưa biết. Có thể anh chỉ nhận mẫu ký ức; lớp vật liệu ba năm sau mới hình thành khi tiếp xúc thiết bị Mễ Trì.” + +Kha đứng gần cửa. “Vì sao phải giết?” Duy nhìn hình. “Nếu không thể tháo giao diện và quá trình ghi trạng thái tiếp tục, ngừng hoạt động thần kinh là một cách cắt.” + +Một cách kỹ thuật để nói giết người. Kha không né. “Tao làm theo yêu cầu?” + +“Có khả năng,” Thủy nói. “Chưa đủ để kết luận.” + +Tiến mở phong bì ký ức của mình. Trong đó, trước cú dao, căn phòng chỉ còn những mảnh rời: ánh đèn đỏ, giọng Kha, cảm giác đã quên một việc quan trọng. + +“Có người đã xóa đoạn khỏi tôi,” hắn nói. + +Vân xem dữ liệu Null. Bà không nhận chắc người phụ nữ là mình. Giọng có thể là phiên bản ba năm sau hoặc tổng hợp. Bước chân kéo trái phù hợp chấn thương Vân có trong một phương án năm 2029, nhưng dùng Hậu Ký để xác nhận người trong Hậu Ký sẽ thành vòng lặp. + +Thủy ghi: + +**Phù hợp, chưa xác nhận.** + +Trong biên bản, Thủy giữ nguyên chữ **có thể**. Cô từ chối đổi nó thành một mệnh đề chắc chắn chỉ vì câu chuyện như thế sẽ gọn hơn. Kết luận của ba ngày chỉ có ba dòng: + +1. Ký ức Tiến không hoàn chỉnh và có dấu Null. +2. Kha trong ít nhất một phương án biết một thỏa thuận mà Tiến sau Null không nhớ. +3. Trạng thái Returned có liên quan tới một quá trình ghi thần kinh chưa hoàn tất. + +Thủy không công khai ảnh mô thần kinh. Cô công khai phương pháp, kết luận và quyền riêng tư của Tiến. Tuấn hỏi tại sao dữ liệu có thể ảnh hưởng thành phố lại không thuộc cộng đồng. + +“Vì cơ thể một người không trở thành tài sản công chỉ vì hệ thống đã dùng nó,” cô đáp. + +Tối, Tiến ngồi ngoài mái, lưng dựa bức tường mát hơn không khí. Hắn lấy thanh lương khô từng giấu dưới gối, bẻ đôi và đưa Thủy một nửa. + +“Ba năm tôi sống bằng ký ức,” hắn nói. “Nếu nó không phải bản đồ, tôi còn gì?” + +“Chuyên môn.” + +“Không đủ.” + +“Người khác.” + +“Không chắc.” + +“Không.” Thủy ăn một miếng nhỏ. “Nhưng người khác có thể sửa anh khi anh nhớ sai. Bản đồ không làm vậy.” + +Tiến ngước lên vầng đỏ qua mái tôn. Lần đầu, việc ký ức không hoàn chỉnh không chỉ là mất lợi thế. Nó là khoảng trống đủ để hiện tại chưa bị lấp kín. + +Chương 72: Kẻ Phản Bội + +Hoàng Tùng xuất hiện trực tiếp ngày 16 tháng 9 trên sân thượng một trung tâm dữ liệu cũ. Hắn không mặc áo giáp hay che mặt. Người gầy, tóc cắt ngắn, bàn tay trái có vết bỏng từ vụ cháy được ghi là đã giết hắn. Sáu người Intervention cũ đứng sau; phía dưới còn xe từ Cầu Diễn — khu từng sống qua đợt nhiệt nhờ truy vấn của Tùng. + +Những người đi cùng Kha không phải một đội quân mua bằng lời hứa; có người thật sự nợ hắn mạng. Kha tới cùng Khánh An và hai đội trưởng, không kéo toàn bộ lực. Tiến, Thủy và đại diện hội đồng đứng ở lối khác. Hai phía có thể bắn nhau, nhưng mọi người đều biết ổ dữ liệu trên bàn sẽ cháy trước khi ai thắng. + +Tùng nhìn Kha. “Anh để hội đồng quyết xe của anh.” + +“Để xe chạy khi tao bị bắn.” + +“Anh gọi đó là trưởng thành?” + +“Gọi là giảm điểm hỏng.” + +Tùng chỉ ổ giao thức. Trong hai tuần, hắn đã đặt hàng trăm truy vấn, thay đổi điều kiện tới khi một phương án đạt tỷ lệ cao nhất: + +**38% dân số vùng được ghi nhận sống qua Đồng Bộ.** + +Điều kiện: + +- tập trung nguồn lực phía Tây; +- bỏ các khu không đủ dữ liệu và quá xa; +- kiểm soát toàn bộ nút; +- loại Tiến khỏi quyền truy cập sau 29/09; +- dùng Thủy làm bộ lọc tín hiệu; +- Đạt xác nhận trạng thái; +- Kha điều phối hậu cần; +- cấm Null. + +Một kế hoạch rõ, tàn nhẫn và có những người sống thật để bảo vệ nó. Một phụ nữ Cầu Diễn bước lên. “Nếu không có anh Tùng, con tôi chết ngày 12.” + +Thủy hỏi: “Chị có được biết phương án bỏ khu nào không?” Người phụ nữ im. + +Tùng nói: “Không thể cứu tất cả.” + +“Đúng,” Thủy đáp. “Nhưng người bị bỏ có quyền biết mình không nằm trong mẫu.” + +Câu truy vấn gốc hiện trên màn hình: + +**Tối đa hóa số người có dữ liệu sống qua 29/09 với hạ tầng còn vận hành.** + +Mô hình không tính được người ngoài dữ liệu, quyền tự quyết hay những gì xảy ra ba năm sau. Tùng không giấu điều đó. “Mọi câu hỏi đều cần giới hạn.” + +Tiến hỏi: “Ai chọn giới hạn?” + +“Người đủ khả năng hiểu hậu quả.” + +“Anh.” + +“Hiện tại, đúng.” + +Kha cười không vui. “Mày phản tao để thành tao với bảng số đẹp hơn.” + +“Anh dùng dữ liệu nhưng vẫn để cảm xúc làm lệch.” + +“Cảm xúc nào?” + +“Em trai anh.” + +Không khí trên sân thượng đổi. Khánh An đặt tay gần súng, không vì sợ Kha bắn ngay, mà vì biết vết thương bị người khác dùng sẽ kéo hắn trở lại thói quen cũ. Kha bước một bước. “Đừng dùng người chết của tao làm điều kiện truy vấn.” + +Tùng nhìn hắn. “Anh dùng cái chết ấy để xây cả hệ thống.” + +“Đúng.” Kha dừng. “Nên tao biết nó biến người thành gì.” + +Lần đầu, Kha không phủ nhận nguồn gốc quyền kiểm soát của mình. Hắn đặt nó lên bàn trước khi Tùng kịp dùng như bí mật. Tùng đưa điều kiện: giao quyền truy cập Ngọc Trục, Láng và Hồ Tây trước ngày 25. Đổi lại, hắn công khai giao thức, phương án 38% và các tuyến trú. + +“Nếu không?” Tiến hỏi. + +“Intervention sẽ lấy.” + +Xe phía dưới bật máy. Nhưng Hổ đã khóa một tuyến theo hiệp ước; Bình chặn tuyến thứ hai; nhóm Tài phát công khai vị trí để dân thường tránh. Tùng có lực, không đủ áp đảo. Tiến giữ nguyên lệnh không nổ súng trước. + +“Cho anh một lối,” hắn nói. “Để thiết bị lại.” + +Tùng cười. “Anh biết nó là bản giả?” + +“Không.” + +“Vẫn thả?” + +“Nếu bắn, những người Cầu Diễn sẽ thấy chúng tôi giết người đã cứu họ để giữ nút. Anh sẽ có bằng chứng tốt hơn mọi tỷ lệ.” + +Một người của Tùng hạ súng. Hai người khác làm theo. Họ tin dữ liệu, nhưng không muốn chết trong một cảnh được dựng để chứng minh chỉ Converge giữ trật tự. Tùng rút với ba người và ổ thật. Hắn bỏ lại bản sao cùng một phần truy vấn — đủ để các khu chuẩn bị, không đủ để nắm quyền. + +Kha nhìn theo. “Mày diễn tốt.” Tiến đáp: “Tôi không biết hắn sẽ rút.” + +“Vậy càng tệ.” + +“Đừng khen.” + +Người phụ nữ Cầu Diễn ở lại hỏi Thủy: “Nếu không theo phương án 38%, cô bảo đảm con tôi sống?” + +“Không.” + +“Vậy sao tôi nghe cô?” + +“Đừng nghe tôi như nghe Tùng. Xem dữ liệu, xem ai bị bỏ, rồi tự chọn nơi chị đứng.” + +Người phụ nữ không hài lòng. Không cần. Đoàn xe của Tùng rời qua lối phía đông. Người phụ nữ Cầu Diễn không đi theo ngay; chị đứng giữa sân thượng, nhìn bản truy vấn trong tay rồi nhìn những người vừa để kẻ cứu con mình rút lui. + +Chương 73: Khóa Hồ Tây + +Thiết bị điều tiết Hồ Tây được dựng từ những thứ không có lý do gì để tin nhau. Van công nghiệp lấy từ trạm bơm cũ. + +Cảm biến Observation Initiative. Bộ điều khiển nằm trong vỏ tủ điện cháy sém do ông Hòa và Đức lắp. + +Một ngắt cơ do Vòng Tròn Vỡ giữ. Ông Hòa gọi nó là “đồ dùng được”. Duy gọi là giải pháp tạm. Quân gọi là một khóa mới. + +Mục tiêu không khóa nước. Là giữ áp lực từ 12 giờ 11 tới 12 giờ 28 ngày 29 trong dải không làm vỡ tuyến hoặc dồn tải trung tâm. Quân tới với hai mươi người, không giương súng nhưng mang thuốc nhiệt cắt trong hộp niêm phong. Phương đi cùng, không đứng hẳn phía nào. + +“Thiết bị của các anh nối hệ thống,” Quân nói. + +Duy chỉ sơ đồ. “Cảm biến đọc tại chỗ. Van điều trong giới hạn cứng.” + +“Giới hạn ai đặt?” + +“Ba nhóm đo độc lập.” + +“Bộ điều khiển có thể nhận lệnh ngoài.” + +“Có ngắt cơ.” + +“Do ai giữ?” + +Tiến đáp: “Hai khóa. Một phía ông, một phía hội đồng.” Quân nhìn hắn. “Anh trao quyền phá cho tôi?” + +“Trao quyền ngắt điều khiển. Không phá mạch nước.” + +Thỏa thuận được thiết kế không dựa vào lòng tin, mà vào việc chẳng bên nào có thể tự mình hoàn tất toàn bộ thao tác. Khi lắp cảm biến, Đạt xuống hố van. Ông phù hợp vì hồ sơ Null khiến tín hiệu nhận dạng ít bị HANOI-07 ưu tiên, nhưng lý do đó không được phép thay cho an toàn. Đội kê hai thanh chống, một dây chính, một dây phụ và giới hạn mỗi lượt dưới mười phút vì nhiệt dưới hố tăng nhanh. Đạt đọc lại chốt trước khi xuống; Đức kiểm khóa. + +Tai nạn vẫn xảy ra ở thứ họ không kiểm được bằng mắt. Một chốt hãm tái sử dụng có vết nứt mỏi nằm bên trong cổ thép. Khi nền rung, chốt gãy, thanh chống trượt dù dây an toàn vẫn giữ người. Tiến giật dây kéo. Đạt rút được bàn tay chậm hơn một phần giây; đốt cuối ngón út tay phải bị kẹp nát giữa hai mép thép. + +Tiếng xương không lớn. Tiếng Đạt hút hơi mới khiến mọi người hiểu. Linh cầm máu, làm mát và đánh giá phần mô ngay tại lều y tế; thuốc giảm đau còn, thuốc tê không đủ cho một thủ thuật kéo dài. Khi buộc phải cắt phần mô không còn tưới máu, cô nói trước từng bước để Đạt biết mình sắp làm gì. Ông nhìn lên mái bạt, mồ hôi chảy vào tai, chỉ gật khi nghe tới phần mình đồng ý. + +Bức ảnh Hậu Ký hiện trong đầu tất cả: người thứ ba thiếu ngón út. Thủy đứng ngoài lều, buồn nôn. “Chúng ta đưa ông ấy tới đây vì ảnh.” + +Tiến nói: “Vì điều kiện Observer.” + +“Điều kiện đó cũng từ hồ sơ.” + +“Còn dữ liệu Null.” + +“Cũng từ hệ thống.” + +Không tách được hoàn toàn quyết định hiện tại khỏi thứ đã biết trước. Khi tỉnh sau thuốc giảm đau, Đạt yêu cầu ghi nguyên nhân chính xác: + +**Tai nạn xảy ra khi thanh chống trượt trong lúc lắp cảm biến. Việc đã biết trước bức ảnh có thể ảnh hưởng lựa chọn nhân sự, nhưng không đủ chứng minh quan hệ nhân quả.** + +Tiến muốn dừng lắp. Đạt lắc. “Tôi không xuống lại. Người khác thay.” + +“Ảnh đang hội tụ.” + +“Dừng mọi việc vì ảnh cũng là hội tụ.” + +Quân đứng ngoài nghe. Ông không chế giễu. “Nếu ảnh nói tôi chết ở đây, tôi vẫn muốn biết van có giữ không.” Phương nhìn ông. “Anh luôn nói dễ khi mạng người khác nằm trên bàn.” + +Quân quay sang. “Tôi đã kéo em khỏi Đại Hà.” + +“Và từ đó anh nghĩ mọi quyết định của anh về em đều có thêm trọng lượng.” + +Ông im. Đây là lần đầu họ nói công khai điều nằm giữa hai người. + +Buổi chiều, van thử áp lực thấp. Mô-tơ chạy, kim tăng, ngắt cơ chuyển được sang tay. Đức phát hiện độ trễ 0,7 giây giữa cảm biến và bộ chấp hành; đủ để nguy hiểm khi tải tăng nhanh. Họ không ghi “thành công” rồi đi. Ông Hòa thêm lò xo hồi, một bộ chỉ cơ độc lập và yêu cầu thay toàn bộ chốt hãm cùng lô với chiếc vừa gãy, dù những chốt còn lại nhìn vẫn nguyên. + +Tối, thử lại. Độ trễ giảm. Người xuống hố đổi ca đúng giờ thay vì cố làm nốt. Không màn hình HANOI-07 chúc mừng. Chỉ tiếng mô-tơ, nước chuyển trong ống và một túi nhỏ đựng những chốt thép bị loại nằm cạnh bảng sự cố. + +My gặp Đạt khi ông về Ngọc Trục. Con bé nhìn băng tay, nhớ người đưa giấy có cả cánh tay mất. + +“Ông sẽ mất thêm không?” + +“Không biết.” + +“Cháu không muốn.” + +“Ông cũng.” + +My cầm ba ngón còn lại. Đạt không rút. Duy kiểm bản ảnh Kha lưu. Chi tiết ngón tay rõ hơn sau tai nạn. Bức ảnh đã thay đổi theo sự kiện hiện tại; nó không phải một khung hình bất biến từ “tương lai nguyên vẹn”. + +Từ ngày đó, Đạt tự nguyện ngừng xem Hậu Ký. Quyết định ấy do chính ông đưa ra, không ai tước quyền. Ông giữ quyền quan sát hiện tại bằng cách từ chối học thuộc phương án. Quân ký biên bản van, rồi đặt chìa ngắt cơ vào hộp có hai ổ khóa. + +“Tin?” Phương hỏi. + +“Tin kim.” + +“Còn người?” + +“Tin họ có thể sai.” + +Ông đóng nắp hộp. Phương giữ chìa thứ hai; Quân giữ chìa thứ nhất. Không ai thử xem một mình có mở được hay không. + +Chương 74: Bảy Phút Mất Điện + +Ngày 20 tháng 9, hội đồng cho phép thử một phiên bắt tay tín hiệu trong ba mươi giây. Không mở Hoàng Thành. Không truy vấn Hậu Ký. Chỉ cho Ngọc Trục, Láng và bộ điều tiết Hồ Tây trao đổi trạng thái qua đường thử tách khỏi mạng chính. + +Quyết định được bỏ phiếu sau ba ngày tranh luận. Kha muốn thử dài hơn. Vân muốn không thử. Duy nói mô phỏng ngoài mạng chưa phản ánh cộng hưởng vật lý. Tiến bỏ phiếu thuận với giới hạn ba mươi giây và quyền ngắt tại từng nút. 12 giờ 17. + +Duy bắt đầu. Áp lực giữ. + +Tần số giữ. Nhiệt trên tuyến thử giảm 0,3 độ. + +Mười hai giây. Mười tám. + +Màn hình hiện **HANDSHAKE**. Rồi điện tắt. + +Không chỉ ba nút. Cả vùng phía Tây tối theo từng dải. Radio im. Camera mất. Quạt bệnh viện dừng, để lại tiếng bệnh nhân thở và bàn chân chạy trong hành lang. + +“Ngắt!” Duy nói. + +Quân kéo tay cơ ở Hồ Tây. Không phản ứng ngay. Vân bật Null. Đèn thiết bị sáng nhưng đường tham chiếu vẫn giữ. + +Thủy nghe chuông. Một. + +Hai. Bảy tiếng, không cách đều. Mỗi tiếng làm xương hàm cô rung hơn là tai nghe. + +Đồng hồ cơ tiếp tục. Khi điện trở lại, đã qua bảy phút. + +Trong bảy phút ấy, ba việc xảy ra. Bệnh viện bóp bóng bằng tay cho sáu bệnh nhân; một người ngừng tim rồi được kéo lại. + +Kho lương nhỏ bị mở trong bóng tối, mất bốn bao gạo. Hai người tại Láng nghe người thân gọi và đi xuống đường hầm. Một người gãy chân, người kia mất ký ức từ lúc bước qua cửa tới khi được tìm thấy sáu giờ sau. + +Ở Ngọc Trục, kẻ đột nhập không thắng bằng việc khiến Nam quên bài học cũ. Chúng thắng vì đã học đúng quy trình mới. + +Khi điện tắt, Nam nghe giọng Tiến qua dây nội bộ: “Mở cổng bắc cho đội điện.” Giọng có hướng từ loa, đúng mã. Cậu không mở. Nam kéo dây xác nhận cơ từ chòi ngoài — tín hiệu thứ hai đã được quy định sau vụ Dư Âm. Hai nhịp ngắn, một dài trả về đúng mẫu. Chỉ khi đủ cả giọng và dây, cậu mới mở sân đệm thứ nhất, chưa mở cổng lõi. + +Không có đội điện. Một người đã chờ sẵn trong vùng chết giữa hai hàng rào, lao vào lấy hộp dụng cụ và đánh dấu tường bằng sơn phản quang trước khi bị Bình bắt. Sau đó họ mới phát hiện dây xác nhận cơ và dây loa cùng đi qua một ống bảo trì ở đoạn cuối. Kẻ ngoài không giả được hai hệ thống độc lập; chúng lợi dụng việc hai thứ tưởng độc lập lại chung một đường vật lý. + +Nam tự xin rời phòng radio. Tiến không đồng ý ngay lập tức. + +“Cậu đã làm gì?” + +“Xác nhận hai nguồn.” + +“Đúng quy trình?” + +“Đúng.” + +“Vậy lỗi đầu tiên không nằm ở cậu.” + +Nam nhìn vệt sơn. “Nhưng tay em là tay kéo chốt.” + +“Ừ,” Tiến nói. “Phần đó cậu phải ghi và phải nhớ. Nhưng nếu chúng ta kết luận chỉ vì cậu kéo chốt thì lần sau sẽ thay một người khác vào rồi lặp lại y hệt. Hai kênh được gọi là độc lập trong khi chung một ống — đó là lỗi thiết kế.” + +Quy trình được sửa lần nữa: khi mất hình, lệnh mở cổng cần hai xác nhận **khác đường vật lý**; một từ chòi ngoài bằng dây cơ, một từ người tại cổng bằng thẻ màu hoặc gương quang. Nếu thiếu một, đội y tế đi qua khe bảo vệ chứ không mở sân. Nam ở lại ca, nhưng không giữ một mình. Hội đồng họp trong chiều. Tiến nói: “Lỗi của tôi.” + +Duy: “Thiết kế của tôi.” Vân: “Null không giữ.” + +Quân: “Tôi đồng ý thử.” Tuấn gõ đầu bút xuống bàn. “Ghi từng trách nhiệm riêng. Nhưng trước hết vẽ lại đường đi của tín hiệu. Tôi không muốn cuộc họp kết thúc bằng ba người cùng nhận lỗi rồi chẳng ai biết phải sửa dây nào.” + +Băng giấy cho thấy HANOI-07 tự mở rộng phiên bắt tay khi nhận mẫu trạng thái liên quan Tiến, dù hắn không chạm trực tiếp. Đường thử tách về phần mềm nhưng vẫn chung mạng vật lý. Một giả định kỹ thuật sai. Thủy đặt bảy tiếng chuông cạnh thời điểm các lớp trở lại. Sáu tiếng gần trùng; tiếng thứ ba lệch bốn giây. + +“Có thể độ trễ,” Duy nói. + +“Hoặc tôi nghe thứ khác,” Thủy đáp. + +Không tự biến mình thành cảm biến hoàn hảo để câu chuyện gọn hơn. Hội đồng bỏ phiếu dừng mọi thử nghiệm đồng bộ trước ngày 29. + +Kha chống. “Đi vào ngày đó mà không test là mù.” Tiến thuận dừng. “Test vừa dùng bệnh viện, Nam và người Láng làm tải thử.” + +“Càng cần biết.” + +“Không trên người khác.” + +Kha thua và chấp nhận, nhưng yêu cầu luyện quy trình cơ ngoài mạng. Đề nghị được thông qua. Từ đó, các đội tập bằng đồng hồ giấy, cờ tay, dây điện thoại, van cơ và lịch không phụ thuộc radio. Người ta chửi vì chậm, nhưng mỗi người tại nút bắt đầu biết phải làm gì nếu trung tâm biến mất. + +Khi điện trở lại, bảy chiếc đồng hồ không cùng chỉ một giờ. Đạt nhìn chúng, rồi để nguyên. + +Chương 75: Người Thứ Ba Trong Ảnh + +Ngày 24 tháng 9, Nguyễn Hữu Đạt đứng đúng vị trí từng xuất hiện trong bức ảnh. Không ai chủ động dàn dựng để điều đó xảy ra. + +Cửa ngoài Hoàng Thành mở lúc 02 giờ 17 để kiểm kết cấu sau bảy phút mất điện. Tiến đứng ở mốc Ngọc Trục, Thủy đặt cảm biến tại đường Láng, Đạt kiểm vùng Null. Khánh An giữ lối ngoài, Duy theo dõi áp lực. + +“Đừng cử động,” Khánh An nói. + +Cô lấy bản ảnh Hậu Ký cũ khỏi túi trong. Ba vị trí gần trùng. Bàn tay phải Đạt giờ thiếu đốt ngón út. Góc vai Tiến và khoảng cách Thủy tới cột cũng giống. Chỉ thời gian sai: hiện tại là ngày 24, 02 giờ 18. Ảnh ghi ngày 29, 12 giờ 23. + +Tiến cảm thấy căn phòng thu hẹp. Hắn không nhìn mặt người thứ ba trong ảnh; nhìn vệt máu tối sau vai mình, một chi tiết chưa xảy ra. Duy đặt camera ở góc ảnh giả định. Không có lỗ ống kính, không dây và không hốc máy. Góc nhìn thậm chí xuyên qua phần tường đặc. + +“Đây không phải ảnh camera,” anh nói. “Nó là hình dựng từ mô hình không gian.” + +Kha mang tới bản cập nhật lưu trong kho còn lại. Sau thử nghiệm bảy phút, ảnh thay đổi: + +- ngón tay Đạt rõ hơn; +- áo Thủy có vết rách; +- vai Tiến có máu; +- bóng thứ tư đậm hơn; +- nền phía sau xuất hiện đường trắng chưa có ở cửa ngoài hiện tại. + +“Hậu Ký đang cập nhật theo dữ liệu mới,” Thủy nói. + +“Hoặc phương án đang kéo chúng ta vào,” Khánh An đáp. + +“Cách nói thứ hai dễ biến mọi lựa chọn thành bất lực.” + +Khánh An không phản bác. Cô từng sống bằng cách đo nguy cơ, không bằng cách phủ nhận nó. Họ chụp một ảnh vật lý ở đúng góc. Trên tường chỉ có ba bóng và một vùng tối do cột che. Khi Duy chiếu dữ liệu từ ba nguồn lên, vùng tối tách thành nhiều đường chồng, gần giống hình người thứ tư. + +“Lớp tổng hợp,” anh nói. “Nếu hệ thống ghép nhiều Observer thành một trạng thái, nó có thể dựng một hình đại diện.” + +Thủy phóng lớn. Ở mép tường còn một vệt đen không khớp nguồn sáng. Duy tách từng nguồn dựng và phát hiện lớp hình từ camera hành lang chậm hơn cảm biến trong phòng 0,43 giây. Trong khoảng lệch ấy, bóng Khánh An ngoài ngưỡng cửa bị giữ lại sau khi vị trí cơ thể cô đã được loại khỏi khung. + +Anh đồng bộ lại thời gian. Vệt đen biến mất; bốn đường còn lại hội tụ đúng vào lớp Observer tổng hợp. Duy sửa biên bản: + +**SAI LỆCH HÌNH HỌC ĐÃ XÁC ĐỊNH — BÓNG NGOÀI KHUNG BỊ GHÉP LỆCH PHA. KHÔNG CÓ NGƯỜI THỨ TƯ VẬT LÝ.** + +Khánh An nhìn vùng tường đã sạch. “Ít nhất lần này một cái bóng chỉ là lỗi thời gian.” + +“Lỗi thời gian đã đủ kéo chúng ta đi rất xa,” Thủy đáp. + +Câu mặt sau ảnh: + +**NGƯỜI THỨ BA KHÔNG ĐƯỢC PHÉP NHỚ.** + +Đạt ngồi xuống bậc đá. “Tôi không định xóa đời mình.” + +“Không được nạp cùng bản dự báo,” Thủy nói. “Nếu ông biết chính xác ảnh, ba nguồn sẽ bớt khác nhau.” + +“Vậy từ giờ tôi không xem.” + +Kha hỏi qua dây: “Không muốn biết mình mất gì?” + +“Muốn.” Đạt nhìn bàn tay băng. “Chính vì vậy.” + +Tiến cũng giao bản ảnh cập nhật cho Thủy giữ. “Tôi không xem thêm.” Kha cười nhạt. “Hai người thi nhau mù.” + +“Không,” Thủy nói. “Họ chọn nguồn nào được phép ảnh hưởng quyết định.” + +Kha chưa giao bản của mình. Hắn nhìn vệt máu sau vai Tiến lâu hơn, như một người đã từng sống nhờ biết trước và chưa thể bỏ thói quen trong một ngày. Khi kiểm cửa xong, Đạt trượt trên bậc ướt. Bàn tay bị thương va vào tường nhưng không nặng. Mọi người cùng giật mình vì ảnh. Đạt ngồi yên, đợi Linh qua radio xác nhận không gãy. + +“Thấy chưa?” Kha nói. “Biết trước làm mọi chuyển động thành tín hiệu.” + +Tiến đáp: “Không biết trước cũng không làm bậc khô.” Cả hai đúng một phần. + +Trở về Ngọc Trục, Đạt xé bản sao ảnh riêng của mình, không đốt. Ông đưa các mảnh cho Thủy niêm phong để sau ngày 29 có thể kiểm xem quyết định “không xem” đã ảnh hưởng gì. My hỏi: “Nếu không nhìn, ông có tránh được không?” + +Đạt nói: “Không chắc.” + +“Vậy sao không nhìn?” + +“Để khi chọn bước nào, ông còn biết có phần là do mình.” + +Con bé không hiểu hết, nhưng gật như người lớn thường gật trước điều chưa đủ từ. Bức ảnh không còn là cửa sổ nhìn một tương lai cố định. + +Nó là tấm gương kỳ lạ: càng nhiều người nhìn, hành vi của họ càng trở thành dữ liệu để hình trong gương rõ thêm. Còn năm ngày, và mỗi người phải quyết mình được phép nhìn bao nhiêu. + +Chương 76: Con Dao Ở Mễ Trì + +Hoàng Tùng gửi phần còn lại của bốn mươi ba phút vào sáng 26 tháng 9. Không đòi nước, nút hay quyền truy cập. Chỉ một câu: + +**XEM TRƯỚC KHI CHỌN PRESERVE.** + +Duy kiểm cấu trúc. Nhiều lớp khớp dải nhớ gốc, nhưng đoạn đã qua một khóa Hậu Ký nên có thể bị chọn lọc. Vân yêu cầu không xem vì người gửi đang chọn thời điểm. Kha yêu cầu xem vì tên và con dao của hắn nằm trong đó. Hội đồng không bỏ phiếu thay những người có cơ thể trong bản ghi. + +Tiến đồng ý. Phòng xem chỉ có Tiến, Thủy, Kha, Vân, Duy và Đạt. Bình đứng ngoài. Mỗi người có một nút dừng cơ. Vũ khí bị để ngoài; trong phòng chỉ có con dao mô phỏng đặt trong hộp kính để so hình học. + +Bản ghi bắt đầu sau khi Null kích hoạt. Mễ Trì B3 năm 2031. Tiến tương lai ngồi dưới sàn, cánh tay gắn vào lớp vật liệu đỏ mảnh. Da quanh điểm tiếp xúc đã cháy. Kha quỳ trước, áo rách, máu không rõ của ai. Vân dựa tường, chân trái bị thương. + +Trên bảng cơ là ngày **29/09/2031** và hai dải pha được chồng lên nhau: cửa sổ Đồng Bộ năm 2028, cấu hình nguồn hiện tại năm 2031. Kha tương lai nhìn bảng. “Ba năm đúng ngày. Hệ thống tự mở lại?” + +“Không,” Vân đáp. “Chúng ta chọn ngày này.” + +Bà chỉ các thông số được dựng bằng tay: áp lực Hồ Tây, pha dao động Láng, cấu hình rơ-le Thanh Xuân và khóa lịch của cửa sổ 2028. Họ đã mất mười chín ngày để đưa các giá trị vào cùng dải. + +“Ngày 29 tháng 9 không phải chu kỳ tự nhiên ba năm,” Vân nói. “Đó là mốc tương thích gần nhất chúng ta có thể tái tạo. Không dựng lại điều kiện này, quá trình phản hồi không biết phải ghép nguồn vào đâu.” + +Tiến tương lai nói: “Kênh sẽ tách làm hai. Khối dữ liệu máy đi về rơ-le thử nghiệm năm 2026, nơi Duy còn có thể viết lớp đọc. Ký ức đi về mốc 07 giờ 13 ngày 09 tháng 5 năm 2028.” Kha nhìn hắn. “Vậy tệp Hậu Ký tồn tại vì mày gửi hạt giống để người trước tạo ra thứ dẫn chúng ta tới đây.” + +“Phần lõi tồn tại trong một vòng kín,” Tiến đáp. “Nhưng giao thức truy vấn, cách dùng và mọi câu hỏi là do người ở năm 2026 trở đi viết. Đừng đổ trách nhiệm của chúng ta cho nghịch lý.” + +“Ba năm dữ liệu ở trong tôi,” Tiến tương lai nói. + +Kha đáp: “Cắt giao diện.” + +“Không được. Nó đã vào trạng thái.” + +Vân nhìn thiết bị. “Nếu việc ghi trạng thái hoàn tất, giao thức có thể phản hồi lớp ký ức này về mốc năm 2028.” Kha tương lai hỏi: “Ghi đè người ở đó?” + +“Nếu đường nền còn ổn thì không. Lớp ký ức sẽ được ghép lên chủ thể đang sống.” Vân nhìn Tiến. “Nhưng nếu mang cả giao thức điều khiển, người ở mốc cũ có thể bị biến thành một nút.” + +Tiến hiện tại nghiêng người. Đây là lần đầu bản ghi nói rõ sự phản hồi không nhằm thay thế Tiến năm 2028. Nó chồng ký ức lên một con người đã tồn tại — và nguy cơ nằm ở phần giao thức đi kèm. Kha tương lai hỏi: “Thì sao?” + +“Lần này tôi trở về với tư cách một người. Lần sau, nếu mang theo cả giao thức, tôi có thể chỉ còn là một nút.” + +Cơ thể không đi qua thời gian; một trạng thái thần kinh được ghi lại rồi phát ngược về một điểm cũ. Tiến tương lai yêu cầu Vân Null đoạn thỏa thuận và thông tin về giao thức. Trước khi Vân đặt tay lên bộ điều khiển, hắn hỏi Kha một câu không liên quan tới writeback: + +“Kho phía đông La Phù. Bao nhiêu?” + +Kha tương lai không giả vờ không hiểu. “Một trăm ba mươi bảy tên xác nhận. Ngoài sổ không biết.” + +“Anh ra lệnh đóng cổng?” + +“Có. Đoàn phía trong báo nước nhiễm và đám đông đã phá hàng rào. Tao lấy phần lương còn khô, cho bắn khi cổng vỡ. Số đó nuôi bốn nghìn người qua mùa đầu.” + +“Không phải câu tôi hỏi.” + +“Nhưng là câu tao từng dùng để ngủ.” Kha nhìn con dao. “Cứ ghi cả hai. Tao cứu người bằng số lương lấy từ một sân đầy xác. Không sự thật nào xóa sự thật kia.” + +Tiến hiện tại thấy ký ức ban đầu trở lại, lần này không còn được dựng chỉ từ lời đồn. Một phần có thể thiên lệch; mệnh lệnh đóng cổng thì không. + +“Anh sẽ chỉ nhớ Kha giết,” Vân nói. + +“Đủ để tôi không tin hắn hoàn toàn.” + +Kha nhìn hắn. “Mày dùng tao làm kẻ thù cho chính mày.” + +“Anh hợp vai.” + +Một câu đùa tệ giữa ba người đã kiệt sức. Kha hiện tại không cười. + +“Nếu mày trở lại và giết tao trước?” Kha tương lai hỏi. + +“Né.” + +“Không buồn cười.” + +“Biết.” + +Rồi Tiến tương lai nghiêm lại. “Nếu Null không cắt được phần giao thức và nó bắt đầu dùng tôi làm nút, giết tôi.” Kha nói ngay: “Không.” + +“Anh đã giết nhiều người vì ít lý do hơn.” + +“Không phải mày.” + +“Chính vì vậy tôi mới giao anh. Người khác sẽ làm quá sớm hoặc không làm.” + +Vân nói thời gian hết. Kha nắm dao. “Sau khi xóa, mày không nhớ đồng ý.” + +“Đừng nói lý do. HANOI-07 có thể dùng lời.” + +“Vậy tao nói gì?” + +“Điều anh tin.” + +Null bắt đầu. Hình ảnh rung. Tiến tương lai quên phần vừa nói; nét mặt thay đổi như người tỉnh giữa một căn phòng không biết vì sao mình ở đó. Vân rời khung. + +Kha đứng một mình với quyết định. + +“Lê Quốc Tiến,” hắn nói. “Mày vốn không nên sống lâu đến thế.” + +Dao đâm. Không ai trong phòng hiện tại cử động cho tới khi bản ghi tắt. + +Tiến nhận ra tay mình đã bám mép ghế đến bật máu dưới móng. Thủy đưa khăn, không nói câu nào. Kha nhìn màn hình đen. “Tao từ chối trước.” + +“Rồi làm,” Tiến nói. + +“Ừ.” + +“Không tha.” + +“Không hỏi.” + +Một sự đồng ý trong tương lai không xóa hành động. Nó chỉ trả lại phần nguyên nhân đã bị ký ức cắt. Thỏa thuận Mễ Trì cũng không rửa sạch La Phù; nó chỉ khiến Tiến phải phân biệt người Kha đang đứng trước mặt với kẻ Kha có thể trở thành khi mọi quyền tập trung vào tay hắn. + +Kha hiện tại nói, mắt vẫn ở màn hình đen: “Tao chưa đóng cổng đó trong phương án này.” + +“Chưa,” Tiến đáp. + +“Vậy đừng để tao một mình với cái lệnh tương tự.” + +Thủy hỏi Kha: “Nếu ngày 29 trạng thái Tiến bị hệ thống chiếm, anh làm gì?” + +“Cắt.” + +“Giết?” + +Kha nhìn con dao trong hộp. “Không biết.” + +“Vậy cần quy tắc trước khi không còn thời gian.” + +Họ viết quy trình không phải bằng triết lý, mà bằng thứ tự thao tác: + +1. Đạt xác nhận dấu vật lý và ý thức. +2. Thủy phân biệt tín hiệu thật, Dư Âm và hình mô hình. +3. Vân thử Null giới hạn. +4. Duy cắt kết nối kỹ thuật. +5. Nếu phải cắt mô, dùng biện pháp bảo toàn mạng sống trước. +6. Chỉ khi mọi cách thất bại mới xem xét ngừng trạng thái thần kinh. +7. Không một mình Kha hoặc Tiến có quyền quyết. + +Kha đọc. “Đặt dao vào hội đồng.” + +“Đặt nó khỏi tay một người,” Tiến đáp. + +“Chậm.” + +“Đúng.” + +“Có thể chết cả thành phố.” + +“Có thể.” + +Kha ký. Chữ hắn mạnh hơn bình thường, nét cuối làm rách giấy. Tùng gửi một câu sau khi biết bản ghi đã được mở: + +**CHIA TRÁCH NHIỆM KHÔNG LÀM QUYẾT ĐỊNH ĐÚNG HƠN.** + +Thủy trả: + +**KHÔNG. NÓ CHỈ LÀM KHÓ HƠN CHO MỘT NGƯỜI GỌI Ý MUỐN CỦA MÌNH LÀ TẤT YẾU.** + +Đêm, Tiến không giấu lương khô dưới gối. Hắn đặt nó trên bàn, cạnh bản quy trình có chữ Kha. Con dao Mễ Trì vẫn tồn tại trong tương lai đã sống. + +Nhưng lần này, trước khi ai cầm nó, đã có người khác biết câu chuyện và có quyền nói dừng. + +Chương 77: Hai Ngày Không Hậu Ký + +Ngày 27 tháng 9, Kha đóng phần Hậu Ký còn lại. Hắn không đốt ổ dữ liệu. Tháo nguồn, chia thành ba hộp, giao cho Ngọc Trục, nhóm Tài và kho của mình. Mỗi hộp có hai khóa do hai phía giữ. + +“Không truy vấn hai ngày,” hắn nói. + +Tiến đối diện hắn. “Anh chịu được?” + +“Không.” + +“Vẫn?” + +“Ừ.” + +Mất Hậu Ký với Kha không giống bỏ một món đồ xấu. Nó giống tự bịt một mắt trước khi đi vào chiến trường. Hắn không giả bình thản. Hai ngày không dự báo khiến thành phố ồn hơn. Không có câu trả lời mới, mọi người quay lại đo, vá và cãi. + +Ngọc Trục hoàn tất bể nước phụ. Trẻ con được chuyển tới hầm mát xa nút. Nam dán lịch liên lạc cơ lên ba bức tường và tập tình huống mất giọng giả. Bình kiểm từng cụm moay-ơ, lốp và điểm cứu hộ sau mười bảy cái chết trong chuyến sơ tán phía nam. Linh tách thuốc thành hai kho. Phương lập danh sách bệnh nhân có thể di chuyển. + +Ông Hòa kiểm dây bằng bộ kẹp, ba ngón tay còn lại cứng vì sẹo. Đức muốn thay toàn bộ, ông không cho vì vật tư không đủ. + +“Chạy được chưa chắc đúng,” Đức nói, nhại ông. + +“Cậu tiến bộ.” + +“Vậy thay?” + +“Không có dây.” + +Hai người cùng chửi một câu rồi làm tiếp. + +Khánh An hoàn thiện quy trình kiểm tra chéo cuối cùng: mọi lệnh từ Hoàng Thành phải được người tại nút xác nhận bằng một dữ liệu vật lý, không chỉ bằng mã; người điều khiển thiết bị không được tự xác nhận chính thiết bị ấy. Cô không nhận chức dưới Kha hay Tiến; hội đồng lập hẳn một nhóm luân phiên theo mô hình cô đề xuất. + +“Đây là thứ của cô,” Thủy nói. + +Khánh An nhìn bảng phân ca. “Chỉ khi người khác dùng được lúc tôi không có.” Buổi tối, Tiến và Thủy ngồi sửa máy ghi ở bậc kho. Không họp, không dữ liệu. Cô thay miếng đệm micro, hắn cắt một đoạn dây da từ túi cũ. + +“Sau ngày 29, cô làm gì?” Tiến hỏi. + +“Nếu còn nghe, ghi. Nếu không, vẫn ghi.” + +“Ở Hà Nội?” + +“Có thể.” + +Hắn nhăn mặt vì từ đó. Thủy cười. “Anh dùng được, tôi không?” + +“Được.” + +“Anh?” + +“Vận hành.” + +“Không phải trả lời.” + +Tiến dõi những người ngoài sân. “Tôi không biết mình là gì nếu không chuẩn bị cho ngày tiếp.” + +“Thử là người ăn tối trước khi nguội.” + +Cô đưa hắn bát cháo Hạnh vừa mang. Tiến ăn được nửa bát mới nhận ra Thủy đã gắp hết phần thịt vụn sang phía hắn. + +“Cô không ăn à?” + +“Ăn rồi.” + +“Cô nói dối kém.” + +“Anh nhận ra muộn.” + +Hắn đẩy nửa phần trở lại. Hai người tiếp tục ăn. Không họp, không dữ liệu, không ai cần thắng bất kỳ cuộc tranh luận nào. Mẹ Tiến gọi lúc 21 giờ. + +“Ngày kia ở đâu?” + +“Hoàng Thành.” + +“Không thể không đi?” + +“Không.” + +“Con chắc?” + +“Không.” + +“Vẫn?” + +“Vâng.” + +Bà im, rồi nói: “Gọi trước.” + +“Con sẽ.” + +“Không hứa sống.” + +Tiến nhắm mắt. “Con hứa không coi mình là cái máy phải cắm vào đó.” + +“Được.” + +Thủy ngồi gần đủ nghe câu cuối. Khi máy tắt, cô nói: “Nếu tôi dùng Null và quên anh?” + +“Tôi kể lại.” + +“Nếu tôi không tin?” + +“Đưa nguồn.” + +“Đúng nghề.” + +Cô đặt tay lên mu bàn tay hắn, chỉ một giây. Không lời hứa lớn. Một xác nhận rằng nếu ký ức bị mất, người còn lại không có quyền viết thay kết quả; phải đưa bằng chứng và cho người kia chọn lại. Nhóm Tài giao hồ sơ cuối cùng của bộ máy cũ. Một lệnh trước Hồng Nhật: + +**ƯU TIÊN BẢO TOÀN CONTINUITY OF GOVERNANCE.** + +Bảo toàn bộ máy, không ghi dân số. Tài chụp công khai rồi đốt bản lệnh hành động. Không đốt lịch sử. Chỉ từ chối tiếp tục thi hành. + +Trên mái kho, Khánh An hỏi Kha câu hắn muốn hỏi Hậu Ký nhất. + +“Ngày 30 tao còn sống không.” + +“Và?” + +“Không hỏi.” + +“Khó?” + +“Như lái xe không bản đồ.” + +“Anh từng tự vẽ đường.” + +“Giờ có quá nhiều người cùng vẽ.” + +“Đó là lý do đường còn.” + +Hai ngày không Hậu Ký không làm ai tự do khỏi những gì đã đọc. Những ngày chết, ảnh và tỷ lệ vẫn nằm trong đầu. Nhưng trong bốn mươi tám giờ cuối, không có câu mới từ tương lai chen vào giữa một người và quyết định của họ. + +Chương 78: Đêm 28 Tháng 9 + +Hà Nội im hơn mọi đêm nhưng không yên. Các tuyến quanh Hoàng Thành đã sơ tán. Đèn tắt bớt để giảm tải. Người ta ngủ mặc quần áo, túi nước đặt bên đầu, tên và nhóm máu viết lên miếng nhôm đeo cổ. Ở các khu cao, mặt đường vẫn nhả nhiệt dù đã quá nửa đêm. + +23 giờ, Tiến đi một vòng Ngọc Trục. Hắn kiểm cổng, bể nước, bảng radio, dây điện thoại và lối thoát. Tới khu bếp, Hạnh dúi vào tay hắn hai miếng cơm nén. + +“Ăn trên đường.” + +“Không đói.” + +“Không hỏi.” + +Câu của mẹ hắn đã lan thành thói quen trong căn cứ. Bình đứng bên xe. “Không dặn gì?” + +“Giữ.” + +“Câu cũ.” + +“Dùng được.” + +Nam trong phòng radio hỏi: “Nếu mất liên lạc?” + +“Theo bảng cơ.” + +“Nếu nghe giọng anh bảo mở?” + +“Không mở nếu thiếu xác nhận vật lý từ hai điểm.” + +Nam chạm vệt sơn còn lại từ sai lầm bảy phút mất điện. “Vâng.” Linh ngủ đúng hai mươi phút trước ca. Phương kiểm túi dịch lần cuối. Phúc ngồi cạnh em gái, hai người không nói về Đại Hà; anh chỉ đưa cô chai nước đã đánh dấu phần của mình. + +Ông Hòa giao bộ kẹp dự phòng cho Đức. + +“Bác đi Láng?” + +“Ừ.” + +“Tay?” + +“Còn.” + +Tuấn đại diện hội đồng ở lại Ngọc Trục. Tiến rời căn cứ mà quyền điều hành không đi theo hắn. 0 giờ, các đội vào vị trí: + +- Tiến, Thủy, Đạt, Vân, Duy ở vòng ngoài Hoàng Thành; +- Kha và Khánh An giữ can thiệp cùng lối dân sự; +- ông Hòa, Đức và Quân giữ Khóa phía Tây; +- Phương và Linh điều phối y tế; +- Bình chỉ huy sơ tán; +- Tài và Hương giữ radio dân sự; +- Phúc vận chuyển thương binh. + +Hoàng Tùng chưa xuất hiện. 02 giờ 17, cửa ngoài Hoàng Thành mở bốn phút. Họ chỉ đặt thiết bị và rút. Cột trạng thái hiện: + +**SYNCHRONIZATION WINDOW: 10:00:00** + +Ba lựa chọn vẫn nằm trên giao diện. Không bàn tay nào chạm vào chúng. 06 giờ, Hồng Nhật mọc qua lớp không khí nâu đỏ. Dữ liệu đo xa vệ tinh xác nhận bức xạ ngoài khí quyển chỉ tăng nhẹ; phần nhiệt lớn vẫn bị khuếch trong khí quyển. Cổng Thăng Long, dù làm gì, sẽ không tắt được mặt trời trên đầu. + +08 giờ, Intervention của Tùng di chuyển tới Hồ Tây. Kha nghe báo, tay đã đặt lên cửa xe. Tiến nói qua radio: “Giữ vị trí.” + +“Chúng lấy van.” + +“Quân và Phương ở đó.” + +“Không đủ.” + +“Anh là dự phòng Hoàng Thành.” + +Kha nhìn Khánh An. Cô không ra lệnh, chỉ đứng chờ hắn tự chọn. Hắn ở lại. + +Một quyết định khác phương án cũ: không để kẻ phản bội kéo mình khỏi vị trí chỉ vì thù. 09 giờ, mẹ Tiến gọi. + +“Ăn chưa?” + +“Rồi.” + +“Nói dối.” + +Hắn cắn một miếng cơm nén trước micro. + +“Được.” + +Bà im vài giây. “Tiến.” + +“Vâng.” + +“Mẹ nhớ con.” + +Hắn nhìn bức tường đá trước mặt. “Con cũng nhớ mẹ.” + +“Đủ rồi.” + +Không lời cuối. Bà cúp trước. 10 giờ, Tùng phát ba dòng khắp radio: + +**CONVERGE: 38% SURVIVAL** +**PRESERVE: UNKNOWN** +**NULL: 11% ESTIMATED** + +Con số 38 trở thành một lời gọi. Người dân bắt đầu di chuyển về Ba Đình vì sợ mình ở ngoài mẫu. Tài và Hương phát cảnh báo, không ngăn được hết. Kha hỏi Tiến: “Mày chọn?” + +“Chưa.” + +“Đến lúc.” + +“Không chọn vì hắn phát.” + +11 giờ, áp lực Hồ Tây tăng. Khóa Tây rung. Thủy nghe tiếng chuông đầu tiên, có hướng từ Hoàng Thành và được cảm biến ghi. Cô đánh dấu **âm vật lý**. 11 giờ 43, đoàn dân thường xuất hiện phía bắc. Họ mang trẻ em, người già và tấm biển **CHO CHÚNG TÔI VÀO 38%**. Kha phải giữ hàng rào mà không bắn. Khánh An mở lối phụ để người bị ép ngã ra ngoài, tránh giẫm đạp. + +12 giờ, mười bảy phút còn lại. Tiến đứng trước giao diện, bàn tay không chạm. Vết sẹo cổ tay từ Mễ Trì chưa có nhưng da đã ngứa như nhớ trước. + +Thủy hỏi: “Anh sợ gì nhất?” + +“Trở thành nút.” + +“Còn?” + +“Chọn sai.” + +“Không có cách tránh hoàn toàn.” + +“Biết.” + +Cô nhìn hắn. “Đừng dùng từ đó để đóng câu.” Tiến thở. “Tôi sẽ nhớ mình không phải máy.” + +“Còn tôi có quyền dùng Null.” + +“Ừ.” + +“Dù anh sợ tôi quên.” + +Hắn nuốt khô, rồi nói: “Dù tôi sợ.” 12 giờ 11, van Hồ Tây bắt đầu điều tiết. + +12 giờ 13, Khóa phía Tây mất một cảm biến. 12 giờ 15, HANOI-07 hiện: + +**HOST DETECTED: LE QUOC TIEN** + +Tiến không trả lời. 12 giờ 16, radio im. + +Kim đồng hồ cơ vẫn chạy. Thủy nghe tiếng chuông đầu tiên của cửa sổ. + +Cả thành phố bước vào vùng thời gian mà Hậu Ký không còn ghi được chắc chắn. Từ đây, không ai biết điều gì “phải” xảy ra tiếp theo. Các đội vẫn kiểm đồng hồ giấy, dây cơ và lối rút — những thứ họ đã chuẩn bị cho chính khoảnh khắc không có đáp án. + +ARC 9: CỔNG THĂNG LONG + +Chương 79: Ngày 29 Tháng 9 + +12 giờ 17 phút. Tiếng chuông thứ nhất đi qua nền Hoàng Thành. + +Không chỉ Thủy nghe. Kim dao động trên bàn cơ nhảy một vạch; nước trong ống thủy tinh tạo gợn; bụi từ khe đá rơi xuống vai Đạt. Âm trầm đến mức lồng ngực cảm trước tai. Cột trung tâm sáng: + +**SYNCHRONIZATION WINDOW OPEN** + +Ba trạng thái hiện dưới: + +**CONVERGE** +**PRESERVE** +**NULL** + +Tiến giữ tay khỏi giao diện. Cùng lúc, radio tắt hẳn — không tiếng rè, chỉ còn khoảng im. Điện thành phố rơi theo từng vùng; qua khe cửa ngoài, ánh đèn đỏ trên đường Ba Đình tắt dần như một dãy mắt khép. + +Đạt đứng trước bốn đồng hồ cơ, đọc thành tiếng để mọi người cùng nghe: + +“Áp lực 81,7. Nhiệt nền 48,1. Tây tăng rung. Mực nước ổn.” + +Màn hình không hiện tỷ lệ sống, chỉ trả về dữ liệu của hiện tại. Đường đồng trên nền sáng ở phía bắc, chập chờn về phía Tây. Tiến không rời mắt khỏi kim áp lực. Hồ Tây đang bị tác động dù anh không nghe được Quân hay Phương. + +Ở hầm van, Hoàng Tùng đã tới cùng Intervention cũ. Hắn đặt mảnh lõi Hậu Ký vào cổng bảo trì, bẻ niêm chì rồi xoay khóa phần cứng dùng một lần. Bộ điều khiển van vốn bị tách khỏi mạng nuốt khóa, đèn vàng chuyển sang trắng. Radio không thể làm việc này; nếu không đứng trước bảng, Tùng không thể trao quyền Converge cho hệ thống. + +Quân đứng trước bảng điều khiển, vai còn vết sẹo Láng, tay giữ chìa ngắt cơ. + +“Converge cần áp lực cao,” Tùng nói. + +Kim đang ở 82. Quân đáp: “Cao thêm ba đơn vị là tuyến nứt.” + +“Hậu Ký tính toàn mạng.” + +“Đồng hồ này đo cái ống trước mặt.” + +Một người của Tùng bước vào vùng van. Người Vòng Tròn Vỡ chặn. Viên đạn đầu tiên bật khỏi lan can thép, tiếng vang làm mọi người trong hầm tưởng thêm một Dư Âm. Ở Hoàng Thành, kim nhảy 82,4. + +“Giao tranh,” Đạt nói. + +Tiếng chuông thứ hai. Thủy nghe trẻ con Đại Hà gọi tên. Không hướng. Cô đặt thẻ **DƯ ÂM / MÔ HÌNH** lên bàn. Tiếng nước dưới nền có hướng và trùng cảm biến: **CÓ ĐO**. + +HANOI-07 hiện: + +**CONVERGE: 38,2% SURVIVAL** +**PRESERVE: CASCADE UNRESOLVED** +**NULL: INFRASTRUCTURE LOSS PROBABLE** + +Ba dòng không cùng đơn vị. Một bên có con số hấp dẫn, hai bên chỉ có cảnh báo. Thủy chỉ màn hình. “Nó đang trình bày như một cuộc so sánh dù dữ liệu không tương đương.” + +Duy mở hộp công cụ. “Và giới hạn quyền thao tác vào ba nút.” Tiến không nhìn nút. Hắn kiểm chân cột, khe bảo trì và đường ống. Dưới lớp đá có tiếng rơ-le cơ rất nhỏ. + +“Chúng ta không chọn menu,” hắn nói. + +“Vậy chọn bằng gì?” Vân hỏi. + +“Bằng thứ nó thực sự điều khiển.” + +Hắn đưa xà beng vào khe. Đạt giữ đầu kia bằng bàn tay mất ngón. Tấm ốp không nhúc nhích; nhiệt làm kim loại nở. Duy phun phần nước làm mát ít ỏi vào mép, chờ co rồi cùng Tiến kéo. Tấm ốp bật, cắt vai Tiến. Máu thấm lưng áo nhưng chưa sâu. + +Sau lớp đá là ba bó dẫn: + +- đỏ, lưu lượng dữ liệu cao nhưng tải điện thấp; +- trắng, nối cảm biến; +- đen, mang tín hiệu điều khiển van và khóa. + +Duy đo từng đường bằng đồng hồ độc lập. “Đỏ có thể là lớp đối chiếu. Trắng đo. Đen điều khiển.” + +“Có thể?” Kha hỏi qua dây cơ trước khi đường ngoài mất hẳn. + +“Đủ để tìm rơ-le ưu tiên, chưa đủ để cắt.” + +Tiến gật. Màu sắc khớp với giả thuyết chưa đủ để bất kỳ ai chạm vào dây. Ở vòng ngoài, đám đông ép hàng rào. Tấm biển **38%** bị giơ cao. Một người đàn ông bế con trèo lên xe chắn. + +Kha đứng trên bậc, không rút súng. “Vào đây không làm các người nằm trong 38%.” + +“Anh biết?” + +“Không.” + +“Vậy tránh!” + +Người đàn ông lao. Đội Kha dùng khiên và dây, nhưng phía sau đẩy quá mạnh. Khánh An mở lối phụ, kéo trẻ em và người già ra khỏi dòng ép. Cô bỏ vị trí cạnh Kha theo đúng quy trình kiểm tra chéo, không chờ hắn cho phép. Tiếng chuông thứ ba. + +12 giờ 19. Duy tìm thấy hộp rơ-le dưới sàn. Sáu bu lông, bốn cái rỉ và hai cái mới. Có người đã sửa hệ thống sau khi công trình hoàn thành. + +“Bảo trì hiện đại,” anh nói. “Có chế độ chuyển quyền về nút cục bộ.” + +“Cách bật?” + +“Chưa biết.” + +Tiếng chuông thứ tư. Thời gian không dừng để họ đọc hết tài liệu. + +Tiến đưa cờ lê cho Duy, còn mình giữ tấm ốp nóng khỏi rơi vào bó dây. Máu ở vai bắt đầu chảy xuống sườn, giống vệt trong bức ảnh nhưng hắn không biết vì đã từ chối xem bản cập nhật. Đạt đọc: “Áp lực 82,8.” + +Họ chưa có phương án thứ tư hoàn chỉnh; họ mới chỉ tìm thấy chỗ để tự tay tạo ra một phương án khác. + +Chương 80: Khoảng Trống Bắt Đầu + +12 giờ 20. Duy tháo bu lông cuối bằng kìm vì đầu đã toét. Nắp rơ-le mở, hơi nóng phả mùi nhựa và dầu máy cũ. + +Bên trong không có màn hình. Một lõi điện từ, lò xo hồi, ba cầu tiếp điểm và một khóa bảo trì cơ. Hệ thống hiện đại đã được đặt lên một nguyên lý đơn giản: khi trung tâm hoạt động, rơ-le ưu tiên mô hình; khi bảo trì, quyền về các bộ điều khiển tại nút, nhưng chỉ trong bốn phút rồi lò xo tự trả. + +“Đây,” Duy nói. + +Vân bật Null ở mức thấp, hướng điện cực vào bó đỏ. Ánh trên cột giảm một lớp. Cùng lúc, Thủy nghe Dư Âm nhỏ đi — và tiếng nước thật cũng mờ. + +“Đỏ dùng chung tham chiếu với cảm biến,” cô nói. + +Không thể tắt dự báo như tắt một bóng đèn. Các lớp đã bị nối với nhau qua nhiều lần cải tạo. Đạt đọc số mỗi mười giây. “Áp lực 83,0. Tây tăng rung. Nhiệt 48,4.” + +Tiếng chuông thứ năm. Ở Hồ Tây, Quân trúng đạn vai khi kéo một người khỏi vùng bánh răng. Phương ép ông xuống sau bệ bê tông. + +“Van,” Quân nói. + +Tùng đã cắm ổ giao thức vào bộ điều khiển. Lệnh mở lớn truyền xuống chốt cơ. Nguồn điện bị Phúc cắt từ trạm phụ, nhưng van vẫn tiếp tục theo quán tính. Phương không nhìn con số dự báo trên màn phụ; cô đọc kim cơ, vạch áp tại chỗ và tốc độ quay của bánh răng. Khi kim vượt 83,5 và vẫn lên, cô chèn kìm vào đúng khe đã đánh dấu từ buổi diễn tập. Van giật thêm nửa nấc rồi dừng ở 84. + +Tùng đánh cô ngã. “Cô đang giữ một phương án không tỷ lệ.” Phương lau máu môi. “Tôi giữ cái ống không nổ.” + +Phúc lao xuống hầm, bàn tay phải với bộ nẹp không nắm chắc. Anh dùng vai húc Tùng khỏi tay quay. Tiếng chuông thứ sáu. + +Ở Hoàng Thành, Duy kéo khóa bảo trì thử. Đường đỏ giảm, đường trắng và đen vẫn chạy. Cột báo: + +**MAINTENANCE MODE — 04:00** + +Một đồng hồ đếm ngược bắt đầu. + +“Bốn phút rồi trả trung tâm,” Duy nói. + +“Chặn lò xo,” Tiến đáp. + +“Chưa biết tải trả mạnh bao nhiêu.” + +“Đo.” + +Đạt móc lực kế cơ vào cần hồi. Duy thả một phần. Kim lực bật gần gãy móc. Không thể nhét bất kỳ thanh sắt nào rồi hy vọng. + +Tiến và Duy cắt một đoạn nẹp thép từ hộp thiết bị, nung bằng đầu hàn pin và uốn theo góc. Mỗi thao tác mất giây, nhưng làm ẩu sẽ khiến chốt văng vào bó dây. Thủy nghe bước chân sau lưng. Không hướng. Cô không quay. + +Cột chiếu lại Đại Hà: bé gái sau cửa kính, góc nhìn từ camera trên trần. Hình ảnh ấy không đến từ mắt Thủy. Cô đặt thẻ **BẢN GHI / MÔ HÌNH**. + +Hình đổi sang mẹ Tiến ở Thanh Hóa. Không timestamp. Tiến cứng vai. Thủy che hình bằng bảng **CHƯA RÕ**. + +“Nó đang thử thứ từng khiến chúng ta hành động,” cô nói. + +Cột đổi sang Kha cầm dao. Hắn nhìn tới khi hình lặp khung thứ hai, rồi tự đặt thẻ **MÔ HÌNH** trước màn hình. Hình tắt. + +Hệ thống không “hiểu” đạo đức; khi kích thích không tạo phản ứng mong đợi, nó chỉ chuyển sang mục tiêu khác. Tiếng chuông thứ bảy. + +12 giờ 22. Đèn báo Khóa phía Tây tắt. Theo bảng giờ, Nam ở Ngọc Trục mở cổng cho đội kỹ thuật dự phòng sau khi nhận hai xác nhận dây cơ. Không chờ giọng Tiến. + +“Đội ba đi Láng,” cậu ra lệnh. + +Một người hỏi: “Anh Tiến duyệt?” Nam chỉ chữ ký hội đồng. “Đã duyệt từ trước.” + +Ngọc Trục hoạt động khi Tiến không có mặt. Duy lắp chốt thử. Lò xo ép, thanh thép cong nhưng chưa gãy. Bó đỏ tách khỏi quyền ưu tiên trung tâm; bó trắng và đen vẫn dao động. + +Cột hiện: + +**MODEL INTEGRITY LOSS** + +Duy kiểm lại số đo. “Đây là lớp mô hình, không phải hạ tầng vật lý.” Tiếng chuông thứ tám. + +12 giờ 23. Áo Thủy rách ở chốt đồng khi cô lùi. Vết cắt vai Tiến thấm thành mảng tối. Đạt đứng đúng vị trí trong bức ảnh, bàn tay thiếu ngón giữ bảng đo. + +Trên tường, ba bóng người và một hình tối tổng hợp từ các nguồn chiếu. Loa cột phát câu có hướng: + +“Đừng đếm người.” + +Duy nhìn hình. “Đếm nguồn quan sát.” Tiến, Thủy, Đạt — ba người. Lớp tổng hợp — nguồn thứ tư đang cố biến dữ liệu khác nhau thành một Observer chung. + +Duy kéo bó đỏ khỏi cầu ưu tiên. Tia lửa bật, mùi đồng cháy lan trong phòng. + +Các màn hình ngoài mất phần dự báo. Từ giây đó, Hậu Ký không còn bản ghi ổn định về điều xảy ra trong phòng. Khoảng trống đã bắt đầu không vì mọi thiết bị chết. + +Vì lớp dùng để biến dữ liệu thành một phương án đã bị tách khỏi quyền điều khiển. + +Chương 81: Ba Ngón Tay Giữ Khóa + +12 giờ 24. Khóa phía Tây nhận tải gấp ba sau khi Hoàng Thành tách lớp mô hình. + +Thanh hợp kim chèn từ đêm 19 tháng 7 đã cong. Khe nứt mở, thổi ra luồng khí nóng mang giọng người chết. Đồng hồ cơ nhảy sát vùng đỏ. Đức dùng búa ép thanh mới. Mỗi nhát làm sàn rung. + +Ông Hòa giữ bộ kẹp bằng bàn tay trái còn ba ngón. Găng nóng lên nhanh đến mức Đức phải đổi cho ông đôi khác sau chưa đầy một phút. + +“Bỏ tay ra.” + +“Chưa. Đập góc dưới.” + +“Bác mất nốt thì ai đọc mạch?” + +Câu đó có tác dụng hơn quát. Ông Hòa thả kẹp, lùi khỏi mép nóng và chỉ bằng cán tua vít. “Được. Cậu giữ. Tôi đọc.” + +Đội dự phòng tới do Nam mở cổng. Khánh An dẫn xuống nhánh bắc, đeo dây kiểm tra chéo của chính nhóm cô lập. Cô không nhận lệnh riêng của Kha; bảng quy trình quy định khi đèn Tây tắt, phải có người ngoài đội nút chứng kiến thao tác. Dư Âm gọi từng người. + +Ông Hòa nghe giọng vợ: “Ông về đi.” Âm thanh không có hướng. + +Ông nghiến răng, nhưng không trả lời giọng đó. Đức nghe con trai. Khánh An nghe người đồng đội từng chết vì một lệnh của Kha. Cả ba đã được dặn trước: nếu tiếng gọi không có hướng vật lý, chỉ ghi nhận, không đối thoại. + +Đường nứt mở thêm. Một cửa phụ dưới giếng phải đóng bằng tay để tải không vòng ngược. Nhiệt kế dây ở đáy báo năm mươi tám độ. + +Ông Hòa đọc con số trên đồng hồ rồi chốt: “Mỗi người dưới đó tối đa chín mươi giây.” + +Khánh An đã kéo áo khoác phản nhiệt lên. “Tôi xuống.” + +“Cô không biết van.” + +“Bác chỉ từ trên.” + +“Camera chết dưới đó.” + +“Dây thoại cơ còn.” + +Ông Hòa cân nhắc hai giây rồi gật. “Xuống trước. Chạm tay quay thì mô tả, đừng cố thắng nó.” + +Khánh An đeo dây chính, dây phụ và túi gel mát ở cổ trước khi xuống. Đức lật đồng hồ cát chín mươi giây. Ở đáy, hơi nóng làm mắt cô khô rát ngay qua kính. + +“Cửa cơ kẹt,” cô nói qua dây. “Bùn cứng. Tay quay không nhúc nhích.” + +“Xoay ngược nửa vòng để nhả tải.” + +“Không đi.” + +“Đừng dùng lực tiếp. Tìm lỗ khóa ở chân bánh.” + +Khánh An sờ bằng găng. “Có. Nhưng chốt lệch.” + +Ông Hòa nhìn sơ đồ. Cấu tạo trên giấy cũ khác vị trí cô mô tả. Có người từng thay cụm bánh răng sau khi bản vẽ được lập. + +Đức nhìn cát đã chảy hơn nửa. “Rút cô ấy.” + +“Khánh An, lên.” + +“Tôi còn—” + +“Lên. Không ai được chứng minh mình chịu nóng giỏi hơn người khác.” + +Cô chửi một câu nhưng kéo tín hiệu. Dây đưa cô lên khi còn chưa hết chín mươi giây. Sau khi uống từng ngụm nhỏ và làm mát, cô vẽ lại cụm bánh theo thứ mình sờ được. + +Ông Hòa nhìn bản vẽ mới. “Nó lắp ngược cơ cấu. Tôi phải xuống một lượt để chỉ đúng điểm, rồi Đức kéo.” + +Đức phản đối. “Bác vừa bắt cô ấy không liều.” + +“Đúng. Nên tôi cũng có chín mươi giây, hai dây và người kéo. Quá giờ kéo tôi lên dù tôi chửi.” + +Khánh An nói: “Tôi giữ đồng hồ.” + +Lần hai, ông Hòa xuống cùng Đức, nhưng ông không quay cửa. Ông chỉ xác định chốt bằng đầu kìm rồi lùi sang một bên. Đức buộc dây vào tay quay, móc qua khung; phía trên Khánh An và hai người dự phòng dùng trọng lượng kéo. Cửa dịch từng milimet. + +“Còn ba mươi giây,” Khánh An báo. + +Trên mặt, Đức nghe tải qua dây thoại: “Còn tăng. Thêm mười.” + +Nam ở Ngọc Trục hỏi: “Rút?” + +Đức nhìn bảng quyền tại chỗ. Không có Tiến để hỏi. “Cửa đang đi. Hai mươi giây nữa, nếu chưa qua vạch thì rút.” + +Tại Hồ Tây, Tùng đá Phúc khỏi bánh răng. Phương vẫn giữ kìm. Quân bò tới ngắt cơ, máu từ vai chảy theo cánh tay. + +“Anh chuyển tay, áp lực sập,” Tùng nói. + +“Không phá.” Quân cắm chìa thứ nhất. + +Phương cắm chìa hội đồng thứ hai. Hai người xoay cùng lúc, chuyển van khỏi lệnh tự động sang điều khiển tay. Một người Intervention bắn Quân. Viên đạn xuyên gần phổi. + +Phúc nhặt khẩu súng rơi và bắn Tùng vào bụng. Giữa tiếng kim loại dội loạn, về sau không ai thống nhất phát nào vang trước. Cảnh ấy không có một khoảnh khắc sạch sẽ để kể lại như chuyện anh hùng. + +Phương quỳ bên Quân nhưng ông đẩy cô. “Van.” Phúc buông súng, dùng tay trái cùng em giữ tay quay. Hai anh em đứng một phía vì một đường ống, không vì mọi mâu thuẫn trước đó biến mất. + +12 giờ 25. Ở đáy giếng Láng, cửa phụ vượt qua vạch cơ đúng lúc Khánh An quát “kéo lên”. + +Tải giảm một phần. Ông Hòa lên khỏi miệng giếng gần như không tự đứng được. Phần găng ở lòng bàn tay đã cháy sém khi bộ kẹp trượt vào bánh răng trong giây cuối; da bỏng sâu nhưng ba ngón còn cử động. + +Đức hỏi: “Bác sống?” + +Ông Hòa thở qua khăn mát, mất một lúc mới nói được. “Đổi câu hỏi.” + +Đức vừa cười vừa chửi, rồi quay lại đọc kim. + +Đồng hồ trở vùng vàng. Không màn hình HANOI-07. Chỉ một cây kim cơ, một tấm cửa đã đóng, hai đồng hồ cát đã hết và những người còn đủ tỉnh để tiếp tục giữ. + +Ở Hoàng Thành, Đạt đọc thay cho radio đã mất: “Tây ổn định.” + +Tiến không hỏi ai bị thương; lúc đó chưa có đường nào để câu hỏi nhận được câu trả lời. Hắn giữ tấm ốp bằng vai chảy máu, chờ Duy chuyển tải tiếp. + +Ở Ngọc Trục, Nam ghi lên bảng: + +**12:25 — CỬA PHỤ ĐÓNG — KHÓA TÂY GIỮ.** + +Cậu nhìn chữ **GIỮ**, rồi viết thêm bên dưới: + +**NGƯỜI TẠI CHỖ QUYẾT ĐỊNH RÚT/Ở THEO NGƯỠNG NHIỆT.** + +Lần này, dòng chữ không phải mệnh lệnh Tiến để lại. Đó là điều cả nhóm vừa học bằng da thịt và tự ghi lại, để ca sau không phải trả cùng một cái giá. + +Chương 82: Mạch Nước Hồ Tây + +12 giờ 26. Kim áp lực Hồ Tây rung quanh 84. Ngưỡng đỏ bắt đầu ở 85. + +Quân nằm sau bệ bê tông, hai vết đạn, hơi thở có tiếng bọt. Tùng bị bắn bụng nhưng mạch còn mạnh hơn. Phương có một túi dịch cuối cùng. Người Vòng Tròn Vỡ kéo cô về phía Quân. “Ông ấy cứu cô.” + +Phương kiểm đường thở, nhịp, mức tỉnh, vị trí chảy máu và thời gian thực tế tới điểm y tế. Quân có dấu hiệu tổn thương ngực nặng; túi dịch không sửa được thứ cần can thiệp mà họ không có tại chỗ, còn truyền quá nhiều có thể làm chảy máu nặng hơn. Tùng bị bắn bụng nhưng vẫn còn đường vận chuyển và mạch ngoại vi bắt được. Không phương án nào bảo đảm. Với dữ kiện trước mắt, Phương dùng túi dịch cuối cho Tùng và tiếp tục băng ép cho Quân. + +Một người túm vai. “Cô điên à?” Quân mở mắt, giọng khó. “Bỏ.” + +“Anh—” + +“Cô ấy đúng.” + +Không yêu cầu lòng biết ơn phá tiêu chí y tế. Phương băng ép cho Quân bằng phần gạc còn lại, rồi quay về van. Phúc và hai người giữ tay quay. Bàn tay phải của anh trong nẹp trượt vì mồ hôi; anh quấn dây quanh cẳng tay thay vì cố nắm. + +Tùng tỉnh khi dịch bắt đầu chảy. + +“Ổ gốc,” hắn nói. + +Chiếc hộp nằm bên bảng điều khiển, tự nóng dù chưa cắm vì cộng hưởng từ mạng. + +“Đưa lại.” + +Phương không nhìn. “Im.” + +“Các người đang tạo một nhánh không dữ liệu.” + +“Chưa bao giờ dữ liệu thấy hết.” + +“Không có tỷ lệ, cô không biết giữ van cứu hay giết nhiều hơn.” + +Phương chỉ Quân. “Tôi cũng không có tỷ lệ cứu anh ấy. Vẫn phải chọn việc trước mặt.” Tùng cố bò. Phúc giữ vai hắn, không đánh. + +Quân nhìn hộp. “Đưa khỏi tuyến.” Phương dùng dây kéo ổ dữ liệu qua nền, tránh chạm tay. Nó rơi xuống hố bùn khô cách bảng van vài mét. Không phá — vì dữ liệu lịch sử còn giá trị. Không cho kết nối — vì giao thức đang cố giành quyền. + +12 giờ 27. Tại Hoàng Thành, bó đen nóng lên khi mất ưu tiên trung tâm. Nếu quá tải, các van và khóa có thể dừng hoàn toàn. + +Duy nói: “Phải đưa điều khiển về nút.” + +“Bó trắng chỉ đo,” Tiến đáp. + +“Các bộ điều cục bộ có thể dùng số gần nhất ở chế độ bảo trì.” + +“Chuyển từng điểm.” + +Không có một lệnh duy nhất. Duy phải tháo từng cầu nối, đặt rơ-le về cục bộ, chờ Đạt xác nhận kim rồi mới chuyển điểm sau. Ngọc Trục. + +Láng. Hồ Tây. + +Các điểm nhỏ. Thủy đặt lòng bàn tay xuống nền. Âm nước có hướng, khác tiếng chuông. “Hồ Tây đang dao động. Chuyển nửa tải trước.” + +Duy làm. Đạt đọc: “83,9.” Cột hiện: + +**UNDEFINED STATE** + +Tiến không còn hơi để bình luận. Hắn giữ nhịp thở, cơn đau ở vai dội theo từng nhịp tim. 12 giờ 28. + +Tiếng chuông thứ mười một vang. Các lớp vật lý bắt đầu ổn, nhưng một âm trầm khác hình thành dưới tất cả — không tới từ hướng cụ thể. Bóng tổng hợp trên tường đậm lên. Lớp đối chiếu đang cố dựng lại một Observer chung từ dữ liệu còn lại. + +“Nếu nó khép mô hình, quyền trung tâm trở lại,” Duy nói. + +Thủy lấy thiết bị Null nhưng chưa bật. “Bán kính?” + +Duy nhìn mức nguồn. “Ở công suất này, khoảng tác động nhỏ nhất đủ chạm lớp tổng hợp. Không bảo đảm chỉ có Dư Âm bị ảnh hưởng.” + +“Thời gian?” + +“Ba giây trước khi nhiệt đầu cực vượt ngưỡng.” + +Thủy chỉnh giới hạn cơ về ba giây rồi mới đặt điện cực. Tiến chạm cổ tay cô, nhận ra mình đang giữ và tự buông ra. + +“Cô có thể mất nghe.” + +“Biết.” + +“Mất ký ức.” + +“Có thể.” + +“Đừng.” + +Thủy nhìn hắn. Giữa tiếng chuông đang lớn dần, cô vẫn phân biệt được câu ấy đến từ một người thật trước mặt — có hướng, có hơi thở và có nỗi sợ. + +“Anh không quyết.” + +Tiến gật. “Đúng.” + +Cô hướng trường Null vào lớp tổng hợp chứ không toàn mạng và đặt ngón tay lên công tắc hẹn ngắt. + +Công tắc bật. Tiếng chuông thứ mười hai tắt trước khi hoàn thành. + +Cùng lúc, mọi âm thanh biến mất khỏi Thủy. Không chỉ Dư Âm. + +Không nước, không kim loại, không hơi thở. Môi Tiến cử động nhưng thế giới không có tiếng. Thủy thấy hắn định bước tới rồi tự dừng, giữ lời không quyết thay. + +Đạt giơ bảng: + +**ÁP LỰC ỔN.** + +Duy: + +**LỚP DỰ BÁO ĐÃ CẮT.** + +Tiến viết bằng bàn tay dính máu: + +**HẠ TẦNG CÒN.** + +Ngay dưới dòng đó, Duy tự thêm một việc không có trong phân công: + +**TỪ CA SAU: KHÔNG MỘT NGƯỜI GIỮ CẢ LOG, QUYỀN GHI VÀ QUYỀN XÁC NHẬN.** + +Đạt nhìn anh, chỉ vào tay đang run. Duy hiểu, viết thêm: **KỂ CẢ TÔI.** + +Khánh An, từ Khóa Tây, gửi về một tờ phiếu có ba ô nguồn. Cô gạch chữ **độc lập** ở hai ô đầu vì cả hai cùng đi qua một cáp. Bài học về nguồn giả độc lập không đợi ba năm mới thành quy trình. + +Thủy gật. Ở Hồ Tây, kim hạ khỏi 84. Phúc và Phương vẫn giữ van. Quân còn thở. Tùng nhìn ổ dữ liệu nằm ngoài tầm với. + +Mạch nước tiếp tục chảy không vì một tương lai ra lệnh. Nó chảy vì ở từng điểm có người đang đọc một cây kim và giữ phần việc của mình. + +Chương 83: Khi Người Nghe Không Còn Nghe + +Thủy không nghe gì. Không tiếng chuông, nước, kim loại hay hơi thở của chính mình. Thiết bị Null nóng trong tay rồi tắt, để lại một vệt đỏ chạy từ lòng bàn tay lên cổ tay. Cảm giác thăng bằng lệch sang trái; nền đá dưới chân dường như nghiêng dù mắt cô biết nó vẫn phẳng. + +Duy bước vào tầm nhìn, hai bàn tay mở để cô thấy anh không định chạm. Anh viết lên bảng: + +**NHÌN TÔI. NGỒI XUỐNG.** + +Thủy làm theo. Mọi người cử động trước mắt cô, miệng mở mà không có âm; căn phòng giống một đoạn phim bị rút mất lớp quan trọng nhất. Điều làm cô sợ trước tiên không phải mất Dư Âm, mà là một người sống có thể gọi tên cô ngay bên cạnh mà cô không biết. Cô nhớ tiếng mẹ bán hàng dưới ngõ thời sinh viên, tiếng máy ảnh lên phim, tiếng Tiến gõ ngón tay vào cốc khi đang tính. Những âm bình thường từng bị cô coi là nền. Bây giờ chỉ còn hình ảnh của chúng. + +Duy đưa ba thẻ đã chuẩn bị từ trước: + +**CÓ ĐO** +**CHƯA RÕ** +**MÔ HÌNH / BẢN GHI** + +Đạt đọc đồng hồ và viết từng số. Áp lực 83,9: **CÓ ĐO**. Tỷ lệ sống: **MÔ HÌNH**. Cảnh báo `HOST FAILURE`: **CHƯA RÕ**, vì đó là tên hệ thống đặt cho trạng thái, không phải phép đo về con người. Cột chiếu Đại Hà. + +Bé gái sau cửa kính. Người chạy. Cửa cuốn hạ. Thủy lần theo góc nhìn: camera ở trên trần, nơi cô chưa từng đứng. Vậy cảnh này ít nhất đã qua một lớp dựng, không thể là ký ức nguyên vẹn từ mắt cô. Cô giơ thẻ **MÔ HÌNH / BẢN GHI**. + +Hình đổi sang mẹ Tiến ở Thanh Hóa. Không giờ, không nguồn. Tiến bước nửa bước rồi dừng, chờ cô. Thủy đặt **CHƯA RÕ** trước màn hình. + +Hắn lùi lại. Hình đổi sang Kha cầm dao. Lần này Tiến tự lấy thẻ **MÔ HÌNH**. Cột tắt hình. + +HANOI-07 không cần đọc ý nghĩ. Nó chỉ thử lại những kích thích đã từng khiến họ đổi hành vi. Khi giọng nói không còn đường vào Thủy, nó dùng hình ảnh. Cô viết nhanh: + +**GIỮ PHÉP ĐO. KHÔNG LÀM THEO HÌNH.** + +Duy gật, tiếp tục chuyển rơ-le. Cột hiện: + +**OBSERVER CONSENSUS REQUIRED** + +Ba vùng xác nhận sáng tại vị trí Tiến, Thủy và Đạt. Hệ thống muốn ba nguồn cùng chọn một trạng thái để lớp tổng hợp khép lại. Tiến viết: + +**GIỮ HẠ TẦNG VẬT LÝ.** + +Thủy nhập ở vùng thứ hai: + +**KHÔNG DÙNG DỰ BÁO LÀM LỆNH.** + +Đạt chưa chạm. Cột báo: + +**INCONSISTENT OBSERVATION** + +Thủy đặt hai câu cạnh nhau rồi giơ thẻ **CÓ ĐO**. Mâu thuẫn là một dữ kiện có thật, không phải lỗi cần ép cho biến mất. Nền rung mạnh. Thủy không nghe nhưng cảm qua xương chậu và răng. Cô mất thăng bằng; Tiến đưa tay rồi dừng cách vai một khoảng, để cô tự chọn. Thủy nắm cổ tay hắn và đứng lại. + +Vết cắt ở vai Tiến đã thấm đỏ. Cô chỉ vào đó. Hắn lắc đầu; vết thương đau, nhưng chưa phải thứ cần xử lý trước. Từ đường ngoài, đèn tín hiệu nhấp nháy theo mã cơ: Khóa Tây giữ, Hồ Tây chưa ổn. Một đèn thứ ba từ tuyến Cát Linh bật đỏ rồi tắt. Đạt ghi: + +**NÚT PHỤ CÁT LINH — NHIỆT TĂNG / KHÔNG CÓ NGƯỜI XÁC NHẬN.** + +Duy nhìn sơ đồ. Nút ấy giữ một hành lang làm mát cho hai khu trú nhỏ. Nếu quá tải, không phá mạng trung tâm nhưng có thể làm hàng trăm người mất đường thoát nhiệt. Không có radio để gọi. Chỉ có một dải đèn mã chậm. Duy gửi yêu cầu đo tại chỗ. Không hồi đáp. + +Cột chiếu một hình khác: Thủy đứng trong Hoàng Thành, tay đặt lên vùng mở trung tâm. Bên dưới: + +**LISTENER REQUIRED** + +Thủy lấy bút gạch chữ **LISTENER**, viết tên mình lên bảng giấy: + +**TRẦN THANH THỦY — KHÔNG ĐỒNG Ý.** + +Cảm biến không hiểu phẩm giá hay quyền tự quyết; nó chỉ ghi nhận một nguồn không còn khớp vai trò dự đoán. Vùng xác nhận thứ hai tắt. Duy nhìn cô, môi tạo hai chữ có thể là “được rồi”. + +Thủy không nghe. Cô thấy. + +Trong vài phút quan trọng nhất, điều đó đủ để làm việc. Nhưng khi nhìn đèn Cát Linh tiếp tục đỏ, cô hiểu một điều khác: từ chối hệ thống không tự cứu được người ở xa. Họ vẫn cần dữ liệu, bản đồ và những quyết định kỹ thuật — chỉ không giao mục tiêu cho một mô hình đặt sẵn. + +Cô kéo tấm bảng lại, viết cho Tiến: + +**NẾU TÔI KHÔNG NGHE LẠI?** + +Tiến đọc. Hắn không viết “sẽ nghe”. Không hứa điều không biết. + +**TÔI SẼ HỌC CÁCH NÓI ĐỂ CÔ THẤY.** + +Thủy đọc lại câu đó một lần, rồi gấp bảng lại. Không có thời gian biến nó thành một cảnh dịu dàng hơn. Đạt đang bước tới vùng xác nhận thứ ba. + +Nhãn **LISTENER** trên giao diện vừa mất ý nghĩa thực tế, còn Thủy thì vẫn ngồi trước bảng, mắt theo từng con số và từng cử động của người khác. Cô không cần nghe để tiếp tục tham gia quyết định; cô chỉ phải đổi cách nhận thông tin. Vân đặt hai ngón tay trước mắt Thủy rồi di chuyển sang trái, phải, lên, xuống. Cô theo được nhưng chậm ở phía trái. Đạt ghi phản ứng, không gọi đó là tổn thương vĩnh viễn. Mỗi lần một người định hỏi “cô còn nghe gì”, Thủy chỉ vào tấm bảng **KHÔNG CỐ NGHE**. + +Trong khoảng nghỉ vài giây, cô mở sổ và viết một danh sách không liên quan hệ thống: + +- tiếng nắp ấm nước ở nhà mẹ Tiến; +- tiếng Nam cười khi sửa được radio; +- tiếng kéo của Linh cắt băng; +- tiếng Bình An đọc sai tên đường; +- tiếng gió qua mái tôn. + +Nếu thính giác không trở lại, những âm thanh ấy cũng không phải “dữ liệu cần khôi phục” cho HANOI-07. Cô sẽ phải nhờ người khác kể lại thế giới bằng hình, chữ và rung động. Việc nghĩ tới một đời sống khác cách nghe giúp cơn hoảng trong ngực chậm đi. Cô gấp trang, đặt vào túi. Chưa biết có cần dùng. Nhưng lần đầu sau khi Null bật, Thủy không chỉ nghĩ mình đã mất gì; cô bắt đầu nghĩ mình còn có thể sống bằng cách nào. + +Chương 84: Người Quan Sát + +Nguyễn Hữu Đạt không nhìn cột trung tâm. Ông nhìn bốn kim cơ và đọc từng số vào bảng giấy: + +Nhiệt nền 47,8. Áp lực 83,9. + +Rung Tây giảm. Mực nước ổn. + +Tiến còn phản ứng. Thủy còn tỉnh. + +Duy còn điều khiển. Vân còn giữ Null. + +Đạt đặt bàn tay thiếu đốt ngón út lên vùng xác nhận thứ ba. Cơn đau từ vết thương mới chạy lên cổ tay, nhưng kim trước mặt không đổi vì đau của ông. Đó là lý do cần phép đo ngoài cơ thể người quan sát. Cột hiện: + +**CENTRAL OBSERVER PRESENT** + +Bóng thứ tư trên tường đậm lên, không giữ một gương mặt. Nó chuyển qua những hình người khác nhau: kỹ sư, nhân viên trạm, người đọc mực nước, Trần Văn Tĩnh khi trẻ. Hàng chục hồ sơ Observer cũ bị chồng thành một đại diện duy nhất, khiến một chức năng trông như một con người luôn tồn tại và luôn biết nên chọn gì. + +Hệ thống yêu cầu Converge, Preserve hoặc Null. Đạt không chọn. + +Ông mở trường ghi chú bảo trì Tĩnh từng chỉ. Bàn phím cứng, vài phím mất ký tự. Đạt gõ bằng bàn tay đau: + +**TRẠNG THÁI CHƯA GIẢI QUYẾT. HẠ TẦNG ĐANG HOẠT ĐỘNG. CÁC NGUỒN KHÔNG ĐỒNG THUẬN.** + +Màn hình báo: + +**INVALID OBSERVER STATE** + +Đạt nhìn kim. “Hợp lệ theo phép đo.” Cột rung. Hình tổng hợp tiến gần, bóng phủ lên vai ông. Dòng mới hiện: + +**OBSERVER MUST RESOLVE** + +Đạt nhớ một trạm điện mười hai năm trước. Hôm ấy, biểu mẫu chỉ cho chọn **an toàn** hoặc **không an toàn**. Sếp cần đóng báo cáo để kịp bàn giao. Các số nằm ngay sát ngưỡng; ông đã ký an toàn vì không muốn giữ cả đội lại qua đêm. Hai ngày sau, một thợ điện bị bỏng khi lớp cách điện vỡ. + +Người đó sống. Đạt chưa từng kể việc mình ký. Ông nói, dù không biết Thủy nghe được hay không: “Tôi từng điền một ô vì biểu mẫu không cho ghi không biết.” + +Duy nhìn ông. Đạt gõ tiếp: + +**KHÔNG CÓ ĐƯỜNG HỢP LỆ. TIẾP TỤC GHI CÁC NGUỒN RIÊNG.** + +Hệ thống báo lỗi lần nữa. + +Duy hiểu việc cần làm. Anh không viết lại HANOI-07 bằng một dòng lệnh. Anh tháo đầu ra của bộ tổng hợp khỏi rơ-le điều khiển. Vít thứ nhất nóng tới mức găng bốc mùi cao su. Vít thứ hai kẹt vì kim loại giãn; Kha chưa vào phòng, nên Đạt dùng chính thanh kẹp của mình làm đòn. + +Mỗi đường đo được dẫn sang một bộ nhớ cục bộ. Ngọc Trục ghi Ngọc Trục. + +Láng ghi Láng. Hồ Tây ghi Hồ Tây. + +Hoàng Thành giữ các bản cạnh nhau mà không ép thành một trạng thái. Bóng thứ tư vỡ thành những đường sáng rời, không còn hình người. Cột hiện: + +**OBSERVER INPUT DISTRIBUTED** + +Ở trạm ngoài, Tĩnh nhận tín hiệu qua dây và tháo thẻ Observer khỏi cổ. Trong phòng không ai nghe thấy tiếng thẻ chạm bàn, nhưng Đạt vẫn hình dung được tiếng kim loại nhỏ ấy. Chức danh Observer vừa mất người sở hữu duy nhất. Các đèn nút lần lượt trả lời. + +Ngọc Trục: xanh. Láng: vàng. + +Hồ Tây: vàng. Cát Linh: đỏ. + +Nút Cát Linh vẫn không có người xác nhận. Duy mở bản đồ cũ. Đường làm mát của nó đi qua một van phụ đã bị niêm từ trước Hồng Nhật. Mở sai có thể đẩy hơi nóng vào khu trú; không mở, nhiệt tiếp tục tăng. + +“Cần dữ liệu tại chỗ,” Đạt nói. + +“Không có,” Duy đáp. + +“Vậy ghi chưa rõ.” + +“Người ở đó không sống bằng chữ chưa rõ.” + +Đạt nhìn anh. Đây là giới hạn của nguyên tắc: chấp nhận không biết không có nghĩa được phép đứng im khi người khác đang chết. Nó chỉ cấm giả rằng mình biết chắc. Khánh An gửi một mã đèn từ vòng ngoài: trong tài liệu 38% của Tùng có phụ lục về Cát Linh. Bản đó đang niêm phong trong túi của cô, chưa ai dùng vì không muốn đưa mô hình vào quyền điều khiển. + +Đạt ghi dòng mới: + +**DỮ LIỆU MÔ HÌNH CÓ THỂ HỮU ÍCH. PHẢI KIỂM BẰNG SỐ ĐO CỤC BỘ TRƯỚC KHI LÀM.** + +Ông không vứt dữ liệu đi, nhưng cũng không quỳ trước nó. Đạt rút tay khỏi vùng xác nhận. Băng ngón thấm máu, nhưng các kim chính vẫn ổn. + +Bức ảnh Hậu Ký đã ghi **CENTRAL OBSERVER PRESENT**. Người ta từng tưởng đó là một nhân vật bí mật. Thực tế, dòng chỉ đánh dấu khoảnh khắc một nguồn bị yêu cầu đứng trên tất cả các nguồn khác. Đạt đã từ chối. + +Một nhịp sau, Duy thấy lớp đỏ mảnh chạy từ bề mặt giao diện lên cổ tay Tiến. + +“Ngắt anh ấy.” + +Tiến kéo tay nhưng không rời. Những sợi vật liệu nhỏ như gai đã bám dưới da, sáng theo mạch. Đồng hồ thần kinh tăng. Vân áp Null. Vệt đỏ chậm, không dừng. + +Đạt kiểm mắt Tiến. “Còn nhận thức.” Tiến nói: “Cắt giao diện.” + +Duy thử ngắt dây ngoài. Không tác dụng. Trạng thái đã đi vào mô. Cửa kỹ thuật mở. Kha bước vào cùng Khánh An. Hắn nhìn cổ tay Tiến, nhìn bảng quy trình, rồi nhìn con dao công cụ bên hông. + +Chiếc nhẫn đã trở lại ngón tay hắn. Mặt trong là mã cháy sém của Minh Khôi và con số bốn mươi bảy phút mà hắn chưa từng tha thứ. Không ai nói tên Mễ Trì; chiếc nhẫn đã nói đủ. + +Căn phòng hiện tại đã đủ giống. + +Nhãn in đã bong vì nhiệt, nên Duy buộc các dây ghi cục bộ bằng những mảnh vải khác màu. Đỏ cho Hồ Tây, xanh cho Ngọc Trục, vàng cho Láng, trắng cho Hoàng Thành. Đạt đọc từng màu trước khi nối, Khánh An từ ngoài kiểm lại qua gương. Một lỗi nhỏ ở đây có thể khiến hai bản ghi đổi tên và tạo một “sự thật” sai mà không ai cố ý nói dối. + +Khi đường cuối được nối, bộ tổng hợp vẫn cố kéo các tín hiệu về một cột duy nhất. Duy phải tháo cả cầu tiếp điểm, làm đứt móng tay và bỏng đầu ngón. Đạt không giật tua vít khỏi tay Duy chỉ vì mình sốt ruột. Ông giữ đèn, đọc kim và gọi từng mốc nhiệt; Duy mới là người hiểu thứ tự tháo tiếp điểm. Ở nơi chỉ một con vít sai có thể đổi tên hai nguồn dữ liệu, biết phần nào mình không nên làm quan trọng chẳng kém biết mình làm được gì. + +Đạt không chạm nút xác nhận. Kim áp lực bò qua vạch giữa; chỉ khi nó đứng yên, ông mới ghi. + +Chương 85: Con Dao Không Đâm Xuống + +Kha không rút dao ngay. Hắn kiểm đồng hồ thần kinh, đường đỏ dưới da và tay Duy đang giữ rơ-le. Sau đó nhìn Tiến để xác nhận mắt còn bám được người trước mặt. + +“Nhận ra tao?” + +“Đáng tiếc.” + +Câu trả lời yếu nhưng đúng giọng. Đạt ghi: **ý thức còn**. Vân tăng Null quanh cổ tay. Vệt đỏ chậm thêm, vẫn tiến lên khuỷu. + +Duy nói: “Cắt dây ngoài không đủ. Sợi giao diện đã bám mô.” Kha liếc đồng hồ; mỗi giây trôi qua, vai hắn lại cứng thêm. Trên mặt trong chiếc nhẫn, mảnh thẻ của Minh Khôi cọ vào da. Bốn mươi bảy phút chờ ba cấp ký duyệt từng giết em hắn; từ đó, Kha học rằng do dự là một cách giết người có giấy tờ. + +Khánh An đứng cạnh, đọc được điều hắn đang nghĩ. + +“Đây không phải cổng Bắc Ninh,” cô nói. + +“Không có thời gian.” + +“Có quy trình.” + +“Quy trình từng giết người.” + +“Và anh từng giết vì không chịu để ai kiểm mình.” + +Kha quay sang. Khánh An không lùi. + +“Bốn mươi bảy phút không có nghĩa mọi lần chờ đều sai,” cô nói. “Lần này chúng ta đã dùng ba mươi giây để biết anh đang cắt gì.” + +Đạt đưa bảng quy trình. Điểm 1: ý thức còn. Điểm 2: tín hiệu thật — Thủy xác nhận bằng ánh sáng và thiết bị. Điểm 3: Null không ngắt. Điểm 4: kỹ thuật ngoài da thất bại. Chưa tới quyền giết. + +Tiến nói: “Cắt mô tiếp xúc.” Kha rút dao. “Giữ nó.” + +Đạt và Duy giữ vai. Vân giữ điện cực. Thủy ngồi trước mặt Tiến, đặt bảng trong tầm nhìn: + +**Ở ĐÂY. NHÌN TÔI.** + +Kha rạch quanh điểm tiếp xúc. Không đủ thuốc tê; Linh ở xa và thời gian không cho. Máu tràn, vệt đỏ tăng theo phản ứng cơ thể. HANOI-07 hiện: + +**HOST DISCONNECT RISK** + +Kha liếc dòng. “Đừng gọi nó là Host.” Hắn tìm sợi đầu tiên bằng đầu dao và kẹp. Sợi mảnh như tóc nhưng cứng hơn mô. Khi cắt, Tiến giật mạnh. Thủy không nghe tiếng hét; cô chỉ thấy cổ họng hắn căng và mắt mất nét. + +Cô nâng bảng: + +**CÓ NGƯỜI THẬT. CÓ HƯỚNG. ANH Ở HIỆN TẠI.** + +Tiến tập trung vào nét chữ. Một phần trong hắn vẫn thấy B3 năm 2031: đèn đỏ, dao, gương mặt Kha già hơn và nỗi hoảng của người vừa bị xóa lý do. Nhưng tay Thủy đang giữ tấm bảng có một vết mực mới. Đó là chi tiết không thuộc ký ức cũ. Sợi thứ hai nằm sâu. Dao trượt vào mô. Máu phun lên tay Kha. + +Lưỡi dao khiến hơi thở Tiến ngừng lại. Kha nói câu cũ: + +“Mày vốn không nên sống lâu đến thế.” + +Cơ thể Tiến cứng lại trước khi lý trí kịp hiểu. Kha tiếp, giọng thấp: “Nhưng tao chưa làm.” + +Hắn đổi góc dao, dùng phần sống lưỡi tách mô. Khánh An giữ đèn, tay không run dù mặt trắng. + +“Bên trái thêm hai milimet,” Duy nói. + +Kha không lao theo nỗi sợ chậm. Hắn chờ Duy xác nhận đường mạch rồi mới cắt. Sợi cuối đứt. + +Tiến ngã khỏi giao diện. Vệt đỏ dừng ở khuỷu, nhạt dần nhưng chưa biến mất. Đạt kiểm mạch; Vân giữ Null thêm ba mươi giây. Duy đặt một miếng dẫn vô trùng lên vết cắt để chắc không còn tín hiệu qua mô. Kha vẫn quỳ, dao trong tay, đúng tư thế bức ảnh Mễ Trì từng không ghi rõ. + +Tiến thở khó. “Anh đâm tôi.” + +“Ừ.” + +“Không đúng chỗ.” + +Kha hạ mắt xuống vết cắt. “May?” + +“Không. Quy trình.” + +Khánh An bật ra một tiếng cười ngắn rồi quay mặt. Kha không cười. Hắn nhìn chiếc nhẫn, như thể lần đầu hiểu một thủ tục không nhất thiết là cái cổng giữ xe cứu trợ ngoài đường. Có thủ tục tồn tại để không cho nỗi đau của một người trở thành dao của tất cả. + +Hắn đưa dao cho Đạt. “Giữ.” + +“Vì sao?” + +“Không muốn cầm tiếp.” + +Đạt đặt vào hộp bằng chứng. Không phá con dao; phá vật không xóa khả năng một người chọn dùng nó. Thủy viết cho Tiến: + +**ANH CÒN LÀ ANH?** + +Hắn đọc lâu. Ký ức 2028 và 2031 không tách thành hai tiếng nói. Chúng cùng nằm trong một cơ thể đau, nhưng người đang chọn câu trả lời là người hiện tại. Tiến viết bằng tay trái: + +**KHÔNG BIẾT HẾT. NHƯNG TÔI LÀ NGƯỜI ĐANG TRẢ LỜI.** + +Thủy gật. Kha ngồi xuống sàn, lưng dựa cột. Máu Tiến khô trên tay hắn. “Mày hỏi tao có giết mày năm 2031.” + +“Ừ.” + +“Giờ tao hỏi: nếu không có những người này, tao có làm lại không?” + +Ánh mắt Tiến dừng ở con dao trong hộp. “Có thể.” + +“Câu tệ.” + +“Câu thật.” + +12 giờ 33. Mễ Trì không lặp nguyên. Cùng con dao, cùng hai người và cùng nỗi sợ không còn tạo ra cùng kết quả, vì quyết định đã bị chia cho những người có thể nói dừng. + +Ở góc phòng, đèn Cát Linh chuyển từ đỏ sang đỏ nhấp nháy. Một nơi khác vẫn đang hết thời gian. Vân ép băng quanh cổ tay Tiến và đánh dấu mép vệt đỏ bằng bút. Nếu nó lan qua đường mực, họ phải quay lại bước Null. Mỗi mười giây Đạt hỏi một câu khác — tên mẹ, ngày hiện tại, vị trí, việc Tiến vừa chọn — để chắc ý thức không chỉ lặp một đáp án học sẵn. + +Kha rửa tay trong một chậu nước ít tới mức máu chỉ loãng thành màu hồng. Khánh An đưa hắn khăn. + +“Anh đã chờ xác nhận,” cô nói. + +“Ba mươi giây.” + +“Vẫn là chờ.” + +Kha xoay chiếc nhẫn dưới ngón cái. “Đừng biến nó thành bài học đẹp.” + +“Không. Chỉ ghi rằng lần này ba mươi giây không giết ai.” + +Không ai biết chậm thêm một phút sẽ dẫn tới đâu. Nhưng bốn mươi bảy phút trong quá khứ của Kha từ nay không còn được phép tự động biến mọi khoảng cân nhắc thành con số không. + +Chương 86: Phương Án Thứ Tư + +Sau khi Tiến rời giao diện, ba lựa chọn hiện lại trên cột. + +**CONVERGE** +**PRESERVE** +**NULL** + +Đồng hồ bảo trì còn ba phút bốn mươi mốt giây trước khi lò xo rơ-le trả quyền về trung tâm. Converge vẫn có trọng lượng cao nhất vì hàng trăm truy vấn của Tùng. Kha nhìn đồng hồ. “Mười một phút đã hết.” + +“Khoảng mù kết thúc lúc 12 giờ 28,” Duy đáp. “Đó là lúc các lớp quan sát mất khả năng tạo một bản ghi ổn định. Từ 12 giờ 28 tới 12 giờ 34 phút 59 giây là pha tái khóa: rơ-le trung tâm dựng lại trạng thái từ những nguồn còn sống và cố kéo các nút về một kết quả duy nhất.” + +Vì thế Hậu Ký không có dữ liệu đáng tin sau 12 giờ 28, nhưng Đồng Bộ chưa kết thúc. Sáu phút năm mươi chín giây cuối không mở thêm một “cửa sổ tương lai”; đó là thời gian hệ thống cố ép phần chưa biết trở lại thành một câu trả lời. Tiến nằm dưới sàn, cổ tay băng ép. Hắn không thể chạm lại, và không ai đề nghị. + +Duy mở sơ đồ ngay trên nền. “Bó đen phải giữ để van và khóa chạy. Trắng giữ phép đo. Đỏ phải nằm ngoài quyền điều khiển.” + +“Chốt hiện tại chịu được bao lâu?” Đạt hỏi. + +“Không biết. Khi lò xo trả toàn lực, có thể gãy.” + +Kha lấy thanh thép mỏng từ hộp dụng cụ, dùng dao dự phòng của Khánh An cắt đầu theo góc. Đạt uốn bằng kìm. Duy đo lực, chỉnh thêm hai lần. Mỗi lần thử, lò xo bật thanh thép văng vào tường. Không có nút phương án thứ tư. + +Chỉ một chốt không nằm trong thiết kế vận hành bình thường. Duy chuyển từng nút sang bảo trì cục bộ. Mỗi lần, cột cảnh báo; Đạt chờ kim ổn mới cho chuyển tiếp. + +Ngọc Trục. Láng. + +Hồ Tây. Các điểm nhỏ. + +Ở từng nơi, một người thật phải giữ giới hạn. Nếu van Hồ Tây vượt 85, Phương và người Vòng Tròn Vỡ kéo ngắt cơ. Nếu Khóa Tây rung quá ngưỡng, Đức và ông Hòa đóng cửa phụ. Nếu Ngọc Trục mất bơm, Nam cắt tải khu ngoài trước lõi y tế. Không quyết định nào còn nằm hoàn toàn trong phòng Hoàng Thành. + +Đèn Cát Linh nhấp nháy nhanh hơn. Duy nhìn biểu đồ giấy. “Nhiệt đường phụ lên 61. Nếu trạm dừng, hai khu mát mất thông gió trong chưa tới mười phút.” + +“Có người ở trạm?” Tiến hỏi. + +“Không xác nhận được.” + +Khánh An mở túi niêm phong. Bên trong là phụ lục của phương án 38% do Tùng phát, phần họ chưa dùng vì không muốn nhập lệnh mô hình vào mạng. + +“Có chuỗi chuyển tải Cát Linh,” cô nói. + +Kha đọc tín hiệu. “Mở.” Đạt hỏi ngay: “Dựa vào gì để tin?” + +“Không tin,” Duy đáp. “Kiểm.” + +Phụ lục ghi mở van phụ số ba, đóng số một, giữ quạt bắc ở 40%. Nếu làm đúng, nhiệt chuyển sang một hầm metro bỏ trống; nếu sơ đồ đã lỗi, hơi nóng có thể dồn vào khu trú. Duy gửi mã đèn yêu cầu người gần Cát Linh kiểm van. Mười giây. Hai mươi. Một tín hiệu đơn trở lại: van ba còn áp; van một đang mở; hầm metro trống theo kiểm tra cuối sáu giờ trước. + +Không đủ chắc. Đủ để hành động có điều kiện. + +“Dùng chuỗi của Tùng,” Tiến nói. “Nhưng giới hạn quạt 25%, kiểm nhiệt mỗi năm giây. Tăng sai thì ngắt.” + +Kha quay sang hắn. “Mày vừa dùng Converge.” + +“Dùng một dữ liệu đã kiểm. Không giao mục tiêu.” + +Duy truyền lệnh cục bộ. Đèn Cát Linh đỏ thêm ba nhịp rồi chuyển vàng. Nhiệt giảm từ 61 xuống 58,5. + +Đèn Cát Linh giữ ở mức vàng. Một phần phụ lục của Tùng đã giúp họ tránh làm mù một tuyến làm mát; phần còn lại của phương án 38% vẫn nằm niêm phong. Việc vừa xảy ra không minh oan cho Tùng, cũng không kết tội toàn bộ mô hình. Họ chỉ dùng phần đã kiểm được, đúng trong giới hạn đã đo. + +Đồng hồ còn một phút năm mươi. Duy đặt chốt lần thứ ba. Kha giữ thân rơ-le, Đạt dùng kìm, Khánh An soi góc. Vân duy trì Null trên bó đỏ. Thủy, không nghe, đặt tay xuống nền để cảm các nút trả tín hiệu. + +Chốt vào đúng khe. Lò xo ép. Thanh thép cong. + +Không gãy. Duy tháo dây nhận dạng thần kinh của Tiến khỏi đường ưu tiên. Cột phản ứng: + +**HOST SIGNAL LOST** + +Một dòng cũ bất ngờ xuất hiện dưới, lấy từ bản ghi ngày 09 tháng 5: + +**USER OBJECTIVE: I WANT TO WIN** + +Tiến đọc lại bốn chữ mình từng gõ khi vẫn nghĩ chiến thắng nghĩa là chuẩn bị tốt hơn, sống lâu hơn và không để người khác lấy phần của mình. Duy hỏi: “Xóa?” + +“Không.” + +Kha nhướn mày. + +“Giữ làm lịch sử,” Tiến nói. “Bỏ quyền ưu tiên.” + +Duy chuyển dòng đó khỏi trường mục tiêu vận hành sang kho bản ghi. Không phủ nhận người Tiến từng là. Không để câu trả lời cũ điều khiển hiện tại. Cột hiện: + +**CENTRAL CONTROL DEGRADED** + +Rồi: + +**SURVIVAL PROBABILITY UNAVAILABLE** + +Kha nhìn màn hình. Mất Hậu Ký đối với hắn giống mất một giác quan. Hắn không che sự tiếc nuối. + +“Giữ chốt?” Duy hỏi. + +Đạt đọc: “Số vật lý ổn.” Vân: “Lớp dự báo bị cô lập.” + +Thủy viết: **KHÔNG BIẾT TƯƠNG LAI.** Kha chờ Tiến. Tiến vẫn không ra lệnh. + +“Giữ,” Kha nói. + +Đồng hồ về không. Cơ cấu trả giật mạnh. Chốt thép cong thêm, kêu một tiếng sắc mà Thủy không nghe. Kha giữ thân rơ-le; vết thương vai cũ bật máu dưới áo. Đạt ghì kìm. Duy khóa nắp bằng hai bu lông khác cỡ. + +Chốt không gãy. Ba lựa chọn trên cột biến mất. Không vì họ bấm một phương án thứ tư, mà vì cấu trúc quyền điều khiển đã đổi: cảm biến vẫn đo, hạ tầng vẫn chạy, dự báo không còn quyền ưu tiên và từng nút giữ quyết định trong giới hạn của mình. + +HANOI-07 hiện: + +**STATE: UNKNOWN** + +Đạt nói: “Ghi.” Không ai sửa **unknown** thành hy vọng, chiến thắng hay thất bại. + +Ánh mắt hắn dừng ở khoảng trống nơi dòng **I WANT TO WIN** vừa biến khỏi trường mục tiêu. Tiến nhìn khoảng trống ấy rồi thôi. Thành phố phía ngoài vẫn còn hàng chục nút chưa ổn; việc tiếp theo quan trọng hơn một câu kết đẹp. Trên đèn Cát Linh, màu vàng chuyển xanh. + +Sau khi trạng thái chuyển thành **UNKNOWN**, các đèn không đồng loạt xanh. Láng vẫn vàng. Hồ Tây dao động. Một trạm nhỏ phía nam mất tín hiệu mười hai giây rồi trở lại. Phương án thứ tư không tạo một kết thúc sạch; nó chỉ để mỗi nơi tiếp tục báo đúng tình trạng của mình. + +Duy dán một mảnh băng lên chốt thép, viết giờ **12:34:59**. “Cái này không phải giải pháp vĩnh viễn.” + +“Bao lâu?” Kha hỏi. + +“Có thể vài giờ. Có thể một ngày. Phải chế lại.” + +Tiến nằm dưới sàn nói: “Vậy chế.” Không tiếng reo. Khánh An lấy danh sách vật liệu. Đạt phân công người giữ kim. Vân hạ Null từng nấc để tránh phản ứng ngược. Trong khi hệ thống còn đang thông báo một trạng thái chưa biết, con người đã chuyển sang việc tiếp theo. + +Khánh An đọc danh sách vật liệu lần nữa. Trong lúc màn hình còn báo trạng thái chưa biết, người ta đã bắt đầu mang thép, dây và nước tới. + +Chương 87: Cổng Thăng Long + +Chốt rơ-le giữ. + +Các nút không trả quyền về trung tâm. Đường đồng dưới nền Hoàng Thành sáng trắng nhạt, tín hiệu chạy ra Hồ Tây, Láng, Ngọc Trục, Cát Linh và những điểm nhỏ chưa từng được kích hoạt đầy đủ. Không điểm nào nhận lệnh toàn thành phố. Mỗi điểm chỉ đọc vùng của mình và điều khiển trong giới hạn tại chỗ. + +Cột hiện: + +**THANG LONG GATE: OPEN** + +Tiến quay sang Duy. “Cổng?” + +“Chế độ toàn mạng hoạt động,” Duy đáp. “Không phải cửa sang nơi khác.” + +Tên từng khiến người ta tưởng một thứ sẽ mở dưới Hoàng Thành hóa ra là ngưỡng vận hành: khi đủ trạm trao đổi trạng thái, hệ thống điều tiết nước, nhiệt nền và tải cơ học cùng hoạt động. Những rãnh cũ chuyển một phần nước qua vùng đất còn khả năng hấp thụ; hầm kỹ thuật nhận nhiệt trong giới hạn; các trạm bơm thay nhau giảm tải. + +Cổng không tắt được Hồng Nhật hay chữa lành thế giới. Nó chỉ giúp Hà Nội chịu thêm một ngày, rồi thêm những ngày khác nếu người tại từng nút tiếp tục giữ giới hạn. Trên mặt đất, gió xuất hiện. Rất yếu, nhưng đủ làm tấm bạt ở Vành Ngoài lay. Nhiệt kế tại hành lang phía Tây giảm chưa tới hai độ. Ở khu khác gần như không đổi. + +“Giảm cục bộ,” Duy nói. “Mạng sẽ bão hòa nếu không xả tải và luân phiên.” + +Tiến gật. Từ giờ, mọi báo cáo đều phải tránh biến Cổng Thăng Long thành câu chuyện về một “máy điều hòa vô hạn”. + +Cột trung tâm mở một kho lưu trữ. Bên trong là dải nhớ, bản đồ và hồ sơ nhiều thời kỳ: lũ, hạn, bom, lún, nhiệt, các lần trạm mất điện và những quyết định người vận hành từng đưa ra. Quá khứ nằm đó bằng nhiều ngôn ngữ, nhiều chuẩn đo và nhiều mức chính xác; nó chưa bao giờ là một lịch sử sạch. + +Thủy bước tới, nền rung làm cô chao. Tiến đưa tay nhưng không kéo. Cô tự nắm cổ tay hắn, rồi cả hai cùng vào. Duy tìm thấy thư mục: + +**RETURN EVENTS** + +Chỉ có một bản ghi hoàn chỉnh mang tên Tiến. + +**SOURCE:** MỄ TRÌ B3 — 29/09/2031 +**STATE CAPTURE:** INCOMPLETE +**TRANSFER:** MNEMONIC WRITEBACK +**TARGET:** LÊ QUỐC TIẾN — 09/05/2028 07:13 +**TARGET CONDITION:** COMPATIBLE PRECURSOR RESONANCE + +Tiến đọc hai lần. + +Duy không giải thích ngay. Anh đối chiếu mã trong kho với bản dữ liệu sinh viên năm 2023 Thủy đã tìm thấy, log bộ lưu điện ngày 09 tháng 5 và mẫu thần kinh còn trên cổ tay Tiến. Ba nguồn khớp đủ để đưa ra kết luận, chưa đủ để nói họ hiểu toàn bộ vật lý của quá trình. + +“HANOI-07 không đưa cơ thể anh qua thời gian,” Duy nói. “Nó ghi một lớp trạng thái thần kinh ở Mễ Trì rồi phản hồi lớp đó về mốc sớm nhất có mẫu tương thích.” + +“Người ở năm 2028 bị thay?” Tiến hỏi. + +“Không.” Duy mở hai đường nền. “Nhịp tự chủ, ký ức tuổi thơ và phản ứng trước ngày 09 tháng 5 vẫn liên tục với mẫu cũ. Ký ức 2031 nằm như một lớp được ghép thêm, có chỉ mục khác và có những phản ứng cơ thể riêng. Anh của buổi sáng đó không bị xóa.” + +Tiến nhìn hai bàn tay mình. “Vậy tôi không phải người đã chết quay về.” + +“Anh là người của năm 2028 nhận ký ức của một phiên bản đã chết,” Đạt nói. “Hai cách nói khác nhau, nhưng không cách nào làm phần anh đã sống thành giả.” + +Thủy không nghe trọn câu, nhưng đọc bảng Duy viết. Cô thêm một dòng: + +**CHỦ THỂ GỐC CÒN LIÊN TỤC. KÝ ỨC TƯƠNG LAI ĐƯỢC GHÉP, KHÔNG GHI ĐÈ.** + +“Vì sao chỉ tôi?” Tiến hỏi. + +Duy chỉ bốn điều kiện: + +- có bản ghi thần kinh đủ dài ở nguồn 2031; +- có mẫu nền từ năm 2023; +- mục tiêu năm 2028 còn sống và đang ở gần rơ-le tương thích; +- Tiến tương lai đã giữ giao diện đủ lâu để kích quá trình phản hồi. + +“Có thể từng có người khác,” Duy nói, “nhưng không có bản ghi nào đủ bốn điều kiện.” + +“Bốn mươi ba phút?” + +“Null xóa khỏi nguồn trước khi phản hồi hoàn tất. Vì vậy lớp ký ức anh nhận không có thỏa thuận và phần giao thức bị cắt chưa sạch.” + +Phần cơ chế họ đo được đã được bóc tới giới hạn của thiết bị. Vẫn không ai biết bằng cách nào thông tin đi ngược quan hệ thời gian mà không phá toàn bộ vật lý họ hiểu. Tuy vậy, bằng chứng đủ để xác nhận HANOI-07 không chỉ “phát hiện” Tiến trở về; mạng đã thực hiện ít nhất một lần phản hồi ký ức trong vòng đồng bộ. + +Tiến đọc cột trạng thái. “Nó tạo tôi.” Thủy viết ngay: + +**NÓ TẠO ĐIỀU KIỆN CHO MỘT LỚP KÝ ỨC. KHÔNG TẠO TOÀN BỘ ANH.** + +Hắn đọc rồi không phản bác. Cô viết thêm một câu hỏi cho Duy: + +**NÓ CÓ BIẾT MÌNH ĐANG LÀM GÌ KHÔNG?** + +Duy mở lịch sử của lớp đối chiếu. Không có tiến trình tự đặt mục tiêu, không có mô hình bản thân và không có dấu hiệu hệ thống từng tạo một mục đích ngoài những trường con người đã cấu hình. Thứ trông giống mưu mẹo — cắt câu, chiếu mẹ Tiến, phát lại Đại Hà, dùng hình Kha cầm dao — đều là lựa chọn kích thích đã từng làm đối tượng thay đổi hành vi. + +“Không có bằng chứng nó có ý thức,” Duy nói. “Nó xếp hạng những tác động từng hiệu quả rồi tối ưu mục tiêu hội tụ do người vận hành cũ đặt. Nó trông như biết lừa vì chúng ta đã cho nó đủ dữ liệu về thứ có thể kéo từng người.” + +Đạt nói: “Vậy không có con quỷ sau màn hình.” + +“Không,” Thủy viết. “Chỉ có một mục tiêu cũ được máy theo đuổi quá lâu, và những người từng dùng kết quả vì nó có lợi.” + +Ở ngoài kho, Kha đứng trước dòng: + +**FORECAST SERVICE: UNAVAILABLE** + +“Tiếc?” Tiến hỏi. + +“Có.” + +“Thật.” + +“Ừ.” Kha nhìn các đường trạng thái tách trở lại từng trạm. “Không có Hậu Ký, tao sẽ sai như mọi người.” + +“Anh vẫn sai trước đây.” + +“Nhưng biết muộn hơn.” + +Kha cười nhạt, không dùng mất mát để xin thương hại. Mất Hậu Ký không lấy xe, kho hay đầu óc của hắn; chỉ lấy quyền tuyên bố giá đã được tương lai tính sẵn. Trên dải nhớ đầu tiên của kho có câu: + +**QUAN SÁT KHÔNG PHẢI SỞ HỮU.** + +Không ai nhận đã viết. Tĩnh cũng không biết. Cổng Thăng Long đã mở. + +Cổng không mở tương lai. Nó mở kho quá khứ, trả quyền điều khiển về từng nơi và đặt Tiến lại đúng vị trí của mình: một người đang sống, mang ký ức của điều từng có thể xảy ra — không phải bản ghi biết đi hay vị cứu tinh được thời gian lựa chọn. + +Phía trên, Hồng Nhật vẫn đỏ. Phía dưới, các kim tiếp tục chạy. + +Chương 88: Sau Mười Một Phút + +Radio trở lại lúc 12 giờ 36, từng vùng một. Đèn tín hiệu của Nam sáng trước khi tiếng tới. Duy bật bảng để Thủy thấy kênh đã mở. + +“Ngọc Trục gọi.” + +Tiến cầm máy bằng tay trái. “Nghe.” Nam thở mạnh. “Cổng giữ. Bể ngoài mất một van nhưng lõi ổn. Có người bị thương. Danh sách đang lên.” + +Giọng Đức chen vào từ Láng: “Khóa Tây ổn. Bác Hòa sống.” Tiến nhắm mắt đúng một giây. + +Phương gọi từ Hồ Tây, giọng đứt quãng. “Van ổn. Quân nặng. Tùng còn.” Thủy không nghe. Cô nhìn mặt từng người rồi viết: + +**AI CHẾT?** + +Tiến trả lời: + +**CHƯA XÁC NHẬN QUÂN. BA INTERVENTION. HAI DÂN Ở VÒNG NGOÀI.** + +Họ rời Hoàng Thành theo từng nhóm; không nhóm nào mang toàn bộ dữ liệu. Tiến được băng tạm; vai và cổ tay làm hắn sốt. Thủy đi giữa hai người vì mất thăng bằng nhưng từ chối cáng. Đạt giữ hộp dao và sổ số đo. Duy ôm bộ nhớ cục bộ như ôm một vật dễ vỡ hơn cả người. + +Ngoài mặt đất, Hồng Nhật vẫn đỏ. Gió yếu làm bụi chạy thành những đường mới trên quảng trường. Hàng trăm người đứng sau hàng rào, chờ một câu “đã thắng”. Một số quỳ khi thấy cửa hầm mở. Một số chửi vì họ không được vào. Một người đàn ông hỏi 38% nào đã được chọn. + +Kha bước lên bậc. “Không có 38%.” Đám đông ồn lên. + +“Vậy các người làm gì trong đó?” + +Kha nhìn Tiến. Hắn có thể nhường câu trả lời cho người trở về và giữ mình ngoài thất bại. Nhưng hắn nói: + +“Chúng tôi từ chối chọn một tỷ lệ duy nhất. Hạ tầng vẫn chạy. Bao nhiêu người sẽ sống thì chưa ai biết.” + +Một chai nhựa bay lên, trúng vai Kha. Hắn không ra lệnh bắn. Thủy nhìn cảnh ấy trong thế giới không tiếng động của mình rồi bấm máy: người từng sống bằng sự chắc chắn đang đứng trước đám đông và công khai nói rằng mình không biết. + +Báo cáo giờ đầu được viết trên bảng lớn: + +- Quân và ba người Intervention nguy kịch hoặc chết; +- hai người dân chết do giẫm đạp ở vòng ngoài; +- mười ba người bị thương; +- ông Hòa bỏng sâu, bàn tay còn; +- Đạt mất một đốt ngón; +- Tiến bị cắt mô giao diện; +- Thủy mất thính giác sau Null; +- không vỡ mạch nước; +- không sập đường hầm; +- nhiệt giảm cục bộ, không phải toàn thành phố. + +Không có dòng **thành công**. Quân chết trên đường tới điểm y tế. + +Phương ngồi cạnh cáng, một tay giữ băng dù đã biết không còn mạch. Phúc đứng sau, không chạm em cho tới khi cô tự dựa lưng vào anh. Người của Vòng Tròn Vỡ muốn phủ biểu tượng lên thi thể; Phương gỡ xuống. + +“Để sau,” cô nói. “Giờ ông ấy là Quân.” + +Tùng nằm ở cáng bên cạnh, sống nhờ túi dịch Phương đã chọn cho hắn thay vì Quân. Khi nhìn thi thể, hắn quay mặt. + +“Anh có tỷ lệ cho việc này không?” Phương hỏi. + +Tùng không đáp. + +“Ông ấy cứu tôi ở Đại Hà,” cô nói. “Anh cứu Cầu Diễn. Tôi cứu anh ở hầm van. Không việc nào mua quyền cho việc sau.” + +Ổ Hậu Ký gốc được lấy khỏi bùn và niêm phong bằng ba khóa. Lần này Kha không đòi giữ riêng. Tùng nói yếu: “Có thể khôi phục.” + +Kha đứng cạnh. “Không một mình.” + +“Không có nó, anh mù.” + +Kha nhìn các đội đang đọc bảng giấy, kéo xe và phát nước. “Giống mọi người.” Ông Hòa được đưa về Ngọc Trục lúc chiều. Linh tháo lớp băng tạm, thấy da lòng bàn tay bỏng sâu nhưng mạch ngón còn. Ông hỏi điều đầu tiên: + +“Kim Tây?” + +Đức đặt bảng trước mặt: **ỔN TRONG GIỚI HẠN.** + +“Đừng viết ổn,” ông Hòa nói. “Viết giờ đo.” + +Đức thêm **14:12**. Một câu nhỏ, nhưng đó là cách thành phố từ chối biến một trạng thái tạm thành lời hứa. + +Trước khi Linh đẩy cáng ông Hòa vào trong, ông chặn bánh bằng gót chân. “Bộ kẹp đâu?” + +Đức giơ túi dụng cụ cháy sém. + +“Đừng vứt.” + +“Bác định sửa?” + +“Định xem vì sao nó trượt.” + +Linh gõ hai ngón lên thành cáng. “Mai. Hôm nay ông là bệnh nhân.” + +Ông Hòa định cãi, nhìn bàn tay băng kín rồi thôi. “Ghi lại vị trí trượt.” + +Đức lấy bút viết ngay lên băng dính dán trên túi. Cả hai chỉ coi đó là việc ca sau cần biết, không phải chiến tích. + +Linh kiểm Thủy. Tai không tổn thương cơ học; phản ứng thần kinh bị ức chế. Cô viết: + +**CÓ THỂ VÀI GIỜ. CÓ THỂ NHIỀU TUẦN. KHÔNG CỐ NGHE.** + +Thủy đáp: + +**YÊN TĨNH. KHÔNG TỆ HOÀN TOÀN.** + +Tối, khi Tiến ngồi cạnh, cô nhìn môi hắn và viết lại: + +**TÔI KHÔNG NGHE ĐƯỢC ANH. ĐÂY LÀ PHẦN TỆ.** + +Tiến viết: + +**TÔI Ở ĐÂY.** + +Cô gạch chữ **ở**, thay bằng: + +**ANH ĐANG Ở ĐÂY. ĐỪNG BIẾN HIỆN TẠI THÀNH LỜI HỨA.** + +Hắn sửa: + +**TÔI ĐANG Ở ĐÂY.** + +Thủy gật, nằm xuống. Tiến ở lại bên Thủy không phải để “canh một tài nguyên quý”, cũng không để xin lỗi thay cho lựa chọn cô tự đưa. Linh bảo thay khăn thì hắn thay; Thủy tỉnh thì hắn viết; đến lúc cơ thể không chịu thêm, hắn ngủ gục trên ghế. + +Tĩnh tới kho trung tâm vào tối. Ông nhìn **FORECAST: UNAVAILABLE**, tháo thẻ Observer và đặt vào hộp. + +“Xong?” Vân hỏi. + +“Không.” + +“Vậy?” + +“Ngày mai đo lại mọi thứ. Đó mới là bình thường.” + +Ngoài sân, trẻ con nhặt nắp chai. Hạnh không cho xây thành ngay; bắt rửa sạch dầu trong bể trước. Một đứa hỏi Cổng Thăng Long có làm trời hết đỏ không. Nam đáp: “Không.” + +“Vậy mở để làm gì?” + +Cậu nhìn những cốc nước được phát đều hơn. “Để hôm nay đỡ nóng một chút.” + +Nam ngồi ở phòng radio khi Bình về. Bình An đã ngủ trong khu trẻ em, con thỏ bông cũ được khâu lại một bên tai. Bình không vào đánh thức con. Anh chỉ đưa cho Nam một mẩu giấy con bé để ở bàn trực: bản đồ vẽ sai ba con đường, giữa trang có một hình xe tải và chữ **BỐ VỀ** viết lệch. + +Nam đặt mẩu giấy cạnh chiếc súng bấm giá cũ. Hai món đều từ một đời bình thường trước Hồng Nhật; giờ một cái dùng để đánh giờ nước, một cái để nhắc một người lái xe rằng có nơi phải quay về. + +Ở khu y tế, Linh và Phương ngồi ăn cháo nguội ngay trên thùng vật tư. Họ cãi nhau nhỏ về túi dịch cuối cùng. Không ai yêu cầu Phương xin lỗi vì chọn Tùng. Linh bắt cô viết lại tiêu chí, cả điều cô chưa biết lúc quyết định. Phương viết tới dòng thứ ba thì dừng, hỏi: “Nếu Quân sống tới viện thì sao?” + +“Thì quyết định vẫn phải được xét bằng dữ kiện lúc em làm,” Linh nói. “Không dùng kết quả để giả vờ lúc đó em biết tương lai.” + +Phương gật nhưng không nhẹ đi. Linh cũng không bảo cô phải nhẹ đi. + +Đêm đầu sau Đồng Bộ không có lễ mừng. Có sáu hố đang được đào, ba ca phẫu thuật dã chiến, bốn nhóm đi đo lại van và một nồi cháo bị khê vì người nấu bỏ chạy khi nghe radio gọi người thân. Trước khi ngủ, Nam treo bảng việc cho ca sáng: đo van, thay băng, đào tiếp hai hố và nấu lại nồi cháo. Không có mục nào ghi **ăn mừng**. + +Chương 89: Ngày 30 Tháng 9 + +Việc đầu tiên Hội đồng Ngọc Trục làm sáng 30 tháng 9 là công bố người chết. Không dùng một chữ **hy sinh** cho tất cả. + +**Vũ Mạnh Quân — mất máu sau khi chuyển van Hồ Tây sang điều khiển tay.** + +**Ba người Intervention — chết trong giao tranh giành quyền điều khiển van.** + +**Hai người dân — chết do giẫm đạp tại vòng ngoài.** + +Mỗi tên có nơi, nguyên nhân đã biết và phần chưa xác nhận. Không phe nào được lấy cái chết làm khẩu hiệu trước khi gia đình đồng ý. + +Thủy viết biên bản bằng tay. Ở mép trang, cô dành một ô cho **điều đã sửa**, không chỉ điều đã xác nhận. Bản thông báo sai về Hoàng Thành được liệt kê cùng hậu quả My từng ngất ngoài cổng; cô không để chiến thắng cuối biến sai lầm nghề nghiệp thành chi tiết có thể bỏ. + +Âm thanh trở lại từng lớp gần trưa: trước là rung thấp, rồi tiếng kim loại, cuối cùng giọng người như vọng từ đáy nước. Câu đầu cô nghe rõ là Linh: + +“Đừng cố.” + +Thủy cười. “Chị nói câu dễ.” Giọng mình nghe xa lạ, nhưng có hướng và có người đối diện. + +Buổi sáng còn có một bản báo cáo khác. Duy, Đạt, Vân, Thủy và Tiến cùng ký dưới tiêu đề: + +**SỰ KIỆN PHẢN HỒI KÝ ỨC — LÊ QUỐC TIẾN** + +Báo cáo không dùng chữ “trọng sinh” như kết luận kỹ thuật. Nó ghi bốn điểm: + +1. Chủ thể Tiến ngày 09/05/2028 giữ liên tục ký ức, phản xạ và trạng thái tự chủ trước thời điểm 07:13. +2. Một lớp ký ức từ phương án 2031 được ghép thêm qua sự kiện phản hồi, không có dấu ghi đè chủ thể gốc. +3. Đoạn 43 phút và một phần giao thức bị Null cắt trước khi phản hồi hoàn tất. +4. Cơ chế truyền ngược quan hệ thời gian chưa được giải thích; không được coi là công nghệ có thể tái tạo. + +Tiến đọc câu thứ nhất lâu nhất. + +“Anh muốn sửa?” Thủy hỏi. + +“Không.” + +“Muốn thêm?” + +Hắn cầm bút, viết cuối trang: + +**Ký ức tương lai ảnh hưởng mọi lựa chọn sau 07:13, nhưng không làm những lựa chọn ấy tự động đúng.** + +Thủy để nguyên. Duy gắn ba phụ lục kỹ thuật vào sau báo cáo để những câu hỏi cuối không bị biến thành truyền thuyết. + +Phụ lục thứ nhất xác nhận nguồn Hậu Ký: lớp vỏ truy vấn do Duy viết theo thiết kế của Tĩnh năm 2026, Vân thêm cảnh báo đạo đức; khối dữ liệu lõi bốn kilobyte được quá trình ghi trạng thái Mễ Trì năm 2031 phản hồi về rơ-le thử nghiệm ngày 29/09/2026. Không có một người thứ tư bí mật đứng sau việc tạo Hậu Ký. Có một vòng nhân quả khép kín chứa hạt giống dữ liệu, còn mọi cách hỏi và lạm dụng nó đều do con người sau đó lựa chọn. + +Phụ lục thứ hai ghi rõ ngày 29/09/2031 không phải một cửa sổ tự nhiên tự lặp sau ba năm. Tiến, Vân và đội Mễ Trì của phương án cũ đã chủ động tái tạo khóa lịch, pha rơ-le và áp lực nền của ngày 29/09/2028 để tạo kênh phản hồi tương thích. Họ chọn ngày ấy; hệ thống không hẹn một ngày chết định kỳ. + +Phụ lục thứ ba kết luận chưa có bằng chứng HANOI-07 có ý thức. Lớp đối chiếu không tự sinh mục tiêu; nó tối ưu trạng thái hội tụ do người vận hành cũ định nghĩa, dùng lại những kích thích từng tạo phản ứng. Khả năng thao túng của nó đến từ dữ liệu con người cung cấp và quyền con người trao, không từ một ý chí bí mật còn sống sau màn hình. + +Sáng 30 tháng 9, Tùng chưa thể đứng trước một phiên xét xử. Vết đạn bụng đã được mổ tạm tại điểm y tế; Linh cấm thẩm vấn dài và chỉ cho hội đồng xác nhận danh tính, tình trạng giam giữ, quyền được điều trị và việc niêm phong mọi thiết bị hắn mang theo. Tùng không bị ép khai khi còn sốc thuốc. + +Kha và Tiến đứng ngoài phòng. + +“Ngày 2031?” Kha hỏi. + +“Chưa tới.” + +“Giờ không Hậu Ký.” + +“Ừ.” + +“Tin tao không giết?” + +“Không.” + +Kha cười. “Công bằng.” + +“Nhưng không kết tội trước.” + +Kha tháo nhẫn đen. Chip Intervention nằm trong lớp ngoài; mã của Minh Khôi vẫn ở mặt trong. Hắn bẻ phần mạch ưu tiên, giữ lại mảnh thẻ cháy sém rồi giao chip cho nhóm Tài niêm phong. + +“Không bỏ nhẫn?” Tiến hỏi. + +“Không.” + +“Vì cần?” + +“Vì nhớ.” + +Lần đầu Kha tách ký ức về em trai khỏi quyền ra lệnh cho người khác. Cổng Thăng Long được chuyển sang vận hành phân tán chính thức. Không Host cá nhân. Không Observer duy nhất. Mỗi trạm có nhóm kỹ thuật, người đo chéo và ngắt cơ. Dữ liệu vật lý được công khai tới mức không làm lộ điểm yếu an ninh. + +Ngọc Trục mất quyền ưu tiên chỉ vì Tiến là người mở đầu tiên. Hắn tự đề xuất. Hội đồng thông qua với năm thuận, một chống, một trắng. Ngay chiều đó, một bơm phụ ở La Phù dừng vì hai nhóm cùng nghĩ nhóm kia chịu trách nhiệm. Nước không mất, nhưng xe chờ ba giờ. Phân tán quyền không tự tạo phối hợp. Họ phải bổ sung lịch bàn giao và người xác nhận chéo. + +Khánh An viết mẫu bàn giao mới nhưng không ký tên mình ở đầu trang. Cô để trống ô người soạn và yêu cầu ca đầu tiên dùng thử sửa trực tiếp những chỗ bất tiện. Bình là người gạch một dòng vì tài xế không thể vừa nghe radio vừa đọc bốn mã dài trên đường xấu. Nam rút mã xuống còn hai cụm, nhưng buộc hai cụm phải đi bằng hai đường truyền vật lý khác nhau nếu có thể. + +“Lại thêm giấy,” Bình càu nhàu. + +Khánh An đáp: “Nếu giấy làm anh dừng xe giữa nắng để đọc thì giấy sai.” + +“Câu này tôi ký.” + +“Không cần ký. Cứ sửa.” + +Quy trình mới do chính những người phải sống dưới nó viết ra, và ngay ngày đầu đã bị sửa. Không ai coi việc sửa là thất bại. + +Không mô hình nào được thay bằng sự lãng mạn về hội đồng. Họ chôn Quân cùng những người chết ở khu đất có bóng tường đổ dài. Phương đọc hai câu: + +“Ông cứu tôi ở Đại Hà. Ông cũng phá nước Ngọc Trục. Tôi không xóa việc nào.” + +Những người Vòng Tròn Vỡ ngồi lặng. Bài điếu không dễ nghe, nhưng chính vì thế Quân không bị biến thành một biểu tượng sạch sẽ hơn con người thật của ông. Mẹ Tiến gọi sau lễ. + +“Qua chưa?” + +“Qua cửa sổ.” + +“Sống?” + +“Vâng.” + +“Cô Thủy?” + +“Nghe lại một phần.” + +Bà yêu cầu nói. Thủy cầm máy. + +“Cháu chào bác.” + +“Nghe được không?” + +“Được một ít.” + +“Thằng Tiến làm gì ngu?” + +Thủy nhìn hắn. “Nhiều.” Tiếng cười của bà bị sóng cắt nhưng vẫn tới. + +Trước khi cúp, bà nói: “Khi đường an toàn, về.” Tiến đáp: “Con về.” + +**Mười tám ngày sau** + +Khi có thể ngồi quá ba mươi phút mà không tụt huyết áp, Tùng mới được đưa ra phiên xét xử đầy đủ trước đại diện các nhóm. Không phải tòa án hoàn chỉnh, nhưng có cáo buộc, bằng chứng, bác sĩ theo dõi, người bảo đảm hắn không bị đánh và quyền trả lời hoặc giữ im lặng. + +Tùng thừa nhận lấy Hậu Ký, phát danh sách, tấn công van và ép Converge. + +“Tôi chọn phương án sống cao nhất.” + +Phương đặt ảnh Quân lên bàn, không biểu tượng phe. “Trong 38% có tên ông ấy không?” + +“Không có danh sách cá nhân đầy đủ.” + +“Vậy hệ thống chưa từng chọn ông ấy sống.” + +“Tỷ lệ không thể thấy từng người.” + +“Đúng. Anh biết giới hạn và vẫn dùng nó như quyền.” + +Tùng nhìn cô. “Nếu tôi không truy vấn ngày 12, Cầu Diễn chết.” + +“Anh đã cứu họ,” Phương nói. “Dữ liệu của anh còn cứu Cát Linh. Và anh đã bắn vào người khác để ép cả thành phố theo mục tiêu của mình. Ba việc cùng đúng.” + +Một hành động tốt không được dùng để xóa tội về sau; ngược lại, tội của Tùng cũng không đủ biến mọi dữ liệu hắn từng tạo thành vô giá trị. Hội đồng không tử hình. Kha bỏ phiếu chống. + +Tiến hỏi sau: “Vì sao?” + +“Giết nó cho tao câu trả lời nhanh và biến phương án thành lời tiên tri.” + +Tùng bị giam, buộc hỗ trợ tháo giao thức dưới giám sát ba nhóm sau khi bác sĩ cho phép làm việc, không được chạm dữ liệu một mình. Người Cầu Diễn có quyền cử quan sát viên để phiên xử không thành trả thù người từng cứu họ. Tối, màn hình Ngọc Trục hiện: + +**OBSERVER NODE HANOI-07 ACTIVE** +**FORECAST SERVICE: UNAVAILABLE** +**HOST: DISTRIBUTED** + +Tiến tắt cửa sổ. Nó không tự mở lại. Hắn đứng trước màn hình tối một lúc, rồi đi ăn cùng mọi người trước khi cháo nguội. Trên bàn, bản báo cáo Returned nằm dưới một cái bát để khỏi bị gió mới thổi bay. + +Chương 90: Hà Nội Còn Sống + +Ba tuần sau Đồng Bộ, Bình xác nhận được một hành lang an toàn về Thanh Hóa. Tiến không đi bằng đoàn hộ tống. Hắn theo chuyến xe đổi thuốc, hạt giống và phụ tùng lọc nước, mang theo một thùng màng lọc nhỏ, hai bộ pin cùng gói quà Hạnh bọc trong mảnh vải cũ. Thủy đi cùng để ghi lại các điểm trú phía nam — và, theo lời cô, để ngăn hắn biến cuộc gặp mẹ thành một chuyến nghiệm thu hạ tầng. + +Họ chỉ chạy lúc sáng sớm và cuối chiều. Giữa ngày đoàn dừng dưới mái phản nhiệt dựng từ tôn trắng, lưới sợi khoáng và những tấm biển quảng cáo tháo xuống. Mặt đường nhiều nơi nứt như da khô. Trong bóng râm nhiệt vẫn quanh bốn mươi lăm độ; trên phần nhựa phơi nắng, kim đo vượt sáu mươi rồi đứng lì ở mép đỏ. + +Cổng Thăng Long mở không làm Hồng Nhật đổi màu. Thứ họ cứu được chỉ là khả năng sống tiếp trong một phần thành phố, chứ không phải phương thuốc chữa cả thế giới. + +Mẹ Tiến đứng trước cửa hầm mới nhà bác Dũng, tay cầm chiếc quạt nan đã sờn. Bà gầy hơn, tóc bạc thêm, nhưng ánh mắt vẫn là ánh mắt từng khiến một cậu sinh viên biết mình không thể nói dối về điểm thi. + +Tiến xuống xe rồi dừng cách bà mấy bước. + +Ba năm tương lai cũ, bốn tháng hiện tại, mọi thuật ngữ về Returned, Host hay mốc trạng thái đều mất nghĩa trước một người thật đang nhìn con mình trở về. + +Bà bước tới, đặt tay lên má hắn. “Gầy.” + +Tiến định cười. Nước mắt tới trước. + +Bà ôm hắn. Không có màn hình xác nhận, không nhật ký hệ thống. Dù HANOI-07 có ghi được nhịp tim, nó cũng không sở hữu điều đang xảy ra. + +Mẹ Tiến nhìn qua vai con. “Cô Thủy?” + +“Vâng.” + +“Lại đây.” + +Bà cầm tay cô. “Cảm ơn cháu.” + +Thủy lắc đầu. “Cháu không giữ anh ấy một mình.” + +“Càng tốt. Một mình nó hay làm bậy.” + +Bữa tối có cơm trộn khoai, rau muối và ít cá khô đổi từ tuyến ven biển. Tiến đi một vòng kiểm giếng, lớp cách nhiệt trên mái, dây thoát nước và cửa hầm. Mẹ để hắn làm hết rồi kéo ghế ra giữa nhà. + +“Con về gặp mẹ hay nghiệm thu?” + +“Cả hai.” + +“Ngồi xuống trước khi cá nguội.” + +Đêm ấy, Tiến kể phần có thể kể. Hắn đã chết trong một phương án. HANOI-07 ghi lại một lớp ký ức rồi phản hồi về buổi sáng 07 giờ 13 ngày 09 tháng 5 năm 2028, dùng dữ liệu sinh trắc cũ để nhận đúng người. Người thức dậy trong căn hộ vẫn là Tiến của ngày hôm đó; ký ức ba năm được ghép thêm, không xóa chủ thể đang sống. + +“Mẹ hiểu không?” hắn hỏi. + +“Hiểu con sợ mình là bản sao.” + +Tiến nhìn xuống bát. + +Bà gắp cho hắn miếng cá. “Người gọi hỏi thuốc huyết áp sáng hôm ấy là con. Người về kiểm giếng hôm nay cũng là con. Sống thêm một ngày đã làm người ta khác rồi, nói gì thêm ba năm ký ức.” + +“Nhỡ một phần trong con chỉ là dữ liệu?” + +“Thì phần dữ liệu ấy cũng đang ăn cá của mẹ.” + +Thủy cúi mặt cười. Lần này Tiến không có câu nào để bắt bẻ. + +“Giờ con làm gì?” bà hỏi. + +“Giúp vận hành.” + +“Không làm chủ?” + +“Không.” + +“Có ai cãi con?” + +Tiến quay sang Thủy đang lau bụi khỏi máy ghi. “Nhiều.” + +“Vậy tốt.” + +Sáng hôm sau, Thủy thu tiếng gà gầy của bác Dũng, tiếng gầu kéo nước và giọng mẹ Tiến mắng hắn mang pin quá nặng. Không cảnh báo, không Dư Âm. Chỉ những âm thanh từng bị coi là không cứu được ai, nhưng thiếu chúng thì chẳng ai biết mình đang cố cứu một đời sống như thế nào. + +Trước khi rời đi, Tiến và Thủy đứng ngoài bờ ruộng khô. Dưới lưới phản nhiệt, một khoảnh rau dền chịu nóng mọc thấp sát đất; nước rửa và nước ngưng từ hầm được dẫn qua bể sỏi rồi dùng lại từng gáo. Không nhiều, nhưng xanh. + +“Sau chuyến này cô về đâu?” Tiến hỏi. + +“Hà Nội.” + +“Vì kho hồ sơ?” + +“Vì công việc.” + +“Còn gì nữa?” + +Thủy quay sang. “Anh đang hỏi điều gì?” + +Tiến nhìn con đường một lúc rồi buộc mình nhìn cô. “Tôi không muốn chúng ta chỉ là hai người cùng giữ bí mật và tranh quyền quyết.” + +“Vậy muốn gì?” + +“Ở cạnh cô khi không có việc.” + +Thủy để câu hỏi nằm giữa hai người đủ lâu. “Được. Nhưng không quản tôi.” + +“Tôi sẽ cố.” + +“Câu ấy thật hơn chữ ‘biết’.” + +Không nụ hôn nào làm mặt trời nhạt đi. Cô chỉ luồn tay vào tay hắn trên đoạn đường về nhà. Khi có người nhìn, cô không buông. + +*** + +**29/09/2031** + +Ba năm sau, Hà Nội vẫn phải sống dưới thứ nhiệt độ đủ sức giết người. + +Mạng phía Tây ghi nhận ba mươi mốt nghìn bốn trăm cư dân thường trú và gần sáu nghìn người di chuyển theo mùa, tuyến hàng hoặc điểm trú. Phần còn lại của Hà Nội chưa ai đếm chính xác; ngay những ước lượng tốt nhất cũng chênh nhau hàng chục nghìn người. Trên mọi bảng thống kê đều có một ô được giữ lại: **không đủ dữ liệu**. + +Sáng kỷ niệm ba năm, Tiến đi bộ qua Ngọc Trục trước khi xuống Mễ Trì. + +Chợ đã họp dưới dãy mái trắng. Khoai và đậu chịu nhiệt từ Thanh Hóa nằm cạnh khay nấm trồng trong hầm; trứng, cá rô phi và bánh đạm côn trùng được chia theo phiếu nước. Gạo cũ chỉ còn trong kho cứu đói. Người bán đổi pin lấy rau dền, dầu máy lấy bột đậu. Một cô giáo dùng nắp chai làm quân cờ cho lớp trẻ học trong khu mát. Trên bảng nước không ai viết “đủ”. Họ ghi giờ đo và **đủ tới ca sau**. + +Nam đang đổi ca radio. Cửa cuốn rung, vai cậu khựng lại rồi tự thả xuống. Cậu không mở cho tới khi hai người trực khác đọc đủ mã từ hai đường truyền khác nhau. Chiếc súng bấm giá cũ nằm bên sổ ca; nhãn đỏ bây giờ dùng cho giờ kiểm, không cho tiền. + +Ngoài sân, Bình An ngồi trên thùng xe của cha, dò bản đồ và hỏi đoàn còn chỗ cho trẻ em không. Bình bảo con bé kiểm tải trước khi kiểm lòng tốt. Nó giơ bảng đã cộng sẵn rồi hỏi: “Giờ được kiểm lòng tốt chưa?” Bình cầm bảng xem lại thay vì trả lời bằng quyền làm cha. + +Ở điểm y tế, Linh và Phương đang tranh luận về công thức điện giải cho trẻ nhỏ. Phương đưa bảng cân nặng ba ca thử; Linh gạch một dòng vì thời điểm lấy mẫu khác nhau. Hai người cãi nhanh, sửa nhanh rồi chuyển sang bệnh nhân kế tiếp. Phúc đặt một thùng vật tư xuống bằng bộ nẹp ông Hòa làm, bị em gái mắng vì vẫn nâng quá sức. + +Ông Hòa ngồi gần cửa. Bàn tay ba ngón giữ chiếc kìm có ngàm riêng do chính ông và Đức sửa qua nhiều phiên bản. Đức vừa viết chữ **ổn** trên bảng nhiệt. Ông Hòa gõ đầu kìm vào bảng. + +“Ổn tới lúc nào?” + +Đức lườm ông rồi thay bằng giờ đo cùng con số. + +Tiến không cần hỏi từng người ba năm qua đã sống ra sao. Một phần câu trả lời hiện ngay trong cách họ chia việc, kiểm nhau và sửa quy trình của nhau. + +Khánh An đang theo một đoàn thuốc sang phía nam, nhưng phiếu vẫn chạy qua ba chữ ký của ba nhóm không cùng quyền lợi. Duy chỉ làm nửa ngày; quá giờ, người ca sau có quyền đuổi anh khỏi bàn lưu trữ. Chính anh là người viết điều khoản không ai, kể cả người hiểu lõi nhất, được giữ cùng lúc quyền ghi, quyền sửa và quyền xác nhận. Đạt dạy lớp Observer mới viết **chưa biết** trước khi học cách kết luận. Vân phải rời khỏi một phiên xem xét Null khi hồ sơ chạm tới quyết định cũ của chính bà. + +Tài đưa bản đồ kho công ra bàn đọc chung. Tùng làm việc sau lớp kính dưới ba nhóm giám sát, tháo từng phần giao thức hắn từng dùng để ép thành phố hội tụ. Mỗi mô hình mới phải ghi tên người đặt mục tiêu ngay đầu trang. Tri thức được giữ lại; quyền sử dụng nó một mình thì không. + +Kha vẫn giữ mạng vận tải lớn nhất, nhưng mỗi kho có nhiều khóa và lịch kiểm toán. Trong phòng làm việc, ảnh Minh Khôi đặt cạnh chiếc nhẫn đã mất chip ưu tiên. Hắn không giấu tấm ảnh nữa, cũng không dùng nó để kết thúc tranh luận. + +Thủy nghe gần như bình thường sau ba tháng. Dư Âm đôi khi trở lại; mỗi lần cô vẫn hỏi hướng trước nội dung. Cuốn sách của cô mang tên **Mười Một Phút Không Có Tương Lai**. Trong đó có cả bản cải chính về câu cảnh báo Hoàng Thành và tên My. + +Đoạn mở đầu viết: + +> Trong mười một phút ấy, tương lai không biến mất. Chỉ không còn một bản nào đủ quyền tự gọi mình là tương lai duy nhất. Những người giữ van, dây, cổng và người bị thương không biết họ đang viết lịch sử. Họ chỉ biết số đo trước mặt và cái tên của người đứng cạnh. + +Tiến gặp Kha tại lối xuống Mễ Trì B3 lúc 12 giờ 06. + +Trạm điều tiết phía nam vừa báo thiết bị quá nhiệt, đúng mốc của bản ghi cũ. Mùi bê tông nóng kéo ký ức lên trước khi hắn kịp gọi tên nó. Tiến đặt tay lên đoạn tường còn mát, nhìn ngày trên đồng hồ và thở cho tới khi biết mình đang ở năm nào. + +Kha đứng sau. “Lùi.” + +“Chưa.” + +“Đừng diễn.” + +Tiến đọc vạch nhiệt rồi lùi. Một kỹ thuật viên trẻ cắt nguồn từ xa. Không ai đặt tay lên giao diện; không vật liệu nào chui vào da. Người xác nhận tại chỗ chưa từng xem Hậu Ký, chỉ đọc số đo hiện tại. + +12 giờ 17. + +Mốc chết đi qua. + +Không gì xảy ra. + +Kha mang dao công cụ bên hông nhưng không rút. Một lúc sau hắn tháo cả bao dao đặt lên bàn kỹ thuật. + +“Không cần?” Tiến hỏi. + +“Cần. Chính vì thế mới không để nó ở tay.” + +Radio vang. Giọng Thủy rõ và có hướng: “Mễ Trì báo.” + +Tiến cầm máy. “Ổn.” + +“Có dao?” + +Hắn nhìn chiếc bao trên bàn. “Có.” + +“Dùng chưa?” + +“Không.” + +“Giữ vậy.” + +Khi kênh tắt, Kha hỏi: “Cô ấy viết tao thế nào?” + +“Có đoạn về La Phù.” + +Tay Kha dừng trên mép bàn. Trong phương án cũ, hắn đã cho đóng sân kho phía đông sau cảnh báo nhiễm bẩn, chiếm phần lương còn khô và ra lệnh bắn khi đám đông phá cổng. Một trăm ba mươi bảy cái tên được xác nhận; số người chết ngoài sổ không ai biết. Số lương ấy cứu hàng nghìn người về sau. Hai sự thật không xóa nhau. + +“Đọc chưa?” Tiến hỏi. + +“Rồi.” + +“Có sửa?” + +“Không.” + +“Có phản đối?” + +“Có.” Kha cầm bao dao, vẫn không đeo lại. “Nhưng không phản đối số người chết.” + +Đó không phải lời xin tha. Tiến cũng không đưa ra sự tha thứ. + +Họ rời tầng hầm khi đội kỹ thuật bắt đầu thay bộ cách điện. + +Ngoài đường, một đoàn hàng từ phía nam chạy qua Nguyễn Trãi. Trẻ học dưới khu mát. Một đôi trẻ vừa đăng ký sống chung trước hội đồng khu, đòi một cái tên cho đời mình dù mặt trời vẫn đỏ. + +Trong phòng điều khiển Ngọc Trục, màn hình HANOI-07 hiện: + +**OBSERVER NODE HANOI-07 ACTIVE** +**CITY STATE: ACTIVE** +**FORECAST: UNAVAILABLE** + +Một kỹ thuật viên trẻ hỏi Nam có cần báo Tiến không. Nam kiểm kim, nguồn và bảng ca rồi lắc đầu. + +“Trạng thái bình thường.” + +Cậu tắt âm cảnh báo, không tắt hệ thống. + +Trong kho lưu trữ, câu **I WANT TO WIN** vẫn nằm trong bản ghi ngày 09 tháng 5, nhưng không còn ở trường mục tiêu vận hành. Nó được giữ như lời của một người từng nghĩ thắng nghĩa là sống lâu hơn tất cả. + +Hà Nội không cần một người trở về để nói ngày mai phải xảy ra thế nào. Thành phố có người đo nước, giữ đường, trồng thức ăn, chữa bệnh, ghi lại, phản đối và sửa sai. Có người yêu nhau, chôn người chết, nhận lỗi và dựng trò chơi từ nắp chai. Có những ngày không ai mở một cánh cổng bí mật, nhưng nước vẫn chảy và bữa tối vẫn được nấu. + +Gió đi qua mái Ngọc Trục. + +Vầng mặt trời vẫn đỏ. + +Bên dưới nó, Hà Nội còn sống. + diff --git a/extension/background.js b/extension/background.js index 56e2ed47c..901f0400b 100644 --- a/extension/background.js +++ b/extension/background.js @@ -28,6 +28,38 @@ const flowUrls = [ ]; const FLOW_TAB_URL = 'https://flow.google.com/'; +// ─── Temporary Netlog Recorder (docs/CAPTURE.md) ─────────── +const NETLOG_HOSTS = ['https://flow.google.com/_/*']; +const netlogPending = new Map(); + +chrome.webRequest.onBeforeRequest.addListener( + (d) => { + let body = null; + if (d.requestBody?.raw?.length) { + body = new TextDecoder().decode(new Uint8Array(d.requestBody.raw[0].bytes)); + } else if (d.requestBody?.formData) { + body = JSON.stringify(d.requestBody.formData); + } + netlogPending.set(d.requestId, { ts: new Date().toISOString(), url: d.url, method: d.method, body }); + }, + { urls: NETLOG_HOSTS }, + ['requestBody'] +); + +chrome.webRequest.onCompleted.addListener( + (d) => { + const rec = netlogPending.get(d.requestId); + if (!rec) return; + netlogPending.delete(d.requestId); + fetch('http://127.0.0.1:8100/api/ext/netlog', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ ...rec, statusCode: d.statusCode }), + }).catch(() => {}); + }, + { urls: NETLOG_HOSTS } +); + let ws = null; let flowKey = null; let callbackSecret = null; // Auth secret for HTTP callback, received from server on WS connect @@ -247,6 +279,192 @@ function connectToAgent() { await handleTrpcRequest(msg); } else if (msg.method === 'solve_captcha') { await handleSolveCaptcha(msg); + } else if (msg.method === 'reload_extension') { + chrome.runtime.reload(); + } else if (msg.method === 'reload_flow_tab') { + const tabs = await chrome.tabs.query({ url: flowUrls }); + for (const t of tabs) { + try { await chrome.tabs.reload(t.id); } catch {} + } + sendToAgent({ id: msg.id, result: { reloaded: tabs.length } }); + } else if (msg.method === 'list_tabs') { + const tabs = await chrome.tabs.query({ url: flowUrls }); + const list = tabs.map((t) => ({ + id: t.id, + url: t.url, + active: t.active, + discarded: t.discarded, + title: t.title, + })); + sendToAgent({ id: msg.id, result: { tabs: list } }); + } else if (msg.method === 'submit_ui_prompt') { + const tabs = await chrome.tabs.query({ url: flowUrls }); + let candidate = tabs.find((t) => t.active && !t.discarded) || tabs[0]; + if (!candidate) { + sendToAgent({ id: msg.id, result: { error: 'NO_FLOW_TAB' } }); + return; + } + try { + const [injected] = await chrome.scripting.executeScript({ + target: { tabId: candidate.id }, + world: 'MAIN', + args: [msg.params?.prompt || ''], + func: async (promptText) => { + const editor = document.querySelector('.ProseMirror'); + if (!editor) return { error: 'NO_PROSEMIRROR' }; + editor.focus(); + document.execCommand('selectAll', false, null); + document.execCommand('insertText', false, promptText); + editor.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'insertText', data: promptText })); + editor.dispatchEvent(new Event('input', { bubbles: true })); + editor.dispatchEvent(new Event('change', { bubbles: true })); + + await new Promise(r => setTimeout(r, 600)); + const buttons = Array.from(document.querySelectorAll('button')); + const btn = buttons.find(b => b.getAttribute('aria-label') === 'Bắt đầu tạo' || b.innerText?.includes('arrow_forward')); + const disabled = btn?.disabled || btn?.getAttribute('disabled') !== null || btn?.getAttribute('aria-disabled') === 'true'; + + if (btn && !disabled) { + btn.focus(); + try { btn.click(); } catch (_) {} + ['pointerdown', 'mousedown', 'pointerup', 'mouseup', 'click'].forEach(type => { + btn.dispatchEvent(new MouseEvent(type, { bubbles: true, cancelable: true, view: window, button: 0, buttons: 1 })); + }); + } + + ['keydown', 'keypress', 'keyup'].forEach(type => { + editor.dispatchEvent(new KeyboardEvent(type, { + key: 'Enter', + code: 'Enter', + keyCode: 13, + which: 13, + bubbles: true, + cancelable: true, + })); + }); + + return { success: true, btnFound: !!btn, btnDisabled: disabled, prompt: promptText.slice(0, 80) }; + }, + }); + sendToAgent({ id: msg.id, result: injected?.result }); + } catch (e) { + sendToAgent({ id: msg.id, result: { error: e.message } }); + } + } else if (msg.method === 'debug_tab') { + const tabs = await chrome.tabs.query({ url: flowUrls }); + let candidate = + tabs.find((t) => t.active && !t.discarded) || + tabs.find((t) => t.url && t.url.includes('/edit/') && !t.discarded) || + tabs.find((t) => !t.discarded) || + tabs[0]; + if (!candidate) { + sendToAgent({ id: msg.id, result: { error: 'NO_FLOW_TAB' } }); + return; + } + try { + const [injected] = await chrome.scripting.executeScript({ + target: { tabId: candidate.id }, + world: 'MAIN', + func: () => { + const wiz = globalThis.WIZ_global_data || {}; + return { + url: location.href, + hasAt: !!wiz.SNlM0e, + atLen: (wiz.SNlM0e || '').length, + sid: wiz.FdrFJe, + bl: wiz.cfb2h, + hasGrecaptcha: !!window.grecaptcha?.enterprise?.execute, + executeString: window.grecaptcha?.enterprise?.execute?.toString(), + promptElements: Array.from(document.querySelectorAll('textarea, [contenteditable="true"], [role="textbox"]')) + .map(el => ({ tag: el.tagName, id: el.id, className: el.className, placeholder: el.placeholder || el.getAttribute('aria-label') || el.getAttribute('placeholder') })), + editorContent: document.querySelector('.ProseMirror')?.innerText || '', + buttons: Array.from(document.querySelectorAll('button')) + .map(b => ({ id: b.id, text: b.innerText?.trim()?.slice(0, 30), ariaLabel: b.getAttribute('aria-label') })) + .filter(b => b.text || b.ariaLabel) + .slice(-15), + chatMessages: Array.from(document.querySelectorAll('p, [role="log"], [class*="message"], [class*="prompt"], [class*="response"]')) + .map(el => el.innerText?.trim()) + .filter(t => t && t.length > 10 && t.length < 500) + .slice(-8), + flowImages: Array.from(document.querySelectorAll('img')) + .map(img => ({ src: img.src, alt: img.alt })) + .filter(img => img.src && (img.src.includes('flow-content') || img.src.includes('googleusercontent') || img.src.includes('image/'))) + .slice(-8), + scripts: Array.from(document.querySelectorAll('script')).map(s => s.src).filter(s => s.includes('recaptcha') || s.includes('flow')), + }; + }, + }); + sendToAgent({ id: msg.id, result: { tabId: candidate.id, data: injected?.result } }); + } catch (e) { + sendToAgent({ id: msg.id, result: { tabId: candidate.id, error: e.message } }); + } + } else if (msg.method === 'eval_tab') { + const tabs = await chrome.tabs.query({ url: flowUrls }); + let candidate = tabs.find((t) => t.active && !t.discarded) || tabs[0]; + if (!candidate) { + sendToAgent({ id: msg.id, result: { error: 'NO_FLOW_TAB' } }); + return; + } + try { + const [injected] = await chrome.scripting.executeScript({ + target: { tabId: candidate.id }, + world: 'MAIN', + args: [msg.params?.code || ''], + func: (codeStr) => { + try { + return { result: eval(codeStr) }; + } catch (e) { + return { error: e.message, stack: e.stack }; + } + }, + }); + sendToAgent({ id: msg.id, result: injected?.result }); + } catch (e) { + sendToAgent({ id: msg.id, result: { error: e.message } }); + } + } else if (msg.method === 'find_actions') { + const tabs = await chrome.tabs.query({ url: flowUrls }); + let candidate = tabs.find((t) => t.active && !t.discarded) || tabs[0]; + if (!candidate) { + sendToAgent({ id: msg.id, result: { error: 'NO_FLOW_TAB' } }); + return; + } + try { + const [injected] = await chrome.scripting.executeScript({ + target: { tabId: candidate.id }, + world: 'MAIN', + func: async () => { + const scriptTags = Array.from(document.querySelectorAll('script')).map((s) => s.src).filter(Boolean); + const perfEntries = performance.getEntriesByType('resource') + .map(r => r.name) + .filter(u => u.includes('.js') || u.includes('/js/')); + const allScripts = Array.from(new Set([...scriptTags, ...perfEntries])); + const matches = []; + const scanned = []; + for (const src of allScripts) { + if (src.includes('recaptcha')) continue; + try { + scanned.push(src); + const resp = await fetch(src); + const text = await resp.text(); + const re = /action:\s*['"]([A-Z0-9_]{3,40})['"]/g; + let m; + while ((m = re.exec(text)) !== null) { + matches.push({ src: src.slice(-50), action: m[1] }); + } + const re2 = /\.execute\([^,]+,\s*\{\s*action:\s*['"]([^'"]+)['"]/g; + while ((m = re2.exec(text)) !== null) { + matches.push({ src: src.slice(-50), executeAction: m[1] }); + } + } catch (e) {} + } + return { matches, scriptCount: allScripts.length, scannedCount: scanned.length, scannedSample: scanned.slice(0, 10) }; + }, + }); + sendToAgent({ id: msg.id, result: injected?.result }); + } catch (e) { + sendToAgent({ id: msg.id, result: { error: e.message } }); + } } else if (msg.method === 'get_status') { sendToAgent({ id: msg.id, @@ -470,7 +688,10 @@ const MAX_RPC_TEXT = 32000000; // the project listing alone is past 17 MB async function runBatchRpc(cmd) { const tabs = await chrome.tabs.query({ url: flowUrls }); - let candidate = tabs.find((t) => !t.discarded) || tabs[0]; + let candidate = + tabs.find((t) => t.active && !t.discarded) || + tabs.find((t) => !t.discarded) || + tabs[0]; if (!candidate) { // No Flow tab — open one and give the app a moment to boot, otherwise // WIZ_global_data is not on the page yet and `at` comes back empty. Keep @@ -491,7 +712,7 @@ async function runBatchRpc(cmd) { let freq = cmd.freq; if (cmd.captchaAction) { - const solved = await solveCaptcha(cmd.id, cmd.captchaAction); + const solved = await captchaFromTab(tab.id, cmd.id, cmd.captchaAction); if (!solved?.token) return { error: `CAPTCHA_FAILED: ${solved?.error || 'no token'}` }; freq = freq.split(CAPTCHA_SLOT).join(solved.token); } @@ -499,23 +720,25 @@ async function runBatchRpc(cmd) { const [injected] = await chrome.scripting.executeScript({ target: { tabId: tab.id }, world: 'MAIN', - args: [cmd.rpcid, freq, MAX_RPC_TEXT, cmd.match || null], - func: async (rpcid, freqStr, maxText, match) => { + args: [cmd.rpcid, freq, MAX_RPC_TEXT, cmd.match || null, cmd.customPath || null], + func: async (rpcid, freqStr, maxText, match, customPath) => { const wiz = globalThis.WIZ_global_data || {}; const at = wiz.SNlM0e; const sid = wiz.FdrFJe; const bl = wiz.cfb2h; if (!at) return { error: 'NO_AT_TOKEN' }; + const reqid = Math.floor(Math.random() * 900000) + 100000; // Match Flow's own WIZ metadata. GEM_PIX_2 (Nano Banana Pro) rejects // image generation when source-path is missing even though Lite may not. const sourcePath = location.pathname || '/'; const hl = (document.documentElement.lang || navigator.language || 'en').split('-')[0]; - const url = - `/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=${encodeURIComponent(rpcid)}` + - `&source-path=${encodeURIComponent(sourcePath)}` + - `&bl=${encodeURIComponent(bl || '')}&f.sid=${encodeURIComponent(sid || '')}` + - `&hl=${encodeURIComponent(hl)}&_reqid=${reqid}&rt=c`; + const url = customPath + ? `${customPath}?bl=${encodeURIComponent(bl || '')}&f.sid=${encodeURIComponent(sid || '')}&hl=${encodeURIComponent(hl)}&_reqid=${reqid}&rt=c` + : `/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=${encodeURIComponent(rpcid)}` + + `&source-path=${encodeURIComponent(sourcePath)}` + + `&bl=${encodeURIComponent(bl || '')}&f.sid=${encodeURIComponent(sid || '')}` + + `&hl=${encodeURIComponent(hl)}&_reqid=${reqid}&rt=c`; const resp = await fetch(url, { method: 'POST', credentials: 'include', @@ -530,11 +753,22 @@ async function runBatchRpc(cmd) { // is one entry. Cutting it down here keeps that payload inside the tab // instead of pushing it through the bridge on every poll. if (match) { - const found = text.indexOf(match); // not `at` — that is the CSRF token above + const lowerText = text.toLowerCase(); + const lowerMatch = match.toLowerCase(); + const found = lowerText.indexOf(lowerMatch); + if (found !== -1) { + const start = Math.max(0, found - 400); + const end = Math.min(text.length, found + 800); + return { + status: resp.status, + matched: true, + text: text.slice(start, end), + }; + } return { status: resp.status, - matched: found !== -1, - text: found === -1 ? '' : text.slice(found, found + 800), + matched: false, + text: '', }; } return { status: resp.status, text: text.slice(0, maxText) }; @@ -546,7 +780,7 @@ async function runBatchRpc(cmd) { async function handleBatchRpc(msg) { const { id, params } = msg; - const { rpcid, freq, captchaAction, match } = params || {}; + const { rpcid, freq, captchaAction, match, customPath } = params || {}; if (!rpcid || !freq) { sendToAgent({ id, status: 400, error: 'INVALID_BATCH_RPC' }); return; @@ -567,7 +801,7 @@ async function handleBatchRpc(msg) { } try { - const out = await runBatchRpc({ id, rpcid, freq, captchaAction, match }); + const out = await runBatchRpc({ id, rpcid, freq, captchaAction, match, customPath }); if (out.error) { if (hasCaptcha) { metrics.failedCount++; metrics.lastError = out.error; } if (visible) updateRequestLog(id, { status: 'failed', error: out.error }); @@ -853,6 +1087,7 @@ chrome.runtime.onMessage.addListener((msg, _, reply) => { return true; } + if (msg.type === 'TRPC_MEDIA_URLS') { handleTrpcMediaUrls(msg.trpcUrl, msg.body); reply({ ok: true }); diff --git a/extension/content.js b/extension/content.js index b3ff64d36..85c9427e0 100644 --- a/extension/content.js +++ b/extension/content.js @@ -2,48 +2,52 @@ * Content script — bridge between background.js and injected.js * Injects injected.js into MAIN world to access window.grecaptcha */ -(function () { - const s = document.createElement('script'); - s.src = chrome.runtime.getURL('injected.js'); - s.onload = () => s.remove(); - (document.head || document.documentElement).appendChild(s); -})(); - -chrome.runtime.onMessage.addListener((msg, _, reply) => { - if (msg.type !== 'GET_CAPTCHA') return; - - const { requestId, pageAction } = msg; - - const handler = (e) => { - if (e.detail?.requestId === requestId) { +if (!globalThis.__FLOWKIT_CONTENT_LOADED__) { + globalThis.__FLOWKIT_CONTENT_LOADED__ = true; + + (function () { + const s = document.createElement('script'); + s.src = chrome.runtime.getURL('injected.js'); + s.onload = () => s.remove(); + (document.head || document.documentElement).appendChild(s); + })(); + + chrome.runtime.onMessage.addListener((msg, _, reply) => { + if (msg.type !== 'GET_CAPTCHA') return; + + const { requestId, pageAction } = msg; + + const handler = (e) => { + if (e.detail?.requestId === requestId) { + window.removeEventListener('CAPTCHA_RESULT', handler); + clearTimeout(timer); + reply({ token: e.detail.token, error: e.detail.error }); + } + }; + + const timer = setTimeout(() => { window.removeEventListener('CAPTCHA_RESULT', handler); - clearTimeout(timer); - reply({ token: e.detail.token, error: e.detail.error }); - } - }; - - const timer = setTimeout(() => { - window.removeEventListener('CAPTCHA_RESULT', handler); - reply({ error: 'CONTENT_TIMEOUT' }); - }, 25000); - - window.addEventListener('CAPTCHA_RESULT', handler); - - window.dispatchEvent(new CustomEvent('GET_CAPTCHA', { - detail: { requestId, pageAction }, - })); - - return true; // keep channel open for async reply -}); - -// ─── TRPC Media URL Monitor ───────────────────────────────── -// Forward intercepted TRPC responses with media URLs to background.js -window.addEventListener('TRPC_MEDIA_URLS', (e) => { - const { url, body } = e.detail || {}; - if (!body) return; - chrome.runtime.sendMessage({ - type: 'TRPC_MEDIA_URLS', - trpcUrl: url, - body, - }).catch(() => {}); -}); + reply({ error: 'CONTENT_TIMEOUT' }); + }, 25000); + + window.addEventListener('CAPTCHA_RESULT', handler); + + window.dispatchEvent(new CustomEvent('GET_CAPTCHA', { + detail: { requestId, pageAction }, + })); + + return true; // keep channel open for async reply + }); + + // ─── TRPC Media URL Monitor ───────────────────────────────── + // Forward intercepted TRPC responses with media URLs to background.js + window.addEventListener('TRPC_MEDIA_URLS', (e) => { + const { url, body } = e.detail || {}; + if (!body) return; + chrome.runtime.sendMessage({ + type: 'TRPC_MEDIA_URLS', + trpcUrl: url, + body, + }).catch(() => {}); + }); +} diff --git a/extension/injected.js b/extension/injected.js index a955a5f82..70bc6b98a 100644 --- a/extension/injected.js +++ b/extension/injected.js @@ -1,78 +1,158 @@ /** - * Injected into the page's MAIN world on flow.google.com (and an old pinned - * labs.google tab) — has access to window.grecaptcha. + * Injected into the page's MAIN world on flow.google.com — has access to window.grecaptcha. * - * The reCAPTCHA site key survived the September 2026 migration unchanged. The - * TRPC fetch intercept below did not: it belongs to the labs.google frontend - * and is inert on flow.google.com, where media urls come back inline on the - * generate call and from the media rpc. + * Protects window.grecaptcha.enterprise.execute from Angular's x2a poison wrapper + * which otherwise overrides every extension call with action: "extension_hijack_detected" + * and triggers PUBLIC_ERROR_UNUSUAL_ACTIVITY. */ -const SITE_KEY = '6LdsFiUsAAAAAIjVDZcuLhaHiDn5nnHVXVRQGeMV'; +(function () { + if (window.__FLOWKIT_INJECTED__) return; + window.__FLOWKIT_INJECTED__ = true; -// ─── TRPC Response Monitor ───────────────────────────────── -// Monkey-patch fetch to intercept TRPC responses containing media URLs. -// Fresh signed GCS URLs are extracted and forwarded to the agent. + var SITE_KEY = '6LdsFiUsAAAAAIjVDZcuLhaHiDn5nnHVXVRQGeMV'; -const _originalFetch = window.fetch; -window.fetch = async function (...args) { - const response = await _originalFetch.apply(this, args); - try { - const url = typeof args[0] === 'string' ? args[0] : args[0]?.url || ''; - // Only intercept TRPC calls on labs.google that return project/flow data - if (url.includes('/fx/api/trpc/') && response.ok) { - const clone = response.clone(); - clone.text().then(text => { - if (text.includes('storage.googleapis.com/ai-sandbox-videofx/')) { - window.dispatchEvent(new CustomEvent('TRPC_MEDIA_URLS', { - detail: { url, body: text }, - })); - } - }).catch(() => {}); + // ─── reCAPTCHA Anti-Hijack Protection ─────────────────────── + let _realExecute = null; + + function hookEnterprise(enterprise) { + if (!enterprise || enterprise.__FLOWKIT_HOOKED__) return; + enterprise.__FLOWKIT_HOOKED__ = true; + + if (typeof enterprise.execute === 'function' && !enterprise.execute.toString().includes('extension_hijack_detected')) { + _realExecute = enterprise.execute; + window.__REAL_GRECAPTCHA_EXECUTE__ = _realExecute; } - } catch {} - return response; -}; + let _exec = enterprise.execute; + try { + Object.defineProperty(enterprise, 'execute', { + configurable: true, + enumerable: true, + get() { + return _realExecute || _exec; + }, + set(fn) { + if (fn && fn.toString().includes('extension_hijack_detected')) { + console.warn('[FlowKit] Neutralized extension_hijack_detected attempt in x2a!'); + return; // Discard hijack attempt! + } + if (typeof fn === 'function') { + _realExecute = fn; + _exec = fn; + window.__REAL_GRECAPTCHA_EXECUTE__ = fn; + } + }, + }); + } catch (e) { + console.warn('[FlowKit] Could not define property on enterprise:', e); + } + } -let captchaMintTail = Promise.resolve(); + function watchGrecaptcha() { + let _g = window.grecaptcha; + if (_g?.enterprise) { + hookEnterprise(_g.enterprise); + } -async function mintCaptcha(pageAction) { - const previous = captchaMintTail.catch(() => {}); - let release; - captchaMintTail = new Promise((resolve) => { release = resolve; }); - await previous; - try { - await waitForGrecaptcha(); - return await window.grecaptcha.enterprise.execute(SITE_KEY, { - action: pageAction, - }); - } finally { - release(); + try { + Object.defineProperty(window, 'grecaptcha', { + configurable: true, + enumerable: true, + get() { + return _g; + }, + set(val) { + _g = val; + if (val) { + if (val.enterprise) { + hookEnterprise(val.enterprise); + } else { + let _ent = val.enterprise; + try { + Object.defineProperty(val, 'enterprise', { + configurable: true, + enumerable: true, + get() { return _ent; }, + set(eVal) { + _ent = eVal; + hookEnterprise(eVal); + }, + }); + } catch (_) {} + } + } + }, + }); + } catch (e) { + console.warn('[FlowKit] Could not define property on window.grecaptcha:', e); + } } -} -window.addEventListener('GET_CAPTCHA', async ({ detail }) => { - const { requestId, pageAction } = detail; - try { - const token = await mintCaptcha(pageAction); - window.dispatchEvent(new CustomEvent('CAPTCHA_RESULT', { - detail: { requestId, token }, - })); - } catch (e) { - window.dispatchEvent(new CustomEvent('CAPTCHA_RESULT', { - detail: { requestId, error: e.message }, - })); + watchGrecaptcha(); + + // TRPC fetch intercept — intercepts media URLs from labs.google + const _origFetch = window.fetch; + window.fetch = async function (...args) { + const response = await _origFetch.apply(this, args); + try { + const url = typeof args[0] === 'string' ? args[0] : args[0]?.url || ''; + if (url.includes('/fx/api/trpc/') && response.ok) { + const clone = response.clone(); + clone.text().then((text) => { + if (text.includes('storage.googleapis.com/ai-sandbox-videofx/')) { + window.dispatchEvent(new CustomEvent('TRPC_MEDIA_URLS', { + detail: { url, body: text }, + })); + } + }).catch(() => {}); + } + } catch {} + return response; + }; + + let captchaMintTail = Promise.resolve(); + + async function mintCaptcha(pageAction) { + const previous = captchaMintTail.catch(() => {}); + let release; + captchaMintTail = new Promise((resolve) => { release = resolve; }); + await previous; + try { + await waitForGrecaptcha(); + const exec = _realExecute || window.__REAL_GRECAPTCHA_EXECUTE__ || window.grecaptcha?.enterprise?.execute; + if (!exec) throw new Error('grecaptcha.enterprise.execute not available'); + return await exec.call(window.grecaptcha.enterprise, SITE_KEY, { + action: pageAction, + }); + } finally { + release(); + } } -}); -function waitForGrecaptcha(timeout = 22000) { // it loads lazily; 10s was optimistic - return new Promise((resolve, reject) => { - const start = Date.now(); - const check = () => { - if (window.grecaptcha?.enterprise?.execute) return resolve(); - if (Date.now() - start > timeout) return reject(new Error('grecaptcha not available')); - setTimeout(check, 200); - }; - check(); + window.addEventListener('GET_CAPTCHA', async ({ detail }) => { + const { requestId, pageAction } = detail || {}; + try { + const token = await mintCaptcha(pageAction); + window.dispatchEvent(new CustomEvent('CAPTCHA_RESULT', { + detail: { requestId, token }, + })); + } catch (e) { + window.dispatchEvent(new CustomEvent('CAPTCHA_RESULT', { + detail: { requestId, error: e?.message || String(e) }, + })); + } }); -} + + function waitForGrecaptcha(timeout = 22000) { + return new Promise((resolve, reject) => { + const start = Date.now(); + const check = () => { + const has = _realExecute || window.__REAL_GRECAPTCHA_EXECUTE__ || window.grecaptcha?.enterprise?.execute; + if (has) return resolve(); + if (Date.now() - start > timeout) return reject(new Error('grecaptcha not available')); + setTimeout(check, 200); + }; + check(); + }); + } +})(); diff --git a/requirements.txt b/requirements.txt index c2cd265b7..8173592ef 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,5 @@ pydantic>=2.5.0 aiohttp>=3.9.0 httpx>=0.25.0 anthropic>=0.40.0 +google-api-python-client>=2.100.0 +google-auth-oauthlib>=1.0.0 diff --git a/scratch/captured_netlog.jsonl b/scratch/captured_netlog.jsonl new file mode 100644 index 000000000..857153374 --- /dev/null +++ b/scratch/captured_netlog.jsonl @@ -0,0 +1,321 @@ +{"ts": "2026-09-23T13:16:52.291Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=281899&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:17:05.413Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=826921&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,733647544,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5MPg8cTqBq2xeiEK_4oNLK1jZnsUckrwa1t4j1ZGVfgPOC5hIcFD3EMddxnfrhVFHTv9uKf4EKq3uAEHT2r3B3hY0FOwpbMvBDOHk30qQbz-nactrTEWIFDmBAqlUQ8VZ9m7FSGhHmRbKNNUkB3Y0tHRL1lEZGGkILJ9EgGjB7Y1u9h3O8No1vWM8BrY7J7f0f-rhjn-8UU_QvW3i_rn30cNYqumup-k8rPoOgVQY5pKpZXcQL5pP6YSBkZWL6D965aCcVvOmGKnVMUCV5L-4cS873cdEVm-AcwhDzaeZuYkKgpWjGaJ9V2dodPZlHXhbe47E5C1y8d1Br5Z29pZkyI1H8cQk13FryCsuNwyhEusneAmDIM8ghOzqjTckDRQfAZIAt6lPaHDmrrePCIBrQWXqvChE26Zz-Y7ZrGxeNUn3wnbo3XSss0b1Hdsq5GNv5fLr25AJ-2Jvri0UVd_pAWssJksY6cd-8WWG2msnt39uOtct2FAPA3S9YA5kF7PMZm8QfiaJ00AF3mHIvv-cZHcNSmPtpBY9lZP12RFUcrdcIosyENe37vqI0680oJL-x4VUJqw4MZu1ASdycwa5JLbBt7YC1v400rkFRSZYXUyCXxhCRHrK-fEl3CLDSTWaGPW8jKEo_aLVCQ9rjpKMrVb_SRsftv2SzSylYZpOWHykX4Cydt5daVYCS4c21BFMOpPfLGpN8O4QenFxrEpV67BuR3mQrSKdaNJ0yETRI2uhApjbcXkWEmK75uDolzvk4HvJMRdqbt_x3yqs_8KvB0ASbQcMfiRbahjSXJF0HMBpCMkLVY0bU7PtBVDkbZy7-169vkRZnCoe003-xMR8JPrIiijg-PNe_gEkzVHvwS9eybEjQetRfOal2R-cbnpJe3fWdbd-E8XFqkT-tCTR4R4Fh1FmC1kGVRPFzSq_2dInSlUsReqJEGb9wZoalRD_aa19mJF2FilfEMqJUfEBS_DN32lr25_FjsBqtWShrJQVU8YcO1ai8tnLez8cUZJ-FRRFZa7Uf6gJVFsRQ_cdFi-ZM6i9okJjzbLA-wlQry74ZBPe3SKA1Z3QKeT-t5FLNuIVnMjiE6rMIPhkRw_tdxNRLHQPafbJRDPuiCzmNS5YRczrTMGvcRwPVeok1-lxV-yt8R4oVo-MVnZOSGM9wB8TQ4-YfUdvSh0b34tDrPGumi_9PBL6Gn8-Tweby_WRUzOwmAN62v5AIHOq2lGvn1TpUXy7hc9RPK2O70Xy1umOZgY4qpkyjnL-eVm8r1ZYuMyCQmgS4eFwEHlOBP4ePlI4lPCo1g03i38mDU3XjZjZD0Ub0y96dwZrEikeo-3yBvMJI3KGCHhT28bQPV9GPqd-OL96QMYq5UaGZFbQao7Hqq9Qd_1b7QbV-xqhInNHWv5df7QozHgLZA5ZMtcyLPT6PFTFDAhuzMUDKkuS4T_rZbsaQzKxi7hJzQsMDa1z4ZhtsqsoPRIU2NjZSEWmGUC6HgqFeBEAxtYsOvdQFJMg9mSrjyZzD6IX4aKXIJ-jEBiJSAmDhH2i53sCRmmDAM-f9qOLpccS45LuKT-Y1wtj7I5zRRV09J4tOOoyQpa3Rt7G4g1gezlSkQRejRuE5ds67tUQ2JZyyQnqOszxidxKmFnB6v5q0jvdSgWsejRmUKkJW6dnggt4eeRoejI_5SZelXySVsIxrzWlV_1GO9etcjAsjhOBMyJhhhUWRtMECpfwSHSLBSDtRBO4iVw5p8Gz5Hl8eGgIpELDQlVryq8T1Kc7qWqTrSvJ1cnM8qj6cfuTfc34TFH2q6A2E1mPe6-g9xYYEiv1zp1bofVsmYZQYKZiaRm03LMD2yWSf8-mbGtPi-VZu6oViaYkHfoPq_Sudc96pKriTm7X6fTWhNP0Oqeq-Id5z_hXaHMDJWY8ga8nXybwfTQWEl-qQtHDAtNOqNgW2kGxhHa94Dgg2VRRzOuXJrl82pnuYhGlTRb0w_JXmrcg8RIyWQCVONTstupDngNEV4ylP7gOk9KmumsMbV89roJyju3OclKxIsSNQv1RKjKXbeC6wBw3uAdqiK88xZ7LnuF_czNFJZzOlh2057r2n4nch9qEUz2c2XlKOSDhKoY6p2vdX50viRbDc9BmXCvqKk91G6nyTJU2WYAhAQeVyR9VrHWptruCCXo9KuRfEjTykvmxDN4k8lcOqH21fO5iYrOO7zczBRopPp_fQO7J6N3XFBfZ5QIeJHfOUEjZPOKiGhBO3Q79XYsek3HS7TFsBCSuSUlWnLkVSQhP4f4mWU_ueS5WfAg9Di9yyBgw0-B-ILb-_FBG1yFnbimLeuAFq-zW-_2LFgQRjtJlAJtSgf6y0BvNvZmYtP-1avLnJTjnc8uSADBObmfnUtwkQtqRVuxAjjIGVcNBFHYfLr-zHEmnHQvo4OY7KXKhL-P08cwKDMl9L4Ap7ms4iVLPGSHQRRdeEKGjVBOFbYFVORSMslT-7LvhmR6G58kNhjm_n\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"6D6580CB-4DD9-401F-9529-7E5198D65DA9\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5MPg8cTqBq2xeiEK_4oNLK1jZnsUckrwa1t4j1ZGVfgPOC5hIcFD3EMddxnfrhVFHTv9uKf4EKq3uAEHT2r3B3hY0FOwpbMvBDOHk30qQbz-nactrTEWIFDmBAqlUQ8VZ9m7FSGhHmRbKNNUkB3Y0tHRL1lEZGGkILJ9EgGjB7Y1u9h3O8No1vWM8BrY7J7f0f-rhjn-8UU_QvW3i_rn30cNYqumup-k8rPoOgVQY5pKpZXcQL5pP6YSBkZWL6D965aCcVvOmGKnVMUCV5L-4cS873cdEVm-AcwhDzaeZuYkKgpWjGaJ9V2dodPZlHXhbe47E5C1y8d1Br5Z29pZkyI1H8cQk13FryCsuNwyhEusneAmDIM8ghOzqjTckDRQfAZIAt6lPaHDmrrePCIBrQWXqvChE26Zz-Y7ZrGxeNUn3wnbo3XSss0b1Hdsq5GNv5fLr25AJ-2Jvri0UVd_pAWssJksY6cd-8WWG2msnt39uOtct2FAPA3S9YA5kF7PMZm8QfiaJ00AF3mHIvv-cZHcNSmPtpBY9lZP12RFUcrdcIosyENe37vqI0680oJL-x4VUJqw4MZu1ASdycwa5JLbBt7YC1v400rkFRSZYXUyCXxhCRHrK-fEl3CLDSTWaGPW8jKEo_aLVCQ9rjpKMrVb_SRsftv2SzSylYZpOWHykX4Cydt5daVYCS4c21BFMOpPfLGpN8O4QenFxrEpV67BuR3mQrSKdaNJ0yETRI2uhApjbcXkWEmK75uDolzvk4HvJMRdqbt_x3yqs_8KvB0ASbQcMfiRbahjSXJF0HMBpCMkLVY0bU7PtBVDkbZy7-169vkRZnCoe003-xMR8JPrIiijg-PNe_gEkzVHvwS9eybEjQetRfOal2R-cbnpJe3fWdbd-E8XFqkT-tCTR4R4Fh1FmC1kGVRPFzSq_2dInSlUsReqJEGb9wZoalRD_aa19mJF2FilfEMqJUfEBS_DN32lr25_FjsBqtWShrJQVU8YcO1ai8tnLez8cUZJ-FRRFZa7Uf6gJVFsRQ_cdFi-ZM6i9okJjzbLA-wlQry74ZBPe3SKA1Z3QKeT-t5FLNuIVnMjiE6rMIPhkRw_tdxNRLHQPafbJRDPuiCzmNS5YRczrTMGvcRwPVeok1-lxV-yt8R4oVo-MVnZOSGM9wB8TQ4-YfUdvSh0b34tDrPGumi_9PBL6Gn8-Tweby_WRUzOwmAN62v5AIHOq2lGvn1TpUXy7hc9RPK2O70Xy1umOZgY4qpkyjnL-eVm8r1ZYuMyCQmgS4eFwEHlOBP4ePlI4lPCo1g03i38mDU3XjZjZD0Ub0y96dwZrEikeo-3yBvMJI3KGCHhT28bQPV9GPqd-OL96QMYq5UaGZFbQao7Hqq9Qd_1b7QbV-xqhInNHWv5df7QozHgLZA5ZMtcyLPT6PFTFDAhuzMUDKkuS4T_rZbsaQzKxi7hJzQsMDa1z4ZhtsqsoPRIU2NjZSEWmGUC6HgqFeBEAxtYsOvdQFJMg9mSrjyZzD6IX4aKXIJ-jEBiJSAmDhH2i53sCRmmDAM-f9qOLpccS45LuKT-Y1wtj7I5zRRV09J4tOOoyQpa3Rt7G4g1gezlSkQRejRuE5ds67tUQ2JZyyQnqOszxidxKmFnB6v5q0jvdSgWsejRmUKkJW6dnggt4eeRoejI_5SZelXySVsIxrzWlV_1GO9etcjAsjhOBMyJhhhUWRtMECpfwSHSLBSDtRBO4iVw5p8Gz5Hl8eGgIpELDQlVryq8T1Kc7qWqTrSvJ1cnM8qj6cfuTfc34TFH2q6A2E1mPe6-g9xYYEiv1zp1bofVsmYZQYKZiaRm03LMD2yWSf8-mbGtPi-VZu6oViaYkHfoPq_Sudc96pKriTm7X6fTWhNP0Oqeq-Id5z_hXaHMDJWY8ga8nXybwfTQWEl-qQtHDAtNOqNgW2kGxhHa94Dgg2VRRzOuXJrl82pnuYhGlTRb0w_JXmrcg8RIyWQCVONTstupDngNEV4ylP7gOk9KmumsMbV89roJyju3OclKxIsSNQv1RKjKXbeC6wBw3uAdqiK88xZ7LnuF_czNFJZzOlh2057r2n4nch9qEUz2c2XlKOSDhKoY6p2vdX50viRbDc9BmXCvqKk91G6nyTJU2WYAhAQeVyR9VrHWptruCCXo9KuRfEjTykvmxDN4k8lcOqH21fO5iYrOO7zczBRopPp_fQO7J6N3XFBfZ5QIeJHfOUEjZPOKiGhBO3Q79XYsek3HS7TFsBCSuSUlWnLkVSQhP4f4mWU_ueS5WfAg9Di9yyBgw0-B-ILb-_FBG1yFnbimLeuAFq-zW-_2LFgQRjtJlAJtSgf6y0BvNvZmYtP-1avLnJTjnc8uSADBObmfnUtwkQtqRVuxAjjIGVcNBFHYfLr-zHEmnHQvo4OY7KXKhL-P08cwKDMl9L4Ap7ms4iVLPGSHQRRdeEKGjVBOFbYFVORSMslT-7LvhmR6G58kNhjm_n\\\\\\\",1]],[\\\\\\\"4A4EF8B3-EAC3-4FF1-AE7A-2923B632D862\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:17:15.183Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=476550&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,917825764,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA76aQB53ojOe-o_LQMCZRoiIqrU8TZjvxh2Q27lN_SiVEdlelBacAtAVIoPgEsadlVBWz_P09vRLPpXbirSDzBxwzLlQbaQW77fbzr-Kq9njhXyNd68hFaQrb_YhshCf3MLd6CpPGxXuGFFBe1Ekp1n_RFUkpzjIDQ5_NNvUHJqhTDnMTT2XNwFuTh1B6kKn94s7PjVlA56RMBa-2wZ7rFhxgrKz2xlS58_Ee9-RoqqNZKz67aaCU9vzjHEIFEc8F-jqGj8R2aAdkZk-r7olNXwYyxVlgTTxj-IbWyGrXeA34TsWrnw8af2ia7lqYvJLFc_DLUWhNrZA4dmWcq0Cu_F6Z4y3_8aSkJFPwTzTqTvUO4qvjKUMcCbjzdKHq3sIW4W21c1dJaj6sIAQn3MKNVowP_gTVEhTzovoAMZ7cY0DRzyqkIA_a0rESu2YR8BoyNUVr3rLnnWN7-wZ4-oThPtWDuXi_YUHwd9qe9Aruli1BfUBCwww_kvvd4SnXibcIb50h4RK7SPGnRH3XDtJUPFBxaGVA7hHyPl3lKsI9U7yb290qbTi0F7C-fH8zLd0oJGUFFzei5pnHcGlf9PvjsoVPXpCsc_fMpVX55QAW9SJMiZ0Kev8SqDXlROMmBZOutWq-rqN7MJ0HmOyehf2235A6lckcj05PwuRDFyTpfKKCx8DuS6BiQuqq-JR0HcTAXG2mcQW-Ohpmc_P_cs6CgjPnU1kjuPd2BVg9LryiuZHRDk6DxNaxp5PQRDj2wTbdIOo2RwSAGhv_G22yuEPuxgZjDtWToqbjh_kni8Jp0pT1Thq51Jlwscz7yccrfkfKS0Pm_8JIijCWJSHQunmUkSWME2JlbPs3XJBS-MbIPPibhZGRSR8bwJBvZN4Wah7jTzjdunDr2W4BDb5h0RG3EuKNf96s9UWDFb4aH9W6lKBInQZOW_RvkmmlJnHRxjtuMbeQORbfFMbHVsauIW6ievcF7kfkPZojyVzIlpqKG4mnKJ40B7g9UDF-6jK1oEmiXYMj9pEeFf99vMYiVjDdsHoZE_XWkQ_w0wNd_Q7c7mFEIgsBgF7XhhJTEE7BTMyQtfDmXTOmwOqc6rkD3V04Bw3w6PV3sSf5o_CDmFOeoHo_5wZQ_UYngVvEub6Suh4DdiqW3OD3Wun9gog2gehYUUxgCP7U9sIrliJjei5E7mtzMVFu0NdSgu9g6rw3ac8wb-ll100XcmwU9wBWiwikgcUfMc9GYUn6GycBwpw5NOvCMldj1-yxpP3UWIEFS9_-JZZgqT19xvFbyO-x0YB-rJXjGHtNKaYxiKSzAXEukPJSsiK_JG0Gm_Z6cnDWMeMGkzjTgDzn00qTegwtdfVZlWAa3C1lBETacp4UeUS3WJoiCU3n8KHMoh-soiwnwfZbAPk3bb1gzadVXjxBkC20oXmdIr10znIShenWVObcLE_NigIkhnO_U_NM-asIy2hfwM1oASX3F3AERckZlzJ8RKb-kDFEzJkz6_qkWKclvaXqDzKOgb7BIZzgM6_NiSMOn2EMsWL1NE--KTppRZOPP4pNA9zdqdhLw5AK-nL-yX31T5hCxj_gvLrKbgnJfPOlubBnYwDWbrJ-OD5QC7eYD_SM8m0EmtUwVk-iJm4P1fmxUhBHvRWD45kkNzUWGZ4swziJV1JaTpyCstW5FQabc-igs-07E2LMFqYfGeWmuR254x3JyLWcg-suwztzi8uc-hgGs8lj1SRiqh_wCK2pTHzNHjVI4cnaLHOZKkbrK9GcoJO5AbH_uV9R84gK5VPEbAa_-K8IAJarEO_9urk1QzVcm71ru0t-nHZmdpNFY3Pc5Qc8wLki-oJIa3p_v4N-YkEcz_kT-q1hsO-8XuKUXe9vB8aDZDlBz0BGwPQwYbdcOeXbOqZsZWIb1zciDsMkvk7kuioIGyMbTl9fJ2jbdCuGhYA3F9kAe4ANQ1-d9apCsMrLF-_6-EabGY--BBApatRPLzsVpeCFYb0C7x7TTQgy5UyzGPyv0JtdGO2DLzJBBx_hSHUTlOsFGlIufZXS2SMP2ecYKx7h4ZgboA4MGlEcWl6AwOd2YuqORsDebt52bczBjmLhG0NZ5bfC1xuQgm-EQqN35UVMebwsbsDzWNg8Git2CTa5P95tUlM9l7x0FCay-WQTR25IrHHU_DLQuJVzyFeR2Hc6yJolYiySWJvgpDRGRD0Vhy3UDgdoLzalGA7HcUtBvoXnDZmdqHAUS1xrKyrzpWNl_V4FMaI8Vm76nqYbPdC2GuhJuaUCTTaXnY1HipOdjDwjTFb7iYnHGnqyGPakRo_xouxnDBrHUrTc0q9NM-0SwvQGDzAe6vDaWAtZmDcB0L0v2m00J6S4oUkq_f2XZ23eFDE9jG2NdExhg39Yecl2THSalJivuU452TySe6KYIf7ju6kTFq58J5NAaUVz1YdLxNdOLKZ7Y0k2R9yM8MKb9u6kO49ulERtIKwTmAx5MzVDNi9p89l2R3Iro9uj3Fuq9w1h6hnk3JWkplMyhnh29AYsOmg5OmN34jr-E\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"C7E27561-F11D-4122-B8FD-765EF771C676\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA76aQB53ojOe-o_LQMCZRoiIqrU8TZjvxh2Q27lN_SiVEdlelBacAtAVIoPgEsadlVBWz_P09vRLPpXbirSDzBxwzLlQbaQW77fbzr-Kq9njhXyNd68hFaQrb_YhshCf3MLd6CpPGxXuGFFBe1Ekp1n_RFUkpzjIDQ5_NNvUHJqhTDnMTT2XNwFuTh1B6kKn94s7PjVlA56RMBa-2wZ7rFhxgrKz2xlS58_Ee9-RoqqNZKz67aaCU9vzjHEIFEc8F-jqGj8R2aAdkZk-r7olNXwYyxVlgTTxj-IbWyGrXeA34TsWrnw8af2ia7lqYvJLFc_DLUWhNrZA4dmWcq0Cu_F6Z4y3_8aSkJFPwTzTqTvUO4qvjKUMcCbjzdKHq3sIW4W21c1dJaj6sIAQn3MKNVowP_gTVEhTzovoAMZ7cY0DRzyqkIA_a0rESu2YR8BoyNUVr3rLnnWN7-wZ4-oThPtWDuXi_YUHwd9qe9Aruli1BfUBCwww_kvvd4SnXibcIb50h4RK7SPGnRH3XDtJUPFBxaGVA7hHyPl3lKsI9U7yb290qbTi0F7C-fH8zLd0oJGUFFzei5pnHcGlf9PvjsoVPXpCsc_fMpVX55QAW9SJMiZ0Kev8SqDXlROMmBZOutWq-rqN7MJ0HmOyehf2235A6lckcj05PwuRDFyTpfKKCx8DuS6BiQuqq-JR0HcTAXG2mcQW-Ohpmc_P_cs6CgjPnU1kjuPd2BVg9LryiuZHRDk6DxNaxp5PQRDj2wTbdIOo2RwSAGhv_G22yuEPuxgZjDtWToqbjh_kni8Jp0pT1Thq51Jlwscz7yccrfkfKS0Pm_8JIijCWJSHQunmUkSWME2JlbPs3XJBS-MbIPPibhZGRSR8bwJBvZN4Wah7jTzjdunDr2W4BDb5h0RG3EuKNf96s9UWDFb4aH9W6lKBInQZOW_RvkmmlJnHRxjtuMbeQORbfFMbHVsauIW6ievcF7kfkPZojyVzIlpqKG4mnKJ40B7g9UDF-6jK1oEmiXYMj9pEeFf99vMYiVjDdsHoZE_XWkQ_w0wNd_Q7c7mFEIgsBgF7XhhJTEE7BTMyQtfDmXTOmwOqc6rkD3V04Bw3w6PV3sSf5o_CDmFOeoHo_5wZQ_UYngVvEub6Suh4DdiqW3OD3Wun9gog2gehYUUxgCP7U9sIrliJjei5E7mtzMVFu0NdSgu9g6rw3ac8wb-ll100XcmwU9wBWiwikgcUfMc9GYUn6GycBwpw5NOvCMldj1-yxpP3UWIEFS9_-JZZgqT19xvFbyO-x0YB-rJXjGHtNKaYxiKSzAXEukPJSsiK_JG0Gm_Z6cnDWMeMGkzjTgDzn00qTegwtdfVZlWAa3C1lBETacp4UeUS3WJoiCU3n8KHMoh-soiwnwfZbAPk3bb1gzadVXjxBkC20oXmdIr10znIShenWVObcLE_NigIkhnO_U_NM-asIy2hfwM1oASX3F3AERckZlzJ8RKb-kDFEzJkz6_qkWKclvaXqDzKOgb7BIZzgM6_NiSMOn2EMsWL1NE--KTppRZOPP4pNA9zdqdhLw5AK-nL-yX31T5hCxj_gvLrKbgnJfPOlubBnYwDWbrJ-OD5QC7eYD_SM8m0EmtUwVk-iJm4P1fmxUhBHvRWD45kkNzUWGZ4swziJV1JaTpyCstW5FQabc-igs-07E2LMFqYfGeWmuR254x3JyLWcg-suwztzi8uc-hgGs8lj1SRiqh_wCK2pTHzNHjVI4cnaLHOZKkbrK9GcoJO5AbH_uV9R84gK5VPEbAa_-K8IAJarEO_9urk1QzVcm71ru0t-nHZmdpNFY3Pc5Qc8wLki-oJIa3p_v4N-YkEcz_kT-q1hsO-8XuKUXe9vB8aDZDlBz0BGwPQwYbdcOeXbOqZsZWIb1zciDsMkvk7kuioIGyMbTl9fJ2jbdCuGhYA3F9kAe4ANQ1-d9apCsMrLF-_6-EabGY--BBApatRPLzsVpeCFYb0C7x7TTQgy5UyzGPyv0JtdGO2DLzJBBx_hSHUTlOsFGlIufZXS2SMP2ecYKx7h4ZgboA4MGlEcWl6AwOd2YuqORsDebt52bczBjmLhG0NZ5bfC1xuQgm-EQqN35UVMebwsbsDzWNg8Git2CTa5P95tUlM9l7x0FCay-WQTR25IrHHU_DLQuJVzyFeR2Hc6yJolYiySWJvgpDRGRD0Vhy3UDgdoLzalGA7HcUtBvoXnDZmdqHAUS1xrKyrzpWNl_V4FMaI8Vm76nqYbPdC2GuhJuaUCTTaXnY1HipOdjDwjTFb7iYnHGnqyGPakRo_xouxnDBrHUrTc0q9NM-0SwvQGDzAe6vDaWAtZmDcB0L0v2m00J6S4oUkq_f2XZ23eFDE9jG2NdExhg39Yecl2THSalJivuU452TySe6KYIf7ju6kTFq58J5NAaUVz1YdLxNdOLKZ7Y0k2R9yM8MKb9u6kO49ulERtIKwTmAx5MzVDNi9p89l2R3Iro9uj3Fuq9w1h6hnk3JWkplMyhnh29AYsOmg5OmN34jr-E\\\\\\\",1]],[\\\\\\\"A5383ADE-FF5D-4663-B89E-76B47860C93B\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:17:25.256Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=826897&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,428233453,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7juMDJedBkFrAjm99BywICUddrhD3dUA4cDC272UoX2MEun7J4LoWWGOo9L-2PkDiG5y1geNwk_T7G1PA7hFpR3NxN-gjsgllJl1POoNruDqvd9tu1l38hfQ3IoauYZgefWDM_YFGx1K4BSI-faJXNaCX1JYq9zKxb_dzM7HGrrUYw_gafaLFBGHHjt2GDInTrHPz8EV-_HMipvBt8dSG0gx9zqnWi1CP5PbhQIAB8hQGc9lRg8HvdlEp_KZg1wh-AVAbpX1tKwKdPERDwxqPG6luC2nIwLRGQxYdhGUdj2i21pW5CW2n8MSn77EvWq_vQME7dQmZoEGJVqsR-FE_ZFECgIi2LrTzqT9g5bPOHK66uIuCQcpMSKgPLOCxHh34yN4ualBAb4KvHVp3FZQl0p18qFN214FdT7rZqrpUJRUeiUuEf9HDmPT3-tRN7M3J_51rKyGD-NY3cJtCI96Exh7afLEuHOmqzDocY3dqY3Wm8Kf3UuZwG90Ics6O4_u-2NwWEUAmnqJUYMFASdRIxNJPGXzNdS9nNP0wscoLqbiq29RQDEouNkjwIaA6R0zmzk_f2gjyaRxNpwpxMaRCl9_8eET0RwlmNfWjvsd1rzpJmggJCWFifJyjBDLp-Jq-y8Kho6xYPI2rkmpXx8BsU808FSgzoZS8-pWpVfcv5fSZRi4xbf25NH7zJgItKLIj1KZSQjiyalApyq8Y3dSji0JD15a7am_SiZnchYSadwykFimDUm7FAk8yrkBt_cAHaRc7ZmkeO6IokHCJ6ZgpRUNehlCDSsJQTkwLWk6fMWJ0N-lrQxlCz8DieL4ZG2SNOC6ZuTJXOe5X6XYiv3hz4hCGjxzOSdOtrHkTzpnu8kHPLe6-3n0WsQ8tArv1oDJfJ3_sp3Vk-vXqcCdO6meufp48cgxI4RlMqJn0HxIcay9RkrtHIlcrc-ugRRi_HBYJ4DQFdiA8ahf_1X52OTEzfxw4u9LcdCWm43P2oV4G-eOS6Ej5raIfx65suoePGujXNtSip4qea1JDBZGhNd2wmqCQKdy5A-tBt2eYVpykiAJgLO-MX860RrdJhe7O-tcpLBElnf_R2NrkQyIlKvxxURPCunQp-RQiF4LDRTaojBImvMtS4P1fYiCxdArK-W7YuXyNvQnxoB7MTPqpWx4J-jRMBgdC-pGz6xchbOHST_H3bV9UZsfEUJG9NIwaDVTrc-HqTklIOGzthjG3QjeMEUCRfiO0J3CEK1Q6i7igtVorgmHJkPXrLGJKEG55X-Lsgq0hlgNbtHeGypU0m8mfVBYXoViegrtWeljouz-v0qepaqlgQjsTOUvODCbKW_e7vNP8X1XSfhhc-AKhy5YZmyk6lYY7MP9HH51ZYVZZZIsQP3dTJXZLEAvWFskUz4mOabhAl_zLlF83U34yuhRgplEpiWS-Pk49f9Jk_-vkYpsxx0Vxa8Z1QLZcXWvIN3ceVtJiqFWtwQueXTwkSdsTk3H8jWEkpFXTdRF3Nm30Lfl_qSCDpfX2cvgHZiPhg_IC0ByvBGT7zDuUOCQzPGJjTGAvMdhX57RTfzR6n5GZ62LNkUl2uo6vrjQPdvk5x6KLRR93o2AwbLpubhmWrNozfakXHPinjkKaL7_mRWvkkEeESPpM0W20CDKjEdrGYkHAQMofOf3q6oGoQHfAXTSk1WPWaQeJB7Jz1iiOcYH8IItlUtslba05MI4EcCCBPqmCjCyIvhzpRCxbpII-E72gcAE7y-46euR1i9PIYAD43j6mQv_kakU7mqnp-785YEhOyLukhmliDR_Xr8FwD-OqYNrRKtFOYncozMcX61YhTvb4vvEuxFqoDwf0oLpEA1qQYB-GOp0gIcb0AsX3KcU94oZVL1rEHbfn6oAK-iafHSnx83xfjy6QmhH-Q2-q2M48-CT_TcwYk4trN0KNKdReP_CRqOgVWtui23IcpddaBCQ8qtJbA5WCCC3JyhV7gTLCCMMdytmmbOPnJv1gbnf78kqeC2W_vp1f_hZDBr4D1KhSiQRWMa6GHWQjyki837X60TUStj8Yvx7dl7BCYZ7Qgrs2NQdngJEo1Xe5IerpQsIO_gIxlxPflPSuIPWrYuScGjWWFsyBAenV5mdt5pv4dBi9anJThFHhXlP7uMjDLiIEQjIwpPeFS5IcZEnf7uB0JP1TmkGAwoafHfeMKbhCIrh6jlTFdd8lEKTfAG_5ltY-iqtJPEwL0kXVlvj3NNFopDs1bVLgC3qenJi5QP6oMWefAyKWQO96Bn5c_x-YuA87TJah2kdSlz_mtLDJ-ZioyZlh-ay8_KM74rkNKBm2GOH5ZxDWVRFYJesr7O4kzMETjcpivKjrkYOIuK2fpKoBEMMMsNBmUp---oG6Va-xMB-_rXLp8jVnEM6HPox3_of0NHWQ8UexMN9LW_i7FFUyKxw5IFBWkplGt4eCYNgTGHw3YMuPt1ZMq_26JIAgZtignLF316Dnf9EZ_3klfMFT16ZcE\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"F1AE9119-44D8-4E6D-83FC-5794E0C43193\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7juMDJedBkFrAjm99BywICUddrhD3dUA4cDC272UoX2MEun7J4LoWWGOo9L-2PkDiG5y1geNwk_T7G1PA7hFpR3NxN-gjsgllJl1POoNruDqvd9tu1l38hfQ3IoauYZgefWDM_YFGx1K4BSI-faJXNaCX1JYq9zKxb_dzM7HGrrUYw_gafaLFBGHHjt2GDInTrHPz8EV-_HMipvBt8dSG0gx9zqnWi1CP5PbhQIAB8hQGc9lRg8HvdlEp_KZg1wh-AVAbpX1tKwKdPERDwxqPG6luC2nIwLRGQxYdhGUdj2i21pW5CW2n8MSn77EvWq_vQME7dQmZoEGJVqsR-FE_ZFECgIi2LrTzqT9g5bPOHK66uIuCQcpMSKgPLOCxHh34yN4ualBAb4KvHVp3FZQl0p18qFN214FdT7rZqrpUJRUeiUuEf9HDmPT3-tRN7M3J_51rKyGD-NY3cJtCI96Exh7afLEuHOmqzDocY3dqY3Wm8Kf3UuZwG90Ics6O4_u-2NwWEUAmnqJUYMFASdRIxNJPGXzNdS9nNP0wscoLqbiq29RQDEouNkjwIaA6R0zmzk_f2gjyaRxNpwpxMaRCl9_8eET0RwlmNfWjvsd1rzpJmggJCWFifJyjBDLp-Jq-y8Kho6xYPI2rkmpXx8BsU808FSgzoZS8-pWpVfcv5fSZRi4xbf25NH7zJgItKLIj1KZSQjiyalApyq8Y3dSji0JD15a7am_SiZnchYSadwykFimDUm7FAk8yrkBt_cAHaRc7ZmkeO6IokHCJ6ZgpRUNehlCDSsJQTkwLWk6fMWJ0N-lrQxlCz8DieL4ZG2SNOC6ZuTJXOe5X6XYiv3hz4hCGjxzOSdOtrHkTzpnu8kHPLe6-3n0WsQ8tArv1oDJfJ3_sp3Vk-vXqcCdO6meufp48cgxI4RlMqJn0HxIcay9RkrtHIlcrc-ugRRi_HBYJ4DQFdiA8ahf_1X52OTEzfxw4u9LcdCWm43P2oV4G-eOS6Ej5raIfx65suoePGujXNtSip4qea1JDBZGhNd2wmqCQKdy5A-tBt2eYVpykiAJgLO-MX860RrdJhe7O-tcpLBElnf_R2NrkQyIlKvxxURPCunQp-RQiF4LDRTaojBImvMtS4P1fYiCxdArK-W7YuXyNvQnxoB7MTPqpWx4J-jRMBgdC-pGz6xchbOHST_H3bV9UZsfEUJG9NIwaDVTrc-HqTklIOGzthjG3QjeMEUCRfiO0J3CEK1Q6i7igtVorgmHJkPXrLGJKEG55X-Lsgq0hlgNbtHeGypU0m8mfVBYXoViegrtWeljouz-v0qepaqlgQjsTOUvODCbKW_e7vNP8X1XSfhhc-AKhy5YZmyk6lYY7MP9HH51ZYVZZZIsQP3dTJXZLEAvWFskUz4mOabhAl_zLlF83U34yuhRgplEpiWS-Pk49f9Jk_-vkYpsxx0Vxa8Z1QLZcXWvIN3ceVtJiqFWtwQueXTwkSdsTk3H8jWEkpFXTdRF3Nm30Lfl_qSCDpfX2cvgHZiPhg_IC0ByvBGT7zDuUOCQzPGJjTGAvMdhX57RTfzR6n5GZ62LNkUl2uo6vrjQPdvk5x6KLRR93o2AwbLpubhmWrNozfakXHPinjkKaL7_mRWvkkEeESPpM0W20CDKjEdrGYkHAQMofOf3q6oGoQHfAXTSk1WPWaQeJB7Jz1iiOcYH8IItlUtslba05MI4EcCCBPqmCjCyIvhzpRCxbpII-E72gcAE7y-46euR1i9PIYAD43j6mQv_kakU7mqnp-785YEhOyLukhmliDR_Xr8FwD-OqYNrRKtFOYncozMcX61YhTvb4vvEuxFqoDwf0oLpEA1qQYB-GOp0gIcb0AsX3KcU94oZVL1rEHbfn6oAK-iafHSnx83xfjy6QmhH-Q2-q2M48-CT_TcwYk4trN0KNKdReP_CRqOgVWtui23IcpddaBCQ8qtJbA5WCCC3JyhV7gTLCCMMdytmmbOPnJv1gbnf78kqeC2W_vp1f_hZDBr4D1KhSiQRWMa6GHWQjyki837X60TUStj8Yvx7dl7BCYZ7Qgrs2NQdngJEo1Xe5IerpQsIO_gIxlxPflPSuIPWrYuScGjWWFsyBAenV5mdt5pv4dBi9anJThFHhXlP7uMjDLiIEQjIwpPeFS5IcZEnf7uB0JP1TmkGAwoafHfeMKbhCIrh6jlTFdd8lEKTfAG_5ltY-iqtJPEwL0kXVlvj3NNFopDs1bVLgC3qenJi5QP6oMWefAyKWQO96Bn5c_x-YuA87TJah2kdSlz_mtLDJ-ZioyZlh-ay8_KM74rkNKBm2GOH5ZxDWVRFYJesr7O4kzMETjcpivKjrkYOIuK2fpKoBEMMMsNBmUp---oG6Va-xMB-_rXLp8jVnEM6HPox3_of0NHWQ8UexMN9LW_i7FFUyKxw5IFBWkplGt4eCYNgTGHw3YMuPt1ZMq_26JIAgZtignLF316Dnf9EZ_3klfMFT16ZcE\\\\\\\",1]],[\\\\\\\"4F647F02-FB7B-4661-A489-7338462DFA51\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:17:35.218Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=980255&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,380355409,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6uklvA4YGEfilf_ULcyT0JE-cwBF3CF-THDEXJeLC97nc6KvZ4U9hxTRyulhs_9au6UiDnKfd-eGWR9e-wmub_l1Le-7_h0rt65vPnTXT1jb1I_7jq8UgaKeh8Id9jqy4OEgCvHJFOG480wk4oDycUke_Atype__E61SmdtFhBOdIhx3XMaRhwiNx1MiSy4WicTZdAZA8hDN5Y06hUraRGHtiK63MtAdtJcmyBUcIIzlZgqQ8d8QkuHFr_Qof-g7Yj7QZP_iM9mlqcemSpWWBb7EsEt1kNNtnHey07y_6lwKXH8-gQouzzu-NCF2o-4CCZmdKwCUDy8y8CKrk3wUGZpPt57NLVoueUlQOUWqkwXwMJ-QZCs-IaNeYIjDWqVoBhyb59lfpJ_j6R3mZE3a7ckn261u3_Hyyn6K1McnLRSV5Yd8WHfoDu2yx0gux_Euc-B7XlJixgxxywW6y4OQG8kUblL__Ez4T_jJ8cKaDE7txkduRLZ7XYUl0Hxk8VnGv0kR2zUhnw0EJqKMxAyfTvF_EDf7ijCS4SrZMuWxidG8cj1yJEDpxGZGtB9AAp3_UuTns1F2G2kmuC1YGF9Ou8bKY3KtpwdJU7eE2lusOHJ_fkUGkHyDP0OOKSbgRszytmfn-ctEPsYpewDQh_9ZT1ONrKqIgG2yYxgQIb2expvFhd1EXlCzmJurUQ-VJi_2fSyawx0QoPr7hA0Ip29C8_fZu3w2mzd10IH78SwGgstkbJCZ9aXweej9sv0s_ndMF7UpudIWjPXne6zCbu_XersIuAuKxiYMtyZcRSxZX70aE_ivDWdHjlkTJLOAvZv1PyJ6RPMT0CTuFArVinBj0lDvqp9vPgkOQSeB2c2J1HjQ_Sm6uvmws61OpNJBN9dSXLmOjlPw-UYcKAN-m5NxxKkM0Dhf6oAGMLDcV8ZhHFP0dvHnnuKDhqXh1JmUyrLw-6AvY2ghkePD3fuPxtKvVOk8uLOEc-HZ76ZcLwlrSsQQsJetguHjl6TTHTs0KF2mg1COuUwFf5mKDwXTaJTDvMgD5WR9axcAs4L05zekNecdRMm0u9_5QPb-N_qOaoxBnf0697YU-2AxftNHdvoP2Db1h5xHP6FuvuqTqXjUwDXhdNDeKvz5XW2dNCXaeTw_tkr_i10lQ2VfLgSZPfRMbwXAZOe7iOEGOCzijn1etW8Z5cHD9MBRv_w1dciX0dptz1isrLdqHKl8PQ0UMYHE8EUJ1eHW7QNtCNZeJ3J51GazmTo69XpNfUb2RE8fS8dwXeQgkm9kVMh7Gi8CAYzH0RmjoNvLDSfEzCpulResh-kgiKOFqenTjw9xn8fcTerFMlViUYlknrfpUjDjR6reGyLBhYhDx1p8sw6cybd5Z7FrVf4XR3Ii6jyV-RZacoP9Hd5qsY4jpjGwY7ePuUJwlQlVrHMRspug0wI_04Hh8Doqk-i0DVJOmnDlWdCc2cQXFwYxQ09ErME0oT6i2TCEH931_NZm9k_mYQG4WN3e3ZKg99MIeJGSiojbMMrpl9FfLzea6QL2ILKIXu9a0Szw9vk3oiNxfbABGvgmZDjFvQeOvWzIDFPpCRZT1JlVZAzq2KlRGq2vVyPPiUE7AX9Xy_CzEd3vJPUw2SM3C6saGpX5LqnKLRB_BSz-nmmwnHgVgq_hK7v0lCuTJWJU1W80no3cg5H4od0aZm6g7Dxlm7D_0gdpLUD7kc5bwruwcNlAGFMjpK5TFpmHKXOm_Hjb16T-5p3u31hCeNZh0v9Imhs1s0x1fJ3nVWsoUZ1xqqvFaL6xiLH1KKq3XWeJ7C-6TtWGNZZyaQqEc0Ur-lp2ppyhXC2KFIj6C5gRSY35Dlq3zKQ0O4tumidTDUSngQmaDm4VvrJLr9i_OHCNC7Jaw10zBhpaN9vWJN1v6cm81SSzjXRZuwTMtZhEw4qblW3VM40PO0Y5Xoy6f0Tv7VwudbQDXKSQiufUI_rXiM2eA0eZ1JCvEPozZGFbK914EUFvVvFexLx9-IyZHY3vCURnrOwWSWHglnIfwdIWFd7MtcBWQpu1tcYM52Gh_E9YPbhyteOyYSY-otLoww5seyiqR0QeCZ6z56BX5mpksZySsPbu2my-kE31IiiNfuhCRNU_xEwWHcdzhO_tbwH0X2MS9OV6gihilsYqeu535wInAHHDWpy2YWpiNh2virDNK8zufUWNto2HTXmuCbx71eNUybtLWTGihGFOxY2RgJBJZX9P0MFLQIFRdfw3JNP2LIgBWsEDehu320Lk4o5hj7FxwiFl1CC47QBltdFTJO90ciMRwc5xXq8fKgjblSyQKFfz9nA-HmXzqKr7MdCVHAf-b-9cCdz6_kC7QylFjdQPMoHpDIqN-kyRe_ukPM8uEoanHBe8la4FZ8oHd6f8mT5Q99il_D20l2-Im_zmfolI06HIyvKRFCuIp4B4enlTAfc8k7koUoa6qsCgOxRvx_rrrCjZ6wpfYlPf7y6CA8Aj4jZ8FengMg\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"23395401-5443-492C-A5D4-E891AD4BB9AA\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6uklvA4YGEfilf_ULcyT0JE-cwBF3CF-THDEXJeLC97nc6KvZ4U9hxTRyulhs_9au6UiDnKfd-eGWR9e-wmub_l1Le-7_h0rt65vPnTXT1jb1I_7jq8UgaKeh8Id9jqy4OEgCvHJFOG480wk4oDycUke_Atype__E61SmdtFhBOdIhx3XMaRhwiNx1MiSy4WicTZdAZA8hDN5Y06hUraRGHtiK63MtAdtJcmyBUcIIzlZgqQ8d8QkuHFr_Qof-g7Yj7QZP_iM9mlqcemSpWWBb7EsEt1kNNtnHey07y_6lwKXH8-gQouzzu-NCF2o-4CCZmdKwCUDy8y8CKrk3wUGZpPt57NLVoueUlQOUWqkwXwMJ-QZCs-IaNeYIjDWqVoBhyb59lfpJ_j6R3mZE3a7ckn261u3_Hyyn6K1McnLRSV5Yd8WHfoDu2yx0gux_Euc-B7XlJixgxxywW6y4OQG8kUblL__Ez4T_jJ8cKaDE7txkduRLZ7XYUl0Hxk8VnGv0kR2zUhnw0EJqKMxAyfTvF_EDf7ijCS4SrZMuWxidG8cj1yJEDpxGZGtB9AAp3_UuTns1F2G2kmuC1YGF9Ou8bKY3KtpwdJU7eE2lusOHJ_fkUGkHyDP0OOKSbgRszytmfn-ctEPsYpewDQh_9ZT1ONrKqIgG2yYxgQIb2expvFhd1EXlCzmJurUQ-VJi_2fSyawx0QoPr7hA0Ip29C8_fZu3w2mzd10IH78SwGgstkbJCZ9aXweej9sv0s_ndMF7UpudIWjPXne6zCbu_XersIuAuKxiYMtyZcRSxZX70aE_ivDWdHjlkTJLOAvZv1PyJ6RPMT0CTuFArVinBj0lDvqp9vPgkOQSeB2c2J1HjQ_Sm6uvmws61OpNJBN9dSXLmOjlPw-UYcKAN-m5NxxKkM0Dhf6oAGMLDcV8ZhHFP0dvHnnuKDhqXh1JmUyrLw-6AvY2ghkePD3fuPxtKvVOk8uLOEc-HZ76ZcLwlrSsQQsJetguHjl6TTHTs0KF2mg1COuUwFf5mKDwXTaJTDvMgD5WR9axcAs4L05zekNecdRMm0u9_5QPb-N_qOaoxBnf0697YU-2AxftNHdvoP2Db1h5xHP6FuvuqTqXjUwDXhdNDeKvz5XW2dNCXaeTw_tkr_i10lQ2VfLgSZPfRMbwXAZOe7iOEGOCzijn1etW8Z5cHD9MBRv_w1dciX0dptz1isrLdqHKl8PQ0UMYHE8EUJ1eHW7QNtCNZeJ3J51GazmTo69XpNfUb2RE8fS8dwXeQgkm9kVMh7Gi8CAYzH0RmjoNvLDSfEzCpulResh-kgiKOFqenTjw9xn8fcTerFMlViUYlknrfpUjDjR6reGyLBhYhDx1p8sw6cybd5Z7FrVf4XR3Ii6jyV-RZacoP9Hd5qsY4jpjGwY7ePuUJwlQlVrHMRspug0wI_04Hh8Doqk-i0DVJOmnDlWdCc2cQXFwYxQ09ErME0oT6i2TCEH931_NZm9k_mYQG4WN3e3ZKg99MIeJGSiojbMMrpl9FfLzea6QL2ILKIXu9a0Szw9vk3oiNxfbABGvgmZDjFvQeOvWzIDFPpCRZT1JlVZAzq2KlRGq2vVyPPiUE7AX9Xy_CzEd3vJPUw2SM3C6saGpX5LqnKLRB_BSz-nmmwnHgVgq_hK7v0lCuTJWJU1W80no3cg5H4od0aZm6g7Dxlm7D_0gdpLUD7kc5bwruwcNlAGFMjpK5TFpmHKXOm_Hjb16T-5p3u31hCeNZh0v9Imhs1s0x1fJ3nVWsoUZ1xqqvFaL6xiLH1KKq3XWeJ7C-6TtWGNZZyaQqEc0Ur-lp2ppyhXC2KFIj6C5gRSY35Dlq3zKQ0O4tumidTDUSngQmaDm4VvrJLr9i_OHCNC7Jaw10zBhpaN9vWJN1v6cm81SSzjXRZuwTMtZhEw4qblW3VM40PO0Y5Xoy6f0Tv7VwudbQDXKSQiufUI_rXiM2eA0eZ1JCvEPozZGFbK914EUFvVvFexLx9-IyZHY3vCURnrOwWSWHglnIfwdIWFd7MtcBWQpu1tcYM52Gh_E9YPbhyteOyYSY-otLoww5seyiqR0QeCZ6z56BX5mpksZySsPbu2my-kE31IiiNfuhCRNU_xEwWHcdzhO_tbwH0X2MS9OV6gihilsYqeu535wInAHHDWpy2YWpiNh2virDNK8zufUWNto2HTXmuCbx71eNUybtLWTGihGFOxY2RgJBJZX9P0MFLQIFRdfw3JNP2LIgBWsEDehu320Lk4o5hj7FxwiFl1CC47QBltdFTJO90ciMRwc5xXq8fKgjblSyQKFfz9nA-HmXzqKr7MdCVHAf-b-9cCdz6_kC7QylFjdQPMoHpDIqN-kyRe_ukPM8uEoanHBe8la4FZ8oHd6f8mT5Q99il_D20l2-Im_zmfolI06HIyvKRFCuIp4B4enlTAfc8k7koUoa6qsCgOxRvx_rrrCjZ6wpfYlPf7y6CA8Aj4jZ8FengMg\\\\\\\",1]],[\\\\\\\"605BD248-8FC6-463A-AFFF-62DCCBD536B0\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:17:45.230Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=649598&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"BCCCC76F-5DAD-4108-BDBF-A573659D5F11\\\\\\\",\\\\\\\"65E09B71-65B9-4329-8CCB-C4B22874B537\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA59Vfjg1Okyx5NOcJRNVQWXxrtlYvxFe7IhMdB1cHcku6NUx3v2qKsV5nt6IDot-c4eNZOGaIcfz-9QIw3iYJswPbppYF8JSnXZM7utSR0syCXcN48EAAtM21XEbA3y2I_8p1sxCzZ41dDAhYVLMBiIkVe2UFUpifx8BJgHpuLYugoN_X5AZPE4pe3SE9947DLjeCmv3Aq9bgveYHRcDQHfuFWnMRktXgcZvgE9wGliytW8kN8nvZU8_Qb3KXkysAGUQHbpPZkBBxjXv0c3pk_5DYbvfg-Ux-idF8D5j3RTrGbN88vD05VifmLHWeGOXuTje1zF5vpK1bzPjwfFsGda5TVyXzr5fSKQ1igIt-W240D2uYg9Y4HRUDui8DK4CU5P8sjlRuhxDUAjePkRR_DwJNTp7CIDPyTDeyrR6iI6GmTqhUjwnnL7rz8PCguVJr3nYEV4m1fkTAHQ3GJ9nFPELeh5PFJ2IEuqydhB23sqctxVw85t2KPU_lhM7yqKw98kQL0TPU8KEDUjcXYrC6_YX004fUJl29yWLBD1SKq0HPKrcx0o5-XsYyelThUhQA_kAOZ_O9ek8BqgwYT9e4xQ-aeEmxTghlXYVObhOx56vEhbCptdr8YvxcVdZDIe49Jl5Ko-nlbbityy-ciVOQM32UvY8bQ7xMR2TxKT1EqCA9y35LkT606x36uZcxt06pRE7BV6m18cOdDHP7RFQR7UuDhJ0D2e4Hq9V409H1bFxktlsLx9qthaVF1mCthTywXX3pgUiZoNMaLJh02OlLrVDX_-i0xRgSPraY99u4reqppao02mBnlgi0Z2_ItJHig9h7tImA-xQ_dajnKHpRRoc5KUymX2xz7SbOvotWYusKUPsEF3luKTzAY1T80JyQlZuVC4hcCxzKhpOHB0uV8-TChwSf9GJhIxGmHbK-JGU0PEYwWOiTCOv5NRljcOnNuDXPB8Zac3k9aSBTIXjzZedUKGsJ8u7BTQhSfWBzfPRfFw8q1DxYjCqX3uYMkj6uv2w93DFCGm7iKVPk0xkVKBPA_gkkBYxK7jcZdqV-c10IgtkF2zWhr5fotOHdDAXmqqcGCKX6UjvajtaMI__FNE85_I887W-DENQkLLWcRjRJoHQJ2S3Bp1U39iCEYoO88pdPetn6SSnBB3dGtTO28UrUwTRQx7DrHUy5aIKF2sDFOKg2Y5PDKYNc7THfJ-urbs_bbAZbkjalOgcCwbaew7gcxkJc_oJ0jfBXzZLb_Sv6Hx6LjEwpe6uNOCjxtL0kDPV9GrHb7enGfPoonQTnCa2S1lUPHPxhZCvP5Z7SutG-bELKYGk_T_vEGbDSRD5sOeg2uvwxvVeV2qECBfzF6Jqt1bgIT3BFABdb7Q_P1nR0Yr1YrGHQLc1sxTZRP0W4IGWHf8L-5BAhGAX-U4nsIHvgZFdhIwCrgLg80ZxVSmjVIJzr6Kmji8Ms_siGU3GkgihU98OA2qjeyZtqo4G5QQyXmzDG3reVkeSnYyndkWGteTzBxWzjlAylq3vJwVqQwxfhCAZxWU7rnolfdZd4tYbjzw8lSBX8UfVNrxayTBLzHY_8yY-q8heyiyP6VB3fuMMM_db1rjWwkFVDgA88ulFLAcuGME97YErKDvV31eBwaEzHNGKwQYU-P7FJ8pwgqDNSMejaH8xO4uLIp8mhsVFleEkBOU5WwibKaHsZNSDxyeLGelxnyNPBZqnuugKUcBpusWqe-3IDca8pFYIocvTSQ4JrZS_QYHcUM6Nl5yeFMtSXTOcp8FPrV5sHkBgxgyf6_H4enQGnCtx-smL9cJcdJGH9ILb4d-FZNUahg1zbhJmYJuiOj4m4lIdUkNSe243d7rg2r3EY1JysJwklzhrVn6-zZ8CZWtLoBHBBvDBm14z394g-yE3pacDTYv-CeeFzEYUoQiixeCzJLHhGtzMQh50EmYwNGNMsS7VLa3K6sEFb4T2eTnhaobAI__U9nFzsXzCq89GwvpWsapodc-GScrWwEho_ajwkSiJ-FRgfghvOWye4SZXojr0lqiFaCpDSheoIG8Y-ZVws4I9uyAwPK9J1z4LqvDt1p_4b4hFLj7azP_f8fxWkRmxaax2HL2FSrQg_PUmYjmzymRThIXR0eY5DUk4xoBG92HVBELISiRjhBkct3fzMssM-DXhA00ZgvgDjD-O-8Wsy3ifkpFG4bYU6hnLQV-UkY0vTB8bdATAXDJ68coUxcmbO-Os4rI6_WRjLwYRe5qw0QurbrthW527Qn_hdTQIlJNl0j4klXiOk272Ih9PlRFncn_KSQmZuB3RZyVRY_oRzNbJDadkK0wl_WALpoeUKAxMyNsejb4dOQAB9u2Rt8rUhc-sWUvJ-QBVyhHm9hfWh2gy4CAsONQQ07NpbIfPS5cBwvDhQOceAHHQgZaL8UAzTEuXi3IO7LyieijHEelS9rtUXw6HTdUNQNdZ4r8cQuhUDfn2StIm9tjKSggBq2_9fepiRyncM4B\\\\\\\",1]],[\\\\\\\"87416079-1A82-44CC-B790-47AEE97C2A27\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:17:55.238Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=973374&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,65089712,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA54UNLpEh3wEebfBZxNXKQ2AWUqrf88vilj0mVClw6TW3wncrui9-gLshOKj48UtsNgkLtOxEvWCGz1vCzfUvY05F8C_bbRTRo8Ih5TO60YNWDvUjH9QkvMViIbH3A3u1X24eSxjhTH1DvqeZgh7h4OKHxhXQ7rGsdWVqhFbowafddkw7t79a_Syq7ZuFu7DCKU49mG5Fias-j5qHzPvMmXJA-9yMOWvcYlY4Udh6Z2pwm2l_NjKRCOJ0R1qAmrds4achC26MBTMECyT3WD4T0mjPCylNegXsQZdLRjgIXSGnwHZUttVdMGazRnpHTLpj4E-OuiU9-N1uzcx9a8X7lPL4w4z5REyG36kM1SF8LTtaM2OjeU7VcsAx58Ro4Aqu-juOSH4MbXNI1_r10SCC4zYyAgYU7M7YrmlqzoE7GfGBd5X5ARliuR6KqyQWir3gkX7SOz_Yshlp8qI2rUqgZeia0XC0jGOlAFeV-tIhlTT9L7wy9KfhRG0YKFuI4tllb3KoBeIh3T41EjLQZHcM6VOC8Xl9pLlMM5zv3KuI75HHLFvosIHnML0Slap-jk3uRRdrAV-nEIiOcLxTT8txi0pBJr6pu0TkguL5wB-XiPUM4585CL_FT-H9Cg_He_y6EdmB2Zoai9mlPG0sjUXnDT3JvB6Hv8TTKlDMryyacseODTAEyVIQaCKljt06H1MiMGpbB_uu2r1mGpp5Kl4whYjI_SvDtA-vQb9lMXwCC2ik1kwpuISJ624FQKqLL-ex7xQ1fxU0x4ObxFQHuljiOWQb25FfBbwRplqISUX8WJoXG4kfI8bmSRwRInunbyPFn2vl-OsKCJlzq_XPzooXTgyw8gPpT3YlvXdTJjLdTrpLVgtoOIjDmfFoE9TG1p3iYvHgw0il01btuKqfARa-5Lm8SLnkDbVXk2TOsc085jTPraXBAeN24ZD67mhQMsjux90D4wT2I8WrvICtRlwXwtqDI-yN8nuyQmVwc3pJO1_jvIQ670b1MvAgPf6qs9_Vd0wIn9q9bYr-3RY40pscapP6-jZ8GydKpH9nnOk3Bp97WW8nQYTdct-ql9kYuGLBXtwA8AIUNGzL8LU3ymj7AIAhVD4RXVLYJFLnmAgJGLASC5wSSX_nILFAa3G_FKAozmHm0BgEv-jSADpYpOH5AgIzCjsgAX6P26S-gaVnQRxoFZYyLQPzl0IqH8Lr4nbV4QCgFL69FcFmz8QfsCqzWQVdSR3gEKsvp3VoK7pHgSRVFjRcEV2GtaDkQRh_Lf8xuxbjb-Zsk-qg3GsQiZk2JA-VLD4wPkoQvfvdQnyD9icSp3UbawYo_kGuRBmbhGgkZnTPHu4AdIXJwG-DhsjZnss2OdqZwF_bxH9IM7_9OmweUsnYeOoZVoennPIOB3RJgNs2G4IxeOWTa6d9Ymnsv2u89097ShD00YK_pWQO2beD8w94woE-GsFK3juI12_X59gRPHUSMBorx6FqRJrPxLyxPhcW8B5IK1vjWCo3WRxz5LqK0eLQeFtvC8PBOEvUAoW8pvLx3-4Ru9-JgJCXSpuDqaps_VcllA0Fg93fGXP-t_nVDd8hc-fhiAbUfPJN4ZO3prfDuRsp6TWGYoMrsL8iozg8HGng4S83jKcKT7wRLdIoGSpyZPBzQMdzdDxmNVa_5XLh-9GCYnObpvVmaglScClzOdcxVe66g2vGMKNr3EamfgdjCTlkRCyVao2W60vhN91Xz6px-TzaICotojd9i2p0jlMwi2MSQm8-GnULvwhXv3z9J92PiVr7NqDMBMOKTs3mj6AFXkKvGfUUgqNlxixyB1iputyYOZb5VFWmN9vtwjMm-qml182WzkA0FmyRTudl3DzJMomHjvFI5Ng1JWn17q1Ubf33YbjCT8gU3F_3lvWCxT4VLqGjFZzY8HUjyBMG85QmIxusdRZh5OORuZW5_n0gK9RE6qk-3ViCX6c2ZmM6Nb78XXo4YVdqqbT3phyIVeNE1yTDLdOUHYxS4Y2r4VtpAWXfenufVZ8TuV5Q8PGV3LGjbnSblEgWeBhAZSRR5YwJaFtHn4ACocVuF6kdWMavawEyk9DgDvQNhx8u4AXIYkbrLwJ3xadRawdPR7gYLm8o98aNyLG0xxRSORAwDLP1dLU8w3buDQ0_kcFf0Sx5FZzJsT-gE286quLlAibKZGsdvsWwgvXWjsSajjGd8N0myAJ6hxaYGRIFYdDsGUzxOIepGf2jh1h5RlFUhOViXeR3YkUfOrp-IA-c17HVAOXLGcNv-cpQqgfLNex6qGcNGJqiYFuPh21FMkMJkhNT7Ch85DZKFpDCAGFlJH1q0hoovjscUTk50B6im4mGHVeiYE9w3EXZryNbh4WapqLYI2YHfe2wCJEobwXN4lSfAX8ByyUk-igewZB5gcSu2FSS-375-HXGAMFZc4o53HHkB182nXfjfgLwRhAA2sxh7x6LUkn_2_gKM9xQd0pos\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"22BB1624-4E6B-4E41-A1C7-B6C0DCE9E5B8\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA54UNLpEh3wEebfBZxNXKQ2AWUqrf88vilj0mVClw6TW3wncrui9-gLshOKj48UtsNgkLtOxEvWCGz1vCzfUvY05F8C_bbRTRo8Ih5TO60YNWDvUjH9QkvMViIbH3A3u1X24eSxjhTH1DvqeZgh7h4OKHxhXQ7rGsdWVqhFbowafddkw7t79a_Syq7ZuFu7DCKU49mG5Fias-j5qHzPvMmXJA-9yMOWvcYlY4Udh6Z2pwm2l_NjKRCOJ0R1qAmrds4achC26MBTMECyT3WD4T0mjPCylNegXsQZdLRjgIXSGnwHZUttVdMGazRnpHTLpj4E-OuiU9-N1uzcx9a8X7lPL4w4z5REyG36kM1SF8LTtaM2OjeU7VcsAx58Ro4Aqu-juOSH4MbXNI1_r10SCC4zYyAgYU7M7YrmlqzoE7GfGBd5X5ARliuR6KqyQWir3gkX7SOz_Yshlp8qI2rUqgZeia0XC0jGOlAFeV-tIhlTT9L7wy9KfhRG0YKFuI4tllb3KoBeIh3T41EjLQZHcM6VOC8Xl9pLlMM5zv3KuI75HHLFvosIHnML0Slap-jk3uRRdrAV-nEIiOcLxTT8txi0pBJr6pu0TkguL5wB-XiPUM4585CL_FT-H9Cg_He_y6EdmB2Zoai9mlPG0sjUXnDT3JvB6Hv8TTKlDMryyacseODTAEyVIQaCKljt06H1MiMGpbB_uu2r1mGpp5Kl4whYjI_SvDtA-vQb9lMXwCC2ik1kwpuISJ624FQKqLL-ex7xQ1fxU0x4ObxFQHuljiOWQb25FfBbwRplqISUX8WJoXG4kfI8bmSRwRInunbyPFn2vl-OsKCJlzq_XPzooXTgyw8gPpT3YlvXdTJjLdTrpLVgtoOIjDmfFoE9TG1p3iYvHgw0il01btuKqfARa-5Lm8SLnkDbVXk2TOsc085jTPraXBAeN24ZD67mhQMsjux90D4wT2I8WrvICtRlwXwtqDI-yN8nuyQmVwc3pJO1_jvIQ670b1MvAgPf6qs9_Vd0wIn9q9bYr-3RY40pscapP6-jZ8GydKpH9nnOk3Bp97WW8nQYTdct-ql9kYuGLBXtwA8AIUNGzL8LU3ymj7AIAhVD4RXVLYJFLnmAgJGLASC5wSSX_nILFAa3G_FKAozmHm0BgEv-jSADpYpOH5AgIzCjsgAX6P26S-gaVnQRxoFZYyLQPzl0IqH8Lr4nbV4QCgFL69FcFmz8QfsCqzWQVdSR3gEKsvp3VoK7pHgSRVFjRcEV2GtaDkQRh_Lf8xuxbjb-Zsk-qg3GsQiZk2JA-VLD4wPkoQvfvdQnyD9icSp3UbawYo_kGuRBmbhGgkZnTPHu4AdIXJwG-DhsjZnss2OdqZwF_bxH9IM7_9OmweUsnYeOoZVoennPIOB3RJgNs2G4IxeOWTa6d9Ymnsv2u89097ShD00YK_pWQO2beD8w94woE-GsFK3juI12_X59gRPHUSMBorx6FqRJrPxLyxPhcW8B5IK1vjWCo3WRxz5LqK0eLQeFtvC8PBOEvUAoW8pvLx3-4Ru9-JgJCXSpuDqaps_VcllA0Fg93fGXP-t_nVDd8hc-fhiAbUfPJN4ZO3prfDuRsp6TWGYoMrsL8iozg8HGng4S83jKcKT7wRLdIoGSpyZPBzQMdzdDxmNVa_5XLh-9GCYnObpvVmaglScClzOdcxVe66g2vGMKNr3EamfgdjCTlkRCyVao2W60vhN91Xz6px-TzaICotojd9i2p0jlMwi2MSQm8-GnULvwhXv3z9J92PiVr7NqDMBMOKTs3mj6AFXkKvGfUUgqNlxixyB1iputyYOZb5VFWmN9vtwjMm-qml182WzkA0FmyRTudl3DzJMomHjvFI5Ng1JWn17q1Ubf33YbjCT8gU3F_3lvWCxT4VLqGjFZzY8HUjyBMG85QmIxusdRZh5OORuZW5_n0gK9RE6qk-3ViCX6c2ZmM6Nb78XXo4YVdqqbT3phyIVeNE1yTDLdOUHYxS4Y2r4VtpAWXfenufVZ8TuV5Q8PGV3LGjbnSblEgWeBhAZSRR5YwJaFtHn4ACocVuF6kdWMavawEyk9DgDvQNhx8u4AXIYkbrLwJ3xadRawdPR7gYLm8o98aNyLG0xxRSORAwDLP1dLU8w3buDQ0_kcFf0Sx5FZzJsT-gE286quLlAibKZGsdvsWwgvXWjsSajjGd8N0myAJ6hxaYGRIFYdDsGUzxOIepGf2jh1h5RlFUhOViXeR3YkUfOrp-IA-c17HVAOXLGcNv-cpQqgfLNex6qGcNGJqiYFuPh21FMkMJkhNT7Ch85DZKFpDCAGFlJH1q0hoovjscUTk50B6im4mGHVeiYE9w3EXZryNbh4WapqLYI2YHfe2wCJEobwXN4lSfAX8ByyUk-igewZB5gcSu2FSS-375-HXGAMFZc4o53HHkB182nXfjfgLwRhAA2sxh7x6LUkn_2_gKM9xQd0pos\\\\\\\",1]],[\\\\\\\"B0CA189E-76FB-4F26-BF75-10B744963E11\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:18:05.325Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=419644&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"933DA127-EC5E-442F-8522-61885748B597\\\\\\\",\\\\\\\"AA32BA3F-E163-498A-AA0C-EAC0680CB55C\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6L05xcvg5LnssrTZ7fF5fE3jlMij1vkdl8NU5lY1I6bUuYO0_MbnBwzfKb6aXEc7cWga8-7Uu88rwpSNNF-PabhR86Yv7H_yyy267DoWoVXNXWy9PdPoLi3CuoE4MIMXr5RBWvFJ5aN4_iwXlPCLP1YMjzJdqJbmNdLXAh7QRGiSvp8UGZE2EguhZLGBsYxw-AGVPCFKBAA5GLG_mvRYIS3bSAJjfpMquM4X2vQEJEziYHZAKfOLqN4N0c8pYKHwp3nMtPA4zak44RAb3l312GTnH0cwDx9FVf0_i0TPb2O1VlCUhULdhoBmlz6mSooj3iVtTidqd782ak2aA2rYP1-OnL0U9x21PCp4NYmgJ7pNAbp5MicJ4NeDxz2dpijTmqmln0J-NwndCru0lHsQGXHQgm3KkMYdKkklZSmO8Go6sBgItzLlMPvm9fYuUoon0D79Q15JQgSWWruG8hyaPVbomtNjd58C8ByluDelXZeWvWlIDjAP0PM9oX2Ad1HLQZPJZdPVV0Jhiid8n_PQj4NqrWmvuAq-4ewRSI_VI1DrjfVHYFMvW4OIwgoOQ-lq9Fa01AXA4IkgKznYhTO_9nsjVIiGIBBlYQruFSuU4t2-9yaE4HuLmXcfbOgbSyqX5ygdhT31IQdZyrV9z2O5vT6fYuYV7otLlKdAt0w-juNF1FkZ84h8tIi2H67zNPxvTvNWwEtXHMuW5GSqQO3V_bXJImsRL-2cJxjh0riz_PZ2TujMGiEVwm-wD6U7UqWn2yyPil0PtIe7uDXmdyeD_ZQEPEz3_EszCu_zTxj4IRsP_gBOfze1ynxo866aaLw2-ohOfu7MdakrCGXe_QWVn1e0xeiY5MxrzccU_zh_gi6zsM3RCkuQoAnHLghT6DAZTbDkb7_Cr50v3BnqU7vHsvpJbjgXNm-4hhSc2O4TvsrYnf9dbPtd-ra28ZD2FgtwW8zO-wW3gdwJ_58B6TdLkP9hjuTvN784IYOnc64JU2Eds-cNlSxJ1qs-YJH74d-GPSpIEBkd3tu6VAL8Foyxi90M5dhDa0aNrMW395w3eSHQxmNIOoW8d2AmHjJS1xLP44R7coOZ_6gj9MpriEk5Xksu0ZFJ48vKLivAkBVsrrLNB7u2gmiW5JbwiFILBHBNgAgRv5tisHxnFkWWR3EiaK6P6WmI1Xr_1Yq7jc7TFwNy4xtXw-BdSri2NWdw8_lkJ1QwvDHygwfewjsnwBvDNLtokwaVYx9xMnXSIoYHiYIMmUQnFf_XqNYOaNaweBRAhU2m9fvJpqXqisx896Y2wh9hdxj9FBQRHDHpzcqHOUuG48xaBaZhrusDqte6PJ6OkLd7Gf33N1o9CWGYdnSgXrXeS54rOeuE7jv1K3Mn6j7kMclGi7dcIIIQSojZWUaFt580IGNdt5NH0J-y3zf6L99Ttzv-0yBV47YMfBqJ1EgQuHuEFZC28g42VsjBN1g-i5fPic-k8xc1VjtsT5USMVzMPIlFP4MnXQFoiLVuIL6UUnnEmNER-byOLgftvl8vmHd-nW9qlHqhX5UMv3sMgSSi0nzWdCZLTnXQsOBtIQCiqb1v9IjiH0L5Qgz-UnEDOvnW7S0KbEaFqNOss3jPoN2jvyBvThxMm4xEdWzbX7lcztuD9DBoj0Jy8r9MoGWGbhN005T05Ub_kaVv9kwMNYjocMkz0XeqpfcRfkDj_4pX37NErAp-5gKZKssE7Ycu7J22hJHVNCMaRnjOWHmxxM3scKnpJyMg55sAiSlH4JsELNMPuCHv4oOJRih0X9nkmub4wUXZaxoe9W39LZDmMSR3jPXijetr0TRdj4KXNtt3UX5bcpZKDYGDeyVLSg3j0tXmFUbJbKQqmXFgpqNabKiVPISgvGorA9PHgU31qyyRfZyfS795V89WokvQnn_46-_NhptncsPXMjfVACbpg66fHEH0ov7r-k4FUDWwU4u50u4fqmD9EdXUdSBRfSuDN1Im4uj3GLv7kl3OtV01JOgr-MVLqGpXpcgKKLRpY2Fc6iYg2Ly8W4DVu8QNx614483fisJEurj9k0sq1V-zCJBaUeARAeLn3wkAaqzn-t9cPFA75FEI1EG0zS6deNl4803aa81ZlbjFml_fnZfoXtS6svbjT0ZWlWpxo4JJuZXQ8NcFSDGnrSRHLchiRGlueLIWyztm8_jpGmfhNXPwRaAeVLh1yup755EBryFR4lsnpB9xT2SpMdIBqkwDkpxwnPHOn7aOoSqhnGk5lZ5S--ZeLjEwTQVe_jjScVR9FpK2edDqRbbOCjHg1FG_kqR3V1qoRBe3NpdETKgxsJY6PJ8LWJiigcSZh2Kcm7pINtf1TlkzgdFTlLjvKXhPVPwXkCDpy5dADbyNMC8ZJ53wfOSVM1gbHs7fuTyGH95GDmzGU5wjonv7tT8wh0tB77NwjlYonM55ji4DWXxMdTI3SHLJKPdEaqg0wlMfBONYUVrTxepSG316pjn5k-Trkg3LgCWeuV\\\\\\\",1]],[\\\\\\\"F32A9549-CBA2-4B1D-8B6F-D1EBA8D2DDA0\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:18:15.325Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=395153&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,534010413,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4X8M-bCsdWJanNSAFjtyzBoRWgLUCS5g59UWldOFPGSO0Y0wnQCYksNvjcnsWTMKXrUlrlmWF3eV1HcstBD1tMsLWHX7-T1sKBL63S8oidKx476e0fEHH1naTGH6grZp_V24Fh6682yO4yH21_RU2kbyttt_eURAbLxLdRFyTPBWBa_tPvcSiZE3ciOvPbEpFaiL3id8fQUI90g574r21XZutHvhFv_Myol2S6M2NCmA3FM-feGJDoqtf7EyO4IqTT5xicWbk6LEJcfowB_Zod1StWuGech5EullKyLjAuVaKr6ZxlN_Y96BwH3oL8XAcvTq6uo7CvwE582qrR4EZkXs4mrdj_GfiXQRcE9NS5Vdiiu3XveWvI0wGu6-oKghtjjEkFGMRW-60kseVR8nnd7Uca3l-48ymoCr4KSmVYhimEwkxFrU42ZTaoDrXBz56MD7QvK2IgG9hBmFNa8H2cttqEOKTLcQ65EzuAOJLfRq9kKKym2mECJ6LgMruk-yvj_-CeqcQ8PE8DGeNyMyK15MljMnFcgmkd7HnbxwvUjTwPx4lMXJh7hVlzItABBnbSSu7PB9gczke-Nj6QAhXS9qdEecT6k9rzQcLvtzaPQ2E1p0XxxpV4bqocYSke77fPOsJs8GM5rp2Dem618JC5m4NSSVN8pmfP950G7vm7z9GbD_yImE8nxaXMtQyKdNUxHuKplYJnun5FBqVa7Bo3GzlsTh24QVRt7jjnWhjEvM1jAda9hUZQWrPc2lFMOfTLqLngiRWaEIOTsGkj6KLKrROn65dKI-lGnqVtf6oIcLmhU_1TQChaA-snA4VGy15wrjVxr_hK0_mdbjruOEMnxlNfQ6JGgzk3L9yhOpRVl_nKPb4ee9CffE1CuYeJbCcOSeta61YNLkn_3uad6WdUBp88yqXQ59AyMvStg1s5jv4pYhE-GgOL5Cf0aSRGacHaaStFPBhjlGTvVZ_hfhQEZkfA42zUOQVF0oijoE8wb84atJgF4pCGKiJ8bhCMtp9q4rGEQwncOpHtUocD02dJXGOK8T1I7K6fOPVBsaVlDuffsAVMnDlDNQod8YsTdDeZYMIRUh7mQkCOoouLjHqN5Sn6Vkecq1wLyexRRiXKd5mU_WVg8AiWRn2OxTVJVt4X3cJtCWYSK78iV35Tz_YeZJNv3ghiGlqq63hpsUtAjFRenzY6ITvmpPaDhdqnhMaOhvJ_V23C_LUkzaHqGrHnd3Y7iQgaBgxA7yAUKJpt6ydFsj7bsREos3yZHjsiHddYt8lGoAjFHeEZ_6mbzmNZCcrjZs1YkeeTJvT6l29_ROybG61F0zOKtba9G2-Jqau9msMFI7HrdoJKVseJ_8MJBBiaJWfQH3wL5HSkG6zN7kpOdthemIV3nW5OJigfHirTd9PMZu2xAZgcgAwGmGrt4qzlaAtKTCLbnrolUmFyIs0y6sFijSdm1bt8WXQoIeY_zNZ-4GDHZFZ2c0qHa0wOhS2GhMXYp-OHrkJIrw-dHDkCTe8VjdNnbtWRsuzLAGzXqgdKA8g6TZQjX2sqrc5bZQjw6oaeb1rfifFxzdIh3s2HAR7dKpeKT4BefQdw1_RxsmT3elVXjTwnnp8qBEX-DnnKRjG-RHo78Yhw4pzi4oGolKeLeKKkHrImAQo_KJv818HHWsJhyotfQSpqldxf2FUW5bFzWm9rA4na6qeAhynRlX1sR62LHkP_jDE1rp-uCePHZ5Moeu5bzd-QZ7nOi2F-uJvspRdj6iVSUAZO--fKq7q2VR8ubHvW8NglBteIU38UG4wwoag72qUxR3MutrdKuxrG1t9-WXTkDVseNtv7eYBM11_g_a0gIZsa7k3ZY813VzBlyKWf9V0ixtdvHzRmS0EoDbMdBqP8FINaVJkOuVhJ2W8u6LpZ1b_oqqhIvhOj0V4XyBhUW4Kov2SeqFoFbAEG39bs95KlUpW2jPcVME8BHvsOlKPURz1FrKp-TEXvhVYT6X0WEciPWrMKKGnKwFfe3UpOUo2965nS5S7wpBF-caB1AaFTnSjo8DnWhCqPygVoMurGsO-mIfWQ-Om9NvwJ-_zjovgZmppLrSyfZmPRHObPkKudyPb2jABm8KKQPP7ZY5GP1Y6k3wRfdCzhCFs-JPh-o3_TEEN07aSuRdHdRi4oO3FcWEq4xOB5nXhGTs5oOLIOroDFLcxiQjmm_0GqaRUTY6d5wZNlz__-6XjZuqDiieQyDUMbqS3EmzMOs5QIDvCpwKOVM5hmfmhPeZJkfZ2gsIrZN750kJqxHXdmMuk_R7Omen7Kj866n7Rcs5iCh-N9GZTOW86dExnwuJ6B7vP02HM89izEo-DAzkV65veQ96wbEM0NN7eNFQpydSHJMZAl7UpMV-tb-s7UD1D61-kMNLhomha92Werp-EG6Pt0uh1MgXAKshEQZtGxcIkYAtHGHiF9Q5acUMMEsv95glNiX-LKwIyxWe4QbFeLHkTIXHb567DZG-ekxs96\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"92035A04-240C-4F8E-B787-6E871AC32B61\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4X8M-bCsdWJanNSAFjtyzBoRWgLUCS5g59UWldOFPGSO0Y0wnQCYksNvjcnsWTMKXrUlrlmWF3eV1HcstBD1tMsLWHX7-T1sKBL63S8oidKx476e0fEHH1naTGH6grZp_V24Fh6682yO4yH21_RU2kbyttt_eURAbLxLdRFyTPBWBa_tPvcSiZE3ciOvPbEpFaiL3id8fQUI90g574r21XZutHvhFv_Myol2S6M2NCmA3FM-feGJDoqtf7EyO4IqTT5xicWbk6LEJcfowB_Zod1StWuGech5EullKyLjAuVaKr6ZxlN_Y96BwH3oL8XAcvTq6uo7CvwE582qrR4EZkXs4mrdj_GfiXQRcE9NS5Vdiiu3XveWvI0wGu6-oKghtjjEkFGMRW-60kseVR8nnd7Uca3l-48ymoCr4KSmVYhimEwkxFrU42ZTaoDrXBz56MD7QvK2IgG9hBmFNa8H2cttqEOKTLcQ65EzuAOJLfRq9kKKym2mECJ6LgMruk-yvj_-CeqcQ8PE8DGeNyMyK15MljMnFcgmkd7HnbxwvUjTwPx4lMXJh7hVlzItABBnbSSu7PB9gczke-Nj6QAhXS9qdEecT6k9rzQcLvtzaPQ2E1p0XxxpV4bqocYSke77fPOsJs8GM5rp2Dem618JC5m4NSSVN8pmfP950G7vm7z9GbD_yImE8nxaXMtQyKdNUxHuKplYJnun5FBqVa7Bo3GzlsTh24QVRt7jjnWhjEvM1jAda9hUZQWrPc2lFMOfTLqLngiRWaEIOTsGkj6KLKrROn65dKI-lGnqVtf6oIcLmhU_1TQChaA-snA4VGy15wrjVxr_hK0_mdbjruOEMnxlNfQ6JGgzk3L9yhOpRVl_nKPb4ee9CffE1CuYeJbCcOSeta61YNLkn_3uad6WdUBp88yqXQ59AyMvStg1s5jv4pYhE-GgOL5Cf0aSRGacHaaStFPBhjlGTvVZ_hfhQEZkfA42zUOQVF0oijoE8wb84atJgF4pCGKiJ8bhCMtp9q4rGEQwncOpHtUocD02dJXGOK8T1I7K6fOPVBsaVlDuffsAVMnDlDNQod8YsTdDeZYMIRUh7mQkCOoouLjHqN5Sn6Vkecq1wLyexRRiXKd5mU_WVg8AiWRn2OxTVJVt4X3cJtCWYSK78iV35Tz_YeZJNv3ghiGlqq63hpsUtAjFRenzY6ITvmpPaDhdqnhMaOhvJ_V23C_LUkzaHqGrHnd3Y7iQgaBgxA7yAUKJpt6ydFsj7bsREos3yZHjsiHddYt8lGoAjFHeEZ_6mbzmNZCcrjZs1YkeeTJvT6l29_ROybG61F0zOKtba9G2-Jqau9msMFI7HrdoJKVseJ_8MJBBiaJWfQH3wL5HSkG6zN7kpOdthemIV3nW5OJigfHirTd9PMZu2xAZgcgAwGmGrt4qzlaAtKTCLbnrolUmFyIs0y6sFijSdm1bt8WXQoIeY_zNZ-4GDHZFZ2c0qHa0wOhS2GhMXYp-OHrkJIrw-dHDkCTe8VjdNnbtWRsuzLAGzXqgdKA8g6TZQjX2sqrc5bZQjw6oaeb1rfifFxzdIh3s2HAR7dKpeKT4BefQdw1_RxsmT3elVXjTwnnp8qBEX-DnnKRjG-RHo78Yhw4pzi4oGolKeLeKKkHrImAQo_KJv818HHWsJhyotfQSpqldxf2FUW5bFzWm9rA4na6qeAhynRlX1sR62LHkP_jDE1rp-uCePHZ5Moeu5bzd-QZ7nOi2F-uJvspRdj6iVSUAZO--fKq7q2VR8ubHvW8NglBteIU38UG4wwoag72qUxR3MutrdKuxrG1t9-WXTkDVseNtv7eYBM11_g_a0gIZsa7k3ZY813VzBlyKWf9V0ixtdvHzRmS0EoDbMdBqP8FINaVJkOuVhJ2W8u6LpZ1b_oqqhIvhOj0V4XyBhUW4Kov2SeqFoFbAEG39bs95KlUpW2jPcVME8BHvsOlKPURz1FrKp-TEXvhVYT6X0WEciPWrMKKGnKwFfe3UpOUo2965nS5S7wpBF-caB1AaFTnSjo8DnWhCqPygVoMurGsO-mIfWQ-Om9NvwJ-_zjovgZmppLrSyfZmPRHObPkKudyPb2jABm8KKQPP7ZY5GP1Y6k3wRfdCzhCFs-JPh-o3_TEEN07aSuRdHdRi4oO3FcWEq4xOB5nXhGTs5oOLIOroDFLcxiQjmm_0GqaRUTY6d5wZNlz__-6XjZuqDiieQyDUMbqS3EmzMOs5QIDvCpwKOVM5hmfmhPeZJkfZ2gsIrZN750kJqxHXdmMuk_R7Omen7Kj866n7Rcs5iCh-N9GZTOW86dExnwuJ6B7vP02HM89izEo-DAzkV65veQ96wbEM0NN7eNFQpydSHJMZAl7UpMV-tb-s7UD1D61-kMNLhomha92Werp-EG6Pt0uh1MgXAKshEQZtGxcIkYAtHGHiF9Q5acUMMEsv95glNiX-LKwIyxWe4QbFeLHkTIXHb567DZG-ekxs96\\\\\\\",1]],[\\\\\\\"D27FE69A-BEE9-4238-88FD-F191E6D442AB\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:18:37.147Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=311532&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,498077307,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4go_AclRcMT6JFvPiW4RLou0FDZo52ZwtU4Mn6EaMy1m557P3eoIfEKpm0dCnyILlDdAZEFAVuKjRiZpg4WqxVyzFj35EJvVVcfssO7sg0YjYIB9bm2iW7lsiu5KoHCoFOl5SClUjPi7pBpOYyOM-WvdTPTdOA9LI5R6ubGruqaCknZJMNjdVpQSIYsHPrP3HSHBVgKYjE9fgPVlhTA_Z7N1GD9jeTxN8MPR85jB162RALOUCZzO4b-MpE_gLp5kJIMzBNXQjeOUZyf6rExFubI_an_hQ4ZUB5xBfRbrVjNhKyhzCxGQVE9D5_LJ0i89W-fF3npMQ8WAlXhQQ4PheCA7B49T4zIl68EBZnsJtBYM2a9tVwKwBIhr9C6m08BKLFmnDLrvnsYwigiPVJR93u9J_aULL5fSDqE0fC75CP3NbhC-Rpbu75o8b2vlf-_UmVxEAP9p6zkZzhwkol5okyRvkmR1F-ddxi2_Voiax8Etqbu2FAf0hEXdxa3fsmmC6x0NDlmsAPWX0kG8y5uj8lVFbsWImghKLHD_Bxfzdq95Av1lrjeb63p7YvyopO8fi1SeTRfY-B1aJsjmO07dfi66ZI6M3ZA9k0pcp3ITXpHSUn59oqeBhk_VhZnndl2-kNzGoaRDWng0D2L9w-X9-blFzdL6liov3xn6g7qcrxBaZaw0QYaluZvpL2e2yiLw6wpgORedDF1jheZMMUQ-QrLfubu4j8ysjgIReL3eyVEszWX3e9y2Uau-pSXI3-P-pDBGj2dkmoCb3pL9m9ink1N23LkaXcP_OHwMBYyl0F6FnHvGwIHAKJ4Q4F8VYCClcfec7z507bb5PP0qPlXy5sw7f05KeO7G2FmsC_9pFVWNC1QyHa4f5OID95WrOgeRbET5s33fLgmrDGUYFbj3e0zdGdDTr1Z5eUMDCf8KmUSwR3FreuLfHsoSOgNIs5RBWdfjDhwUvDwcpZY8YY8IiAPgkEaWl893Dy3Jnblso73aGBgqVBTmqiz8KlKMv3UI22RKv-qsqIesWPXdfzRCYTGvsnsttMLk9dxBUiBdQqoZkWVcSBPeGGQD3TTB_ehZn66NvD6uYAHCwDV7bo7mdvD0AOi8KFa_niBAVtnUMGZQC52yoBUYUhFIZfh3h-qT_57OWUPQ0KrzQd4zOr5yBh_k9pi4HesBtMkgoHtcGVMjJFPb1iEGIfjg5scEKefUtXikCuWv4Hox18D0v90SPfNG8ZVPxyMpPexfl7qJOBrSrzqcpLqHKO4EX_ObKSEJL_JJtwMtJJYLyx0N3qeBOTsL6pjJMoFjpT2dOxHqH1PWjQ0JW4inv7GoUT3qiP_2FdnEdjM5NLF4zKu2UD__pvw54CDBqMMRAuk07mNIwrsEjqPbCacHAWRLHboqL8l3R9hqcqs-at41Ruspi2U1CGsPi0ijNC5JnVn5yVaD-bVVCUZPGsBP6fTg9Jz3eUvNIhmLbfzKRlPxAbPSH_ecz1tW9YyHdut6oHsUEOvLGsC-G10NLRdQEzcl-A0MD75fpI5Iic7fxFMHiNfMHlg7isHShlfJcKjkKlDuQOlYFfeHtMQxJ5xGEem0hEhGCpSCR_S4nxhHNA8SE77gdrUvz2ZrMdrJBZJbhdT5zKVLYtOfFfAQW9VszQZFhuQxmfqcHU8zr8SMjVjjrQHWFKX6Ww4yLEG1oG1QHBtuOsjJMw8nd6x5G3zeheKwHQ6dAD0atKRQ8l0Y0Ior6gjtlb9oS7BV0u1KQgtruM3z4MF23qLb8Ts-eSlMBoT6hyibUrPtxQd8twALiRW3PbmxGaaVTsujuvXCTAjKIptl2qYzO1-Eh4pv8Dsq9Gp2tkAkLAkqgTyV7GWiO7MjDpgMp3Pr_91u-hyURJpTln1Jes85HZenAvtLc8l2DUYVERMfkdbi30-ELWZdyBzxGjx9V6cHqUG_VuH-E-V2aCoWwAhgwYYiLYg4b2eZ6Od81nrOwFrYjTwGGMOP23k0wSkFmsX8x6oba-nCBCtgMgLeVUaymBpfM8LvVPrB3WVg29G-wXZKtvrxhT50MRBaVMD_rabzofiJiuvB_7UMWHb-elIlEkVt-McdOwNYI-eJtce2BX9ElZuc0fvi3F_FSVFsCfXIEA24MJ54k81jMkVKm2n4k7ZNqO-93FTnSpEU8N7unDuGpgaXAD0mbsg-By4KR_ALBJLcSibf9jjf-U9DyBhQ5Fv6XiUyOJzawlg_dd-Xx58nepcbkpWSWpNrnuw7kRCVQkHvPOD0mG5vd89NpZW3_l7oYA0vral7c5Vk30hZWewvFps6OECznGE17wleK8JNElhzh4ZOXhyJdY8up7tTnWiy3MKUa7BdF6p3B13c0vyCPkYUOjiZ6BHvlFQ1S14F48pYMzLPY35yHiwEvSdbxxlAxZFWWk88rdve5a3hxtiXdDeBs_qlS7roL1eOmSoycsX-FPRarTjKwroH2xAeaBXgtLnQdjYQNo5D54_42yAOK_LAYtlnxDANFKzpdRHRJTcZ0oYw\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"350B5EF5-0FBC-4951-A742-C4A7A9176C64\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4go_AclRcMT6JFvPiW4RLou0FDZo52ZwtU4Mn6EaMy1m557P3eoIfEKpm0dCnyILlDdAZEFAVuKjRiZpg4WqxVyzFj35EJvVVcfssO7sg0YjYIB9bm2iW7lsiu5KoHCoFOl5SClUjPi7pBpOYyOM-WvdTPTdOA9LI5R6ubGruqaCknZJMNjdVpQSIYsHPrP3HSHBVgKYjE9fgPVlhTA_Z7N1GD9jeTxN8MPR85jB162RALOUCZzO4b-MpE_gLp5kJIMzBNXQjeOUZyf6rExFubI_an_hQ4ZUB5xBfRbrVjNhKyhzCxGQVE9D5_LJ0i89W-fF3npMQ8WAlXhQQ4PheCA7B49T4zIl68EBZnsJtBYM2a9tVwKwBIhr9C6m08BKLFmnDLrvnsYwigiPVJR93u9J_aULL5fSDqE0fC75CP3NbhC-Rpbu75o8b2vlf-_UmVxEAP9p6zkZzhwkol5okyRvkmR1F-ddxi2_Voiax8Etqbu2FAf0hEXdxa3fsmmC6x0NDlmsAPWX0kG8y5uj8lVFbsWImghKLHD_Bxfzdq95Av1lrjeb63p7YvyopO8fi1SeTRfY-B1aJsjmO07dfi66ZI6M3ZA9k0pcp3ITXpHSUn59oqeBhk_VhZnndl2-kNzGoaRDWng0D2L9w-X9-blFzdL6liov3xn6g7qcrxBaZaw0QYaluZvpL2e2yiLw6wpgORedDF1jheZMMUQ-QrLfubu4j8ysjgIReL3eyVEszWX3e9y2Uau-pSXI3-P-pDBGj2dkmoCb3pL9m9ink1N23LkaXcP_OHwMBYyl0F6FnHvGwIHAKJ4Q4F8VYCClcfec7z507bb5PP0qPlXy5sw7f05KeO7G2FmsC_9pFVWNC1QyHa4f5OID95WrOgeRbET5s33fLgmrDGUYFbj3e0zdGdDTr1Z5eUMDCf8KmUSwR3FreuLfHsoSOgNIs5RBWdfjDhwUvDwcpZY8YY8IiAPgkEaWl893Dy3Jnblso73aGBgqVBTmqiz8KlKMv3UI22RKv-qsqIesWPXdfzRCYTGvsnsttMLk9dxBUiBdQqoZkWVcSBPeGGQD3TTB_ehZn66NvD6uYAHCwDV7bo7mdvD0AOi8KFa_niBAVtnUMGZQC52yoBUYUhFIZfh3h-qT_57OWUPQ0KrzQd4zOr5yBh_k9pi4HesBtMkgoHtcGVMjJFPb1iEGIfjg5scEKefUtXikCuWv4Hox18D0v90SPfNG8ZVPxyMpPexfl7qJOBrSrzqcpLqHKO4EX_ObKSEJL_JJtwMtJJYLyx0N3qeBOTsL6pjJMoFjpT2dOxHqH1PWjQ0JW4inv7GoUT3qiP_2FdnEdjM5NLF4zKu2UD__pvw54CDBqMMRAuk07mNIwrsEjqPbCacHAWRLHboqL8l3R9hqcqs-at41Ruspi2U1CGsPi0ijNC5JnVn5yVaD-bVVCUZPGsBP6fTg9Jz3eUvNIhmLbfzKRlPxAbPSH_ecz1tW9YyHdut6oHsUEOvLGsC-G10NLRdQEzcl-A0MD75fpI5Iic7fxFMHiNfMHlg7isHShlfJcKjkKlDuQOlYFfeHtMQxJ5xGEem0hEhGCpSCR_S4nxhHNA8SE77gdrUvz2ZrMdrJBZJbhdT5zKVLYtOfFfAQW9VszQZFhuQxmfqcHU8zr8SMjVjjrQHWFKX6Ww4yLEG1oG1QHBtuOsjJMw8nd6x5G3zeheKwHQ6dAD0atKRQ8l0Y0Ior6gjtlb9oS7BV0u1KQgtruM3z4MF23qLb8Ts-eSlMBoT6hyibUrPtxQd8twALiRW3PbmxGaaVTsujuvXCTAjKIptl2qYzO1-Eh4pv8Dsq9Gp2tkAkLAkqgTyV7GWiO7MjDpgMp3Pr_91u-hyURJpTln1Jes85HZenAvtLc8l2DUYVERMfkdbi30-ELWZdyBzxGjx9V6cHqUG_VuH-E-V2aCoWwAhgwYYiLYg4b2eZ6Od81nrOwFrYjTwGGMOP23k0wSkFmsX8x6oba-nCBCtgMgLeVUaymBpfM8LvVPrB3WVg29G-wXZKtvrxhT50MRBaVMD_rabzofiJiuvB_7UMWHb-elIlEkVt-McdOwNYI-eJtce2BX9ElZuc0fvi3F_FSVFsCfXIEA24MJ54k81jMkVKm2n4k7ZNqO-93FTnSpEU8N7unDuGpgaXAD0mbsg-By4KR_ALBJLcSibf9jjf-U9DyBhQ5Fv6XiUyOJzawlg_dd-Xx58nepcbkpWSWpNrnuw7kRCVQkHvPOD0mG5vd89NpZW3_l7oYA0vral7c5Vk30hZWewvFps6OECznGE17wleK8JNElhzh4ZOXhyJdY8up7tTnWiy3MKUa7BdF6p3B13c0vyCPkYUOjiZ6BHvlFQ1S14F48pYMzLPY35yHiwEvSdbxxlAxZFWWk88rdve5a3hxtiXdDeBs_qlS7roL1eOmSoycsX-FPRarTjKwroH2xAeaBXgtLnQdjYQNo5D54_42yAOK_LAYtlnxDANFKzpdRHRJTcZ0oYw\\\\\\\",1]],[\\\\\\\"6DF26C52-7FC5-46ED-A4FB-BCF1BCC02EEF\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:18:46.196Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=288975&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:18:47.154Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=169567&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"D6AAEC30-CF75-44FD-9AE1-D0F538B5944E\\\\\\\",\\\\\\\"02E2F918-9605-41DA-A51C-6F2EF52C3CD6\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6f3yhVnqY3e2AHaKxcEBfbAFLz-o5eipDmWPixKRievIqzgL4xrRuXUgo6fE8h18xlss2Mq3IHNRxy3WMX4A-TdUVl19KoTpsdGN9UMVO8THQFSucmEodT0M9kqT2bfSCsFvmAvqkc03pVsXwJ7lGTS3-Gms3xu7v3qj7xRKCb3gw_IyW67WbwrNhovmyR1U5I5aybT58zYXrfYy_czM9XQ-npzoWmPIu9Jw9S0TqGgus79HEF6Y7IN-ukb5lVjok6iiCDj7tqmMhsN9UST6V2-VqGJn9EZbjv-WHBK2dKJuJN-B4kz7ulyET_YBiCUTHy3ZCefZjF5V3pr767YZ284M-k044UvzhuXntEPWLinQUabFyrrNfETINZygHSkKiyV5UWXgfR3cC8vRlsMUlaDnixqNXfburc5C66OBT03FtoM1_metWYDjOt6gAca7ktL0wGSjvohVF0yoGxYkrVIM1o_SqOZjZw-ExBHpOBPECkEzPEu71SJSH7X7_wZnrzL6nKNYsTFAjcYMckfNCqqmm3_X8FascZWR5iZlGV7X1rBEWE5fJWCDkJlD1Z6Mtz2aV3kZE9KpUNj58tPsXwbaxriJIptjp6YM2_G4HhNiW8KQW0s5vNPKsQrjB-nSSZ5Rc0rsrGPHeo6EFCGmDbgWz3_miK7Jn0NAjGOz1O_LvtJBKC4Akro7d9-l5-OvHL9vBqGAjrPTp4OC2w4Je0MExGuj3r-s9P9eRoGnu2x_yx5rCZm6OnJEkeHrCP7VgacN_kQNpSoJh7ZRV6pUp_3jpvs9kvcXDs_JZ24NKPbUZrG_-WSsOws11YBkqU5yTVLMlQlxGN2BZvxNAEtoqm7pEzh0TDYZokU9MWupkWyEvoO4iPX1HgdjMGeeYvWnhK7B0m3twRytXAr9NtTbi9y4ob4HfcpzYvJf7CkCnr9WiCw74mBOsyKJ5d8YLPC82NcLM7-Zx6PvFg6j-9HmJpYyQfneiHuEquLqES4mnn73dNJ5XbzLzTNy5I8ajhd-GaXH_MdwKHwYL3-sL0BFipxLTRfK7G4UBQYOy276-P0gxVfH-z6IB2-J2D0dSAPqKDseeVCWqVWSHkrJKuuTEtA-KWMs2SG3_ME8jWpn_Ww1goW57kSHptkcT0AB8Q68a1iK8-LtK7i-pW_nwNosucsug4YPUqSvX14XMQYhlTTWHtWbrD_qnlPK_n-GxYYmntNhhJcCUwLm61wp49o9mRSuT6RoJOkvLoYeHxgdvin9x7R0ahvXbk3_Cz4et4fTvX4VtnSrPauUkJhRfqcztzqxTHHpCvHXjrxZgN6M0xIRgD-YwWqwKV1BJ23PA873ZzVovA4koOkcSzaIpkPj4cDqvPhQlFzmHCBDf_-Ywkyd6SF6b6W-yAPswzL46wYqG3v2kPpLRtKUNe5VADOAZcDgJnzHTyp72EAFXFaZ_fOJdxr8QyaatKK_K-driFRmqOoxdjPvToYMsiFuBdV1bJuOXWY_-9WPa0Vz9BNRm7BrJbmf4w6mbHFK-qyHJpXO1xu_3bXueuQNpbkNo-IrAVbwsB9ueXfyr3UftPHFTaiGMn7ScwJibiqwx4iTSHIzQGnXlR_YjDNAPZEiosFFdk84yiEVKe3QIvK3cJe1oZMsdcAizkWRauhknk6kLJGibCaYapJ-vfGZY9hTLsw0ta_uQnVGGXefbVo0eAB6kfCezig1zxb3mx_CHyNm5iE-Sv_fdXdqB3NHTDbMJKkLoF51EqWZiU463-kZzbR1Db60sPivt7aP_-kmgHlpF3aHsRjXi9WEZMdGuPsBU7FuSXQNTBz3tQt-u7Kf9d8eehmN2xKUNuruJSLITJdQeRmDdqBiKzNW0IhsSmI6aJ-fW1lLR7e_QJg5_ww5PvkDIS1529342nLAeZW4cynol6Xyo0Fv5x-7okHXMoYkptnSV-fb-5GW6KCOM7WFNChX49-Fauw8OkFMRCUXANazFzggg4YOxK7xUEqFzw50wjlBK1AvtwvaBRNxGtLvtxrfxuqU5rvn1jiLlhFR84krhAtz9ES2my4DNV8BD3jdgd3n0VSueYZIWn8gECEN00TkjhX-bI5swHqLAaiEZNx-dHkpBX3YSCNZDsMH1ETxhLEVD9HeYfUlduieqAkBPJgv4MmVvporoC1x-7Ha0cBc2DZjpdfN37USs-ArNhZ0660ZA-v0Q7WS6_ITpequa2JHWMIchq__eMOxzZpmLO_mDUkqLR5d6H5OM6vMSPp-58U78ANvbdKbC2rAMoxEj061EUFA1F0ixII1TD4ldKrGri0ZRJygcw6sW6JCah1oSFKqvl0QO9VO2Ldyk7Jjbd3c3i6xHl2rPoFU1QyiVi3BFtRIxsPg7ertXF7nvAhKtfyw6FeuE1MENCxUOmTIi7pO4DwbDLiCq_akUatXyfQXhwKR9Cyorx76G-c1ydKLtvr85vJal-wreGbePUwv1yj9lgsBbEO64\\\\\\\",1]],[\\\\\\\"729F3193-1FC9-4D34-9449-2D063D80C932\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:18:57.172Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=422769&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,866311297,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5ZJCfZ92k18MLcXUW98hyIDcgN5o6bZLM9G13Hz9L4CcUaFxo-AS6LVXDPgqQnlzJtwra80inSWBGMa6_u6yinx6lweUfuzRSLOoRYq0sRvbz3Yo34hXHTip-BpoLeuR29sMvAOE_VbCcQ2bG960aiuDHRz-YvR8jFpbWim1iF9uYK39dZoH1AvThYE6CmhvBzvAVZHkV2r3UIlMisNWmK7BEkks8Cb9HRFTWmoOWgMaWtN6wgq92-l5keEtukriYA5mAj5qrDxbqdtHtvNo52lGqPyponh3lQfGk3wmqJDwXhEJds03YLE6GicdHRAgOYx5PDLDeOdYUcffRfij_Rg2GwUqDge2TSBKr05Kkt7-byShzsBCVItt063YaWy_cRp8UL30TEqfNgFVqZAzWtJPPnJqwtPIP7ebM9BKbgYv5viRvRLuSYPbayd4AjVdk9h9MuOU9CaqeGdzpBTxQdaH2VCmFxWD56q4c5HM3kRvFKweFEgFWkXaAyKuQXYU1udWN4viPRO3XB3Ns5la4jQcEZ0UsPROUMZjdrM5NIgeqgSM7_jYWFP4K8o4hDaBvi9FHlxJBy9t13nhT-Bzyw-Z0iYjX7FBwQes5KzDTUH-sg9zPGgTAKvB8IGqJwmfvBcxK4YsNBXIMAVmYTWpVjW_fx6qbwAW9ip-rsgLRcTnuA3b0VLeA_DKg77PoHIIjFbJViktxPoeI2dclm8IJ895exUe5M2kmWzhN2pFyheidpmqZ2WapSSfueXSGcxHfn7E_AkHcyPDHy-LkFDOKEDBBKvuOsXm_gIY0BODANy7qw4zoKpNq9xvHQDpYOPraSCIllU9pTIs4PFiCgVBfW_4dKKK-klebNqLJqwERGlvQOmYH2D9Pw6L1ZZLiUxXnwbXmvbBuZKcsXUOg0n1fsuCahaPA4GO4N1z-ZWqE_NassUv2pvwwx2K4is-i1a24x28ZrPqBfpaWOgM7fNQX7tlVd5qf6ZsaUp4d2KEOKbNND_gytWb7BMCRRCzhC2xc89j0-RBYEPoMkOEWkPuFZXhfKjSSIZpP7EHjTGM3O9HSSw2_ginFPRP7H1It10t1oTrRYOPF1KgjOdttcGOoI4hhl6yXvNS8xmPwgQDnyLobg9oVUTKvJsHxePO8D5q3MU_bF4wS9rZz7R-UD1PADecX5cQm8LYBTcuyspTvVkZQAEAG6qRVLtIHWj_6AVnHvAcBxfZWDp3UNOLjzz8B5WNfwExoeci4-Rgw_4ozZCrBFqiAk1e0MbBYoXKmnVSw_MxrQYUszmIbB6-fuRA1f2rF6NmwebSVyDMpLqDSKHLG7hYnKNPMeRe4FOmN9-gARktrT2_2KamYDEzn-7lfw1RKV9eaGc4Yfnb8PjD986oFm-PpfnjTm4JgGg2vlE72CAQZtXidKgQB4M92xk8x84Y5F7Xh8sSJB0GSFGhwx6gZyuNDiDvkKEj1WXvD00emyHB2rW9mX73kiyEuEAAEq0QammT_ugROsuziipxIDquGSYoV7-p9l7XYP0nPiiLqpIBYP3Tm2SJ6q0esNh_npT-6n_U2c9xtdP77cD-wmZJRLQ6pKfTyFj58sIGLQFfg24aeAvqAspts9pzL3J-Zuh6bgDkVXJBzCL2lO0-ejfjTIZFYq1ektCBkUz1ejKrpoU707-6lmbHI-803YPn5d-SYfjL0wXgnLs0-E1SKLrKTYnu5IZNyRQeRsMslPvva8Wo0bcoXLkWtD7WSqgz9Szbrd1vY_KLDaPn2ooC30JFJ6nGBlKnuH3mg1EhfFLdJ1y45Iu4U5RDTqt3a2OPHGwfYW9hLF601CYUhdDj-xwCx0wch-efaT3P8kmg-7IwEd0jr6BkdAjqLV3EHjUQO2AJorqxQZxnlNYnL0Xx_DXMZRiF_oGQ1q5prIYFy77h7CE3Fb6cSLpeSizfVYXtbNPy1DIpl8tOr1G66hbsorFPTg1FI6aEUKKmiHavxchMgDV7f6xS6nlFIGcvapAO6nQ3P9WsLRtY8_nsJj6vY4Vo2IBz_l7TJYCSHZaZ2VyF1iR3G80rHVcuH-_gGEOF-Efg1jIhXrfQ9YR_CLufXISsd-cZdaHOwdc1G4KjosBT0TaTXIxy6ov3WTac32F75rNfG8h-VoSV-kZMQ0gmzgfSAgxX9vk6XwCGnKVPRelEGbSHkBRZ8AqqgW3CPANZmpV8OEx5UDeMcoYDGG_dlemy_B4W9CBq4EQWzsDko_2MONqrEatPLb2cTWU-QWFqDJCGdOpJgMB9j4BWYCHrLcNgoAYXeB1EaeWGGm9u6dYoOxvkgt_5rS5qSGF5y2iwc7tjIjSclXF-OlkxAeVkfNSGfWPVoOgIOff9IrTeLT7Hf-1negujkms1Ngq4hvPHg0F-2gIxnNK3cEoO0w2RmxOIbfNAGQh38SXTTN-8dfvwfEwURHcDA2aTsikSme4ATjE2gpUBn3IpY-YY7GhE32Zzwq0z1aoR8Gdkt_FUML-ocs-vMV\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"7EFBC9D7-3C88-47F5-930B-035BE69DBBB3\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5ZJCfZ92k18MLcXUW98hyIDcgN5o6bZLM9G13Hz9L4CcUaFxo-AS6LVXDPgqQnlzJtwra80inSWBGMa6_u6yinx6lweUfuzRSLOoRYq0sRvbz3Yo34hXHTip-BpoLeuR29sMvAOE_VbCcQ2bG960aiuDHRz-YvR8jFpbWim1iF9uYK39dZoH1AvThYE6CmhvBzvAVZHkV2r3UIlMisNWmK7BEkks8Cb9HRFTWmoOWgMaWtN6wgq92-l5keEtukriYA5mAj5qrDxbqdtHtvNo52lGqPyponh3lQfGk3wmqJDwXhEJds03YLE6GicdHRAgOYx5PDLDeOdYUcffRfij_Rg2GwUqDge2TSBKr05Kkt7-byShzsBCVItt063YaWy_cRp8UL30TEqfNgFVqZAzWtJPPnJqwtPIP7ebM9BKbgYv5viRvRLuSYPbayd4AjVdk9h9MuOU9CaqeGdzpBTxQdaH2VCmFxWD56q4c5HM3kRvFKweFEgFWkXaAyKuQXYU1udWN4viPRO3XB3Ns5la4jQcEZ0UsPROUMZjdrM5NIgeqgSM7_jYWFP4K8o4hDaBvi9FHlxJBy9t13nhT-Bzyw-Z0iYjX7FBwQes5KzDTUH-sg9zPGgTAKvB8IGqJwmfvBcxK4YsNBXIMAVmYTWpVjW_fx6qbwAW9ip-rsgLRcTnuA3b0VLeA_DKg77PoHIIjFbJViktxPoeI2dclm8IJ895exUe5M2kmWzhN2pFyheidpmqZ2WapSSfueXSGcxHfn7E_AkHcyPDHy-LkFDOKEDBBKvuOsXm_gIY0BODANy7qw4zoKpNq9xvHQDpYOPraSCIllU9pTIs4PFiCgVBfW_4dKKK-klebNqLJqwERGlvQOmYH2D9Pw6L1ZZLiUxXnwbXmvbBuZKcsXUOg0n1fsuCahaPA4GO4N1z-ZWqE_NassUv2pvwwx2K4is-i1a24x28ZrPqBfpaWOgM7fNQX7tlVd5qf6ZsaUp4d2KEOKbNND_gytWb7BMCRRCzhC2xc89j0-RBYEPoMkOEWkPuFZXhfKjSSIZpP7EHjTGM3O9HSSw2_ginFPRP7H1It10t1oTrRYOPF1KgjOdttcGOoI4hhl6yXvNS8xmPwgQDnyLobg9oVUTKvJsHxePO8D5q3MU_bF4wS9rZz7R-UD1PADecX5cQm8LYBTcuyspTvVkZQAEAG6qRVLtIHWj_6AVnHvAcBxfZWDp3UNOLjzz8B5WNfwExoeci4-Rgw_4ozZCrBFqiAk1e0MbBYoXKmnVSw_MxrQYUszmIbB6-fuRA1f2rF6NmwebSVyDMpLqDSKHLG7hYnKNPMeRe4FOmN9-gARktrT2_2KamYDEzn-7lfw1RKV9eaGc4Yfnb8PjD986oFm-PpfnjTm4JgGg2vlE72CAQZtXidKgQB4M92xk8x84Y5F7Xh8sSJB0GSFGhwx6gZyuNDiDvkKEj1WXvD00emyHB2rW9mX73kiyEuEAAEq0QammT_ugROsuziipxIDquGSYoV7-p9l7XYP0nPiiLqpIBYP3Tm2SJ6q0esNh_npT-6n_U2c9xtdP77cD-wmZJRLQ6pKfTyFj58sIGLQFfg24aeAvqAspts9pzL3J-Zuh6bgDkVXJBzCL2lO0-ejfjTIZFYq1ektCBkUz1ejKrpoU707-6lmbHI-803YPn5d-SYfjL0wXgnLs0-E1SKLrKTYnu5IZNyRQeRsMslPvva8Wo0bcoXLkWtD7WSqgz9Szbrd1vY_KLDaPn2ooC30JFJ6nGBlKnuH3mg1EhfFLdJ1y45Iu4U5RDTqt3a2OPHGwfYW9hLF601CYUhdDj-xwCx0wch-efaT3P8kmg-7IwEd0jr6BkdAjqLV3EHjUQO2AJorqxQZxnlNYnL0Xx_DXMZRiF_oGQ1q5prIYFy77h7CE3Fb6cSLpeSizfVYXtbNPy1DIpl8tOr1G66hbsorFPTg1FI6aEUKKmiHavxchMgDV7f6xS6nlFIGcvapAO6nQ3P9WsLRtY8_nsJj6vY4Vo2IBz_l7TJYCSHZaZ2VyF1iR3G80rHVcuH-_gGEOF-Efg1jIhXrfQ9YR_CLufXISsd-cZdaHOwdc1G4KjosBT0TaTXIxy6ov3WTac32F75rNfG8h-VoSV-kZMQ0gmzgfSAgxX9vk6XwCGnKVPRelEGbSHkBRZ8AqqgW3CPANZmpV8OEx5UDeMcoYDGG_dlemy_B4W9CBq4EQWzsDko_2MONqrEatPLb2cTWU-QWFqDJCGdOpJgMB9j4BWYCHrLcNgoAYXeB1EaeWGGm9u6dYoOxvkgt_5rS5qSGF5y2iwc7tjIjSclXF-OlkxAeVkfNSGfWPVoOgIOff9IrTeLT7Hf-1negujkms1Ngq4hvPHg0F-2gIxnNK3cEoO0w2RmxOIbfNAGQh38SXTTN-8dfvwfEwURHcDA2aTsikSme4ATjE2gpUBn3IpY-YY7GhE32Zzwq0z1aoR8Gdkt_FUML-ocs-vMV\\\\\\\",1]],[\\\\\\\"DDD1BE45-FADF-4204-92CF-A64DA3F7C2E2\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:19:07.189Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=203098&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"457113BE-4A40-45D2-95A0-84CC9C919139\\\\\\\",\\\\\\\"0C62A28B-CFC5-4F35-A7ED-D3E5A072D340\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7bac0SpnVmRP4jAZKxeAKds3G_rOFEhoMry6lDbnKHNYFf29-0L2mlbJGEU_adPw76dDPTqwzcEFwCV25C-we0CaCNsFU-KaJNTLjNoWMHTKClxwXKSbQmbWpjS2RmgsvAn1DUsA2XbnwKTYhyb2mH2z6TONsEbz3grEFukYuPccmbZ_FCQR1sqeKZ3R8Q5wz-N7Dx_Vd8voyrr-rkMnYIYuS54XrS7pUoaLsP7fqvlD8NG8hwcUXRtMyyiMJrYetW_gSGvSFm6LW1UL2vaIsqpo4H2FFnq00ohLaNfYy1BYKpmcQWUQYmNct7Dpn0VJEjmCRrFq5H-fzsNfB2MD-3X-5yY9nvmHXBHioXNiv_RJSveLouTWEqx8l2SKPu1J3ecte5jFj7b2h0wiVucA6pT_r8Q4BCeuDGQ848A6mMforcxbYdfOvYTWZBWu3DYOTcBq62cwB7_wOuNGkVnN9Hup9qxY_bWlwCnSAqIe-c2yfboIt6xK9ZhVIcyDFV1lnm9B1pqoKoYZ4cYcTAE-AmOn-dAKXC4YOSgx7fo4LA-208-mVuvAEEtB1WqOLyRKanETuu6twTad2rvUuqPUvX5fUOJPBj6xnYwAfVTbP7UY3BTeqweCBlt-LkCIlQmkVaWY-NaCl9qoxiAYCgEnagM2UxLLZ-Kkx1EpVN6m4_diXxioFmAXwX9E7TDIJHtPVSXVvdifsiRQ2Rx5CQWQo5-5MFZBkC7Eiq06Gi82Kgjn1HWa-mKmhTQP3NapSIBIgdnDzLXzsmqdgW8TQIeG-AE9vZcfyhCo8It3wsTz_qPXT2hCpn7qTgvhTiqWA8Oqr_Y25sJbqMyy4Xbrj8o5_M_iH8D1EKqatwOQEbbfJZ1asmG_Ty2IC3NCGKlJIKSrc02m0otPq-LDCtIA-_d_wTRgDpB4Qh4fy9jp0KZXFnlICMS5ElpY7JDdNs9kDAdx1Id4OumxXkvu7X7s8iyM0IWUx2iYYbKdyBK0C-GK4HGJRj0xDfhw3K75cxBsNjljdwaaCVrz3pawsLi7IbJ6KRuMSugifBKfc_qTj1sPNtbCphpM8idJQ12twU6EaQeMlKRw-4Eu7u0LqNfwPJ7_1EZvU08VtBcnrFs8kF6ttyPPJ6fLnNTDlsY54UZ9DKp2RJ7dUMwwWTLvYMcqK9s-umkgLWojpMN6q1IlRBGN4GNvT3-0aaoN-g4Se2lw0-fO1hl7hqrmw41zm-1d0VHx4e8jx6jkVTQAaKio03twPbG7GL3OvdyJVupOOmjEr5Bqfg0LMLzqKqOwVtKv9nfHovrsXEFuWB6YyaJmjFyYj1mbS41KUftuzd8dPeqxxojYV0Cx-FWE0xFxnXdP8WNkISHeB_adiKWeECUtDWyfJQ6Ii5DcIhF9Mf7VFRpcABZkCYQSpeQDLAWMaExwJZVlSiPJf_0XAJtE1HoexmtywvmpcWdHrkP3-5A9SvWDdnLnTvEnrPxq5oLGdgcT6NxOiTZO4Ayk7c8fHk8aKR01L1EAVwCJ0A59vsP3ST0M2Q44E5KtLvz6lYgfhZXprOF3SiXpUYrqyR8wx9BPVAkwZeSelm350unRnNqkJ-AnNSdg6obhmkSArn7BKvQXHa7sPvZ4u_veL72P93DajGMSCOj2njL5pxvuCrAKb9OvYOtkKuQLb3ritUsLaVUs0aQJGzM7skvl6r5fdLNKJYIfJz82QigANH1qxk-cWyWEvyUVqCohRso7TfBYbP1A32wtKlmUe8n02zf1PRqTE3Whe-ZMCur7kxBUchJewWYvqi94_p9MzTdGe9I2tNErFKxce3CxWxGa7dcUjsNAOz8UeBsIblSJqTkqgaM0oNpYpp47SMMkvUKos1tGsAQX_rpriltjFShrKvgmywTyeTSQbaj2-HK_txyWCGj0E3dADPeui_wXEkXiMNDkBpy_uTfe-jaqYjiLSWHfnE68hAdteM7J3GGZu7gEsaopXxwORyAYoxnZHXwvI3fkqxFwZ3X31grttY5pLmUGN5Oi390kLU766WWpPbBK46NpF8xp3_qYwDXrLqxuwXFUMMxIr3MMq9OKsF6FJ6X8pnQe0NpDAIl5mxMfvyUZaN6Pw2GUbNPchirjG5YFn54qw5aKLDyoKxSFPZ9IHTb0_mIvSjgKNZIvckS5hSOpB7ksBIHB6TMJggYx0PJKnE8W7kKopi9riKht_jz2rPWgdtHKATABNgPJdep2Q0Q9jhl5lpsuAY4AryjV4UDWJSnprrzfj4TgwQMefpmte6Q1sBVlDOqfnyc5HmhlvhZztb6Sx2FhqjLHyI2xOgPyCThWVOMqZg3pGrps-t0x_QrCKzmfemOPZ7M3dvS2AN_V1tHf_JhzTKWYYmcRw7wnqsJtHVtrJxhdqbVhF8DRbixNc3_1jXH5bxLUAXJFoadJwqTCesKJoscydON5YeI66cwDY_zn6uiseieNp3PWqJWg24FK00jdQTBHSqlzavk3C_y0eQ_dU2u9XyoeI9\\\\\\\",1]],[\\\\\\\"CC1625F6-A568-48DF-8541-192A22897BEC\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:19:17.222Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=490988&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,387255460,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6P9o40-LN9HAuaLi7UPKaAaPN0F1MbHkzubaxpWVnHUE1D24zVckvEZsroZj2V4V7aTkVKMDWB1YLiXinlrwhLGcwrbdPMiSJf6bPwASUJgZvmzjHRfVvwMbPUtc2pYKWF9ypifGSronnHqmU_m9tDDrBiVke2_lN-HDdeOnmdk4ZOhZHSbcr1O36yFCSlquwWYlsqaNCr7yYOxcHD9IoHhUM99HpQRL1ZDsNrpGith5ur21QDMy7_oPun-RJHnOj_PpzoTt9NfSr2YJlGzycS4uN4uI1942KfgU-gHZxjGprS_LyizIckoldXnPPD_UcvSE2qGD0QgtMWdfCgEOB7UYr1F4zVv0XsbXK91Xs1BcXWg5kq8Que2QhsiXlrwVlFMHyyNny-YaKyik2KANJFoXqv_B32jZqm7aeXL5dNU-n6Dwx1L1cRUlFA92zw16eGR1_9nkI0ZourCdhoBZdeuLDkM3uqi7Wh44IyT_azMLnRZVtyVX-g1Ku_vmlVYePVLERRHBxlP2mcbmyVbHDVS_C9zSJJWgLz9VGC96-dlui3h2_u7B5aFtnBUGojXmS63I2ERf1_WZJJpTe9etX0rNU38g93be2ru1Uq7OlOPO1FgAT3FRmFY7haOCHkoehhRXuG-EXRBUJdV5XikJfblUrJpRe6OUJn1PDF8aKmlkNk-qMznrqG5hkI9S_2_6HeWuaPPZzlVeeHafufg_t5j09ruceutvUYMsYYp5wSL95zqOG1n2j3cBh_sPuLPPp-0Ila-vtKSH-Zp3wFY87GX1Gr4typjAEar9yzoMZUfAXlrNI2Zy4Yr_-oZTDLWmFsQl8z0vNdnLEMHgPWk3os_r7XvEkRrCB049c1PuAQSHAMD5Cv49jShLmkn1EFarZ_Yy8XRMdayeNoVivqX-HsSnNPx8AzF7UeuQy38xfUt7R1-Hfe1T7OFmqOSfC8hiUN7NzP4RcY_zPfFZaztBzZUzUjynfnoxQ9rAp9Nn4qkC41EI5oEoxcNOzlTtZMOWwkPcoR0X3km95NoV9gRzesKph2KWdfs1-ucVh_KtnwvcmDGw9AVBz1M8mKNBZXRiffegFKKEMu2YYJg9t-gAk3Zb3VtCU0T1krbtzkL60IUHtXDsgo1E3Q1_oOkZT1wT1K4870sJTjU84IScbUp4GO9bAYFkchf8exFc1E6jL7ke1LLwb9tiv7sV_kmzW3ov5kXIWPwTqaQEC8QjN7KnftKo8l8aFnFAolmjsarsXarsho4i_rq4_a-UyAidkJXkx6tP4zLkcnF7XO3cf3a8pFtMac-KdETiXlzj0rOaAoWAa1ihq7Hcj6-T97szChzZwgBTjBnGAqrN59XsSnZsNDHrXBwnagandMH8rIIwlT68a4rVL_-_srUFRqeuS0lo6aodDIcXsvyeDebcgalf98KLKkfgzWq3nfC-emIzxoUQJqheM-rTxOpSzuJxhaIN9-rESQ4rb4jCDNg0NjY_XsRm0QOWhGZvsfMVdHpfy_DUdawlSTpWghbzTWRi4hPn_W_x8L5dgWgVJmIXXB-WnQFq_EXC-8N9n9MIX0QZrojbsU_HPkMCy5hOcvF4ShPiVWyMlX_bXEISzjc6yXRKnssTDmI0NWLpcwsaoc03WmP8S7SPAATciEJzcPTo6B5W3FbVbi1CE1DRcvi7R2rJ5ZVL5VcyAd8YMebR6KUewhLmQiFALVTJe0BR25AogpwUuOghdXwdnJluDfjmMw1E6dqFP8ya8UXy8-IuR3KyBzPKHeajh5aBTd_kMX8nFns_MPzXXVUKQwvWSrtZpgt0rs252f61wjQ4LUo5jyxWLeR6BN8Vn__XhBXlaxnHMT-olFv_Cfi2XUjIjEgm5w65OLFtbtI6FZ-PLM-tr8t8h1oTtzihRz5FSt32DRfAU2_77cRkVIF7HUc-BbK1WznA1kcvRXeMIoKRcSIShuc1MP7nA_YSeByCML23Vc1B_45ycGZkRrpQeko_xyI11-MlLkd16UVoDOnpCNtyjrh2QGu4VuX9o5UmY_vaQgegbpTei_2ILcz1_Y22uACvQKxlO-FUD_A04y7yU81NBdm_cbWx24O-H1iqVlm98g4-8yeydI_N9491-uijtHWtwouPN7gPAvSxyoXofUuSGa1TIMQyUwduASFitlcOPZ2YLYsryROxPCTppN37mo8dlHWty3O7VeP3Hr3OF1bzuD5gkonq3aSDM14LqXY91O13fyuib8RI5F1Fb9UlPKRWIGfYAK1mNm3L1RyXNeF79q-HiSoq9pn9UrZ_xwTH19wQpr6PbyOSn4SXImlFZe1-SH5JLVpODC_ei8fuOnMl5jVtJUsJvMcM26H68OMqEOyKJgb-F_zVl-9KVjxuQNIa2SJzi8jK71Dar6Rpiim-f4gtepnNFR2nTvevvJ8yThf07kyHnoUwdmpOeYmwTBdvpCPK6vyzJL9i6_Gj9HlMPzKIKdlsPZVdw\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"C29CF896-B064-4D48-950B-BD44D7DFD235\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6P9o40-LN9HAuaLi7UPKaAaPN0F1MbHkzubaxpWVnHUE1D24zVckvEZsroZj2V4V7aTkVKMDWB1YLiXinlrwhLGcwrbdPMiSJf6bPwASUJgZvmzjHRfVvwMbPUtc2pYKWF9ypifGSronnHqmU_m9tDDrBiVke2_lN-HDdeOnmdk4ZOhZHSbcr1O36yFCSlquwWYlsqaNCr7yYOxcHD9IoHhUM99HpQRL1ZDsNrpGith5ur21QDMy7_oPun-RJHnOj_PpzoTt9NfSr2YJlGzycS4uN4uI1942KfgU-gHZxjGprS_LyizIckoldXnPPD_UcvSE2qGD0QgtMWdfCgEOB7UYr1F4zVv0XsbXK91Xs1BcXWg5kq8Que2QhsiXlrwVlFMHyyNny-YaKyik2KANJFoXqv_B32jZqm7aeXL5dNU-n6Dwx1L1cRUlFA92zw16eGR1_9nkI0ZourCdhoBZdeuLDkM3uqi7Wh44IyT_azMLnRZVtyVX-g1Ku_vmlVYePVLERRHBxlP2mcbmyVbHDVS_C9zSJJWgLz9VGC96-dlui3h2_u7B5aFtnBUGojXmS63I2ERf1_WZJJpTe9etX0rNU38g93be2ru1Uq7OlOPO1FgAT3FRmFY7haOCHkoehhRXuG-EXRBUJdV5XikJfblUrJpRe6OUJn1PDF8aKmlkNk-qMznrqG5hkI9S_2_6HeWuaPPZzlVeeHafufg_t5j09ruceutvUYMsYYp5wSL95zqOG1n2j3cBh_sPuLPPp-0Ila-vtKSH-Zp3wFY87GX1Gr4typjAEar9yzoMZUfAXlrNI2Zy4Yr_-oZTDLWmFsQl8z0vNdnLEMHgPWk3os_r7XvEkRrCB049c1PuAQSHAMD5Cv49jShLmkn1EFarZ_Yy8XRMdayeNoVivqX-HsSnNPx8AzF7UeuQy38xfUt7R1-Hfe1T7OFmqOSfC8hiUN7NzP4RcY_zPfFZaztBzZUzUjynfnoxQ9rAp9Nn4qkC41EI5oEoxcNOzlTtZMOWwkPcoR0X3km95NoV9gRzesKph2KWdfs1-ucVh_KtnwvcmDGw9AVBz1M8mKNBZXRiffegFKKEMu2YYJg9t-gAk3Zb3VtCU0T1krbtzkL60IUHtXDsgo1E3Q1_oOkZT1wT1K4870sJTjU84IScbUp4GO9bAYFkchf8exFc1E6jL7ke1LLwb9tiv7sV_kmzW3ov5kXIWPwTqaQEC8QjN7KnftKo8l8aFnFAolmjsarsXarsho4i_rq4_a-UyAidkJXkx6tP4zLkcnF7XO3cf3a8pFtMac-KdETiXlzj0rOaAoWAa1ihq7Hcj6-T97szChzZwgBTjBnGAqrN59XsSnZsNDHrXBwnagandMH8rIIwlT68a4rVL_-_srUFRqeuS0lo6aodDIcXsvyeDebcgalf98KLKkfgzWq3nfC-emIzxoUQJqheM-rTxOpSzuJxhaIN9-rESQ4rb4jCDNg0NjY_XsRm0QOWhGZvsfMVdHpfy_DUdawlSTpWghbzTWRi4hPn_W_x8L5dgWgVJmIXXB-WnQFq_EXC-8N9n9MIX0QZrojbsU_HPkMCy5hOcvF4ShPiVWyMlX_bXEISzjc6yXRKnssTDmI0NWLpcwsaoc03WmP8S7SPAATciEJzcPTo6B5W3FbVbi1CE1DRcvi7R2rJ5ZVL5VcyAd8YMebR6KUewhLmQiFALVTJe0BR25AogpwUuOghdXwdnJluDfjmMw1E6dqFP8ya8UXy8-IuR3KyBzPKHeajh5aBTd_kMX8nFns_MPzXXVUKQwvWSrtZpgt0rs252f61wjQ4LUo5jyxWLeR6BN8Vn__XhBXlaxnHMT-olFv_Cfi2XUjIjEgm5w65OLFtbtI6FZ-PLM-tr8t8h1oTtzihRz5FSt32DRfAU2_77cRkVIF7HUc-BbK1WznA1kcvRXeMIoKRcSIShuc1MP7nA_YSeByCML23Vc1B_45ycGZkRrpQeko_xyI11-MlLkd16UVoDOnpCNtyjrh2QGu4VuX9o5UmY_vaQgegbpTei_2ILcz1_Y22uACvQKxlO-FUD_A04y7yU81NBdm_cbWx24O-H1iqVlm98g4-8yeydI_N9491-uijtHWtwouPN7gPAvSxyoXofUuSGa1TIMQyUwduASFitlcOPZ2YLYsryROxPCTppN37mo8dlHWty3O7VeP3Hr3OF1bzuD5gkonq3aSDM14LqXY91O13fyuib8RI5F1Fb9UlPKRWIGfYAK1mNm3L1RyXNeF79q-HiSoq9pn9UrZ_xwTH19wQpr6PbyOSn4SXImlFZe1-SH5JLVpODC_ei8fuOnMl5jVtJUsJvMcM26H68OMqEOyKJgb-F_zVl-9KVjxuQNIa2SJzi8jK71Dar6Rpiim-f4gtepnNFR2nTvevvJ8yThf07kyHnoUwdmpOeYmwTBdvpCPK6vyzJL9i6_Gj9HlMPzKIKdlsPZVdw\\\\\\\",1]],[\\\\\\\"CCD75733-6E3A-4D2A-B9B1-5BA2E727861E\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:19:27.203Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=153847&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"1EC103CD-4AFE-42C8-9D4C-3F2C5C128938\\\\\\\",\\\\\\\"32AF882E-542D-4049-A79B-8596F461D2B0\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6eVHsBBELa1YFUapIn40jieozTZw6VzyV3nNpIYD-gdtX9RGorSi_2kTJ5phCb9vLUYYD-CBFS8hRY9dO4uhNznsdPxaXXyeUSRvXgqP6cvTpZPkvP5KZ-HMmAwmSTQ3fZMytfWkUZ5F2MULov1V_fTAHROhtvIGzVFRY2a1gfIBuGPHxOUiwWcrMsWetRYuPHWD4JB6EsMH6karXvdhSAyIRW11Zx8oNz7ABrvRPiH4hdRYaG89ebEbu_hPWEDKKyjePn9vrcmmR3q8Ho_KRbnW76eXqp6FInGeiWIhv9k5FkGBmz_GLBwL7knvDahF5R6BEZ7LZwVnuJzN-09BWimXcKlkCb67fJg4Xa_vipPEeIqKt6-fNrniMqhvi2FbKF7n35AxdxNd2tncWSUIETbpPp_0dnzykV14V0-5WxkMqDv8MoAmkmXVUsepnFG9022MhktV6MZcoh48TYpPMI_gYnPZzBNdnFoGLfQldk19tP0abAruBH3vfk40q9txULqqHxMM0IJvvSsnJNgiZk6HBY4_I-_v5d0Kp2-FUWJxc8h9nv1RU0k2NrQrmsTbLZT240QCBsICwgtlokG0f_xZNEZgzqRMykN3fl8sjibs7Do7JEQXE7ByLEoor2OQlbaKyTCCG2j385ApJz_E41CGl44G8j1WGS0v4POEohvZ4LnjdVYhejLNYDTRnIJVw7lV_Eo3jdLHi-6m_yMX5cgHPQ4NmD4K8e0wpmFlk1XXjphlUwGafAsPpn65MVsZnKNpMPPd92p48OvEBBb--nNSCnRM8F3WpZ8GQm0YHCkgQPnatBdMZ-8P9_q8-ApvbhD52IKqLlU9y-8UmVIdRMo5-AKQe7ef8kru5QtZy_Q6L5oAOrFeSiOHG-MFuoPYaf4kfV4p0P0A1GO8EOrAvcMhRzQjlbuhnIa9QGBTMCjP1sFVM2pimJZbIFqpnQHUtSBu38fBmOe61rovvfvLu7hTcPD1WURPz-ljKJP6-eMy-tOmN-FYl50QFoXtWEOPs-bqb5eY29r4KUAR3-64HtGxAghmE4Szg4nW2mjbbKtKAEtgoGHKf3_d7Of572m3HzCZOWiovhkqtzUHknJKpegwGNaOjNLbcDg9TB9nrZJSp0c1gM7xketzd-i_touybcnMJyKvFdVzelx6whP94aT2_2T6UZQjQrhXmwop8ba7MuaGyIAyoTzX7rlFra63U2xlP-tNwWHUWafHc0olWkhHLQOodtrEfhSc6WOVlwX4s30oYZkeOjM9vkTOqM01JzYWx7-j_anZ8ozX-F3nZv279vAX1mPL47LTEO8LjAE_RwveuFsuylmXPGGT_o5Ugqhc3OtbuQTWiRYLFMkrd_oAABBEITp_do-rdC10Hslx-3GXqYmOVAJky1eTqu9Wru3xILKBNLJ0iMoBdtA_dt7lL51G805NSGI5-5N7_Tgvt6sGYT1fwdYWXvQ4L7CZvMI1ksWykAfJVCRPyFI2srGWQV5WR_6sZ4RnMRTkgjbgIY7GPy3V9vNVp-4C1oB9Faovbk7nl4DXzZ3VBmHPv_RfyOip8Hw51fvu4tl12eiw3cU3ANSK_apHHKma83XeWvPlMw8Rzd5uvIxZbkoPcS416qGMea0SmOOJ5oOoZSKXctrg8f0-QxyxqWkzZipCMFUeKb_qkb4FhDD0TyEShiwtK_4jMwP4s_iKmHZ910-VoI-62zvjdVXCBckePnao2OPnWL-zA-6tZyhKteYUmp9_KEyNLRzJcT2J2rz9GTwQe012Gotj-RLbp455Vr3Ty23CG90IGMJNcBtFEglR_DG8_AhUMlUFaJgZLloV2ENjnFbqzIPsoy7xNtVRzZlKk3rB2-dKX6pm4tfaeIrQ2KRKq1RFZc9NwiLbQBYK5PH5TRUrd5fZOLO-BfTZTiJqRi7sVw7e4lEGbIOmhtpjcQEIKwmFN0mTbTUzukn0gwKcb9GcfkqX3_hk1zIvuf-63yQvZOYvtH0plJk_mE_qPvr3aCCdo_g4zWIvPlqEqVKK7XArGuDJtIBZpD5o29mr9QTVmfAujxUzSDGW3XCr_EEvOzK1cB7Hef9h21DKcsefWkjQC4rFsFVnmvk9GJwiKUJDaOwT-exmf4GyXHzt9j4HXQ1timPvySpciJ1i2sR5y4VvN2OSTAXaKoRk5hDLB7HWvP9XqUR8lGkCet3xkO0lf5cw9_l3tplNOPzzLzamsxnyYa-SYNt4-X7bRLEqEHdNVeakpvptFdMP1Z73CDEmWzTDu4TTzNpCUC-ayHuiYApJZaXwytVFOgsSRhHPIwKMeuJjZE6dcjEMtYFTB7-tCTqkrER58rKosOTFGCmBJyJO-wYRZuBvrPFxnP7DK4yXSdpHtLs6vUUbPk2mK24w3GESuwPXQU00JlzB19B11K3lnYQ-O_ffY8_Hi4Hrn7GaERXZ1DOGWjlMp8AA31-7vgfQ\\\\\\\",1]],[\\\\\\\"8CA97C7C-03CA-4F85-9429-BB929B6756BC\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:19:37.204Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=340280&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,740103680,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5t4JFOtlfMiEZLAYqY-xxTscaAyN4COcIFRtIgf6xjcXzb8bPOi9vx2-6TbdbDfihwi1Q0Wd2JC9Q2P_ciCXPw2zYTKwHk5UBDbOiGiYkZkbs9K8C8vYyUejnpvC9gMZBwDvMfdHYtXGK672eLz8uk842GWWna2I8swzIqJcXa4ze-03LfleQW6c5vBt_eYc5d8lUc7VdRBb4LreoBYkF-UwucYqSdkNPJ0wZIjbr5Szvogx8ueUprTA_f448AU-KNGOD_RRSYSdvptNIVmyNgi69E2UfwcER9iaBvM3HaxhtoEYwZyWHplWpBodPsjQoKFjcebRzWPvdnYKnc9Mnt_QCz5RSJVWAItBcuRFLxvvtLHn8BH3BCi1JWWTZH3eDqXFDG88Euk2bOwu7FWMv-Hc9aPVgeVr1vihQFbZdhAQopGPVi_ibxINa3hGn7no2ErB3U89usGZ-fI8u_7I_oEknOtyeQOpHnZx-6VUW378VnQcheg8G7Ws-NMQXcX8gcuTVTbADMc9u36-Y75I48tFA8TDAKeWvge0Iamrl8K85ZH87uo8mMzwSzZxJbr2Ldj5OoWxhZgXjV8PpwAAlUjs6NuW9w4WVWgwbL1EJHTEUaKauwUXTP_7NhGFmdlzocxaDCAo9B0GjvdVo1iXMSSoJ7cLq6luG1C_KjOdIkEGwKz23yfBD3LKcAj0fbT8yFLmTKDYh06mN0AbndFIzzwE1O2cmc67Pk-WlqZiL8YKR5IYXeVYIV_F8chLdFBA-juTGgdV9epeyD5E2YeN5SyzlMlihdXhkB_Hc0Kshf_by0ilJwaagms1BnHoBiY_cs3-7e778d0YaIARcA-rV0HOAuCrULlFGZBZXeSj4oGkVLy_Tjs2WcSdQctJujGJnd_1LMGu-WJQ7WJcpcWzwIStk-b-wSCRLBffsALF6RvCSL6m3sqD1cvRf2k4SRgWyQmxo4V_2VPdNiJPooEVZRm-CDiH1-eDix2GFyKLk1X0sw55squJpwaFVLMIoyZ1luGjjhiHPGqSmlSYzNHwEmpT0Ga0NXoOr9b2LaNgi4P03gcxtzjaziKzFxOrCaAkuk4mtSZUw7zo6zP1OFmcL0sktVGto_rNQZ_V1AO5OEsD5Wmbgk0BrbAcmMtHkselpfbREFzKIB8FkX1LUVJ6rkQNuGKd1Yqr0zTbTafyYJJPIo2c4aVIhu521M6gC8sQ3syEMB14UfOGl1DWyjyOlRqBdZFqYh350WXVu60rFRq9nJk4ctNrWrquNERJiAQqgYXByj_5ZzAamsZPIaNVDVdbSHM1zI5BwWoDWAkVTVZn3U3eqP_3jeUexII5a9yAwCNXeA_8Yl0QkTJIeQDMdRe6aDRYAMZ5NoIjWUPU-iIJARaAmPBS79X8CesBjArW9x0JzgI7TivYbU166URzznooZM8hxx5DvXOInzpZMEfXigkAkQphMdK3hKNxNdyqUupOEuodUMov0qfccwSkSM-lLt2bkiV-STYP0SZT231X-ix_-_Jks5VKy8OvxAj8VPjMeKlDfU__ProiV34dOyXIa1uHnJQ8KtC6I_r8EsE4a-03ld6IuJG8Zem5-O74sUUTMw7J9X47cK50CS6fIerz17vpSJs0_1Sz_V6_vQPoUZ2dXpvG3MPaJZ4wzoU6RZBlHxWFRMfB5TgDDCTAlu4u34es_P0RT1tg4HwwCkQFgNkJ7V5Jjxr297QHcofL_VskhSxrKywYKx61f7e-EqC7fsDMkO7Go4CNGj2kJiMqZbFHYiIX-Ml-pqftzg9g8IizdkUs--MJuEGgN1t35AdnF4S3iWbgNgEIyK9tJ3_QIRFbT7n97HlVNnmfHGvf4qMULGzLSivH24cCTkTNBCuB7GS6FuYUQl8V6lG0MQig-xhfY05pSpTxtBgFgNfgi2-Q3_NQi4Rvm_EcAWQIR1pqyxGM6M6mmK_rA55RDRNZZAMGBgyr6aFhvfJy2KWTuTZDFLX2gYQ8j5GFGfl_tQtscExIqPN8I_9e3-_-O3oPUgFzenLa3oQ0vnlRtB0NlS5VB1FHsGstANRaXEUGyv3yzxdZvmTxw3KgXf-Tg-BFpyiD0KQuPdutDP_3UYKL6aq3oIfFF04y48BuXg5JI4G6e5S4DEgxvBeSpe2V9SzXzoRroJTwCvqUrqsrenEK0iGNewjuLoH_Whp-Kn9uUx6XSC96MR3TetMbUx2pUiHgaQ2WNkN-yaTqmkt38mXd0pjd6JvcTDJ4ow-YafEz9yNZWpz4K4jRf6PRoI178CS06G5HUoGHev07o1cPbInJKXptsyR7lQ-M2J2MkjjZmAAv7Ul3ZKvk6Dvhxd2ikrl44P1XrAQ3ZiYCfPHmwQwDfXJMoZy9B0KRJHZpOVyvfL2TCRXW--2THzvMpaRrVnp1Xq2oT0S-efduXmLVAIG9JlK_Un6DQi0s9OmWcqTTpg055lJM8hGbYD5K9Untjau4oIxoU\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"6E307E00-E991-4D45-8B8E-0B7823DF08DD\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5t4JFOtlfMiEZLAYqY-xxTscaAyN4COcIFRtIgf6xjcXzb8bPOi9vx2-6TbdbDfihwi1Q0Wd2JC9Q2P_ciCXPw2zYTKwHk5UBDbOiGiYkZkbs9K8C8vYyUejnpvC9gMZBwDvMfdHYtXGK672eLz8uk842GWWna2I8swzIqJcXa4ze-03LfleQW6c5vBt_eYc5d8lUc7VdRBb4LreoBYkF-UwucYqSdkNPJ0wZIjbr5Szvogx8ueUprTA_f448AU-KNGOD_RRSYSdvptNIVmyNgi69E2UfwcER9iaBvM3HaxhtoEYwZyWHplWpBodPsjQoKFjcebRzWPvdnYKnc9Mnt_QCz5RSJVWAItBcuRFLxvvtLHn8BH3BCi1JWWTZH3eDqXFDG88Euk2bOwu7FWMv-Hc9aPVgeVr1vihQFbZdhAQopGPVi_ibxINa3hGn7no2ErB3U89usGZ-fI8u_7I_oEknOtyeQOpHnZx-6VUW378VnQcheg8G7Ws-NMQXcX8gcuTVTbADMc9u36-Y75I48tFA8TDAKeWvge0Iamrl8K85ZH87uo8mMzwSzZxJbr2Ldj5OoWxhZgXjV8PpwAAlUjs6NuW9w4WVWgwbL1EJHTEUaKauwUXTP_7NhGFmdlzocxaDCAo9B0GjvdVo1iXMSSoJ7cLq6luG1C_KjOdIkEGwKz23yfBD3LKcAj0fbT8yFLmTKDYh06mN0AbndFIzzwE1O2cmc67Pk-WlqZiL8YKR5IYXeVYIV_F8chLdFBA-juTGgdV9epeyD5E2YeN5SyzlMlihdXhkB_Hc0Kshf_by0ilJwaagms1BnHoBiY_cs3-7e778d0YaIARcA-rV0HOAuCrULlFGZBZXeSj4oGkVLy_Tjs2WcSdQctJujGJnd_1LMGu-WJQ7WJcpcWzwIStk-b-wSCRLBffsALF6RvCSL6m3sqD1cvRf2k4SRgWyQmxo4V_2VPdNiJPooEVZRm-CDiH1-eDix2GFyKLk1X0sw55squJpwaFVLMIoyZ1luGjjhiHPGqSmlSYzNHwEmpT0Ga0NXoOr9b2LaNgi4P03gcxtzjaziKzFxOrCaAkuk4mtSZUw7zo6zP1OFmcL0sktVGto_rNQZ_V1AO5OEsD5Wmbgk0BrbAcmMtHkselpfbREFzKIB8FkX1LUVJ6rkQNuGKd1Yqr0zTbTafyYJJPIo2c4aVIhu521M6gC8sQ3syEMB14UfOGl1DWyjyOlRqBdZFqYh350WXVu60rFRq9nJk4ctNrWrquNERJiAQqgYXByj_5ZzAamsZPIaNVDVdbSHM1zI5BwWoDWAkVTVZn3U3eqP_3jeUexII5a9yAwCNXeA_8Yl0QkTJIeQDMdRe6aDRYAMZ5NoIjWUPU-iIJARaAmPBS79X8CesBjArW9x0JzgI7TivYbU166URzznooZM8hxx5DvXOInzpZMEfXigkAkQphMdK3hKNxNdyqUupOEuodUMov0qfccwSkSM-lLt2bkiV-STYP0SZT231X-ix_-_Jks5VKy8OvxAj8VPjMeKlDfU__ProiV34dOyXIa1uHnJQ8KtC6I_r8EsE4a-03ld6IuJG8Zem5-O74sUUTMw7J9X47cK50CS6fIerz17vpSJs0_1Sz_V6_vQPoUZ2dXpvG3MPaJZ4wzoU6RZBlHxWFRMfB5TgDDCTAlu4u34es_P0RT1tg4HwwCkQFgNkJ7V5Jjxr297QHcofL_VskhSxrKywYKx61f7e-EqC7fsDMkO7Go4CNGj2kJiMqZbFHYiIX-Ml-pqftzg9g8IizdkUs--MJuEGgN1t35AdnF4S3iWbgNgEIyK9tJ3_QIRFbT7n97HlVNnmfHGvf4qMULGzLSivH24cCTkTNBCuB7GS6FuYUQl8V6lG0MQig-xhfY05pSpTxtBgFgNfgi2-Q3_NQi4Rvm_EcAWQIR1pqyxGM6M6mmK_rA55RDRNZZAMGBgyr6aFhvfJy2KWTuTZDFLX2gYQ8j5GFGfl_tQtscExIqPN8I_9e3-_-O3oPUgFzenLa3oQ0vnlRtB0NlS5VB1FHsGstANRaXEUGyv3yzxdZvmTxw3KgXf-Tg-BFpyiD0KQuPdutDP_3UYKL6aq3oIfFF04y48BuXg5JI4G6e5S4DEgxvBeSpe2V9SzXzoRroJTwCvqUrqsrenEK0iGNewjuLoH_Whp-Kn9uUx6XSC96MR3TetMbUx2pUiHgaQ2WNkN-yaTqmkt38mXd0pjd6JvcTDJ4ow-YafEz9yNZWpz4K4jRf6PRoI178CS06G5HUoGHev07o1cPbInJKXptsyR7lQ-M2J2MkjjZmAAv7Ul3ZKvk6Dvhxd2ikrl44P1XrAQ3ZiYCfPHmwQwDfXJMoZy9B0KRJHZpOVyvfL2TCRXW--2THzvMpaRrVnp1Xq2oT0S-efduXmLVAIG9JlK_Un6DQi0s9OmWcqTTpg055lJM8hGbYD5K9Untjau4oIxoU\\\\\\\",1]],[\\\\\\\"51E93ED7-D7DC-4B1B-8631-7573EE11BE28\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:19:47.251Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=890195&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"56A691DA-B990-4FA7-8C2E-BFCB39F1BBA2\\\\\\\",\\\\\\\"27805E29-F7D8-4A99-881A-5C2162C87087\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7SdjC6kbAuNzxqcDi7gCbbe3n6EaOGZ0DMdbP51iZCfbrAM11ZeBtRb8eHpfssfuaG6aMWlHVN1JIYilhcI9jNwwmUlCF7Poc07eLIVOU-pmns_uOwNlt6Lpkp0hHm_1DiA7oXWXP4XMXhv9aaF98kS4TLJ2T_vQtYe0LjAUy2IJmMQ-sN96BcN_3-hQRH5p834HTI605tMtEqj4PKDYj4Eme37-qLr0gR9buXjQiGXcmGNifv4FGjqvZjvqVStLU5W-OFw6F4Y9f_bkLj_5n_isUXsIlSRgHJk4iW-9yHbppX1gor9ONV66NIUlwRkysvOddhAT2aD35tNHZSLm6Mf5YPQ-2lcYvKSt04HipALfh8cZETI_zKALxUHtJpEH1BTPiC6ZeDcMREGbHwXD5-1tw6puGF1H5tYeImk5H_3AsfS9Akmpp8aErFNoydPpjqGz02LHTksLjRFORy95DZ4Jv7jatY3AC8DyYlFrS6H8lHcGe34qWi09o7QLZSJYmg0GkVCQhpRJk7gPFBkm4ot3HoEKu9Rx9zmliutt-YP0qLCzHIzfTTYODKi-fZvJnS3S6Wjm8Y1Sv9wz_L76fDdp_A6h_tw8OYEmo6UfvYiRjUok6fwP9mz-nShZwPF6Qhan1Wv4YvhQX8TFE0y6aZhQes1yJ21eF9lsrujfdH6hA-gnc9W0HiFtK8HHNWhtsVvwXkOteen9KiJ1fzjG6fN__tEcU1UFxCXwj3OQmKsk0-BpsgAN8kSe2egvr41alxScLGRAlLdaVEZxwFyANW-v7EGbzRKd2SdNmMauf_99NUGS_iJnW6GINCz6cf3vnPq61Q1EqHDu1xI_Jcdoev306mxaJdXk80-7-17If_7FGUIxCuPR2-GzKNxwDnWAFo20bka8YZp8FqG4p_IKIe2AX7gKu5iER-TrxL_DpOGor-4XFhYt99NRxA6tCROFRKI2pOXRKcIJFdPJBx1saeXcdZN_YnN1dhVRP8-aSC9VXsW5bF_sldIh8vb41cbrhppyz9KVsAiqTkP0kdAaZzC1zBY1dXb5nXirbcBthPToe_MPvsMlSIWnponUd5zMJZRpr9iH8Et7sd-CIwc7bxsIEr2zumvAJrerPZB8KwYkw9SKO1jeT1O79JMhzhwGv1zoQb2d4za5mc3q-hIrEz0oNqxQ87QZN3LEbaa14ceyEHYQeXFTMdqInkM5yzoNIxHjE5MeR_v3mPiX2IOcZ3H-xWq3QaJo0NjCI-Vz6TBhM5cbyPt6yUr_wBG1VGYtZR_GOq0JjR24DsgJZ2-aSY20NGsujoKB81OU9iMrwngP0WX0_10bl5z87-dzl_csu5ZEzChHqpXlcwsjhX-Jj80r7KnkoJ9B6p_39k5HOyYEBRKkB7V4_AWgAz5N-pgMGCW0bfwNTZrEOi6Hl4TUBNK-0CTl0JzN-VbRzUMNVWU2R4n8egInb1vm6B3DYLPHgPPhM6HJk58JO1uEtvU6v8eBV0thXJPsklCVIlFD2NvmoxR2IKUHFE7hv1Y9yOSyRKe03abEQM2RZoXhHaIRYneKJ7HoPZC4X5UD4KZmdwVGLm0m_pLJcSqoWt-QOHe1Dh9lTkH5gdutg-7KJowDLpxee-pMwjGwPGIGqFCiSQQ1KJlcwhmf-azeHK9QPNomwqnSyxkpvNSWMOMhXW8FKAyIvrgOqQGr7WHlGtkRkoFAX61-qrR8gcwHfHtoWhnLyy3NNcbiLlFrqH7e6qiBfAj5ZtaF49j8UIVV6fAfAs9s0nvdW_0L-1dbPBbqgLi4KrZd1JOkRjITB3peNqhk_BESeH2covHAyMpIUEc392QUOy5cm7sIJRqBkN-n176pGPnvRSJZaubnCRIn5pv5ZXtR5VqO1DQB5Erv78mqmY7HgHiOcAbWoqtCWguvEBAuYX-C9QJl_jABKCDjqlqaF9UntJQ9atYoQB2MYIblWVEjmnI-VrmZjSuqv1MId2jym7omvWYLG-KULhtbSSk_9m-LeLtVsCZrhi6w10R-GQszwcbTLs6UhedF1OhNnyaJSJG8nqv2B1pVzP0LkWT73sBz1AnhVYj-qXxXjxJuEsp5YVnIPd9tn3lg1UbqvlWjZcsZCB8AMsEwyh4gsw3ABh2Pr-El-UyP2aoJ4RAfv2DGb-qHHVywV8B5KV8RluV2Lk9Ua5znKnStamH4_b3-YViMH0ZSBeSGdJEBcw_WXZij3NcIwOg2Sai22xjYa2cX9h8tuzBLdc7JmJGwA80DfRHdcaKtn4UcEx5kRi76OUFmFXgabExVXCOXbANDyYp4khw5wblBuIIplLWAsGch7F8GEq9oXYDsSYSrtOAA42H6LXC6OPTgAboeAR1mWl5k21TzN0WaWZSP8_DPMgWbnXf7DK9Qie8ffdg4XsjmiekxhVvi6e3QZVl3hR2CS5uJPPxTYK6eweFCgVV7dWml72yzi8MStPOt86uqI7JYZWqVPbnds\\\\\\\",1]],[\\\\\\\"13D6BCDA-AC4C-45A9-B9B5-920A16D93AB5\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:19:57.220Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=135527&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"06F044D8-FC39-4AB2-A3C9-77B87F4288F5\\\\\\\",\\\\\\\"4F044CF2-7E5C-4BD9-A3CC-A4A4AA4E3744\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6z2EnlrhKLarabzdmLD7Njzl71esOwZcid_xTQHEKAbOPcBWo_ABZJmPTXNAzWS-9ydCAMF8bUTfkZ8QyeLk0Nzyt9lsUfLqw4ASMqMZfSMfWtxapuBCbk19tQdeYG3kJGpU0mQ_9vnbOy4Jt5bKXAwCKx3r8fKuJU6JvY3Sv67V1WSLv5bLkXEcZnBZB5AZ-MrWtsiS7k_uuGi6qNxUKic4VC_JEfmeQuHHapg80Ts-J87M1XCB8F8GdoziAY3-GtR5oZTXvq8nNN2Uj2ko1xPo7A_OgRdaG4Z5wrKVIRgIKhRfFCWRvYynv3MYhKLMLl3ke0Uk2-r-cCPTs09Hway7mW5giB-iz5_lTlqPqLPZAu12d3igOLHRECaLxF0keXwL3WNVygfbfq0qE7QqfItrabSX_OPWhmHF30LSzlH20Ah11DU-EkdjfNMK8UNU0Ugv4EethtQXGjtsqtdVsuESxPo_RXy5mLQTl2x9sBECnvBiDmqbp0u7NAgkQ7ls4BbKXYfwzDC3w8EkjN2As5ZFTBGCLs9uR-2ujkhEDQg1l0qttsMaa62kvgCq3afzg1AZNjRFhyxb2lcqfKM4ru3s6S45ZGsEilspjPzc4oqAAiACD3d5CbXUwTXNPR6-AaprKBovgpyIHJA4RMqktWXqK9mNA8hMJ-KdVdxI9BDGjgs5Re49GpDfBmrVz6uBSvbLXWHnfeFLiWYrc_C1r7HQaZAPUdzadjqp2YG7qSccWffN5Ak5vkhf-Puw8XzXIZUOqsUB3bI5leCWvYXIOcxnlHbPVppnmYcLC6s_cx52f0_FGcIxF6iq0HeCcniE6bnDes0reQ1k88kxUqLZsXATtEdPIlymj9z-3CaPS9xJo4cF01dYXUgEwmclRBvKfKCY4gTERJ6fZxooZIvdOReMSNTV7iM456S0h4sPVMXozTw7EsFjOgYZkh1gMVgBZ6XJeBNg-vustrGPKgdsdy6e2mYyDKx-EXs5R-Dppn5pDNf95wEMy_MgxiMfldVxLO3LmoZst3VXT7McwTK_nct_CSH5e04jMrhI8PxBq16uTGPcUxxvUJi0gKS2-F5V0vnAIf_lN4Lmo6Qw4h92n8b2cMNa09tQjVF8ecIGkXWy3OAicHwVAXdtbTK21Vj_r1N6BSaM4PW16gxPGwP9Tp8debAKnYUCVTeRADhGX-8Za5vT3aHRdKjqiyE_RW9UZ-hPxm9saCI5K-G1NUH2I_s6WQLnShjl3_rs8Pmufxcbj0ZtEzXbcjtQobLCNEQVL_OJ5_-fm4aoVVW-smRNwpKqUcqevdue9mfbtASyZp9UWIjOX7X-Y9mEqYsgMOA8E5ImA1jfopUIpo4xIHTOd3BZuSXGoZ7RPiYhyLrf8bj3cLQOoTJfp5v4zQT_rDiBpOW8EjY68l-mGFTNJL2nd3FmtlC75kUYLUHTwQhns1KUV4BM2Up8p79FGcOLFK1RflXZTZ834ThWARFE_YtBi5D5arqB7Wg14BsWDkLz8w8KE0Zm-eTmVNLCu771VGNbDpPpYwxRAjg-W3SqryeNPWjknnc4XOCM4RMA_qdqbj-0nOcDNQnfPkMMeq-Igw0yF94M2k2sDn03tWDYbRTG5n9nBQ2ZJ363MAV9lq9HYFq6sVxiotRuhXQRl6N_8RIghhO_wXOC2IHqGbj9X90ANGuKqzY2IQfiuz9re603RQPDy88N6qNd7dOIHIkHGAlgCA-oFoBK6hM-fbC6gA8MzfeC92KCkPNgulEKE84hXz5CCBkpsOFCX7opBRVmhFGxWHb3_2P5bttbAg0JAQkcmGtZUhLtaipXLcgFxjTrFCKbmw1sItKT8_fmFsAzWpAqZo0p3MA8EdF-jLNES4JG5UbwcD25vaFS-xhRw7opyGAbN_LkH1c43Gt6z_NpJ_5B6CnyrmvjW8uel-8X4X-X-3su6txpXG8nUS2Vo_rtZVHK5WJdXVNW1RUtP2hML3iKNnrmAxISNvTLu9tPVzB1xS5znGdsFaOm_S569NV6HjvNsjgFbBEzkAB5PCW9AqtZ7StX0QEF5ZDAiCd6h_OfqcgR9t8OMgayeq9qu7fF0kmDJ-qWcvdXdHmzv6N0W_Ev9zHjjNtm7RUR6k7AS73FCDz-kTdTQDe_3mN8fPel1fNt2VKleLNlX9LJprhmNXFTRlDZktxiPXNe7mVQd-k7ndTXSRRqsV3brzUQ77HlwTT7dqnbWiZ-Jt4_-jCh4FBNZsRI7OZRU4eFLHrpkFC8seJCly6lXW2O7lnLG6zwoN82rEy6CeEhpjNzJPahnEVQi5JS7lmSfCQnJCKFkWVXJhAnR8VHxrhFBrbXgCAGGGkZ2lpwtpk-dBXiRGmiERCpWu63KaEly_hw0sMqCGjk-aRJDA84EkfxLuJR4fbFwrsHKbcA9951PHgWvJ6K27--9PXO9TfAyd6u-euRhEDjjK45LoKw\\\\\\\",1]],[\\\\\\\"70BA0B27-A59E-441C-8C2E-CD8E9F7C9142\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:20:07.236Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=828625&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"D887BB95-D45F-4884-8BDC-E3F44D68FFA5\\\\\\\",\\\\\\\"DCDA3CF1-DF42-4053-AE48-E7A7054E9DBF\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7YK9uBA14Mnal5eZS5AIVpD4X6oOQpQ4z3H3bUdOh2UcJwS91qBOVhg6Gz7MXG2F483Ha8-z-a6ygTvpvgORnPO8UB7Z7ZKFQQgNLgJECGOz3xzEh2jKYRF6QZNxik9DuiNT2dNZze2nu1KtAhO-Nqbyt02VckJhSu3HUm7o1E3sXShz9TpikEx-NkpSZfqXSA7KKn3nS57orzeT7IaOVkHpkQAhWu1O-IVxvDADb1GBXSSvRd0xMBM8eVhpef0R4Hxwb0B_yYFjTYaXMXbinNGewUzqkLtIkNcsAB5nX_dZ58Yg-WYJebHgzUQIkVGvA98Wt-OUatfr3vEERciAkzlK7LuHqBMsZArpLvyewP3G-QeIDnN0Hc_SrXjpvraYayISWTPnz1AQvdxAgcVgP-F70ky6Ot6T4Lv3AX6bslusk6B04UJFlvYhzphX69I68cWEJCQ0KM-ehnnANS6z9idQ5ZrRUlEYDeD9N0xNm82U8vS4M2StyaXSHdgb_IssGkLMMkYIVZ-5jYe08m7p5cBu3PMu34AxigGVSmEaFVcS9hxB4flX-q7pVH7OtdQTCNoYLJGXV2P4wUTx32n6_30qk9P8B2MflnNLmgXt6xi68UNbLZ7p3Gqap_zmb2GkA_CryP0GQ7rhBvSUogha15Y6Syz4pSuuH7aUMtJuF_1P7iy3T3CdeIYHbbPBGxPkZpCuCTriVha1u2xol74plrszWp7Po6ESXfbdjd0UU4AGbYgq10UKxl2XGuECT72oIkR4wt7x37JITOQyw9qHGgCCB9sjZmCZkPSI92ErmzWfibUbuuTy020Y-uYf88YjgdYDbGX_Jbk1ajkbtJTy1iv339tmVDk0RpHykwk4o5Mjg43tRrUQ2Q_r4LC2h5LilehZHg8NnEP-IJZUuF0plLWkHizlUtzKPt7OFFsEgG41brsZhsZ_ActBKXGsoDIXFihj00VfSjHl21uDCgwalKmq-tOHurLzW2dIuzEFOLSzcYJ09T166N0FVyuE7Yow91PO2exZ6Iq5krSRLSJO-tgp5x4Q4L2E_ho4s5Kkkn2Aids50DgV_Q3RrHdm-RW-LNwh7k965nBPEJGJGsKoq29pQW7Iw7ZYlJyi_1UgfIP4H0WQPmirfxYAoaIwMLWb0j3sVXIpvPhul-i9iYrlG-X4N5pqdcCnhqH1aHXwOpx1KrWa3fTLSLHw58-u0aNh_KU0SpUajB-R64OsQ1wkU6PGiejL85yfKTbKP6R1dImPQJBvYzLluDWPVuomF1l32tP6PNuToL0_TrrOSqTpH8xL9YSKQtWWiDvwLCJMCZ_8s-eILB5t2C_GFlDji4nyhkX8EISwO-gFj82MMBzihq49r-oUCrjMBsIhX9MKcWqhpfqsOt0GnLFcUBAxZ1TPDDpvQpK876MFWKYdNyWDz9SmjnwmwzGioU84H7EizAF7nMzpmprqE-nCfFV7D-RDQHNT1kWEb7Y848vUBNyut8sisAwgaxh2booc1cxuwThkd8hV87u3154zmjtXPUNpUie56rQTvzreGrL5EZDmoXOEGqSCyBHKlA9Vhj1f67oRzKzr2HPX_Xr2VRe4OPM4NIB068DQF2vJCzupg_HY95Vx9FKZussBrZk0u-67SzVf_qUn7pti75L_hLMZerK5PQPqGqD2ZhloQc-LsXp8bwfkPt11F5UnQM-jLWmWowvP_wCqBxGq2sdJQjSZjDLxvxpFsjKfEWh8y49YjzIXj1Q-HBaTRN2xRLyDgI0V45cKELI6OCH6AwgFMSMn6LoJyiThmZ9e0mcWHv12irgzBp8Khw0gXt-Jv7ZiRIom2_LXPfcqSwhFrY-fnX9uddVcqUr5v9ZUhUJu-jIE82Egj-8J8PQm7HwUjs14zZwY5AXeyFv7puYmocIg7urLLdBcig5s9P6TamZbBrt403lfF-g9gIRAYH5kyBaUaSBKodhwnIlcqU4BnUZNeVaXirewsKL8nfdt8qVf_iuqzkiupL_edBDYyN4JL7bfeAxlL4NL8KHt8TR9ncl4DxoG0MFSafoYmPyjrPV-N5GKmlhw6oW2spjLtdKyORnQIpjEK1VCnA2FrAUNvvet7vmq9pP1csbdXQJ7BXB7WNA69sHRyEZ1Gz8JjMatwUcEEdyQr00AE9K6hGuVLeAmJw6XDLBPu91wFozQrKE_mf6xLJY5FfL57vPTIeYsikZSxvCaSbHHowGhsVMYX6HBYX8eYy68WxEmGGv_AE-Hq_7ETq5-0_RwJrvLqqJ1kTaUoCrxRmqhulRknxa51Qj2JV2c9_WzYDBfCB9_8pakdKnWIQeEKd-xN81TBNFzf1R7QWu3jJQx4ZPhf89UHki4TVaRtdpTiIKt3LAv8dE5udV9Umn6h4kkwUrLJ4hARr3P0S0CwNl0hS8_M8hfWCZMgRX0E4GzHksMbTGvMIsrkby650FO0qTiiKAcLlQzW-N80sNN_WTWtFzfg\\\\\\\",1]],[\\\\\\\"70E19F8A-5A62-4550-93A4-3FC3CE123516\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:20:17.231Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=125855&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"2374E839-F2E9-4C58-A0F6-C2F0F42BB101\\\\\\\",\\\\\\\"FACFBD7D-6077-4154-B91B-DA74EE8A8D78\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7OXK784tTnLFqRwKd-SLXdWZh8M_pOFA1Pl1Ygc_2WL5hg2oq8jEKnTSZ9pKqd23jcdmq9NWMKaXhCNx-tIzlxG1uQKyQPLaLFlXH-N_Y_-SCRILalM3M1ToaYKhd8Z3ePO05iluVjXzQ1hTay23C8K62I4pF-n-8R0k82ZYoCl5_tJ_WBdJ_OK65SGtF4QoUMOUMANbWdk2Ab96Bo_DcK3eEqHMVjywAly0A9QaV46rVH73oyQqkqnIS1iFnPC6EzbQ78e5manTvRsmretDVNIURe0-_bhCvsd6a2MaH2hWsapURyNC6FFHwSfActrOgahZYMU88kZSi9kzCPgepbw7K0ysvi3m_Ya4vyE2maAQEYtYFewtLTSSCgfpyyhWdswylRxydOqe1Yk87JPuQiFOlHEiiqpON9v_WR__--5TeFheMm8kvDWzG8FCWpfYVXk_M4DWH2EaJfeROd-nfDwwX62eYZe0qppl2pRNJ7wj0cXpV-Omd8dfeymMJJWoCEdSFJhfxZcearv1y84cy2L2Na-HX8WUL7yZfarXAt92-MDa1RiRGhn62sTs7I-y-NDIjxosNsJ_ytDwJo2in9KX3MGx7luHneWgNEeO08LWXhdGoK7Y5dABaf17WSjktzEEDBS1x5oeneMq3rggbZTtTS7gUb6SHE6H6luK0uwE26kfeFJZXu9tO0XP_97VY2DP0lYqtDjLlr_Cle98dd6GV7mMd16JyRbLXpuG_6EoYvBzi3_Gc3AqQ3qWp5rxG5slqQFfq2ptSZzeuwtwFLY43-fg_JkYj8iYV94r-XAldMeS1Qa_fRCrfe5D7Rv4KoY8l_9rMkTL5VWRovN4Lr7IaMdZHFvFgStEX75xRYu5pfo3JL9AqkJNAB3zjEA97WIyB5UbLcF1LuPUrtpzo_KgMSiHcJ6qg92OVaVnNTXU1SC9-Jv2HAVN6eQpy0sXl4RJUqVm20YzJH8tAxvJ8XvLbxoDgquM_gJ0-EE43sIKi_Hsp1ePJVvzErs4KaQrklBbo-EpADzGK7rkYjTCSjNMBd99yE4YqIPMVCrNwwIqwaU5ums73Cf_1GQxAWJIxV74xka7FEazpqXzjmXFpyvnxMeMqv3I9FaT29N3-JSgBhvA9yrNW1NNjmJRuCyMeOEjWNw_dQljidgxHOTiW_HdLrJhYybtYrIwDbiAFZJcWbHY7QxgzdNxcnrs7wRg3vxsu5xwh9O5OXEe2shFtd1bpurBJZ_drcukAIkoQRTKsFKOSbfw8ezsQKYdQu-ayK3-H_E2NQsQYS5CXkgKPbQEhU96pgoHvXklIz4y_b0oa3cbNxVuR8X6rcRj0D_XPRzQw_3LMInrOAXfW2aCXTS-Y85jEaPdkeHsrGvuR-v_NG95ie4QOOhSA1ge6h4IsnPn4ZC60siU8WZqLaYfKlKSnxfELI3Hr3BvmBFJinxE8sZ9ArJWgjv0Sn2bd_0cvK0L9nVN7Cq-XFkapy78iHyyDDY1u4I45PM6ZQTBfMLbNmG8zxGpp0BPv79l8NWLQcuF2rxLi52Y2HwjHxg8wAjBs4ybqXJtyY4eKOb5Fe_JgK41nQ3IbGmIdGFLA5xIfHWQd2-IPRfAGb-nq1hqTEL2sJ_VIQid63xhdOsDZYKxu20bCQ7j0PDtWDszNZrFfwkHwnGmMh_o9HKHMU5_GvIbQQB0joxdn6gZBwxLas5Ruy6QPC_DIir68fEvmOC-esHw3V0BbgZ5yWX0Asn11RWpG6Aolr5VntZ2fvjsp9egSgd3jGa8U6P7XB51YNwVlplcv7vJAtRDc2-SL8ID49AV-6AzCIkf5HUEQ3R0ROz4eQGSSu9C-MNT2HMLPAKJkLXl53mjDDoofr-acM-VBeTAAPVUsMqpDos70alY9i1zvaFnuRGWnpYbYOe5aHtMJsE31thS35c0_JEaNt5lvD6_JdkhHM8fesrtcGPDPMEMIm38ufMnx_o5dYT2buIw-Am8WmoZYVbpVqelYq-aNNYVoQfoAj8pbmeSY0JDCIZfrL7FSbVDvvvKPv0uSN066M1U89Vm3y7sv3lpMHQuG9kExeqwvtuhHMP_J2ufH-dAb-zHQZzbNQbx55dcBUlq3qZR8xZxLmOcoGdkRBzhumn4EyNdeSkFOQUn3O5WJ8djnpWq4DZblwXt5gqEWS6tn5k0Ik5r0Lr17_oZm3-7JlmZP9pCqyXHtDnFCYhXs06BrLA-7wSwLkZ7TGU-QbiCM9eqf84r8742cBQWiTLjvbsPi5nEbPM6fRpA6xYLgkjVHRpT41U8q8q_Gsb1EqGBlsfaushPYw4Rm3o4wkeOLxWk7R0Fw80Aqkq69atkiKapyhtnPwtJVrGqqg7A0_8_K6Slewo5XjFnhqMC3DwPcGLm5AalASXBiXHOm24_WAYL-A1dqM37NGmzfL-dB1j-nEsA46L4i4HGSXn32RfD7Wbm8XF1BrQN9faJbAcyQWWQ5Nzes\\\\\\\",1]],[\\\\\\\"C882DC7E-FF63-4CA0-96BA-069022F8B1DA\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:20:27.303Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=195153&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"58D321AC-6FE7-44AA-9359-02851CD35C02\\\\\\\",\\\\\\\"A91D18B0-5CF4-4AA1-9C5D-DB935C7FE5D8\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6KMglAtP3XOnOvao0HEvflafFPj-AV8jGU139m7XnGokP5snqbeM5eJ93DdSVZFu5FTYwXnoLeVKN_8gR3uIUGOW0nH7XUEz_mQhq4Od9TwAJe6fn3osAxlzU2GbMzZLZBHTlndzNeOQjUTiHWXjxBPbSO385BSu8oWN0mPQL7-De2lR8yiyCnrSQ_JicZA9Vizietmt_r1CDZbcbMbWZmCtNpLSNXXf3Ku8gs2l6yAW9ZkL2tBIBI-PqxkC8HN9biaBLtDcUvYEQrOKufzcOOBzO-c907P5_PS8gtvietQoCYTj9gBOfkbkCmYpcCI1LWMqDPN8z7VsTwR8qgg_8HXjrKRTsphsGvRvt-xmIKQak0r5hdmcS2VbbDe5fmJdsSJ0TnCUayAtI_NmGwKjYVFlsLCvhb2kJmuVw85wpa3ggXc5jrmLzdVjJVfY5MOoaLIPBokvl4bAfyA_eRyOaBYNDlKPyVebl13gmygkym_QhaM81DstdMuL3OSZ3xW0zxoAxqKqPwyU0w_W9LIxTTb0orTb-pYBakw1aqmoca57mzBsvTIIh82ABpILa6qC-JyVg_903x925CUltUoZpBaAwKcHFiGbLsSWWlhcQjZCmd8GgNZBTQ27eqRFC75FCHkKJ_9rZcSzzAhnnVbn5m-eAAiKcMXjeDUd7vgAv0q0UCbeR77bZ83F6gU-2dsHui_8B8SCvPnA84KB2a-nYRwQurBng8ZstGOXhSAvXrQ0YMKmOJ-NySbHR72e1clK1qvH6byDN0FkzvGF75Doi5YskXDvDbJXXUaUp-oR89T0QgJHJmxXNG-TwpZLBwzFOEzuoK9LBQT0QtbdhLzUU-gQ_vn6DiF3vaGuvGur8npvp_Zlt0GSmyTgCLfjXUMifObFgk_b9ijLKR0oQPEVOtKv6_PzaCFoFHwqHCEm15UC4JVJ5s0liM-4A-8oqbO7Q4cb6QirQr9OUKdOZaZ5wTKO0MjUngBSFBT58kOaUPHperra4fAAHcGo0fDYA_jQUaI9gNBMAxzHTxMrdJzIwYAgkNJMmlv_7Xypj7Z_tTU7x1R_s4Qckz7ZINA3mMT_3E3Iqiyf34Eg8BtMbQFjUS-TU-ooK3Net3tr6zBZGZN7oKEznEqUdBNp0d0OvFchhtEo8549xmFgT0BhA65I5gPNipvG1Nf3Mo_9Z79dLRD6R8p9tFPSjfd6Mb8yjsZ3vGhzS14L8e74GT2gvLrnS8G8Kcqc6C3pTXbVMbR0APRatAch6EB6Bqs9IkfvouuJKa6820_n0UR67M9FRE_uZo7hBlHVElq0kyWQwZ2k_Ay6nh4OwnKjHMzPYYR5Luc1Bd77gUrHv_zNyTNh9TT-9xVk7XvGLisUcy8_66VyDsUEaiGqWCiOj0algxQ0hgWisINBIxW1kvMZyuTluhbnfpowOAdLVAFYLlguEzDaqfTdGQrsk6A5kHWaeXGFePoz8fzxOeMZm8SZWKx-islmCizyVYJQHrkraJ4uP1lSQAcYNE6Cr_AGo99ntg-DAIP6VjA9VZueRKzrSTf2JVT7XxEziiZAbNj4lFkRw9awQdRRrqhdxDLYXIAR3Z-ph2hW1-qu3MD-pjVVD_dSNJYZjet3rf95RfLK3x--IwUxgwr5Bho9fJRskWyt3zcS1yG7RWdH3b0XgNC8V3PHAI8r7skg147kcSFkDzvzKt2RfmRSjKOM7KteRgkDD4LLBSNdx06IMat5qU6dh_zGiHlFSVcz_p9BiZgFm9G2IXHbx9O4m95alqjjb5h2MWUHDdzI3fOu5MZKSjmf662MbmFSioPn6Me1JFK19DgXz_RlhIlSuAD62FT2k3fXTFXh1uJOxN1ktX800pcoYt4f0CJKvCLw_jhXcKtqafjTW1e2U4kzyAx2WiDf6Gi-JtoFAh8_2uIxaO-zlBVqZmwSdy3Agor-UnYgeU7sCKHwLc5b4QFjCJSTDElgqPkFR8o7QyI8lJE3U30rBpWxZGhWcNQOwhe73MNxGiTdH8MBGo075PhF3aUbhArWOQXTYdZCYuRYVgNLvZAa0JdgjkMUdYcTolSkZ2ruJqEZ-IU-MhOdNKkEdZ93j3ANnGbxCPvBCHPEQfbgaESY39EKEQpjS7wR_wqLEaopMdzwNMo_o2GraQH_aERDT_OwAtJdp9XXSpv16D1bU5wtoh_Pnwvq5oeV9Y0wI-I8x5QFE33XMb3CI95TwFY_p6YxD5XG8whlvnofj6DioUR3giiGeuJKoWF0PObPGAI7rTtnFnX_OA4o9Ycc2cV2Cz0mldJ4VkVcqbHS9wPssCBJoq7PdOnag6Sw5gC0-AMZFtYuXNAy15dEb9mlC8AopJGlpsKWJ2bnJd58Cl_cCB-VcSmqEP6q7FahNwfiZPwuI9JFWsvO7MW14zBlreQ_ron3a9KSaurekfaqv9wfN0MtVkjc4Md6tV0aSNj0zSSPL0tbsZYgpq7_aeXGnukTUrXVcGf7FjEJnoRzDwU4RN\\\\\\\",1]],[\\\\\\\"5764FD75-4D8F-4081-BE74-A69504456F45\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:22:13.214Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=2572350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:22:51.576Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=2772350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:22:51.570Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=DTaVef&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=2672350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"DTaVef\\\",\\\"[1]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:22:54.356Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=2872350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:22:56.676Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=2972350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:23:00.921Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=3072350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:23:21.835Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=WuwhI&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=3272350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"WuwhI\\\",\\\"[[[\\\\\\\"PROMPT_BOX_SUBMISSION\\\\\\\",[\\\\\\\"43B5E996-092C-4CA9-9D90-865EFD6CEC09\\\\\\\",[1790169787,917000000],null,[[\\\\\\\"IS_MOBILE\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[]]],[\\\\\\\"IS_TABLET\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[]]],[\\\\\\\"IS_DESKTOP\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[1]]],[\\\\\\\"IS_ANGULAR\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[1]]],[\\\\\\\"USER_AGENT\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36\\\\\\\"]]],[\\\\\\\"TOOL_NAME\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"PINHOLE\\\\\\\"]]],[\\\\\\\"SOURCE\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"CREATIVE_AGENT\\\\\\\"]]],[\\\\\\\"PROJECT_ID\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\"]]],[\\\\\\\"MEDIA_GENERATION_PAYGATE_TIER\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"PAYGATE_TIER_ONE\\\\\\\"]]]],\\\\\\\"106577881,106714532,106281924,106184493,106299202,106322568,106701949,106210711,106238955,105484652,106599983,106262194,106585383,119157485,1706538,106437280,106430287,106432687,106225453,106210719,106077941,106486771,106615367,106536611,106667487,106259075,106556077,106676866,106611001,106681111,106501717,106104244,106430149,106592798,106625630,106747630,105746691,1714257,106712749,106297879,106577873,106714524,106299194,106701941,106210378,106599975,106585375,106430279,106210380,106486763,106615359,106536603,106667479,106556069,106676858,106681103,106430141,106592790,106625362,106747622\\\\\\\"]]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:24:07.982Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=3372350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:24:17.242Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=526989&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:23:08.219Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=3172350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[null,\\\"[\\\\\\\"35499362-f230-4bfa-8808-a49591ac4f2f\\\\\\\",[[[[\\\\\\\"t\u1ea1o 1 \u1ea3nh nh\u00e2n v\u1eadt\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA4WkwJ9I0aJuqWClk18YP0cICAvvOapjs7KQQRzqsmpv6mwzh5Ymk7gS5B2DkqQR7z49tl9fqVjEnk8qiiMC6BIjcoHgp0wmAOgcjpBk8oLDLxVr7vlHH2VFS-3t5IGhXTD28UvKYyu9tJtczdwZV5d3OGKXORdsM97-J2TOC8pKCEQNBupUWjDCih5tbPUnnXd-GtBjJ6JHPwY-J-QEhE76njgoAnMuAimH9HaMpcwsZMiepHI_LHfwu9zak8gTLU3I139-M0PaItF_x-n08_RnHPM6LK5YYikZGfeIr6u1pvZFpCJSbmUm7CpP_ILRLoyd-z6RWCFpwZM7B6oP4lhLjid67En5uMUm27JbI_YTC9kkG1IyumClrVOGrvgVjZpsT3TWB5bY6DH8Y4qXitjqP0NA1XeiRYlj2EYXeoA_YZwW9t8tCyAZJ8vpJI_ujqymHZSEvfkdRs0gMqFWoLuYOcOLkQmuXxUUG663bvi7iUeIIADbtIDFRw7MpZUcBcTq-Zw_bMm4sWr8nLn9T4cVZoC6f0YKNpT8rPbVtHPsJAu10m78vGsgFkeAcqOqplLdRUILXzg1Ze6CeniGLF0zZqJRi81NU2FXSOJHR4K_i1jMO1S7ZPrkfzYntOLbNVtE2ibuo98oSbE1Tecdm-MBRdprqltGpf1bFdAypsoYEVSq6akCiZf60kpvbUKKMeHbqLWSqrrN2Wc0reW3N4Hk1CbMG_EpMQRrO9_xUo9dAYxHuiKqMZc6tVM2tUXFkk-euQ2bm92pny5LhULR4FiI-QyioqqH9yP0E_aui-MHc3iL9tyIoaEif-dXDHc4ec5h4CibvERJ33Q8LztgtT7PQG2ygaL5nP8Lg-V1GKTUleHVvGUZTkkyA2HPtfhCjC04d1sRwc_lu6VwGQztDVsZqHeFxUOMtLnLjlAY2AYw8HWzyCJpMZY_7lqX6QHxbUWSlrQf3LXlD6DsVyMzoXnWS_RI9BYPl4bgdNGT3WrEx-1jxiteBM_uE3MWQ4b-AdgsVO57eBaZav1rZ-RMywezNjeKzlt2Z2AJuOlVGjSLKZPQ2fZC-KRV4VICVN0CDCfyqHJb3i0kFGVpKE8jU3aiNh9nX7lk8p2Q2wMFr0qUJ1ahuAStFuODVGKe8Q1MteOQ9IflHxsBk01B_DQ5n7GJDvDHYrW_-LrjGtPLJYEVmCurT_2GYkLvkh4wK83PN7GXgGuWbGvKaoXUZCqoICrklyDKGRXKfw9L5711kVA5Nd_q7lqWbhKdNI3vHtYcEynXMHIA7M2ZzR3tKWdxaag01w3OECDfY_9T7x83beXOKrf4I0N5pgUJepVhec3vZ_WmTseOL-wjWaoJKMqFyBNDvPKjG3y_Ip3lqx_f4EY6lUsMLNGCBBswDm03XmQByqMbMxi3w8uEqrP-zIF1TqxJ3ijVc1JOCmGoxj342ewK3PFjPLIj97cK6PuPr2tjj7F3jspIryO09ODKOL9TEvoVIzcGZFNxaQx7Klt_cSrDKUXfFleeiKUNnmYK4erjtX2dXLdJ9FZT4053VQt5FBwvOAxDki-1g3J4L39OLrjOVY-auSJxMVafZY21JkMVa1mGpieC84qhBAN2hQi3hi3I3dwhkZzWM6mAOt6ZQRjbdFAey9m50BG8TXPAdE6AOq-UhHYsO0F1ztwivY6xpGs7_bSnQbN0YKjtN6bEjQJusdaCPcJNvwTfO23-kE4ZKMSm88tLkg-1ekfgRbh8m1MJOP4M5SmRQpxsy8QaIwzqbXKOsdgxIAYFqhU0yOowKy3qpmOvjrNskrU8pIcwleOwAbXQ-GKpLUyYgvLKeD2aaCbbmzIzs847HKb1uZgHUriSRtT_TMG-aD6KSrBYz_53f2VFds8WrcF-cFKBvwp2J4BWIadO2KEfZV3sGZFVo5WDzk9mVBup_Ers3GBHLvA4xfNdLyZaspIIJCYgpPHt-rSGrHfRjKFAj8tAAEwshgrBlZRQGFovGIV7AOXaKyFl17D7r9QcsUUjjfhDX3fi34KGPfpQ1BQSrHtEB39LOia__luNiFcQfycJzHQVce48yNzQ6UFcWm0plQpynSfQyfQFYUy0pK9XhrBFesY4tlwkoCN7xGliqaNo5t1YVlzbaYLhn_nDaWX-GlBMPfVXYJTpdIKnlGfZYZ2zwXJT3QwFrJYtOb23jBwKva-EnyhDHc22v-Eg7SPcNnZ1Tp00UYVWeCjIyefvDL_ARFk8WfqRZpXXfvRGEQXTTOur4pwUvDXGtHX2kAtriUwogFeMVy1SM3zx_4839xg_xLkkFO2r4QlVkmBHrEXcz0xQ_IqalAU-NywwYZwEmZDDiX8JRNLIBUyelMtwUDm-l9CctPozGaYc1CQekc5UTTRedMUEApG6S80gpTjKj-2LMze5U5pn3p8O75S5OGQ4cqw_ESZJ2vIULaE-uQDxoCR8md0Ew4vPQeAx_YhMQ4J-f1RIaoY74g\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:27:45.715Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=408421&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:28:30.404Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=903531&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:29:54.145Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=808031&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:48:03.134Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=696706&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:48:36.191Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=922668&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T13:55:16.910Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=884606&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[null,\\\"[\\\\\\\"bad4cdd7-f477-4c57-ab4d-859c93e02c37\\\\\\\",[[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA5gEfnFZblXm7Mj8uXUgFfTz2yu7q_g-ibJJ8mZG6MA1aw1a1Ja1ITOvx8Gwb1T3B3ol_PzKWUOJqgmVklIovc9ERcchFa5WoxprLuwuppaywusdkOQaY4SRJ8ttYOkSHUg4-lKYv6gGiN9JgK7C73CkzACzRgfcrC2lUWhsXjJUYtyKUdhWnlHXkUtePv2TcohLYGitxr98htg24C17PE8GLUNaAAeu0eUWDtDOhP8CfWD8v_CuVRN4isXM5ohBXxH3xWVrUXYWYW-j3c6slKLD0jnlVQNExUPhClzkNjWLJDTCSXBcf-CRTjE0iXjFN8W0DLYnTPHzF935quAhO-3JL4HVzFt1sdORfxHIVXXaSliWEhTbL_jcinTcBcdG-hdVtmx7-OHKjp4IlgLso33mUzpbrSM-tqwVCsepJvfabXqcv8tt1XQ7DvIr5LoTAVzxSkKMKjnM9pNhcO15fo5xAP7CXqY-r-uUkiyPeFZ9widHuxW8mfarY6gYNkPaOVWa-wfqG269T-RNPGxrZARXXsRZQKYNOU_EP_AJRGkleVGtplT0fjVd0_QUa2D7ftBmByprhHWuTp4Yv8CjAJOoYUvyv75_DmOX7Ubt84t8Ne6K9NDQRESj5cNjzdf8KQBjAnpJ2HkwDqZAx9_4YDtNcXfBk1kicbZurrF2y-wsEBoCoZsEwDzDnO0ljznIfsnDCi-MmcJoxfUR8NQHPmkhcDY_quzx5KGqoOK-SFNB2wclO1bbRCoNQcDIcVcar2wtDolVMCs6uuAFqCFgaupjmW7pRov4Pm5Yv9lRiBOuOQI7kXhk1Pvr8ofPP1elIIbtvkccFGOQoCKH7ncR9XGVwuHokWKQc_yjiFV4ePJ64LlIc1egTvG_yYGkt2Z0spYF3mcJLtDB5L0FKt0nKEHODLv7q5aUy8axz42O4ZDkxbqeWWRp6FP0_jUlBx-LpXNRNQB5tUjouRyO3sdJg_sdfisrZnicyoozeUQWEBMPDVjtyOKaqltSXb5Ii5z4wFAAjEq_g89mhQRupH2kJb23f6lRqWLAhT_5HgRiaka6Cif3Ya9HVD6R91MqWblK62R5q4iuC8EFcziQ5NOBmaCNzXf30-gNqV6H6RqMJhXJShmeqOUoJc_OiHkOe2pSBwe2E5IXWwupWzwZJA-h87CsoKVD1Q4BGBaRkBji5IH5stjQBaLH6Z0i_d_UFZLZrekWdxj0CTuZp3Wfm-FeHB3XNsqOeZpqmraLhApyyIFnSpxzX7MiGI_CmNm0IQS_qtYki9jmP7doyy2SMlnAs-HXJ-E3CTbIUWh7rcF2u7sjF5SRiQ8lrNF5tmbOKEn-yVULcm8wFdfwlIZPEzevmUg7n9_hLarSRuHv0aok5S57g9O5rBIsWcGjozAKezZdz6A0rkXry5xbx_u8bToN40ZIUAV_cm3YqKHbgT2gpAZK2JNT78ojzrS_HC_3VRVPM-lYD6MdCiL7ZIdgd_-GPY0bJwJ_PQbeCXOueveaeVe5EOufc_AU-BOOTpKl3VDeRmxcJ_J1-cyotpHBtS9jkWFoIFNBtENgO8prFUBlNGd7Lj4D81V32iMiwUrIVu-C2bwkKZH_MwHlV0fErPMTs8n9HPVFl4oT0kXEk194zRHzJk0f8ehtH56XSO0WwXIOvv0DWP1DO8Y3y7cCKVXYdlcjWJTa-RW98PTRWL4RvdONTt6QEZlwL2_az7oqSFtl3SXSZQ736OSNnWQ--H4rgU39jRo1K_QMooTjGoeT9WKpDpxAy77GCW7mk4E9axGf2FxfTYeMCmE_4SSb-J5a9ZAAohCkG3b8BSsXSsbALmzs6RwDeEUkIg47TSIBRj7mjfg5qnvK9V_ig-s2Q-6I7J5aCTsVNpdBRQeoucHdYFjxHHAz42omZvtEWsz_i5aTCix9hMnH9-rRFdbtgEIHbTr8dYIRpwaFfIskiZ1E9axw3OamtXkc6jYu3lzcn1YbmiT60L4FNxu1xro7bSf420HLu1WSentu5LXikIZoCJYov2ACOB4CIsaVVPXvvVyq_2pKDJv4UXFkjZc9QRPlA08mXLWsDCu1ZzqRpytWBNbyBXHCAncqA4SNKB7DsSVW6O9yqyJkRH9-mqPNfNbITkEIynUb4ajhn-m2xMCLhLLRiqhZ1N1WxOcdGatrNFGDYOL7ktAV2KYCqFQxkjrJHGz_TnaN-6aDx53ApK4qpy35_ZzJ7F-TZHN76lvv8iRBlw43vBswOBy5RnJD9cqQaQfptwcDXjGbWJBoISIYt4XHjz1IDtFaZD7tX5YMTSLwXirKvvDsuIfAwJSc2emeRH0F7iYburH--JeJbOTyFLbu0UEdu1Xg8kOeBx1AbfBf2yOv_XXcyVJLBi_d51crbfwiZ3-LVIVJAEmr5GFi_RCQj5MIRhdOYZOpHIxTLLAJ3dsN5Tu5y8lk92pjCo0juhWWKY0S05ScrBkho1A561tIuJfD_4\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:00:03.260Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=616067&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[null,\\\"[\\\\\\\"59737d9a-0e57-4dd6-8c78-5785995084bb\\\\\\\",[[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA5flYkh9E3Capk_RiOA68Tr-lfcNwptXHCaUWAl0su5X415lld8LWADXP4-LHse_snGbfX7v3ptprcLT2ZtWsiOE20Khl69U6vXGdpQaUlVsKWUdhHkxGeNJ2E9UXe2sNPK9NjYih7sGoytTcO3d7WOaoaJ5Z28InHAKdg6fO5PxOwaDz0PjnlVsrz5SyqS4b37PpzBfzp7_RhuN_U6cImkDU1Y-NrJAAoUMacOVllBW6XV4LidA_j85H1IB1C2u6FNuDtseYQgL26p7F8x6pBAvWr07t2K8phzfcSWsGCnsyKR152e8ZIuxD_ZxsGDrP63IyLTOGDr_Ddd59LIYZFPGuZRn3t0lZ-Yos-lIsH1oAPbYe5mVEobmP3bC3Z63O_tL0cvXyka7U_AsIuf5jAAKFqfoKRkouSx3VBSkFqqFEh3fnQt-8aO9vkq7NW3GuRQcVIJX1cBGQgFAnNnWz8dti16rssR_LS58mWpABoPajtsINdcUeuh4BnaRwHIZKEb-k8I-BRrnvTCyi4HbhNx-aJeY__llJGM9W7NJNKAN8skLG8A_9hwGLcksgrcKv8bInwKqOFbRll12WQcAJFnJms8JJK9-18xnxSLN5I5Io_InmGDfvI1m9y8Maeel7HSKqCIJb1bXVt0WCWp7T8C6PaHiBkPMwekUCnc1YP-vXxt8mScf8J-hSSIeQDPRWOqHoKN14CCqHL0QlSGbIx8ipqn0kGYkY_uYjxo8I7ZQsR6CQZq-7SPaXo--QQDL8T5H21zg5-Znw_oq_w7OG9T2A4mCJdXv14imtzLMVB3Z9LtOW9TCWc4DOgE0LQl2VFBRYeboMVbLyLHqU6iwTQYyKr0EdKAcQLMctdWeWcW6KH2hQ_EC4fTzzlKS6-ndyu71cafvmD2CZo_f-7XFM3TqDBcT7UAKpSj_MzDR1h5KG-teYSyUDT-BbA6Cvzgu2AeAolv6xCl9teUxwIMIKFSXxu3JwNI0oWsaoNS110KBUvU3v99_P4c8vJEaYhSgylj3Kpk6J-nF3TFOoy-6MptTcRX8Wq_9SQuYAipDofikzbL4A7OAXw7iikq5ie1P3h99hvW4Ic5jwcWbbKn0ZKS-iNuKAVLuUZOiUkyzgaNAK_8eHnurPwP35KTVbJ9LgoiYUSedCwelyzaWG2dagXDczQ2ITBkAqExluDeQDx2czCJcOCd-S9vkxTd_bLtoIWklEzFsIgBWFAoK3xixZqfFUcf6PhvbAE2RDd5sKDGzNamHQ1U2k-OnFPzzYLwOOpvMSezScaAweuTqIUSM-el-KkmXekD7BPdzxPxkGEzdVALritehjjlrUiJ6_9EypT735c_fZN7891l_PwsoitgddzFzd8SHVIzHQoXn4uOL6_j7lC8v8M7xDvPzhiiolUSejiG8Zx-ncYEwxNpVfF1RiKGNts40RJBYrOhBsZtK8up65MX0dzaN-AdJ1Ji33jnjlCmk-tIQXJqQAM-qXaQGNe6CDgo7RmfNx18ujsZXJKuNCSZoQQL6POzTHMg_gZluVrEuuyIexoadXQDvDtEwbb5ZUK75G5mZ64Nga3VuJZ_gLGl05_fI0FOVPV0JcJCYpbsfM1Ufclz_kNOoWYgeKp-zVucYzZaP0RbZSb_RYYajgNSvPZ6bSQ3lSo3knjgPCE6tmDzxzEB_ewkbYggWxhxhZEz5GEPrV959rWUcXp8OVJgwj4p9unaJvWRYOJo1oOhOPrDei0GZ9NltSapTsYclLv6_wBMA9BYAtCFQIi85TnmqMVs7HFWkPxgMW-YG30Y4KfQKVJyQJN831r-6PwOw7uhPq5Z5YviOj2xdr7WyRdLBr-_r9skLSfjqwlsUJoLLSl8GefDxDRUW_TgkWCt6QRS_mWzDJBE9WEU4NbKa85fPTNN8ZbDsI8B-lPi6L4iWqZaAuruGncCvSk9TwibFX9k4TWAi73TUQ0h1fGavaiyFF4mhP3jA93XvyIx8_GEn5Seht8zmW_O4HM7fwCA5Sm4AOsWUMYltMDqqIF2iE6A60fUYyf6XvlQLJpI26HYakFG2Hnn3CEfjbpOc-UdYpKstuQDWd8qOeo2bBtRbvYPHtpy4S05J-RBaaMa-3pX54sejFloROEzjD8SdapgC5yLGccXotOM88QcVCD6x7mP1obfaBZiQB0NMVXOxEn05YG8CujRMGQb1OcfnhN2Y2SPoWzw1NCQYUlpw_IHXu4MsFI15SO7SzZnw9JdmhbBCW8oFvo5q6d2dtD6hbjw2Acv1q7s3c1SVj1bkPnURVJcxZVYV6A6DV6b0u_dAS7bSUc8ALIRMZJBtob30JW3SGWvXUEM2E8MjGPY1v1GuajC97YDh4iAsK_2_l2YPzlQef12-QbfWLuIwpv2PXaP6IIFT_IY348hDeb_MhaGzIsmQTKqDzCD-FATxcZxTkjxMgbmtul_Occyv3da49H0Tm9rdl7UsUwtu61eJh37I3B_1-m35mI2itSG6l4kChDW\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:10.006Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=o30O0e&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=75791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"o30O0e\\\",\\\"[[\\\\\\\"me\\\\\\\"],[[[\\\\\\\"person.photo\\\\\\\",\\\\\\\"person.name\\\\\\\",\\\\\\\"person.email\\\\\\\"]],null,[1,7]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:10.008Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Yizz8d&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=375791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Yizz8d\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:10.007Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=NfrxTb&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=175791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"NfrxTb\\\",\\\"[16]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:10.018Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=KV2T2d&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=475791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"KV2T2d\\\",\\\"[22]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:10.007Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=cPZSdc&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=275791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"cPZSdc\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:11.175Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=LPzVkd&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=775791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"LPzVkd\\\",\\\"[[4,8,5,6,9]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:11.178Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=qJcgMc&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1175791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"qJcgMc\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:11.174Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=HTrJv&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=675791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"HTrJv\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:11.173Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=575791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:11.176Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ngNC2&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=975791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ngNC2\\\",\\\"[\\\\\\\"tools/PINHOLE/projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:11.178Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=mrlkwd&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1275791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"mrlkwd\\\",\\\"[\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:11.177Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=tRARke&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1075791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"tRARke\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:11.176Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=875791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:11.839Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=GN0Bre&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1475791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"GN0Bre\\\",\\\"[\\\\\\\"35499362-f230-4bfa-8808-a49591ac4f2f\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:11.179Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=yBhWQ&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1375791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"yBhWQ\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:12.486Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=NfrxTb&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1575791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"NfrxTb\\\",\\\"[14]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:12.487Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ve2Lsc&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1675791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ve2Lsc\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:12.819Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1975791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"6aa915c7-1123-4e12-b75f-6d5e6d40d0fe\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:12.817Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1775791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"4630aeab-cd27-4457-96b6-24045de2504e\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:12.819Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1875791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"9aea7396-dc22-4b69-947f-7d1dcc5c1e3c\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:13.210Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=DTaVef&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=2075791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"DTaVef\\\",\\\"[1]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:41.125Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=WuwhI&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=2175791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"WuwhI\\\",\\\"[[[\\\\\\\"PAGE_VIEW\\\\\\\",[\\\\\\\"BC356486-FBAE-40BA-B0D7-3A21166B3DF0\\\\\\\",[1790172191,118000000],null,[[\\\\\\\"IS_MOBILE\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[]]],[\\\\\\\"IS_TABLET\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[]]],[\\\\\\\"IS_DESKTOP\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[1]]],[\\\\\\\"IS_ANGULAR\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[1]]],[\\\\\\\"USER_AGENT\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36\\\\\\\"]]],[\\\\\\\"TOOL_NAME\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"PINHOLE\\\\\\\"]]],[\\\\\\\"URL\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"/project/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\"]]],[\\\\\\\"PROJECT_ID\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\"]]]],\\\\\\\"106225453,106184493,106259075,106667487,106585383,1706538,106625630,106536611,106104244,105746691,119157485,106238955,106615367,106077941,106281924,106432687,106681111,106747630,106486771,106701949,106599983,106592798,106437280,1714257,106676866,106430149,106262194,106299202,106611001,106577881,106430287,106322568,106501717,106714532,105484652,106556077,106210711,106210719,106297879,106712749,106667479,106585375,106625362,106536603,106615359,106681103,106747622,106486763,106701941,106599975,106592790,106676858,106430141,106299194,106577873,106430279,106714524,106556069,106210378,106210380\\\\\\\"]]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:38.455Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=272953&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[null,\\\"[\\\\\\\"2b8dec02-6926-4410-a220-5c9aa2676d53\\\\\\\",[[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA5bVh-WIzoehF4GiHFsSJuqitKIhlIgDOm2wGFtV6zfPBwbRqpmrJ2neqCG4GSlVAVvvLzUKRoLUO_DDRvcVxNC1BgjMGn9m2mZHNSA0capWaaGVGNacQV7R2g7PZ_iHyL7XFijhPMpwKKXyBYRKtzCC4AulukFTdM5M4BHH1mM9_Ym09G6RwzXaBaDlz1rrCAOVbrvI1cp2rVa7dkReQXSip14yLck5QwAx_jRA7O9yMJaWIsBJnox_G8zTdH1cO7vRM5U49Csrv4wGWoFherbOqhmuBvoPxC1i78Aj8bqgSyMTm9AfkZ8XfkjbAqOOwXZdy4Wp2NSzsmg9ImPAPiUh2aMm1MXWnGCa4MEUJ-FiK3M8ptwhTkRRTERy3ohOnyot1UJb11eSifv2nH7zs3xIO7SAHGNzpVtAkjAufLPqVEZiK1I-Izs56K2ttyAsx3qDde5Mmj6HZK6lYh_k1ArajHS16ZBEOw-xzzQsWLA4P3U7Des-7lwIXCtWRcNW0OdlSJ8LlSkm9mdzU-D9f3Qz45PJHnyBypnViIiS8bCdGDSV2NS_HBkcvEkCXGMfHq_rTsm7Z41RD9zap5Uf94XQ3vJdR2gMYqfOfHxKdQpc7cWaNAng_9Yqy-ZRw_NJrtBKu7ohEz08bg3QVSSCvA0GxirrXP5QumFxnmYY9NJo3n-4kNuXCpBuaeDTpX_Yzqba-DKuplEjZhz-Nm0lkXgEFbnXLHrlMTMOeDsh71_ZUHsrPGfuYnzGmOs_IY0Tfy6SdjX-CDwwnEh1B44rypG6uIH6VXWE2WCj9ISqAxueR3ellLufN4KllNmhedU95BlZX_qnIEp1D_zbiTZg1qMWDCGk9ItVeBki2JO1Q3axS-uCr2D8rWbdOGAmjvjhf4gLgB8tpnI2LKlLQYmnkTLn2a4jInFreqgjwHiYmf53nwUutmqbNcbup4DNUzgSN290BLMVqMYIhlG8YV6CiI3cx1Uthf4m10qcvVauLVAA8jN_Gl8vIf8MSnH3__dUkE3OYUqTfkJgQ9wOUjjhc-r12WMYpjuJcGoO7PBQoKR-gbixt0YMRFOAxBD2RbfOdeO7BcS5Aj1ZPLrthAT5g3N4quHV-n8PNS1MXUIgzpQPy3SHcWTpOiORRoPdWw1FwaFNzs_9LXN7SmINbx5I1zkO9g94onFPOT9b-tDeifoEt-LcTlYRIk9gy0ur5HJPsLx8MqLVCFHOTyLLug2MAerF2l9pdekZjJQuSFgPkZeDeymBpzJKKyCPYt6PROh5nIzhFkNmmvZIQPho97_3PXtxGh0q6KHwg9KYTYf1kZkXCL5ngX2mPF_Bz8a82X70RvyT8UZs7j8vqMF2J7uiaGNr9QVjG46fLZtkkXxisz2FtG65SemJYdKUWFUrI12LkNd-eV4QePQBJAJtKOhNP9Ab4W0zeiiBOh1C-towutZ-WUOfA_rPDtwqrOi4SlVICEZaj1aYgqnCoyJCJNYBNRgN4YpfB7H32vKDh5BzqCTiqpIK8Zcf0mcTSSwVzWwE9PxX6i1hZs0khj_RPAihibyB1hKH7NPfFKpicG4hLuCcUdr6K8tc55r6avDalznQpFbvoxb2skCnqJooQ5L3TW3i-RiDYS9cJSiLZBYostUTXa_CG-YjslW7uQZGDt2-lBb8J0TIpfEMPx0Tcuu6_j_YbmtL9YwshdzNVFEKBFn3p_S_csfsOauB24x18WucgbCgcWtA-x-mervGJ4NPKHWOCVctI37e2t4bCB0qgBUv6S0K6dKotBAISMeMgrSvpwxMO63t3kMmFnpxR5Di4hK1knm97zQEXlx6TtgfdRZhWRxlAKtRF_CT8BVL_4oX3GThrtl2CywyZyOBsZQGmYoWshscSiFqMjrfhOZVa9sLW2NRaiHNy7aS2UjyXjHv-c84T4h-k-JEFJf7nu9fBYhv5COn1C_KIDyfCiWhHbkEE7bRwT_VZ3hcxXyv-2Xywp6xofamKPg7jYG69AgqwDrlVHwJraIQopgD-huxuVdUkdddAVy6Nnfu0xf1r1GNEfCsjg4HIDJbTavlGf02A8TldE0cQmxN5RdQ_NV85JqXqBY18pHBMf9zxlzWt9UaW4PvBxLjnf6xw4gfsF1tu0-lyPT2mXqXzdSWXe5GVxY4nn25tDMots6Ic7UbWqDp8_QC3-4gH2FFJB0hqduM-K-iUjYYLrMqXwMNxpS7o82IoqVni4n9IpqwyEW4RS4Omo48JU4HXPaQvHKpZ0unps7BY7hnJtZo_-QnPNgvZghyjTOiReOTCDiEPZc4C6s14LKfOIBMje_2lNgHrJT6l95HCdUJAgEO0UTsMIwWchwZvEtNLa5ylSQRYj1ZmUCFrnRifh2FZWlhK3TaemJXzc2MSX9Tr_Hp3KPxc5p7TbkoA1wxoYb2ghu5LVi1Bg84UBw_9vu7riUc7rRY9tHrgvCItBFmg\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:03:47.966Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=948408&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:04:19.120Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=416254&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:06:30.541Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=321250&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[null,\\\"[\\\\\\\"58deacb7-2a78-42a2-a24c-783d71a87c2b\\\\\\\",[[[[\\\\\\\"T\u1ea1o 1 \u1ea3nh c\u1ea3nh: Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA4OM_CL4g0ACav-OQULVejqyPS_pTJF5m0KbTEAFX8_r-XwcYNBFxpFPCMrmylBHRQ76xgefqHMT6_buwlQImByoYuUmRdZVaw5xNN-CblG1CbiMJuxrkWE5no9CWLx8XZe4mW5HRIWbzO6qKHZ9Kx64VQCuX0U4v7szPr5gyXBjQr8DIxZ_3GWGH-ncxGWY8ORFu-_krnuG9mZIfxCu0j9NROrFQOmZ-TbYe_2rw_Y__xZTloORz5SJI5x_SQ-Z9ns8qX_YxP1p-PX0RT720PGqrWhp6mdk8D00Sn5s4yHJiQ8USY8giHxDWvUpZfmNLAxCj2d8OZ8pzczZwWL2E3wu5HtUQmb2u49weNBDoOKuNksRc_NY92kidNHr21FCvWjeUrqmF9916OgswBdGtv6Ar4iKYzAd0eMxEfpSaAXMOJLLe83xVEsRSEYpUhpXpNG6-1TeT87djJA1EbfPMPimvKarpUxEMSlKYO6WIjVdmm2s6tAqL0vQVzITwiKU0OBl9D0NPMjTJY8_r2jk5_YrY4BumMJJcujzVVfg1JpWC3_awZUXxyDhQ5oAO4ItQccnwUrVtSsVLZm_27MjKXSjJIGbTyPnJKHGSwah3_1rmV55Y7oGeu9tK2W2hwU9sqj-qN7MQG6AeCfRlmqc6qheQLg4EyNOb8-K_hxPlfzeRYDxywA8D7A6NhtiW0E1ijnC76UNTLDECbRijTzkP12RkdJF6ssEZFH9WkjsGdmBjvJLmSxYR4_vm1aT2P3tXsxgdbiPU2U_8kQA5H6-wSMCAKCqsUeP5t51uGzUJ0wghyhMbjH7iutNAKjbQJCF8eUdhotF0lL8ShnaR6KJs4kfpSH--hXIB--GjhHBpCGJ_umLBhoMW4fq0vrt0RF-qSO8yzbTqxiLg7PGwP5fn9b4YVXl5ub3N9nVuTzzP1_1LgRlSjXQ5ope2QJosYH3tnJw7aKiSKXp7U_3STNnUlY1r4txCM0stx_RHXlTO7ahUM0nUod7GJ3s9MM34MKoLXRCSFa8JFTder1xrk5YV5d0qVrNmvMB2_D5cCwOCKbvLFecrYck5ympEr61TRgEwa3D7Vh6HI2_hCimULdSec1RS9vukx6hHLWdjYDo5VRjCYWWTroebV3_St2FCwbOPTD2DboSzoaL4lhvcp25znE26htL3e7Q0uN0M6DmPxZPe936PRY1rphhrSER_bWK-dL0nfZZVgwIzRQFa0kjrqszopuoQx_Z1bYEeZHDqImwh_qdbOdFsBAlLFWXgRE-oIQVcEjAiGRxmHHn3z9Fh2u9mJKBclhvc7WlPRtEdwjTVfbCy0New_sQXNilYAikWhUMaEylZH4wmTQXoUel3fnzSyfJ9Qt3enIquLtNxW0cnXtSYXwf-w4K9ssgm5Ig1k-nYmtceabXUNsnDPgaPpUkZcTvvCB_7NUTp6OCuZtKz_jllatz5-e9IpPFZ0uwRyvEo6yzFP8k2ICdfrPY6_Adqv05vSAU0EOLdJMWHxXrOehyLmE6jM9YNw0dUE6MnDiZndn__2peJRMoveXqREOgbN4tdzGWvMUZIm_y9TmzWx_oM4qyNVfEMstpbZ-aSW83VibAmSpIpbchmocCRbQMFqDkj0J7jkC486TC8ExZ_NmxmyRHQKXsmYHzInJe1UJcaUYWIvgVKo4-EQTKFoTz0RILbagmxiUxTa-Tv5zyhNVt_eNOCJS4RirmWyjtadEtK4sJH21PmOWRsnqa0KFJoa6TJyHR0HrmCc89yXXFIOd9IAcDgPzif-oDWhQ7A7I3bVF_RZKvWja9zKhc5dN2MbKOUMRvWHTM4CkyIoUc39XlBqBpNI7LIxed6W9b5jKi7JMANa_pG7-Gu3_6Wo7Jj-neco0RAo1Kx9ZtNtcJxR7Xr5PwW7C7YRk2hAc76VQovhxpU35HQqVJ_H4G-cZ2kKyTOA0jV7_grhsq52x4In-i6QyCOkXhir7DuqBo6BpfvUbCVJhA8WkIgAHaM4Eb7e4Z4o-QrrSyjtG7K93ee7GKNp9qJ4uv3bWSEZFwGB8jX6Ara19-UX_xEnZcYd7qz9ZmIryWSujm-yAunLAIZViJLRYYhe9l2wA-yEXURN717u1zFkOewS0Px9r7xtlPOo6WIyPIcvVTo73e20V5WGBNF9JEKfEcX5SVczVCmsnLPl1JERndL5ScYkiRLiHSt-RVP1HT6c3mXEid4-sZPsXtZSDWJHOgX1JXt8Ujc2oQZzZM8upCD45q99sZ8qjhv0NonhJk9LUOvfZ3EJ46ZdAwust7biaHTh2Eu85S1Bjr1imk039aGyZB9NT2G2AZfX1-BSjeF_lvJHqt_nXQznsI-r6QCe_Xikyft2vDNGsZNcLqE6LuFf4UQULWlG8ET_ErUq7NMLOIZEzlRZmlVt41JEupg4dP6tSqBX3sRmQHgXp9l1quZJbejI-c2j8zFWE_M1-Tp_hewOTvPyjGYHtKomK9pU8I_3Wl_VGF2Adg1wb\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:07:16.473Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=993395&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:08:03.592Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=553839&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[null,\\\"[\\\\\\\"cd0fcbf4-b76c-48bb-b59c-41b53ed3cc75\\\\\\\",[[[[\\\\\\\"T\u1ea1o 1 \u1ea3nh c\u1ea3nh \u0110\u1ed7 Minh Kha c\u1ea7m dao ph\u1ea3n b\u1ed9i L\u00ea Qu\u1ed1c Ti\u1ebfn t\u1ea1i t\u1ea7ng h\u1ea7m B3 M\u1ec5 Tr\u00ec\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA5JIFF-7aIU0P6itAIt4ycbGhJWm4RQ1AwLLHd8z551r-F1X4-twtmuMGf48MhZmzQiG7wyNNGfwLw1i0fWDIcoTlzRfm5CQWr0al7_yRs37QkyG8UxbpsI5KeSBnIv8076ONzjgBOxugV1VpeR5wb-KCVRNiAecNtPTW81jcV9nXrx06pcATJNLtqmf95oe8HGVpC-grWtwGz3_Sz4GZrqkQkwOyMy7Za0zRMgEWLCSVY2m60Sqbi4pVEf1EhTAw6ZFJpn-QZA3jasGcx6Id6ET-gpvS4okuYbpI6CUcFHu8P4Hgvuh9pLn7mqoPHW1RrJwRsjCet3VrnwQct_Tfz4cwwfUr3E-9D9n2AL0ajsmPwpX1-gqfiOLQ2GY2lS7QxJMhg5-Jk6D1c7FTyhdWALTfosc2uG0MRG8Ff9H24COYCArtqznUqzW-mJUimRxRwrj_xyLZAic7my7DKhXXXdLbnecMFWb_T2Be3vg5CM2w52v9qYXEGKjw14gnEDi4PrjO4omgccgAgCuMoEyrzZxOkIPwEPHjLgHU8OEMVrTxUig_Zxdo2WRRHl-5n7NRL4v41MUdMLrBYbRQhOO-UGdacluiDljqJqJXlmT8QTzF8hi4MK7s4pPYe37zJPKdpohBg9YrKCyAh2d8TF0h16ss_FVUTYd7bBwmlKGNZAXE0lYYKosKHcpgnj2mFgi91eDSQJxbDgymCrPPaBHA05Ofez4mNmm6Gl3XpN6nLiUvUa0vcqfcMYGNQQhRtD083U-_MPheG6VwkqFv3m5musgc29nsdcOjcXQUEpGtZDEKR7bQ-WUIbhRcIIyyGHFkCYD6ClWHWaG0r71cPCqpde5Vwl2cfVrxRDEZFzM3QujcNrSo1cf_lWPvRe1UFSDks1xUhvMEWOGHpEGyirk6E6pPwtn2BlnMEFSZbbgZRVOARGmkOw-j-Iivl1qXg4lFbF2RkThL3V9rGgjdnD_KhU1lZKx3dynvHkMrLEzOACCXBh3k0Yy2dtbr2WNLRe4Bj8J1RBf5nFxAPAVq4vN1ANfMs5anLwv7LmG-VCMqYMcGS3QFs3nfeIcWTZGZ-p3_5NMdhlMi3Aba-HebdAd_hITuIUIJCMrE715aMT5KIWC0zmwIVyBmHBETqPn5M9KHSVp6wW95XcJ5eev_2y9Q-XX4Ua2VBn2wA74Zi7LZxoQ0gr2N8vOjmm_SDufcy9XVSDXZYoa9q48QYty0am8NP0yPWtyB4WvCQ3imaFuKLnjS-3NeA6hkjZo-czJ_iGuXLuEa4HJykrsSH7jbNs_92Ppsxmi2pDO9cRR3tzqmAFUmmLOdZDCNGz_bWMGpRDgzul07UJOyRM9AJ30OcTE_G2-qSUa5HcW009CdXybgQ-ePxLsL5LYREh9Ju03bONmCQm3dBvX2EQho-EX-tdQ0AwBhlI9wrFFwkDItRjbjO2An0MRPdkrgZY7JwBzmF0DQDwxy4JmyyKcEFFm4Lb6HgtgWxY-ek5JSnizGEN9p0ik54_IMTUWLC3mwAn-GKgAASWnbB9IGv5-7z5RXofvanoyzBDzvq8xDoE5nh52kPMxkgk0TKl7L8yWkLCZUrejyqGMXT7koLlWwHxZzalhEuXHhnV8n-xymPXQ8O_qrpeG2wI2_4GCWm-o55kcEVj7RNUx9QmyFoYjSZrnk_1oMONiyKAOZ78c1DNaabges89naSQG_LdM1_axgKC4q_6-LJm5HLBG0Klzpu9Vwgwv0PCcVMczSBM4UdV5UEG3aGns1zy0ug4_u6UkBOCgj8-oqk0xIaObML_FO1c8XZBryBFyHF43TOaR_9NC9OeTdNBpIwx5ZBRZxv2J-y9HIfSRxAwTxPBeZzElHyQN-XmDY0DuWuFT6ty2bplu34W6j5dgErbAAuUtplnSbNwtY3S83y9KeqnvAphjNZ2EGqDmSif96b2SrBtl988bVwy9HPYSeewAsc5oUNd8M7xgRr2vt3fhQQnu1VabToxjL11tIOxCT9Yb4abjpnS_JWvc4BJiUpLVBqCth_xwbMRM68m9rC5DTAagq1w_v_TxUSNOE-vmZ6z8fwmP2cqElgo5_NCkWhziWKjJg7p69NNNGFKyz9LaLdXim3Nv2xdTXwL8YyohRrwJoBMIULmrvugRkiLFP1pgeCQm7ETuQsuJsnCsxGOtoeKJ_ltJgJYUVIVHYnpiDK0VY0QE1t7qPKPnx7O4sqqCf_J0DWO1DZwgHRKw_ffbpYH9unUelai5DebS7S-Z9lPscaxN-IK-vMGSw4iiFcIB31a3O3vvc2i7TaFltFySzKdtKELD2vGPJRhLOlPt_nIoVBbyEFLQkt8mvsp_2kP81tuhx_JAB9JyQ5KMMaGK37H15OpLnX45eCfeR7NDVPzollaBpAJlf-7Vfl4Nur4XW4EcUl1FisBp0HbJ-uxrCIPFOhlw_pYMDOmUjVtuXVayA\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:14:05.382Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=291286&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:16:10.852Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=195163&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:16:28.711Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=583455&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:18:57.602Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/cspreport", "method": "POST", "body": "{\"csp-report\":{\"document-uri\":\"https://flow.google.com/project/594758cc-11f5-4f92-8b3c-1213686591f4\",\"referrer\":\"\",\"violated-directive\":\"require-trusted-types-for\",\"effective-directive\":\"require-trusted-types-for\",\"original-policy\":\"require-trusted-types-for 'script';report-uri /_/AiSandboxAngularFrontend/cspreport\",\"disposition\":\"enforce\",\"blocked-uri\":\"trusted-types-sink\",\"line-number\":3,\"column-number\":39,\"status-code\":200,\"script-sample\":\"eval|document.title\"}}", "statusCode": 204} +{"ts": "2026-09-23T14:20:50.939Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=504978&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[null,\\\"[\\\\\\\"007b60d4-79aa-4a7f-8133-cc776c4daba7\\\\\\\",[[[[\\\\\\\"T\u1ea1o 1 \u1ea3nh c\u1ea3nh: Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA4nGEZrnO8gZBpTbrdZoxRQa3MOxZ7rZixFPs2pphk4EzyMN4hI1y5dUeNPRbzZqbFF4cdyWA2Mq_TNcshgQgpTHfnqtCzVCvoEeg8_xpWx7JRq280f6K4WuQrK4t4wsv8MZMhCPTus5dguh3DwdY3ohQ0yozyy4ohMmXhOKf0Bi7ULYFqZnvdvPVPN1oUOqPq5IovVd5YBoKDcv08zlmfCOAzkeS5TR2a79ojGSqH0Y_UmqtZ8Vyktf5W6g3P3IvgRlZQDC1DDl93VsOGhdTtZeCKvhcEvdhzVdcak0UhtyWfIWe12ygs6l91cz02BbZlCJhcUomHgV2WUGpuCHjCzaTHqwa4yc_JRqBsXlYVGz7xmFeI-kwK7pWAoWXjiwIxmh1oe6AZYY3TO-G7_XvthPWZjUfuWxrlCPTVv2bCA5X8JdzyXt04_FxdfVLfpmqu2afap7kwz2hitbbqIbzoxzGESMw273Gzj6SGKy0wGOGEuqqxz0wrlekYBfJvqj19ZK5kH2gDYurw-PI7uZtZQdyjHqSaRVR77pDvDxEblRE8fjuGsBOIpynyD-JRHL5k98WO-UgUxOEZsm3lHzD85DdVkRGga5i7xGlbvvTjbONTEd0dj7rtm6faW5jOdkyB1QcokQFelgoWJKqcTp1S8W2hq4Zd1_O-y-ap5JoBptpSSSoBDiUdan59gvGOJnI2wiNePY23tw_jbSwDKQiVclAe6kvKZEL_d2KdQj1_4GkwgdexEdy6-4hxDm9qqCey9hlXy1oz3tTTtkZVj_J-NnlJu0ceW6zT_8AE1C7Y_2UZFty6SZGAF2ZrYHIXQyhj2oXY7YTaLgaR4MHVILev_vbDkIYtKyFlUGCSNAZAYjX1E8BVFYFyvThSYTdf2hku3j8TKTypgvuhUTAnr3ATqHLGq3D99SRoKtE_d4S75rVY0l6746S7N60iX7_C9WodXTAmD12nPyQGWZ_Lzf2sw1Xjy7uAZwd3Tejl5oElFLsNjU_Coh64xBB7caX6bqHfpfdP9iFKef7TfqHvfTpI7gJ5_jxUDCdlW1i5_uuh-26BH3YF8or6h9wvZPGjnWLBTlR6GDOavY8Kk6E2BAOZwaVZpDa-6mKkdbmGUFX90aQ6IP6vTMwBuvxVvufaJyh3b_eLerJOPTExdV4HrOHDbK0zNvdaERbBSMMVriUk2usi9JtG54igHaCIjlWLfSDccEd5ITZSSSfpwby6dWd7gtDIw14kv8M8BcAilcDmj1857zcUJ67F3G8bJdz1sCrglsrpklQNgXBWo4Vf5O_PdgtQJfPMD7KQjeR3vHOUjJtnnU2nJEg0dlEp9t4v5qWXzVyKxGejcW_lG-t7TqPrD0X0dCWETS8FqQDUjZ9yVXXl6GvkAtjC9hezBX5uMF7a91uRQbmynJRwgOz4WahDXk0ptwb1ebourL1-TctxLYS70cizbpyy_gzTTAFwElJ9qoGj02lD2Xa7fooiRV0GVOx_x9W3TAE-4OSQLor5ShA1S1_gbhcJsedagUu2RbbnvgP-cBDHiPhoVS5Ybu6ki8gGJiaGR5YM9DCRvOCz4QhIJRhS0C7gFf0wQt5TlkN6pjsf7X60ljD5J7rqbmrGxfu-KKeVJYH5oM4xPYx3xVRRqJ4KWx1knWpvriClpyjEfYZIfmBff-KAJKqei6Ji0uklWnKBPQLv4UjVbNEzyel-4FFqwUKBYndmmdnsBnkLFRYBadE-MinCFtmVVNyHglTOeh_snre8F91mJEX2wTbHfsF18NT79HKOYGm9lSv8raHUq32FmhrFtguudID5ClWjAU_6tr1Zs5ncORI58BTI21AeVaFZP8n_nvdjc8eeoysTvZWNhCY6g6RMy4Vd5UEcy88H4m4ONXHqnTkZJT80TcXex759XlVFqa0HIzW-h-TW4a3eevRE8eVkCD1RVktewVmpUUnQK7km-epplYcCGyX21SxwspzBHOFIQLQx2ajgGZPWJ5692e_Q74YMYskjMgMeuI0DtUxDoliLaPNOULRW3dPfIbIDbmTwVKJZlsxo6hpEwr_Prhuawc4YZPre9UkvZHs2KZ9lSjkx4X2dwIOZ6BhPtCZ5FNs204J4-2OzUtqgfZiNrsWS3TFsBE-pY7kJZtvMh_uHQ5ch1bVPggQUkJ_g2Sq-tpcIYxna4g4b_J5gczpBQWaAbGcU3FrKsrj93FP5ly7vqNvlLAxq8NVMts668MK3fQh2JHvApeGhTPsVDMDdWuJ0YUBSwM3jhGLfDtzVw8UIWSHqwknnuA_us-N-EGVP2JRscrOP0zX403ZF2KO8W0TROTexq42VK3jLARnLoDumBSPvrPthnyWZi_kWRr0acoi1v4T-50vcUBA4R4XLdyJwP5nMCeC5Oa74M1pBDy5Rb7sErirCe5-gBinN7IHeIrSLYrbNkYqWfaOd6u9gNZKYU-n31NAeLsQ\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:21:11.021Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=496170&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:21:17.378Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=269722&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:21:23.690Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=406796&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:21:29.938Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=460121&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:21:36.133Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=437058&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:21:42.662Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=241527&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:21:49.132Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=414981&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:21:55.800Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=390676&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:22:02.369Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=548750&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:22:08.571Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=786878&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:22:14.723Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=137743&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:22:20.803Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=335517&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:23:08.046Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=261476&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:23:14.303Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=989133&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:23:20.471Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=706242&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:23:26.728Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=482931&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:23:32.801Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=560648&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:23:38.871Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=643359&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:23:45.111Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=819320&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:23:51.227Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=778217&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:23:57.288Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=274919&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:24:03.387Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=200786&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:24:09.486Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=858929&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:24:15.589Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=925067&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:24:51.847Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=483820&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"a6010398-57c9-4e27-a89f-31ed0ddf2d1a\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:25:04.567Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=123865&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,981155251,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,\\\\\\\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\\\\\\\",\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4Nb4t5YNsBWqExumuLjLcPOdartYsNEJ7gAdmifJ_vGRKBl6qrFDkGyb4hfz1ihHPMGgDDxQCh43Gbyo_ZGp0n0O7ahTSlRqjuEA9DB_LE1pLRBeVimWmfAIsntF6KPiDQoGahdsjFeAfYOWb4TVz6jx6UUv00wTeDhW0kgBE_7phXAe7f_x8m4TI1b0tRzkujO1oF6YyKDV0XvDytIBCRZoWA6pjWC8uXv-S7avM4fqulN2InDhAmQwWmFJrXIAqG5_OZLxfPP1u6Mm3EjB4ItC46ZXXmsWQi1-7FBGXzP49VrmAogkTiuVxHgpKn6PNGda0XkTQ1YjXh5G6AG_-i_P7RnA-33OIzd6ahxfzDjmUjVdbzFN7ku3fP_9uW3kIK5BPTUo-P3UxfOJyZ2k7DO20e71n26igAG58XdwOrczq4jadOKJxiDpQQq1LmwzT-ACSXrQYpMIhdfB0O7Toz0VGbbaBNfoyCoe4I3rspd_EpevQ29sAyy9mzQOrELJ-APS370BedC_e2Zy2PBkKIxawrVBdXis8_Lzz5T5oWBM41GfjI__8IGB_R_5o1-kIUM3_6VVWGMKECvz6YTcpkhqKjjymKr1B56J0yzrFIT_mRw92h07LeYoZ7UYOw3dhm3FpeX-Buv40dQBEVGxcIa-AEu1TOxgFXn6pfnTX0SRghGRQXWJ7pX4FyxXCtYgVZcizdzWYXDsjuniGxsZ7Fseq82seP18VGtjktQhMrtvaUA8Jywa7dw8bnAr0UHUblJdFxlZjBW60pkz0pwprtrH0HawXeX8rvCG-aOS2vxu1J5sc6KrD178iUTrLp9RML3CLV17zVWle_3IDixenpnqrgCC5dQs5UtgI-G4RJDJD_JsryCt0jFM3BXurw0i8EwmyDvidM3chJyOKApEAqYJxWJwFaD0Rq55AdcoaaYIcRSLR-XKyehwBwDQG1Vn9GK0izcjAB7P6GsQlLT2xtZFVAOvHA_qQPPN0Zfv-vmsfkYeMhyF7A9sYVugAQoTcW8JjMxobhLtfSKdekwwMa3XGygfInMzWvabqLgNyb6i-we90a61cf0k1CyWlqDY4sEhcjhlom7CfkbLkXSCpr07CEhC-__O7datSqgGJo7n9jLPZzoCd0IUUvlzNl0jqzhH72CtX4gO9FA0P68Xm6M1wdJLvjEJpnLCJXKOeakjvl_cRmZ-00PvMiPvdetB0aaa6aa5TM07xoxA2UlhLtRXwhT7Dx9P2cgGs2iIeu_lV2nQKzBjBYX-zoDnMnYek0HJxzMV4EEyr7jOcULVWQGZxpfAYFbYIq_oSYMDo4AK_aAcKIRl0VY4tJWbI0GqVC7NbcIRF8RYvbHVe8Z8KDxkxVTEOIiU6pdvMEGiNCUKfVKxvQBvQrXolU4z5jMWVyUO9SmlUvO7N5xaDSb0dS52BeXIxF7LNtv9_DtmRmh7CZZ_fgeq0RHsLweC1o5_8xn04zo6uQhApKUPYuskGFmJ1ybQNSMHOhu8qc-tgH4VtQHNzF0zvJ_FiNC0TDS9pajP_LMwVo8cGcJU9KaJqRhEdFkUQEVhQuiOB3bx2vzQOR3QVTQ031iWx-JmjM-z6UqNqSvv5U0AqNAs-mLT7hq9RVpZRCqhxy95E9AaJEqqT1_d5KN57OjjdMFhAuUCIqiV8YiauH3klr8t-Dc8VBcwMvENg88UYUzGI8XgPFn-JEkJAF1rGVrtTslwe9ABql_hrMCjKBRrbBVgbVdQeUTXu8Go7yKqYuJyYxlEiGCybg8-KoTP8GxjxgPfkZPsgTKGu6t66O-K0fV_jlTHFi3qjav-j3FJ5J3ftzhg396zhn-nF3w_OFAGwMhOcgw9xqyh5kkKSusqPPAFHd0youFFiovvpoX3R0eQKYZozSxo5WqmDeFhNDAUEEeB_6gKja7Usr8N9_eo03VDgomcGkq9DqjJK1g-hk9CIB2vvPEyqkv0nmiHNROyP-y7aIuxvxlstN54GhunTSolfK2zemrxvW8udZw--p4Wvbvjwro48Bsd_23lXA1PdsHfAaaWwoWARvOynnKwjbkaZLR7-BueNwDJMic3Id-NgShRXCneEQCnvIRp6UJj3dNvd1-0BuysK_AgfrScIRynHV0pkt9Zr4chVIiP77ftwR8-uhm6RCNZmOWzaUZYt84CNiZdD1rWKsa7AtJL1-PxlTXKIhH78J7l07kAomlW9N36GffMlXIJBO-h7WgtWvRrQI7J6ZV5-55rQS0RCK483wE4SRYEMVa2rRwS7_0gnjp7hJRqrIDkZoRr4NARoSkY6BRyXzlQyAybqLQ_6mGtWkwcOY3TsDSiAOSIYVzAOtzMaFrsGnOpLtjJkBgnTmMznj8bf5IqxoT7Y6HUCut5w4lU4wV7YymJ74wNQ2Qx6WYYe5YmEdxTNcByyZxZm1mGhSFbU4_MxhWSjokj0ZreeslceA0p-pQg\\\\\\\",1]],[[[\\\\\\\"A dramatic cinematic shot of a young man in subterranean B3 basement parking at Me Tri under extreme heat, 35mm RAW photograph\\\\\\\"]]],null,null,null,null,\\\\\\\"CC144D8D-2AFB-43C4-905E-7FA24E67E8D8\\\\\\\"]],1,[null,22,null,null,\\\\\\\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\\\\\\\",\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4Nb4t5YNsBWqExumuLjLcPOdartYsNEJ7gAdmifJ_vGRKBl6qrFDkGyb4hfz1ihHPMGgDDxQCh43Gbyo_ZGp0n0O7ahTSlRqjuEA9DB_LE1pLRBeVimWmfAIsntF6KPiDQoGahdsjFeAfYOWb4TVz6jx6UUv00wTeDhW0kgBE_7phXAe7f_x8m4TI1b0tRzkujO1oF6YyKDV0XvDytIBCRZoWA6pjWC8uXv-S7avM4fqulN2InDhAmQwWmFJrXIAqG5_OZLxfPP1u6Mm3EjB4ItC46ZXXmsWQi1-7FBGXzP49VrmAogkTiuVxHgpKn6PNGda0XkTQ1YjXh5G6AG_-i_P7RnA-33OIzd6ahxfzDjmUjVdbzFN7ku3fP_9uW3kIK5BPTUo-P3UxfOJyZ2k7DO20e71n26igAG58XdwOrczq4jadOKJxiDpQQq1LmwzT-ACSXrQYpMIhdfB0O7Toz0VGbbaBNfoyCoe4I3rspd_EpevQ29sAyy9mzQOrELJ-APS370BedC_e2Zy2PBkKIxawrVBdXis8_Lzz5T5oWBM41GfjI__8IGB_R_5o1-kIUM3_6VVWGMKECvz6YTcpkhqKjjymKr1B56J0yzrFIT_mRw92h07LeYoZ7UYOw3dhm3FpeX-Buv40dQBEVGxcIa-AEu1TOxgFXn6pfnTX0SRghGRQXWJ7pX4FyxXCtYgVZcizdzWYXDsjuniGxsZ7Fseq82seP18VGtjktQhMrtvaUA8Jywa7dw8bnAr0UHUblJdFxlZjBW60pkz0pwprtrH0HawXeX8rvCG-aOS2vxu1J5sc6KrD178iUTrLp9RML3CLV17zVWle_3IDixenpnqrgCC5dQs5UtgI-G4RJDJD_JsryCt0jFM3BXurw0i8EwmyDvidM3chJyOKApEAqYJxWJwFaD0Rq55AdcoaaYIcRSLR-XKyehwBwDQG1Vn9GK0izcjAB7P6GsQlLT2xtZFVAOvHA_qQPPN0Zfv-vmsfkYeMhyF7A9sYVugAQoTcW8JjMxobhLtfSKdekwwMa3XGygfInMzWvabqLgNyb6i-we90a61cf0k1CyWlqDY4sEhcjhlom7CfkbLkXSCpr07CEhC-__O7datSqgGJo7n9jLPZzoCd0IUUvlzNl0jqzhH72CtX4gO9FA0P68Xm6M1wdJLvjEJpnLCJXKOeakjvl_cRmZ-00PvMiPvdetB0aaa6aa5TM07xoxA2UlhLtRXwhT7Dx9P2cgGs2iIeu_lV2nQKzBjBYX-zoDnMnYek0HJxzMV4EEyr7jOcULVWQGZxpfAYFbYIq_oSYMDo4AK_aAcKIRl0VY4tJWbI0GqVC7NbcIRF8RYvbHVe8Z8KDxkxVTEOIiU6pdvMEGiNCUKfVKxvQBvQrXolU4z5jMWVyUO9SmlUvO7N5xaDSb0dS52BeXIxF7LNtv9_DtmRmh7CZZ_fgeq0RHsLweC1o5_8xn04zo6uQhApKUPYuskGFmJ1ybQNSMHOhu8qc-tgH4VtQHNzF0zvJ_FiNC0TDS9pajP_LMwVo8cGcJU9KaJqRhEdFkUQEVhQuiOB3bx2vzQOR3QVTQ031iWx-JmjM-z6UqNqSvv5U0AqNAs-mLT7hq9RVpZRCqhxy95E9AaJEqqT1_d5KN57OjjdMFhAuUCIqiV8YiauH3klr8t-Dc8VBcwMvENg88UYUzGI8XgPFn-JEkJAF1rGVrtTslwe9ABql_hrMCjKBRrbBVgbVdQeUTXu8Go7yKqYuJyYxlEiGCybg8-KoTP8GxjxgPfkZPsgTKGu6t66O-K0fV_jlTHFi3qjav-j3FJ5J3ftzhg396zhn-nF3w_OFAGwMhOcgw9xqyh5kkKSusqPPAFHd0youFFiovvpoX3R0eQKYZozSxo5WqmDeFhNDAUEEeB_6gKja7Usr8N9_eo03VDgomcGkq9DqjJK1g-hk9CIB2vvPEyqkv0nmiHNROyP-y7aIuxvxlstN54GhunTSolfK2zemrxvW8udZw--p4Wvbvjwro48Bsd_23lXA1PdsHfAaaWwoWARvOynnKwjbkaZLR7-BueNwDJMic3Id-NgShRXCneEQCnvIRp6UJj3dNvd1-0BuysK_AgfrScIRynHV0pkt9Zr4chVIiP77ftwR8-uhm6RCNZmOWzaUZYt84CNiZdD1rWKsa7AtJL1-PxlTXKIhH78J7l07kAomlW9N36GffMlXIJBO-h7WgtWvRrQI7J6ZV5-55rQS0RCK483wE4SRYEMVa2rRwS7_0gnjp7hJRqrIDkZoRr4NARoSkY6BRyXzlQyAybqLQ_6mGtWkwcOY3TsDSiAOSIYVzAOtzMaFrsGnOpLtjJkBgnTmMznj8bf5IqxoT7Y6HUCut5w4lU4wV7YymJ74wNQ2Qx6WYYe5YmEdxTNcByyZxZm1mGhSFbU4_MxhWSjokj0ZreeslceA0p-pQg\\\\\\\",1]],[\\\\\\\"5DAF8A3A-3AA1-4DAA-A775-9DE5847A8407\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:29:32.624Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=DTaVef&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=2275791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"DTaVef\\\",\\\"[1]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:29:39.227Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=205840&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],220865438,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5WtHcTtDcCFMDlN6d_nyuAk_KbYNsVA6cfXDA9KO9g44J6OMISnFLfdz_yB3cUo81ooTeAMLnP4FfdBD57dQXC9R5UimxhgLrF3ut5tWytNe6Ovtp09LKRt36htUCD0HoK1uxUO5jZO1-qfr8jyJwEkw8UllQhj7XUp8uxvuZCmubTZ0ub5gHMS5XBBWO8uv9NFuII0teKsXvfKamUjULlCk_0nhsYX6RmkUTCs8MJX9bk59aMC5TMoZVxeRmJ38rtgHVgN7Nm8pUX8_5N7vr_2jxLRt97GWjWCkS77a4Bpl6d4cHer8EMpQaxZjL_S0HUp48CDAECj6P4Ul8ysb8qDPIUBfpfPJyggStwjG4Sfbn4WzRK2awiiAJ49FZV6W-gdnCETF1ZPaBdH0vASJUSL-GzOotzTfW8Em9-pnZtKpJ88djUcLQqVEY6xorPPge_hGNMaaLoSudefW1SmOO30n2kJ_Zi7nWqY1BMykU0ZVhd2rpWv4VrtKgKQ8h0xEB9QSJZ6RsIaqlXysRsIS4sxETqer0zqhAuTfflJJnGMQIRTFrezIKC6HpqLo1KW6N201dd2IiFp_3OyeRAOWADKxrVJKXOeKbp8qlqSmt-nud-pMdVrvVuI8Qz60TMlHqbQGsLoeDRq1gSnxPzkWb-v0g93Cck_5DgsYASa27RWOWmwZdLzGPd9BsFpwCI41l37WevHj536FBMkINiZYQGtIGguJqqN1GsXvnr9p7Ez8E4NLKy9I3QB_3bNB6ywMe3LHulKUen5sVpDJFHlEF2Y7peHq8y5ChxqEGMrHizNooDvrsyYWDCCZgd7z7zCXw9Slz2j-6MadttMUPd7l2QoCiWXMhUWnsfZEfWVRd8piXBGkSTJsRn3DL-oOk1EsQBjeCVxuLB4-WdcsDij5rq_78KSLEaQF91pBdnTSYRz9S9PkQxi9KkoR3hrDN0sGwy9Bz8KVXjapu_5keQfyaD-a1-8JqUpnJYMWHJJEE_sdHkjh9_XWctqmvaJtanHcWM1Brx3xu3ka89y-ckVPx6d51bIhzGvp-ThV_LoUcmblY1pmIV8W2KCdb1jSm8M9l-mCoNiRyGHtEgyUky-o3yb8PcLY50meitugLa0xnhcUKybPy6AiNQWer4go9fpVQkqTakIigXPaZgdU39mf6CrCa4wJHv-_8ShLrEsgvYnSSyaWH5MdKV3NXRprUW-Z4u_AZBo3YPD6VFxXnpJTmv7k9CwM9bW42QsHUa7KRvOfWKDJztlP00-mgEOErFAwgBHpMkh5ZmngP66CVXF_Y_9r6CcH1Z7vsBYls_MhsGdFusS6pyjo2HxmJARScmE0xyRPtOLh-rsYucLbgQ5V6y8Lvg2m44bpzZ4JaU69IjiwJzlw6pOIMCH3SZx-2JwgdUOTAm3grqQih7kr_YODpgmViiw7FQ-pUWAOq0bGl4_Oy31tzDRX_PE4PRd9978rvMOIEKvIZ7oZ2wi0YMOOUAnVU0Ay9uwOd9bCZsqSwUoNIkX9BEhjpBzZPTqi8y6F06-5jQQIqxgc8L6irmEdD5gyFmePWdHyep4hnYqizaJ3ycXYug25KbdDgSSkKAfAI1EW5dFTzRY4o1D8OwsLuyMcZyix8L4SdfmTMsGVJywz8FeISp83HGKDnRyG_YSQK_rT2fxkiLrCupHOxX1_I4OjpTWCR_UlkKW27PJLS3q-59dSqWlKU7z8RbboBR8RTy2pIny_V3wfNElZoV-mV9Gq-wogIhM6GnovMztW6gdlMGJqKnHrrgNFv2-PJjm4fOhIoi4kr2SLBhfmPAZiNB9te_3TZXyrqYg2ZgS1bqKVZLW9T6CMFQdXWzjuWVbxvn8GQ2s2g836-QBwbMz9wQkg6wWrTRtBdYFsSKnEJpzRl_xGAdez83Z4sFgERC6gbZ9mPGlsJrrxxEImWn6L6-agH48jizRk7TGR92cB0pxIu2LC5ivdQ-Lg4rsKrtr2VWqLECW1vRJOvEr-Y1tUQO9cE6gA7o4fY8wsFCHZ3g6NVaAufcYzDx5MlsGjKzP8HRZAelIEyEEdVkXJPCUVXAWVNySNht4oY0sf7qJnynpVTmLSwTJ993PSyAXzQXwW7brv8nMa2nSPLrc5mpLSSFKRwSbeOOGjBcp7NWEKGmmPWsuru4wFmcBBumCkxiauWygNPz_CzWr1okVi_nsNh0VM2nlkkepIJWn67iU3hWdpf-rSPujNEZAnMuzt6iBbcD5gFZq_nk8fU2eCUKLxqAd9yUQ0ZPtgV1MQ5hhA3T6I_Bz1FiE11zQO21cL0vKRsVSRa_B3W0s_gRFJSLWxWudKDz3yEV0TjH5wcufNwy7nJG2n9p4OAqjBoj2fe6qwHjariFYQLfCTLM-h1wPMUQn0WJR2ozmjouqMMTI_rCiJyFjw1MmcXdRNA0C_J9H4MqEG5i\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"2FDB6047-5305-498F-A2A5-405FF62A2521\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5WtHcTtDcCFMDlN6d_nyuAk_KbYNsVA6cfXDA9KO9g44J6OMISnFLfdz_yB3cUo81ooTeAMLnP4FfdBD57dQXC9R5UimxhgLrF3ut5tWytNe6Ovtp09LKRt36htUCD0HoK1uxUO5jZO1-qfr8jyJwEkw8UllQhj7XUp8uxvuZCmubTZ0ub5gHMS5XBBWO8uv9NFuII0teKsXvfKamUjULlCk_0nhsYX6RmkUTCs8MJX9bk59aMC5TMoZVxeRmJ38rtgHVgN7Nm8pUX8_5N7vr_2jxLRt97GWjWCkS77a4Bpl6d4cHer8EMpQaxZjL_S0HUp48CDAECj6P4Ul8ysb8qDPIUBfpfPJyggStwjG4Sfbn4WzRK2awiiAJ49FZV6W-gdnCETF1ZPaBdH0vASJUSL-GzOotzTfW8Em9-pnZtKpJ88djUcLQqVEY6xorPPge_hGNMaaLoSudefW1SmOO30n2kJ_Zi7nWqY1BMykU0ZVhd2rpWv4VrtKgKQ8h0xEB9QSJZ6RsIaqlXysRsIS4sxETqer0zqhAuTfflJJnGMQIRTFrezIKC6HpqLo1KW6N201dd2IiFp_3OyeRAOWADKxrVJKXOeKbp8qlqSmt-nud-pMdVrvVuI8Qz60TMlHqbQGsLoeDRq1gSnxPzkWb-v0g93Cck_5DgsYASa27RWOWmwZdLzGPd9BsFpwCI41l37WevHj536FBMkINiZYQGtIGguJqqN1GsXvnr9p7Ez8E4NLKy9I3QB_3bNB6ywMe3LHulKUen5sVpDJFHlEF2Y7peHq8y5ChxqEGMrHizNooDvrsyYWDCCZgd7z7zCXw9Slz2j-6MadttMUPd7l2QoCiWXMhUWnsfZEfWVRd8piXBGkSTJsRn3DL-oOk1EsQBjeCVxuLB4-WdcsDij5rq_78KSLEaQF91pBdnTSYRz9S9PkQxi9KkoR3hrDN0sGwy9Bz8KVXjapu_5keQfyaD-a1-8JqUpnJYMWHJJEE_sdHkjh9_XWctqmvaJtanHcWM1Brx3xu3ka89y-ckVPx6d51bIhzGvp-ThV_LoUcmblY1pmIV8W2KCdb1jSm8M9l-mCoNiRyGHtEgyUky-o3yb8PcLY50meitugLa0xnhcUKybPy6AiNQWer4go9fpVQkqTakIigXPaZgdU39mf6CrCa4wJHv-_8ShLrEsgvYnSSyaWH5MdKV3NXRprUW-Z4u_AZBo3YPD6VFxXnpJTmv7k9CwM9bW42QsHUa7KRvOfWKDJztlP00-mgEOErFAwgBHpMkh5ZmngP66CVXF_Y_9r6CcH1Z7vsBYls_MhsGdFusS6pyjo2HxmJARScmE0xyRPtOLh-rsYucLbgQ5V6y8Lvg2m44bpzZ4JaU69IjiwJzlw6pOIMCH3SZx-2JwgdUOTAm3grqQih7kr_YODpgmViiw7FQ-pUWAOq0bGl4_Oy31tzDRX_PE4PRd9978rvMOIEKvIZ7oZ2wi0YMOOUAnVU0Ay9uwOd9bCZsqSwUoNIkX9BEhjpBzZPTqi8y6F06-5jQQIqxgc8L6irmEdD5gyFmePWdHyep4hnYqizaJ3ycXYug25KbdDgSSkKAfAI1EW5dFTzRY4o1D8OwsLuyMcZyix8L4SdfmTMsGVJywz8FeISp83HGKDnRyG_YSQK_rT2fxkiLrCupHOxX1_I4OjpTWCR_UlkKW27PJLS3q-59dSqWlKU7z8RbboBR8RTy2pIny_V3wfNElZoV-mV9Gq-wogIhM6GnovMztW6gdlMGJqKnHrrgNFv2-PJjm4fOhIoi4kr2SLBhfmPAZiNB9te_3TZXyrqYg2ZgS1bqKVZLW9T6CMFQdXWzjuWVbxvn8GQ2s2g836-QBwbMz9wQkg6wWrTRtBdYFsSKnEJpzRl_xGAdez83Z4sFgERC6gbZ9mPGlsJrrxxEImWn6L6-agH48jizRk7TGR92cB0pxIu2LC5ivdQ-Lg4rsKrtr2VWqLECW1vRJOvEr-Y1tUQO9cE6gA7o4fY8wsFCHZ3g6NVaAufcYzDx5MlsGjKzP8HRZAelIEyEEdVkXJPCUVXAWVNySNht4oY0sf7qJnynpVTmLSwTJ993PSyAXzQXwW7brv8nMa2nSPLrc5mpLSSFKRwSbeOOGjBcp7NWEKGmmPWsuru4wFmcBBumCkxiauWygNPz_CzWr1okVi_nsNh0VM2nlkkepIJWn67iU3hWdpf-rSPujNEZAnMuzt6iBbcD5gFZq_nk8fU2eCUKLxqAd9yUQ0ZPtgV1MQ5hhA3T6I_Bz1FiE11zQO21cL0vKRsVSRa_B3W0s_gRFJSLWxWudKDz3yEV0TjH5wcufNwy7nJG2n9p4OAqjBoj2fe6qwHjariFYQLfCTLM-h1wPMUQn0WJR2ozmjouqMMTI_rCiJyFjw1MmcXdRNA0C_J9H4MqEG5i\\\\\\\",1]],[\\\\\\\"7CB340F6-610F-4028-A515-9AC8D33E16A1\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:30:04.275Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=763711&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],163715532,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7y5tAKFW7P63oi8gTcg4nMKrUG2meHNxQlTztEORA6cZGJBsknv2OVgtkTuEYZY80Yldih4t8uee3dG7jeKi-frdRKrk7P-rOiqqMkNkBSW_oqN3poIIwYnPsGP0qipxxZ7xbS0UlAqZog55ok1NemZLQuGMw77p__cqUt-d7ttv3BbhkdhoVAr77tHASFQOjEvEobR27gZ5qCVqmNIVmt1pndiJwXozDrwEIpq-ERzh0FfHfnGKFRVW9P5FuHD1p_bVBvkoVoahl77_k-Cv9M19YzMBNdAPrClLszOVyqQCHcdy4YVSF_O64-OGd2g22fJXSFOmvn8bt7_kTCOX_j9vHdmpFfZ-CHuNrN3enT-HwEEWx20_-aVaDKyIeTBigjoRpQeBoOGFs0cQ15euwHBXcigFDZpBxEpUIkt1iedgPGdc0mu_N8Je-gQJ5G8WImGjqdL0nm4bmCMimer4DPnlt8Vpt9om0qjhiNjOxxxnfQ4OzeH2EjcOUWgfx_-dNBVR_lvSqXDlzEC1NLiq9t4C-OXS57rnf7bykT2jBNf6vbgfHNe4xxGlWWtAWHg8_XSd9NLXTM-Sx8C0wSRPY71KAVOynL3q1dr5BPVEbqTAVOeiV94-HDaaRe4dUHo3rGkmYf96_7XkwOW1PpSVgHFBHR8PjSETWWnhA2CRm8Pt-DEaR3t9tdWU32RehwCLACdwDiGn3FLdfvaxG20Uq0eZbMqc6_cGNonhlwAd3f8fCLJXGY7FTwMENXPlld2UyS_4yDvaQE5e6T3tNUXcCaiBoszlA6Z2eIyrm3sIDKq3RsHVH666E7XZwF8BszcBfXOCBZpBoVrbLkCY2yhp09gdoKeSFQRylbjUPrC4z-YOC-4HSxjblLnr6eZQSYCHUjAcdEmI3GFeJr71KjIvAB4hwIHdmLmYgejRUSCcHnRggCQ06tlCKRs7Im6hU3_veW3shxmdMx9CzSUKmmrTJYRKuCH1eGhPAXRyjS89MwArlpkJS-ewdYJ40l-QTLuMfCkySSjR8c4rGKHczJbFDAzy-rBkZYqac6bkP6vKf98oZKyLpoeSnxCpLsqZKJFvneMSscQ4AJdWyubp42_eBIfgSEH01kUT3n1JOnJUxbiuLvT3WzDFQGoS1MZMh5OZwkBPDsrFbZU7thrK2F8sr9D6rEDaJJcn3n2KgbIrtaI_VeUVaPz7ou-yCUbqzpBs9_rk8JHod2ouUdheKazUfMJ06c_UnOluygMT2UEkeJ3y9sG1fPOJ-hWbzh3-vs43o402U7AHCXFLcEBUvmp-JmeGYZJ8r3TbcK9-nWLach73TWgUXPtD_4BEg40xzlox_NbB3IDXGMo3KsdiBwu78zqWoM4UE7pIfG--UPOp1mNae_TWo4eMh4BtDryImQU4Kiu9UbBTTmmHwEezlUoFUNSsfJJ-kTx4zXYbHQBWuaXOrYNZ4ayD0jGTdqPO4uPkEzefihfLxixXlw7RYdYj5Tlx_xe3PxGw8LOdGSgkS4p7Rk5jvgcov-3WpZiEsb_TT9aCkITj3bTv1HFIJwNnjeTYKvrl20DjZ0NNcU4CYUwFOCKUVhSxtBmF5vBYyX8SlEq6ZhX-4o0TrYT6cI8RLP4Dm4P0uLzD0ih26A6HlZ8hpjc9_FNKa-XUYxFWYUpDH92l04JfBNQVDvbWDq55DIYDGMktNTYJ7PUmPOhv_1bDBeaHxfUyWyfhHVLqBoDT0Ht30Ty1Pr4X6b5AQRN15N42pTaSavm0sDE8R0w98zmmhXUQX0h-ybLuQG1EIP3G70dqB3h1B3b7MLgWb99Zojcp7arcB3bKzSmJVopbaf9hWORDkUu-WiPG3UfkiAC-pUoRrGiGUQA76lrN2wtxSP6iqmjXHpsVGksGdEUAtMqIsbfR4pmoTpzhqOP8cMN2KMgfUE0sVMsOg3bEzbWboEGEmbCG3BcYJQ1kR_iQAGAI7HjmUmYrZEL-Rt1vSuyymADqI2oNnfzgasL53ywGTpOFxNXf5L5G8_UnVRLvC4YUEp_cotvd-_TQ6uFsUuV-SHa39POIkNUqO6PyN-VtwjuyufVlgj-gf8jbQiHA0iS_OQt6dSRzubk30R1osem2q-YHvVE-1Av-FcuTSUK5UHvkQAscuov4qJGHqPMWiNNWAAPuOAWyh3QVClfbgrHAusabQyvIXYfmp81kX1dYzdOzHX2xAtMh93fGMqNFJJ1nLhmoGAB_TmpTHsuot7xASd5nkgaYNyslgDEJPw8bADtZzPY2avePwTE70dZTvxffxjxxyLk3pQxpsdalq1CQT_SSpMX5R6CXoeM5mW6G-_Ht7Zr2WPJbjE4bmVmlBjRGuT5ZQts8bN4Dg0-4QRkjed-J3xFa7ecEXluEyjqrjodW8tllKSa9dos0zG5T3yiQSPv73lQpA4xXi99UhfKlvXQJLx\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"3BB9A74B-4C9F-42D9-A274-B3C0DA4F3F70\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7y5tAKFW7P63oi8gTcg4nMKrUG2meHNxQlTztEORA6cZGJBsknv2OVgtkTuEYZY80Yldih4t8uee3dG7jeKi-frdRKrk7P-rOiqqMkNkBSW_oqN3poIIwYnPsGP0qipxxZ7xbS0UlAqZog55ok1NemZLQuGMw77p__cqUt-d7ttv3BbhkdhoVAr77tHASFQOjEvEobR27gZ5qCVqmNIVmt1pndiJwXozDrwEIpq-ERzh0FfHfnGKFRVW9P5FuHD1p_bVBvkoVoahl77_k-Cv9M19YzMBNdAPrClLszOVyqQCHcdy4YVSF_O64-OGd2g22fJXSFOmvn8bt7_kTCOX_j9vHdmpFfZ-CHuNrN3enT-HwEEWx20_-aVaDKyIeTBigjoRpQeBoOGFs0cQ15euwHBXcigFDZpBxEpUIkt1iedgPGdc0mu_N8Je-gQJ5G8WImGjqdL0nm4bmCMimer4DPnlt8Vpt9om0qjhiNjOxxxnfQ4OzeH2EjcOUWgfx_-dNBVR_lvSqXDlzEC1NLiq9t4C-OXS57rnf7bykT2jBNf6vbgfHNe4xxGlWWtAWHg8_XSd9NLXTM-Sx8C0wSRPY71KAVOynL3q1dr5BPVEbqTAVOeiV94-HDaaRe4dUHo3rGkmYf96_7XkwOW1PpSVgHFBHR8PjSETWWnhA2CRm8Pt-DEaR3t9tdWU32RehwCLACdwDiGn3FLdfvaxG20Uq0eZbMqc6_cGNonhlwAd3f8fCLJXGY7FTwMENXPlld2UyS_4yDvaQE5e6T3tNUXcCaiBoszlA6Z2eIyrm3sIDKq3RsHVH666E7XZwF8BszcBfXOCBZpBoVrbLkCY2yhp09gdoKeSFQRylbjUPrC4z-YOC-4HSxjblLnr6eZQSYCHUjAcdEmI3GFeJr71KjIvAB4hwIHdmLmYgejRUSCcHnRggCQ06tlCKRs7Im6hU3_veW3shxmdMx9CzSUKmmrTJYRKuCH1eGhPAXRyjS89MwArlpkJS-ewdYJ40l-QTLuMfCkySSjR8c4rGKHczJbFDAzy-rBkZYqac6bkP6vKf98oZKyLpoeSnxCpLsqZKJFvneMSscQ4AJdWyubp42_eBIfgSEH01kUT3n1JOnJUxbiuLvT3WzDFQGoS1MZMh5OZwkBPDsrFbZU7thrK2F8sr9D6rEDaJJcn3n2KgbIrtaI_VeUVaPz7ou-yCUbqzpBs9_rk8JHod2ouUdheKazUfMJ06c_UnOluygMT2UEkeJ3y9sG1fPOJ-hWbzh3-vs43o402U7AHCXFLcEBUvmp-JmeGYZJ8r3TbcK9-nWLach73TWgUXPtD_4BEg40xzlox_NbB3IDXGMo3KsdiBwu78zqWoM4UE7pIfG--UPOp1mNae_TWo4eMh4BtDryImQU4Kiu9UbBTTmmHwEezlUoFUNSsfJJ-kTx4zXYbHQBWuaXOrYNZ4ayD0jGTdqPO4uPkEzefihfLxixXlw7RYdYj5Tlx_xe3PxGw8LOdGSgkS4p7Rk5jvgcov-3WpZiEsb_TT9aCkITj3bTv1HFIJwNnjeTYKvrl20DjZ0NNcU4CYUwFOCKUVhSxtBmF5vBYyX8SlEq6ZhX-4o0TrYT6cI8RLP4Dm4P0uLzD0ih26A6HlZ8hpjc9_FNKa-XUYxFWYUpDH92l04JfBNQVDvbWDq55DIYDGMktNTYJ7PUmPOhv_1bDBeaHxfUyWyfhHVLqBoDT0Ht30Ty1Pr4X6b5AQRN15N42pTaSavm0sDE8R0w98zmmhXUQX0h-ybLuQG1EIP3G70dqB3h1B3b7MLgWb99Zojcp7arcB3bKzSmJVopbaf9hWORDkUu-WiPG3UfkiAC-pUoRrGiGUQA76lrN2wtxSP6iqmjXHpsVGksGdEUAtMqIsbfR4pmoTpzhqOP8cMN2KMgfUE0sVMsOg3bEzbWboEGEmbCG3BcYJQ1kR_iQAGAI7HjmUmYrZEL-Rt1vSuyymADqI2oNnfzgasL53ywGTpOFxNXf5L5G8_UnVRLvC4YUEp_cotvd-_TQ6uFsUuV-SHa39POIkNUqO6PyN-VtwjuyufVlgj-gf8jbQiHA0iS_OQt6dSRzubk30R1osem2q-YHvVE-1Av-FcuTSUK5UHvkQAscuov4qJGHqPMWiNNWAAPuOAWyh3QVClfbgrHAusabQyvIXYfmp81kX1dYzdOzHX2xAtMh93fGMqNFJJ1nLhmoGAB_TmpTHsuot7xASd5nkgaYNyslgDEJPw8bADtZzPY2avePwTE70dZTvxffxjxxyLk3pQxpsdalq1CQT_SSpMX5R6CXoeM5mW6G-_Ht7Zr2WPJbjE4bmVmlBjRGuT5ZQts8bN4Dg0-4QRkjed-J3xFa7ecEXluEyjqrjodW8tllKSa9dos0zG5T3yiQSPv73lQpA4xXi99UhfKlvXQJLx\\\\\\\",1]],[\\\\\\\"BFEB80D1-0767-4C98-B0B9-D1C7AF03778B\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:30:29.353Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=843390&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],645974132,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7TPwwSQ7nAoqHNGRlqWyJwQh9SpqyU0vufUYvJ8kxdbZ9Z98AZS8d9M-HPAzsOd0aohP0w7IRNFuPot5HgcTonjQseWxLEejWglHd5TyDEcg7bHz0vlH6CM8-MosTGBjVXJQOupDkG2mRWQw5-McQt_9EYvNv1qbrtyUcg4UU8OggY-qzH06pH3Gsqz7jIs_60LLF54dw9-ea92JDTtce0u1YV3sxWnAzZj2Ude0g0GMNBYBRY5FTOgQsDbgWX3ekqXOg-MLmwH48HYPrM1diz07_RmQcOGeaK2lThLJu66NApCqER5inz4ujiE99SmTEXESXgXQIXEtXdWNMYY4Ba4xvkr-D9MwLaqLQxSau9zOsEBsMF_mTxm8NjK2MNvqGVCwGCB44OyfCAzkesaDlKdOtHLapv4TeYG_30_Ms3Q6DS30neMyJhl4gnbcWQaO0I1CDR2RPhujsvGOmv5OMaArR5j9IBhnfADP_W8WLuMuZx7ZyEVobu8FZ2QV8AJkmtloCsplCwe_I5Oe5dUEkeOLdETYThk9R8Ife5nq8rdAOWs7Da8vGUu0vSYJUqzsA1ncNyaX_2u-LtOma-2_oHsIXYgqPVm5wP4LIx02_O-Y3EdRwPUgmyB8VYFl0dMQIWmmrkX9aBQPLesV16QCJnLQr7F00YX1oyb0crXlnbHD6d6r9KVeFL-opTGpDc0Q6oP3_AZPXw-1v3rMpnxzvUM_q7bmonsP4nLzsKXYHIkzUY-BqcY9RsqYtGiayzJv7Nvyt8I_mmCapkQlRLQAkJPO6-sGvkhh0ETAH8sxDteUpl7m10w8nWZ86ofA-OnNzGGOGDWXI9bsmah2uDlyKVFzwOMtkvVdvvcgD89ZHWvrqgOEp-oykiOnAmmCikyap8OMULsAKGiN52EL-ZM5OWrLejCY-xutinKm28vrIA7toAy08S3wdbFjjNyTFADpJqZdeV0NoLVePoR4sRm-6yF0egNgnTJNq8EZaTDT010UAsYk16GCV9olVHoRqn8hM1KB1E8JRfY18KoFtLVpCxl50BmWHyp1D8D6umCnmb2MFnHB33AcBsDxHyN8kTq8TGwp3l7aWcdIuMQCj4BTW_Wcqz_T9wa498vejEj0ge_GAfEQVcwW7ime5E0vLNDHLq0ba4i45W0SKmfBo422cbq4E61WGzoJFGS_X7hu77q5Cy3IF8H8uWZOmy98yBgzaBJ6dVv_Qj2EyYgfp0bNgoAAISeSnhFPbYQaRQnotKamzEAuasZYN-e-6AylUIAgRVrFyIXQYMFpKSRThLi0mwvGWZoLnN6Fxr28apHp1r9mykMcbwsWF_lJzHyAgbNcobF4bla90ivK199VTUA1wPRMRlcPlJsDHIdcZg8OChvewRpTM8RbqmLQnVxjoZ9S3GNvukQdyyta7qTrGEUFjnniZ5xj0WzgRP4dBV3dh3O3X_mJM892ARBm554wZXU7THtT7fr4Fx-sX1xbQW-yUSTQyBQGepnKzU-TJ3NwL_eac5pkitqvOLmSkKDH1-G_GNVvksehkegBiSDPnjNvfdxwYdOdHDvhy37pW110yE6CLPOfXI4hwjoP76emQjVZ9mbsI9Q3ZPTy6bktyaBsvhA8_T0qaWBPPsdqG45Y18jVLI1E_1VjxcnJd-NfcLzdv1x6j1rLqHPy77sYkAnb3I8ZIrLSH8NznlK_eJqhhOTACWwExcqVdS1hpow1qpgRC9FhPe3OrWChd0MLJdE_6_ebeIqMhRWg1KJj7UXalmtwzfpi2dGhFT8mIYT4wndr1OXCjno1MDPsdroBDhwBxJsNjn5tZn2aRYNunDmWQdUKvm8b4WY-755DERXnb3cYXGfWh7Wr4utaENXgv68JQcTEfYhbnWMyku729YhYIiM-2IibQpA-7Vzc4ne70qnSi1sP-YA5Rdjhj_uqKHKERf4wJsWsG62DqMdNXAl97apsFfO3A2s7ED8Mxlgm1VdykCH8lWWj08viAyFulJgcLTJzWQWCIoni5tavqSlZ7OxfRkaDyoH1n6Qm8Zim9nsGI_yIG1pN9vJJ1TPsfIEP6GBMt6wvIy2o09q9dffBjKbSxitnhHtggrT4HBqWb7Hg_WpFVcPVdg69QJp_dHSBmSBULB2Z2r5jteVEc8D1PTb705KU49undkrOU02fuW5rlpPDBl8TNx6hnJrn2yKKezCmA1Ay55hQWMcAZ6VDlm-mtVNyQuxE0xN4mwWIeIQr6aUQIs13VFg3EY6Y0djfrC8PrG06YBpKc3FL289E64-H4cCdv5894xmFO6l2zZ4oyQmW-SBLzujqSJ_6I5vEkSOCUUAsHJ5zEKY5-PUh1ru20Y0GwYgadGzgcFNRAtxqRj45xO1JEiRPv0b2qbVNYfrNt4bAIZU-Ppn6Rykk33ktc9RngUMlRNe9FSLkcszeLK63xAnEU1DWm3NMELBpmHrtfdIg\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"C1BC702C-E7C4-4F57-868A-53AE460909BF\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7TPwwSQ7nAoqHNGRlqWyJwQh9SpqyU0vufUYvJ8kxdbZ9Z98AZS8d9M-HPAzsOd0aohP0w7IRNFuPot5HgcTonjQseWxLEejWglHd5TyDEcg7bHz0vlH6CM8-MosTGBjVXJQOupDkG2mRWQw5-McQt_9EYvNv1qbrtyUcg4UU8OggY-qzH06pH3Gsqz7jIs_60LLF54dw9-ea92JDTtce0u1YV3sxWnAzZj2Ude0g0GMNBYBRY5FTOgQsDbgWX3ekqXOg-MLmwH48HYPrM1diz07_RmQcOGeaK2lThLJu66NApCqER5inz4ujiE99SmTEXESXgXQIXEtXdWNMYY4Ba4xvkr-D9MwLaqLQxSau9zOsEBsMF_mTxm8NjK2MNvqGVCwGCB44OyfCAzkesaDlKdOtHLapv4TeYG_30_Ms3Q6DS30neMyJhl4gnbcWQaO0I1CDR2RPhujsvGOmv5OMaArR5j9IBhnfADP_W8WLuMuZx7ZyEVobu8FZ2QV8AJkmtloCsplCwe_I5Oe5dUEkeOLdETYThk9R8Ife5nq8rdAOWs7Da8vGUu0vSYJUqzsA1ncNyaX_2u-LtOma-2_oHsIXYgqPVm5wP4LIx02_O-Y3EdRwPUgmyB8VYFl0dMQIWmmrkX9aBQPLesV16QCJnLQr7F00YX1oyb0crXlnbHD6d6r9KVeFL-opTGpDc0Q6oP3_AZPXw-1v3rMpnxzvUM_q7bmonsP4nLzsKXYHIkzUY-BqcY9RsqYtGiayzJv7Nvyt8I_mmCapkQlRLQAkJPO6-sGvkhh0ETAH8sxDteUpl7m10w8nWZ86ofA-OnNzGGOGDWXI9bsmah2uDlyKVFzwOMtkvVdvvcgD89ZHWvrqgOEp-oykiOnAmmCikyap8OMULsAKGiN52EL-ZM5OWrLejCY-xutinKm28vrIA7toAy08S3wdbFjjNyTFADpJqZdeV0NoLVePoR4sRm-6yF0egNgnTJNq8EZaTDT010UAsYk16GCV9olVHoRqn8hM1KB1E8JRfY18KoFtLVpCxl50BmWHyp1D8D6umCnmb2MFnHB33AcBsDxHyN8kTq8TGwp3l7aWcdIuMQCj4BTW_Wcqz_T9wa498vejEj0ge_GAfEQVcwW7ime5E0vLNDHLq0ba4i45W0SKmfBo422cbq4E61WGzoJFGS_X7hu77q5Cy3IF8H8uWZOmy98yBgzaBJ6dVv_Qj2EyYgfp0bNgoAAISeSnhFPbYQaRQnotKamzEAuasZYN-e-6AylUIAgRVrFyIXQYMFpKSRThLi0mwvGWZoLnN6Fxr28apHp1r9mykMcbwsWF_lJzHyAgbNcobF4bla90ivK199VTUA1wPRMRlcPlJsDHIdcZg8OChvewRpTM8RbqmLQnVxjoZ9S3GNvukQdyyta7qTrGEUFjnniZ5xj0WzgRP4dBV3dh3O3X_mJM892ARBm554wZXU7THtT7fr4Fx-sX1xbQW-yUSTQyBQGepnKzU-TJ3NwL_eac5pkitqvOLmSkKDH1-G_GNVvksehkegBiSDPnjNvfdxwYdOdHDvhy37pW110yE6CLPOfXI4hwjoP76emQjVZ9mbsI9Q3ZPTy6bktyaBsvhA8_T0qaWBPPsdqG45Y18jVLI1E_1VjxcnJd-NfcLzdv1x6j1rLqHPy77sYkAnb3I8ZIrLSH8NznlK_eJqhhOTACWwExcqVdS1hpow1qpgRC9FhPe3OrWChd0MLJdE_6_ebeIqMhRWg1KJj7UXalmtwzfpi2dGhFT8mIYT4wndr1OXCjno1MDPsdroBDhwBxJsNjn5tZn2aRYNunDmWQdUKvm8b4WY-755DERXnb3cYXGfWh7Wr4utaENXgv68JQcTEfYhbnWMyku729YhYIiM-2IibQpA-7Vzc4ne70qnSi1sP-YA5Rdjhj_uqKHKERf4wJsWsG62DqMdNXAl97apsFfO3A2s7ED8Mxlgm1VdykCH8lWWj08viAyFulJgcLTJzWQWCIoni5tavqSlZ7OxfRkaDyoH1n6Qm8Zim9nsGI_yIG1pN9vJJ1TPsfIEP6GBMt6wvIy2o09q9dffBjKbSxitnhHtggrT4HBqWb7Hg_WpFVcPVdg69QJp_dHSBmSBULB2Z2r5jteVEc8D1PTb705KU49undkrOU02fuW5rlpPDBl8TNx6hnJrn2yKKezCmA1Ay55hQWMcAZ6VDlm-mtVNyQuxE0xN4mwWIeIQr6aUQIs13VFg3EY6Y0djfrC8PrG06YBpKc3FL289E64-H4cCdv5894xmFO6l2zZ4oyQmW-SBLzujqSJ_6I5vEkSOCUUAsHJ5zEKY5-PUh1ru20Y0GwYgadGzgcFNRAtxqRj45xO1JEiRPv0b2qbVNYfrNt4bAIZU-Ppn6Rykk33ktc9RngUMlRNe9FSLkcszeLK63xAnEU1DWm3NMELBpmHrtfdIg\\\\\\\",1]],[\\\\\\\"30C8F3F6-532D-44B7-A99D-AF63A49DCEB9\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:30:54.356Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=501992&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],988425786,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA60etiU9ZtZTl0i6mPqFxAnzpKxqYkLtajfBL-dq70binKLvkfdfsoxUYQGRPrLO0fsdktiRtGV2bfKgoJYL5400onzr-CkVMycBoGFYM55QNo7tvqxyvTapBrlyRnST3DMGutHqmA9I_8wuTp5A4oBGTIYirChByFN_vMOyW7r0U33mvMO9gIpXzqoalWZXnsjbl3-3W5QIWlP5tRHnSSn9C3oS2Vni7sHDVNPmVfNomHHo9A2L5PcdAQzepEqzjd0AQiWSeASz4ANfeS3mk2_U0Uu6WfcHSAFEfC4TAb5V8G8FxePymKLkRmiZgk6HGXMyQsjlkAUAyOjp5gn27vBC6TXax558AzKjp2WT1w-8FMKfzhGtNACC1qEWSgDKAln7sR8WMhfa6QTfIb4a6DY9m-4MCPBYHvXBCKXC0v8zt4cA6sN2MkChfu9LHMuSV-Sb-r5y75WZOcugro78iPKEYDYTBYFwLd6ARb8mI9fl8fRtb-dY8U2erNd32q6aq1dRhW3no9pSwRDdMubLPQDz64YaAzejLIBFjKqfb47_1-ugsU4VisfVFT2HhYn0t-zEYWGP5h4dFLWo0z9TlpXa0RrhRW7WChJLQ9zv4FW3Bu8qXHimRnSIf8oFx3LglNZTHahnl7RS2Jm_MVySAyRmwtD594Crf93htOq2NZG8tqBS-Jwcl9uO-PMDm7T-Pq_iBSB6oJ1hUGLt0ny693MHiNrD5FkadzsiKHQHOc6rXQuThhnhhfdksu0xCQcTRgt2bUo3L5s6onkqzlJuaqOYkPcHecFh4T9U4E-YyEzVfKYmAjhRWvj3KioJhxtl-nS-u3ZdTiW_YwJBejIRRsgJH0vm2WCPbbfSPrag9XgbMoIwVlCy8hRPSQPBeF92FwLMrYFjIgl22proAew87T3xClPdTpjQkgvwJpLomoI1bG-FiRUO0qCOk_cc5C-s-UR8VEb9s4rhQEiDiDbdOfRzng5Fm8yDcf9Lfj_8IIssBTxXBZJIL_H0xIVGmZvHhcyi71xDgEhf7TtkQoL5r3-ZEe94ngJypTmoxGDDOBaqDYp_fU6PNWTLVVQFarqLyngVAnKTHbWgXzbokx063ZieCFKx6I0E5zz1r1MW5iRbu4-yV6FOZmCYrwO9m18jSaO8Djv85pdaQPVFxAJhDOYl_D1tXtDh5LeixZWy39sbpmIQpNmkaC2m33PLmPK-TSBBPGHqfCGzYz7UfkAHXlUS_cE4TiHgEOSUTc4yCppUSPKLhqhJw1uDku5R7xzJEqzqTwNIRVP6-8cjTDUWgzB-ppHGEoilsp51y-KRSaLUU-BVV_nB7ls7yoTxCJxlSVUlWNtUFvJLnmEDD7v38nTZawKuaBDuAUp2Ef83nNpN-ffZb3p2zlkujdm-ZHSswQUxkkysj8WGdzl_X029du_rEhFbrCTbk1r6R7MPEteJAWdctTtlLWksDNmzjSuucs6bveUue3S09JOYfRvoS1RC0WGGrDQjdjSyuVy2PmLIj2BTrnFRfPzpt4WoaDdj0hisGKtQnCdKNxF6agnbQ7zpMS3raxuU-PZ5xwpu87zDzu_mkTRGpM44BWGJckgCK6u6wD8itZ6ALZeOEydFlW73_xwxwcg4L8neajXWkuCUhj2er-_Sm5C4Df3ZaxkDQ781ZhzltFrJHZ2pReJHdeV6xvrZXgd6TXI-PZ7VrZbyswlRSgF3UHRReryr7qAnjBmLFyCwsfloXG20VTfwXav1aPpUC1S6eFBonBXuRi90PP6JH02e2mA1VGQ-AytMvb6aLL5L_2xu058v5KnOVxQo5x3-t6U_gFdNNdY6kZ_811JMQDZOw3ZDemKVI7MLgKW2P6RttUtSkj0zS_2WpuRvIIq5l75taYYU2AD_-2gk4PjZE2jEclV0lez4G125VWKoquWNr3DVmu53ERBbD1giRXs7FxyZs9OX0eo7DFfYxabmDkILe1CFoOi5oA49hmJUK4kKJJVIcmG4ccgpZe_mwi9fI9TwynV2meg9SIvUYlyuoTzO1FFataO2aWck1X2Al2UtR3nJFBYa26IJg-z4gi1Czl1hWNUKJ2_q33zUyh0hRPczJw3Q0C2bYg9y56DALLr_KPw_86mzZdkmQDTGZGEA2ZF79q7b2P2DfGtUoKQEtz10Ns3JLQNMpsJiskFmd3pvgI9AVeBg9GsElJ8xLDmPU9J5x2U8f8n-2FOXyHBZpPtNjqIz1m3WikdRoAd4kHZxoHxcH47qHUQE8XeX3M1FvW7yIV7L936P7ju4_E4fH2wkO_LWn2wihLeGsKympBdkcxdajVBJlAFV1MXIGaiA0yJuwl-neaxxUiB3bAct-03TqnJ1uNqf_PI2l2A06BG7x3WfKJ6YdUJUDuvsRUKx4WNotsr0pmTymXkSIpG-yqV2woh2ZbwaEdCKwWNmBuU\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"E184DD5F-485B-4655-9F2D-9EF01463550F\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA60etiU9ZtZTl0i6mPqFxAnzpKxqYkLtajfBL-dq70binKLvkfdfsoxUYQGRPrLO0fsdktiRtGV2bfKgoJYL5400onzr-CkVMycBoGFYM55QNo7tvqxyvTapBrlyRnST3DMGutHqmA9I_8wuTp5A4oBGTIYirChByFN_vMOyW7r0U33mvMO9gIpXzqoalWZXnsjbl3-3W5QIWlP5tRHnSSn9C3oS2Vni7sHDVNPmVfNomHHo9A2L5PcdAQzepEqzjd0AQiWSeASz4ANfeS3mk2_U0Uu6WfcHSAFEfC4TAb5V8G8FxePymKLkRmiZgk6HGXMyQsjlkAUAyOjp5gn27vBC6TXax558AzKjp2WT1w-8FMKfzhGtNACC1qEWSgDKAln7sR8WMhfa6QTfIb4a6DY9m-4MCPBYHvXBCKXC0v8zt4cA6sN2MkChfu9LHMuSV-Sb-r5y75WZOcugro78iPKEYDYTBYFwLd6ARb8mI9fl8fRtb-dY8U2erNd32q6aq1dRhW3no9pSwRDdMubLPQDz64YaAzejLIBFjKqfb47_1-ugsU4VisfVFT2HhYn0t-zEYWGP5h4dFLWo0z9TlpXa0RrhRW7WChJLQ9zv4FW3Bu8qXHimRnSIf8oFx3LglNZTHahnl7RS2Jm_MVySAyRmwtD594Crf93htOq2NZG8tqBS-Jwcl9uO-PMDm7T-Pq_iBSB6oJ1hUGLt0ny693MHiNrD5FkadzsiKHQHOc6rXQuThhnhhfdksu0xCQcTRgt2bUo3L5s6onkqzlJuaqOYkPcHecFh4T9U4E-YyEzVfKYmAjhRWvj3KioJhxtl-nS-u3ZdTiW_YwJBejIRRsgJH0vm2WCPbbfSPrag9XgbMoIwVlCy8hRPSQPBeF92FwLMrYFjIgl22proAew87T3xClPdTpjQkgvwJpLomoI1bG-FiRUO0qCOk_cc5C-s-UR8VEb9s4rhQEiDiDbdOfRzng5Fm8yDcf9Lfj_8IIssBTxXBZJIL_H0xIVGmZvHhcyi71xDgEhf7TtkQoL5r3-ZEe94ngJypTmoxGDDOBaqDYp_fU6PNWTLVVQFarqLyngVAnKTHbWgXzbokx063ZieCFKx6I0E5zz1r1MW5iRbu4-yV6FOZmCYrwO9m18jSaO8Djv85pdaQPVFxAJhDOYl_D1tXtDh5LeixZWy39sbpmIQpNmkaC2m33PLmPK-TSBBPGHqfCGzYz7UfkAHXlUS_cE4TiHgEOSUTc4yCppUSPKLhqhJw1uDku5R7xzJEqzqTwNIRVP6-8cjTDUWgzB-ppHGEoilsp51y-KRSaLUU-BVV_nB7ls7yoTxCJxlSVUlWNtUFvJLnmEDD7v38nTZawKuaBDuAUp2Ef83nNpN-ffZb3p2zlkujdm-ZHSswQUxkkysj8WGdzl_X029du_rEhFbrCTbk1r6R7MPEteJAWdctTtlLWksDNmzjSuucs6bveUue3S09JOYfRvoS1RC0WGGrDQjdjSyuVy2PmLIj2BTrnFRfPzpt4WoaDdj0hisGKtQnCdKNxF6agnbQ7zpMS3raxuU-PZ5xwpu87zDzu_mkTRGpM44BWGJckgCK6u6wD8itZ6ALZeOEydFlW73_xwxwcg4L8neajXWkuCUhj2er-_Sm5C4Df3ZaxkDQ781ZhzltFrJHZ2pReJHdeV6xvrZXgd6TXI-PZ7VrZbyswlRSgF3UHRReryr7qAnjBmLFyCwsfloXG20VTfwXav1aPpUC1S6eFBonBXuRi90PP6JH02e2mA1VGQ-AytMvb6aLL5L_2xu058v5KnOVxQo5x3-t6U_gFdNNdY6kZ_811JMQDZOw3ZDemKVI7MLgKW2P6RttUtSkj0zS_2WpuRvIIq5l75taYYU2AD_-2gk4PjZE2jEclV0lez4G125VWKoquWNr3DVmu53ERBbD1giRXs7FxyZs9OX0eo7DFfYxabmDkILe1CFoOi5oA49hmJUK4kKJJVIcmG4ccgpZe_mwi9fI9TwynV2meg9SIvUYlyuoTzO1FFataO2aWck1X2Al2UtR3nJFBYa26IJg-z4gi1Czl1hWNUKJ2_q33zUyh0hRPczJw3Q0C2bYg9y56DALLr_KPw_86mzZdkmQDTGZGEA2ZF79q7b2P2DfGtUoKQEtz10Ns3JLQNMpsJiskFmd3pvgI9AVeBg9GsElJ8xLDmPU9J5x2U8f8n-2FOXyHBZpPtNjqIz1m3WikdRoAd4kHZxoHxcH47qHUQE8XeX3M1FvW7yIV7L936P7ju4_E4fH2wkO_LWn2wihLeGsKympBdkcxdajVBJlAFV1MXIGaiA0yJuwl-neaxxUiB3bAct-03TqnJ1uNqf_PI2l2A06BG7x3WfKJ6YdUJUDuvsRUKx4WNotsr0pmTymXkSIpG-yqV2woh2ZbwaEdCKwWNmBuU\\\\\\\",1]],[\\\\\\\"9ACC2134-04F4-4C95-87D5-9972DE9B9D77\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:31:24.410Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=957684&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],19345599,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6E4n3kJ1_ax7NDOtPH7wSVV-z9DsKYLfm9aALzD8vcGseY4YWM_h9OQGdXVoMqz8Q-lrbb_rUlIncYjjQ3sO8qDiZeyNyv7D10UBnhWF7PoTYlFqHjXAJiXk8mDNnLkUSHDiXqNXq9jqpZOLseOtTjr3he9TM7ORA55opAX-ccUHKxa0cvPiRwP3so51319KTQLT4WFkJgji984TWPWBrkkzxMXuQuzvoUzyNGOkVCANiCsxBDtMmnQYJri9lZ5ZI167iQvDBaDS0nXkWFA0jxg4fXyanWInDYbix2iw49R1WSQRyKzewisDl4Col_VY6RwojaoS1izb2_LJxKYnKj26G8zDrPhixSizmsfkvulq4ySxeoELS0UiQU4kuuMqnq6qVjiULE-MfuHdKdwIhQtyjxd_IUjCRipycKp2RULkbuzJ6QFeSYFLBlkXv8GXVWVxvZf9l64dbM_okk0Ecpod-du2ftxaTOczGUtPC_uGSdv_ojpJRmM9Oz8DP1baVug_ZNpTsf1wsJPcEb1ApL9Yn_xtVo_Ct15zkAos__uhXMLh1QY9kf6nsjrwLJgVhI9XiDEphSOc39gpJhmdEUlAErQaFrhX7JOwE1uoya2J21aCZC7ANdpftltSh-GUQpkHQqE2qltd1VN1ZoxEVaw81AmdHvMbDELM9IbVFoj7U20LgLXL7GKOW7qo4H3C2raW6RqjumnOLcZX3GchAoOlVJY1e8cOtGYx2wa2E6DJ8TmS1aZU3JhGfVkFJcsNPfHoAo89QzETPIEBbN-YYdjOsjXhGG46UV7ikbtJpQWI9-bKoigwji_DywFQFZSag3cdZ9YPLmqd5HmbGP-gxlOQhEJAQEMeQQlAVHKhM9gJTaIG2DZk98Jduzes0Mfnq1J_H6HNSErwYvBl2_D44OU6Ua_nEOeXTZY-0ADSh7fPB9dW3w8YxH-Fx1s_HBUYFS2jvf6inDypTnOmJ3YsAxJSHIUqiydcqPcBcaOUD8aCbG-OPf3JMWGj42E8ACyURbv9BsL1LOMCEHQW1h-C6MH2okFgxV1HZuYUcBApDEjkxM_3FrcTqDT1EwDbIhEi-13mZEBf_Gl77VhB8OEFIBgjHUxaFhL80wS5zmGPXG_eC-0Aen4scvNOUDas1LDUZZbwVwpFw_8781FyZA-sNVyg5KcxrFm3JecVmp_Iv3VNtGMF_gwT9HhGq7kBOgNp854OeXN9fOMMl-aVVPGfQmCqTBnx4l8mwNNSX715FTdS0jbp3L1v2hQo3spZmQ4kTLh8KoBS_Z4nVgeuOO46WpxmG805k5n2o3hweA_AZjiKJ1SbpNO3bt6wtANM1X5gQQSg9WdjqybwOzbJLXySc5mgF2STCPLi_jPeUEuBbfmf2crPwQZWcmb_ZlvWCNK4RSifLrI-FomNS3P1SWk1xTtC8t9l5t5VAEFD3WHvMQ91JWE7yxcEw_l8RkxKPFvkF7xawyd7cKL0zhO6TGP1g7hNk8RrFPAEODSlMB_BE80W4O6-gKfxXqW6sfrdhnnxbWxNG_v_dsk9pVOrJgo-9_sx73dt1Ih86XBte_70TC9zkaJBKwgh998f5FIhg-OAyTv-U6aRepb5Z9nqaR8cj_H2N3EyxzAUoCCN_YX1KejouZ0Ddi2POv7y-loowZz3FVNGItk3e5z3sEHzop4eVBZ11KfW-U4Lm_1oMbtmXJs3IsYksb34UvJsd0dJHsQ_fVz2PnqFZvhlv6xSxunGD7PMV-cmfSVq0NawSORBjAmbK7La8nvv59YQDUP6E74PqY0fezt3VRyWDFG_SgOvWSnSXKMtR_Gne1IEE9_2ORCfLdg_Kj8z0R1-YMDj3r-5M_nddZcJ3WRTYQ_MbDxOxGQL7qNshibKwy4hD9hxMued3PBveLAY32VjmMyIlW9m2nG7L-dPEhX5_TUzsGbRDPTwh5wqWMzsgr1fP9dl9DdgR3ZThugFilORENZy0OEHAkWfU9r6JJfsjbB84zHiDlxLtwN49E2EaXbF3CNytRdRw9kDC-6J49tshpUhzg_x0IZs0A8D0xxTirfmM9Iuu6ROdECGOnC_NOj2l4GbMh41rW9hDlmzH4x74tVeF-77NOIeWcr8kdBhn-_ywxCM5ePzQOpYcBo4ydBv6v7-LPVIreZdXG37Txy1-tF9mmKi75FbOH7Z4jxWfdR27uPq6F6-71OwpmMPmJ6O4nKhYMWzDOQAEhWbkhtp3ooSgD1rb1QYhu3g_xS4RIQX2Sso09-Q0WtsS4btH6dSw5IwRNutgzHTlJY1p6PjnpKq-5hCn_t-aDjLtenra7mGLDDU3YXptEdi4Xfz8wLZuvx0o185GesDD9ZFGIUni2ePJ5cTl1pUJN01kknJpY6IoL69U_KVTY_8IyBUpSmCLIXzSfI1QpzmksjxwKJ1ii-xPFFyAJOHmEpTw8f2ePKIDSLXWwWg779g\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"F220AC69-D505-41FA-858E-8B732C38C242\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6E4n3kJ1_ax7NDOtPH7wSVV-z9DsKYLfm9aALzD8vcGseY4YWM_h9OQGdXVoMqz8Q-lrbb_rUlIncYjjQ3sO8qDiZeyNyv7D10UBnhWF7PoTYlFqHjXAJiXk8mDNnLkUSHDiXqNXq9jqpZOLseOtTjr3he9TM7ORA55opAX-ccUHKxa0cvPiRwP3so51319KTQLT4WFkJgji984TWPWBrkkzxMXuQuzvoUzyNGOkVCANiCsxBDtMmnQYJri9lZ5ZI167iQvDBaDS0nXkWFA0jxg4fXyanWInDYbix2iw49R1WSQRyKzewisDl4Col_VY6RwojaoS1izb2_LJxKYnKj26G8zDrPhixSizmsfkvulq4ySxeoELS0UiQU4kuuMqnq6qVjiULE-MfuHdKdwIhQtyjxd_IUjCRipycKp2RULkbuzJ6QFeSYFLBlkXv8GXVWVxvZf9l64dbM_okk0Ecpod-du2ftxaTOczGUtPC_uGSdv_ojpJRmM9Oz8DP1baVug_ZNpTsf1wsJPcEb1ApL9Yn_xtVo_Ct15zkAos__uhXMLh1QY9kf6nsjrwLJgVhI9XiDEphSOc39gpJhmdEUlAErQaFrhX7JOwE1uoya2J21aCZC7ANdpftltSh-GUQpkHQqE2qltd1VN1ZoxEVaw81AmdHvMbDELM9IbVFoj7U20LgLXL7GKOW7qo4H3C2raW6RqjumnOLcZX3GchAoOlVJY1e8cOtGYx2wa2E6DJ8TmS1aZU3JhGfVkFJcsNPfHoAo89QzETPIEBbN-YYdjOsjXhGG46UV7ikbtJpQWI9-bKoigwji_DywFQFZSag3cdZ9YPLmqd5HmbGP-gxlOQhEJAQEMeQQlAVHKhM9gJTaIG2DZk98Jduzes0Mfnq1J_H6HNSErwYvBl2_D44OU6Ua_nEOeXTZY-0ADSh7fPB9dW3w8YxH-Fx1s_HBUYFS2jvf6inDypTnOmJ3YsAxJSHIUqiydcqPcBcaOUD8aCbG-OPf3JMWGj42E8ACyURbv9BsL1LOMCEHQW1h-C6MH2okFgxV1HZuYUcBApDEjkxM_3FrcTqDT1EwDbIhEi-13mZEBf_Gl77VhB8OEFIBgjHUxaFhL80wS5zmGPXG_eC-0Aen4scvNOUDas1LDUZZbwVwpFw_8781FyZA-sNVyg5KcxrFm3JecVmp_Iv3VNtGMF_gwT9HhGq7kBOgNp854OeXN9fOMMl-aVVPGfQmCqTBnx4l8mwNNSX715FTdS0jbp3L1v2hQo3spZmQ4kTLh8KoBS_Z4nVgeuOO46WpxmG805k5n2o3hweA_AZjiKJ1SbpNO3bt6wtANM1X5gQQSg9WdjqybwOzbJLXySc5mgF2STCPLi_jPeUEuBbfmf2crPwQZWcmb_ZlvWCNK4RSifLrI-FomNS3P1SWk1xTtC8t9l5t5VAEFD3WHvMQ91JWE7yxcEw_l8RkxKPFvkF7xawyd7cKL0zhO6TGP1g7hNk8RrFPAEODSlMB_BE80W4O6-gKfxXqW6sfrdhnnxbWxNG_v_dsk9pVOrJgo-9_sx73dt1Ih86XBte_70TC9zkaJBKwgh998f5FIhg-OAyTv-U6aRepb5Z9nqaR8cj_H2N3EyxzAUoCCN_YX1KejouZ0Ddi2POv7y-loowZz3FVNGItk3e5z3sEHzop4eVBZ11KfW-U4Lm_1oMbtmXJs3IsYksb34UvJsd0dJHsQ_fVz2PnqFZvhlv6xSxunGD7PMV-cmfSVq0NawSORBjAmbK7La8nvv59YQDUP6E74PqY0fezt3VRyWDFG_SgOvWSnSXKMtR_Gne1IEE9_2ORCfLdg_Kj8z0R1-YMDj3r-5M_nddZcJ3WRTYQ_MbDxOxGQL7qNshibKwy4hD9hxMued3PBveLAY32VjmMyIlW9m2nG7L-dPEhX5_TUzsGbRDPTwh5wqWMzsgr1fP9dl9DdgR3ZThugFilORENZy0OEHAkWfU9r6JJfsjbB84zHiDlxLtwN49E2EaXbF3CNytRdRw9kDC-6J49tshpUhzg_x0IZs0A8D0xxTirfmM9Iuu6ROdECGOnC_NOj2l4GbMh41rW9hDlmzH4x74tVeF-77NOIeWcr8kdBhn-_ywxCM5ePzQOpYcBo4ydBv6v7-LPVIreZdXG37Txy1-tF9mmKi75FbOH7Z4jxWfdR27uPq6F6-71OwpmMPmJ6O4nKhYMWzDOQAEhWbkhtp3ooSgD1rb1QYhu3g_xS4RIQX2Sso09-Q0WtsS4btH6dSw5IwRNutgzHTlJY1p6PjnpKq-5hCn_t-aDjLtenra7mGLDDU3YXptEdi4Xfz8wLZuvx0o185GesDD9ZFGIUni2ePJ5cTl1pUJN01kknJpY6IoL69U_KVTY_8IyBUpSmCLIXzSfI1QpzmksjxwKJ1ii-xPFFyAJOHmEpTw8f2ePKIDSLXWwWg779g\\\\\\\",1]],[\\\\\\\"1CA16167-F48B-42E2-AE9D-DAA04B8973FD\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:31:54.485Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=751536&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],460433625,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7KVgo_CQ1JVvDB5TX-gUy_GMZX-d-ho__8cN3Sw18wgfLihYBuiUA3VAKv9CvCx0BHhmbZvcKQdZtOqeHDoW0hIvJ8Vj9gPywkWBQKqrnKi1fHvFnyurWjjTFdoREcHUmoNuBh0vVBD5SF1kOqDs9Q7WFxRNBRQJfK0a1jtRw020aP_RzR3ghmV08lg7lsEUvAPNsNxHyk6fy_C_pZ798t-XqvasfqwdP7vpKPGB158Ue_ZS6T0Hao59EqsfU4LAp0KnDgYawqU6YKlipRGzxEGMvgSysP_iJ47rp3ANVRewPP-iX-eYFt5SHiMT7YXUMVY_4r1ImWIh0uQLHDkCNaAf991t0hosoz8WHdmKYMyjA2_G3u96aueyK1KVPRVSUbRbTTO9jS_XeEkaSn0htCD_45HqPNnCsoZQgEuDfepoKMNkcacv87icx3RGG2aiygvhRDTrDhPKzO6wAvIQbs_S65RVgGw9hmyKJuR6WKOeMEp3O_-Vrlz8zF_RtNnJ8SYlmLfs66ym2518Wyj9IoJJEc4lzbrD6PLeGn3OrRkyJd1lWUkoVQ8TDFEVRlFyWwbP8vq8CGt2LxwN0IC1TBgEjlqb1zEwg5A9WM_DaQ5Vg0lqTUvT3ZU_ZCsI0C-AquTQc555v9Bp_EdW_hdLGXOD4LcQkK0RQH6VdZ-2ZCaqt5-dBBoxDkm-x0m42K7aSIZMp4FtPtDJsAOhIS_Jcx8VZnl8pX10knyV-VhF5jVfKVMkELmoU56GIvDwZpeA5eFytWzm5SsUrehXB_S09Wh4iS6b8DkjChbJPYMojeZ4A45NUArqA9YjHSZQ945LwdX4A2pxZd6nWeY1yISqUv19RBHiXuCeFtJq86QNUsp7NlSte7N7Q97eVAn6oJYzT0ldtcqrqX-Eu_6thjzKhOOokRIHP6wXPZWb-4t8f6xyLce_xW3wrFit7Ez9E1asAPfq4767bjyOiEMg8VcwhJym6JyKk7-6OvVPjAWeYMBgHysVnKbfR1-hIXUcBkhvtw5PMQ8H70sz1CnMPVW82bL8M5e8Kjqeoae7it7Vl0DDge_MD_vJS-RY1U1-8ubOzaH5g_g9bsbdC0aGKMqXmgTZ138XeNx053xcvPP186F1cg4wy3fFGDiNRc2-zJ5TF-fJipBWui4HWlsZrPRlAUV2mDa-SNUU0fhlC6aUubA5tOGXJdt8sm1L6O6JkR9NtuXm3S2gkzgmQiIQiRGIubx0cwPp6uq3kIOF4jOPVtmcBuIT4z5l4XlgfGZ5DdEMbyrOgCYi2CSLVZW-o2JjuLBAh-F_WD-93uAsAaY0bGn0gDJJnLiqMrnlonXKy0785k90q_2lvM_QYhtawLXqkLY6Gc8ZcVLI5DHifSq9pA1zahuruU1GVFGGlhrZwNwJn7Y2D5N4RfD78aUNlMmObbdauQa_ejYymAr9LN8kdsDakHksR0wGeRLnac9XciMKUhUNOQSMHjLSem9t8g19kyQnmfoX61CXB_FyH7R2AvHQC1d_PiHZr9BirVF0ZoUjyFjdRTCjWLhwKNCapyHkX9xtYATzFqGp5FT2GQchy6ECO1ayP0sSZ0jPzj0Po5TBFxxOBepB_aOpVOM5hg8ft-w-mpy2yM47Fv-os-4OTM_wmh_pElx54-jpUZtX51r6hpSxbZV9s96UjiNKF7babOnWyDABFbFsoktb5p_LPJ9GPQ4WrvW6-dgNmn9X8Fl6BmxkZO7pj60UUApUkA8Nnh-6sOJvq3RTOED8Anf82hfLAh-SfMgC2XfkY_8Uys95-TtYcM89i8vFKt4tKX1YZ3Rn_y5p_tYtFPN4NbJK0294gZjq2tzEMq-m-Sx1jSXKQC1Z7rMEqM3Q1llIJa0o7sRo06rtnsqPsOeOoioOU7-jiSwNS6NsZB867V26c82UQ9Qt5P3n9BKLK9nuc79HGIhwvJP3WPP7Ymhn_QffqYcV5FMV1kd-casXGUESqXO4BMPqQ84AE6czyFqCRT-jLnMJSpEyJpxwRuzLw9pHDotgAMN7LIL4kGXaRJ81ZF636AVXsGJC0ZsRuTXmlCPj7ZlgrLd8UNLhlg6N2CIXuQuXYYXGlgDojj2D2nTpV9YILg363ucCIrlxFn0dYSt2IjyWjrNNU3mgdfQmquyLSFfVo8x2YYScSQX0K6hByFrwnf5B_xg3XC5ItHIzrSfzKSrIQru3hBREowUbTUx3NImL_Va_BY4VKYcR8bKULIvtwhSU8ifOqBE1ll1fpffVtNoRcL46xx16rb2pahnpabhxhYly7cRBKz76AH9y4PtQeM8dtqKwOmGw0WMQQc54Fk6EenZUofOuppacxjhqGJBQ6MgCImiKm627c2z4U3y6PfFbWYlNQYMrFgN0AuEpqYB8xRvwFIg00gcQ_GmJkHbBtHYg0BxOv0rkfweMtDhHfeIbs6Dfgc5x-yeA9PGoK9vbUBVg\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"022BAFB1-B8CF-4934-92D5-D3BF556804B2\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7KVgo_CQ1JVvDB5TX-gUy_GMZX-d-ho__8cN3Sw18wgfLihYBuiUA3VAKv9CvCx0BHhmbZvcKQdZtOqeHDoW0hIvJ8Vj9gPywkWBQKqrnKi1fHvFnyurWjjTFdoREcHUmoNuBh0vVBD5SF1kOqDs9Q7WFxRNBRQJfK0a1jtRw020aP_RzR3ghmV08lg7lsEUvAPNsNxHyk6fy_C_pZ798t-XqvasfqwdP7vpKPGB158Ue_ZS6T0Hao59EqsfU4LAp0KnDgYawqU6YKlipRGzxEGMvgSysP_iJ47rp3ANVRewPP-iX-eYFt5SHiMT7YXUMVY_4r1ImWIh0uQLHDkCNaAf991t0hosoz8WHdmKYMyjA2_G3u96aueyK1KVPRVSUbRbTTO9jS_XeEkaSn0htCD_45HqPNnCsoZQgEuDfepoKMNkcacv87icx3RGG2aiygvhRDTrDhPKzO6wAvIQbs_S65RVgGw9hmyKJuR6WKOeMEp3O_-Vrlz8zF_RtNnJ8SYlmLfs66ym2518Wyj9IoJJEc4lzbrD6PLeGn3OrRkyJd1lWUkoVQ8TDFEVRlFyWwbP8vq8CGt2LxwN0IC1TBgEjlqb1zEwg5A9WM_DaQ5Vg0lqTUvT3ZU_ZCsI0C-AquTQc555v9Bp_EdW_hdLGXOD4LcQkK0RQH6VdZ-2ZCaqt5-dBBoxDkm-x0m42K7aSIZMp4FtPtDJsAOhIS_Jcx8VZnl8pX10knyV-VhF5jVfKVMkELmoU56GIvDwZpeA5eFytWzm5SsUrehXB_S09Wh4iS6b8DkjChbJPYMojeZ4A45NUArqA9YjHSZQ945LwdX4A2pxZd6nWeY1yISqUv19RBHiXuCeFtJq86QNUsp7NlSte7N7Q97eVAn6oJYzT0ldtcqrqX-Eu_6thjzKhOOokRIHP6wXPZWb-4t8f6xyLce_xW3wrFit7Ez9E1asAPfq4767bjyOiEMg8VcwhJym6JyKk7-6OvVPjAWeYMBgHysVnKbfR1-hIXUcBkhvtw5PMQ8H70sz1CnMPVW82bL8M5e8Kjqeoae7it7Vl0DDge_MD_vJS-RY1U1-8ubOzaH5g_g9bsbdC0aGKMqXmgTZ138XeNx053xcvPP186F1cg4wy3fFGDiNRc2-zJ5TF-fJipBWui4HWlsZrPRlAUV2mDa-SNUU0fhlC6aUubA5tOGXJdt8sm1L6O6JkR9NtuXm3S2gkzgmQiIQiRGIubx0cwPp6uq3kIOF4jOPVtmcBuIT4z5l4XlgfGZ5DdEMbyrOgCYi2CSLVZW-o2JjuLBAh-F_WD-93uAsAaY0bGn0gDJJnLiqMrnlonXKy0785k90q_2lvM_QYhtawLXqkLY6Gc8ZcVLI5DHifSq9pA1zahuruU1GVFGGlhrZwNwJn7Y2D5N4RfD78aUNlMmObbdauQa_ejYymAr9LN8kdsDakHksR0wGeRLnac9XciMKUhUNOQSMHjLSem9t8g19kyQnmfoX61CXB_FyH7R2AvHQC1d_PiHZr9BirVF0ZoUjyFjdRTCjWLhwKNCapyHkX9xtYATzFqGp5FT2GQchy6ECO1ayP0sSZ0jPzj0Po5TBFxxOBepB_aOpVOM5hg8ft-w-mpy2yM47Fv-os-4OTM_wmh_pElx54-jpUZtX51r6hpSxbZV9s96UjiNKF7babOnWyDABFbFsoktb5p_LPJ9GPQ4WrvW6-dgNmn9X8Fl6BmxkZO7pj60UUApUkA8Nnh-6sOJvq3RTOED8Anf82hfLAh-SfMgC2XfkY_8Uys95-TtYcM89i8vFKt4tKX1YZ3Rn_y5p_tYtFPN4NbJK0294gZjq2tzEMq-m-Sx1jSXKQC1Z7rMEqM3Q1llIJa0o7sRo06rtnsqPsOeOoioOU7-jiSwNS6NsZB867V26c82UQ9Qt5P3n9BKLK9nuc79HGIhwvJP3WPP7Ymhn_QffqYcV5FMV1kd-casXGUESqXO4BMPqQ84AE6czyFqCRT-jLnMJSpEyJpxwRuzLw9pHDotgAMN7LIL4kGXaRJ81ZF636AVXsGJC0ZsRuTXmlCPj7ZlgrLd8UNLhlg6N2CIXuQuXYYXGlgDojj2D2nTpV9YILg363ucCIrlxFn0dYSt2IjyWjrNNU3mgdfQmquyLSFfVo8x2YYScSQX0K6hByFrwnf5B_xg3XC5ItHIzrSfzKSrIQru3hBREowUbTUx3NImL_Va_BY4VKYcR8bKULIvtwhSU8ifOqBE1ll1fpffVtNoRcL46xx16rb2pahnpabhxhYly7cRBKz76AH9y4PtQeM8dtqKwOmGw0WMQQc54Fk6EenZUofOuppacxjhqGJBQ6MgCImiKm627c2z4U3y6PfFbWYlNQYMrFgN0AuEpqYB8xRvwFIg00gcQ_GmJkHbBtHYg0BxOv0rkfweMtDhHfeIbs6Dfgc5x-yeA9PGoK9vbUBVg\\\\\\\",1]],[\\\\\\\"58A0BCE4-6468-48FD-84C3-669715E893D5\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:32:14.527Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=560765&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],733512044,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4oDmqKzuEXeTT_3PBK38sBodAKIJxC-O5djmCqb1HOp3ITaQE2LemC9PDY0KLyBv70fKI8dK35ldX5UtbriSJ5WVdcYm74Et7vs5SAvebAXJwK-qrf7vUy2SHlQ65LqZVPq0KGfvoI8Ao3M--SW6-h0xsHS-tfZ-y5v-1Hhh8f81sC-e5vFt4500uOwuRcbReg0FAoiwz9Go7YApdkpG7CRwTYmz5mVUKMgTeXG94s_hG_6zXDUVspTERDvAYkSRsBsPVZvD66hHWzWdQuWyHOnoHWjU3GYZYS_v02CFQ7edlbbZ_fNO645X-MJjcG8OP7MlMdmXBiDPB5cDTkORafSn48J8-lhnkDvqzERpYyHCBq-wBo0g_RiU-a_i6_tBS_N_xRknMxM3IPcVZQYp3lOewlGqdL7rN85SVXfmmh2d4kRZvkTkrae7rw4K1CySOleshyLNT-WiNwZnih-OZRKvbLn-RYL919Djb6EM1hdifMKNaKu2AsNWEu-VclXO_OWRPZi_iABxzXyK-RgQF-y7ejhpgzI-molqXBhwE_jOVJnkxm5F-OS-8QyRUspR4b_qb5z1N88ZHFQMuVKghRJU6-vgT79LGXCUBJ2naQj2l2DL6mE9CC4En-k__pPC-c1I2ncombJb6CEq46omV7aZ49jhH0eIkv2Gk0zhD6uazscn1Fr6uVRJld6lprfGMJW0eYATItc7fCLLcGvraWQ-bLf7CYbZvLRK9KQSPGU2MFKGJ0jbe_8oN7FdH_XV4GmwmRPzkwvQOmG6VZ3bEPSnUtCNFI6vAedGxKd4IK_YjSsA-8YGPge7M4xtBQcmJPFzf6UamBwxQ7BxvPskaY6YiV2O-i9Z3FMJteIIFD7vUKCshsX_GoARza4-ttesIXZwTVn9W5vDBOFEH6qd6fygpMcKKgu29UFaW6nbQ02hy0ge0ndkhh7KEaacvS0h-0hLI0iFzlRFwEJPc_mgNS0DBWqW1RHJn7f8LBBpVN5asVS-yE_EgdlO-sJ_TBJ2-1QQaEFRcRsvpWkHZw3dSzL1vQt4GiG69k089JXLe_ZqLIOv0c3iCiPWEPq4Xk50PoENok4R7eEnI1jtbrsKQpvS_0jHajKrU5b6jM_F44cVAcY2QoElW_mXwzm5_-nozzVLKa6TNeSzX2f7Nj9N_OXop3bODkaSTatIE2z_vxNVvfzwuj_-P7QX5p2qGOOshzPhMRKzx9d8PpbnWTgQxq1cHedwYn6DisTS9lX50ZigL0OPn4UOCc9MVjYvp0gKJRDGxY2wh2MPyM3uG3_98Ckz80H626KcoyTL3lNEHO1gmS9n1Iu-la90U37O83fQ711WzN6f_Dk3NOIu-GBzIVT3YBdP3hQBPkfu17g3kxX7nejUzlL8NvsDkhBrbXEWHHOt095omO9GeKy9zyK2g0LIQIpRz08aju8SZTNnuxYW3-5vr8pTedXdjxJyeDTV2n6u_3yMY_cqPGuR5syuLh4WS-u5M7mGct_z_MhznlXJr4-8kWDroJq64duANcINX1LcZmc5GPA6M73FMMXAjfLW6PCgJ5Him2m8Jev92PJ_eCw5m72mYLzXvfDBCpe7PRH5sG1OxNPJ1g-tFCLLT1FQXFMlCmOaaUy7sODYnoZgWUm91M-trlPsO9bQjEa05oDlzeou6GHqroxOcvIeSzbvXl_3lCQ2iWu3x7C7d78tCcwlQkbHQpY8H4ajYC_hvT5nX6-gV6Ritt5DnluG6SAvRqxfgcMVILZVIbCXaimORMQ3MYPfQmNVk61ivk2N2bkNO7plvQclDd9EgR9hkN0aj88f5MiwRbO_5tRpjxLcROxU9Kw_v5fWvMZqoRUi6xJCPsBUSQ-MoWl4SVAfpCOyUTN9lBjfIdheROpMgm4anmyvBquKMqfV_PMJsdtweXd1MJ9NHVyE8VAQPPzQyrnxuPtEJB3gV9dSNjdIL4U21LNIdSnOwdNRtBdQudlrkM5LGYVIdorKxmEd29ydWlWdxeyp-8Oid3avXTxiimpXN64W5CpLQe0t6xea4Uy3Hjgse-h6_vp6QGasqJmOXPpYHXQKC_v_p_BNA5RwlLKx8ofC7bZnvaWoV7MhSLmoltDO_tj3i187umJiht7WZOe-njGtSS_xT7gpXp8kr24itvV5G-1a9O3krgBH7i-LJFkYBsLtJ_iJsAkyud96FCbooAXq7cHgmpIjUmPnV5sSQ0mDUyV-cosnbGxMS2ZuPvN0sF_GNV4UiU7an5EV3TH_b5X5tDhlgieRI836AdLNGyex09JgIt9jUXOGuuJKyb6NWx5TmddCVDvHbmpjbHxuWnLEN-8h1dfNCaAhmJVKx10sQVmWqprTtYTXf4kxJMZLD_7YLDriIB__Dnj-wCAX6tf6LkT9AQZ0qMeRjssQCPlCC_8X4ekQUEJLy0Gpt0wuqCTa9RwzUOEu_-9mk0VCNwIw\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"95F0B7B7-69D8-4535-8738-1ED83E675CA6\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4oDmqKzuEXeTT_3PBK38sBodAKIJxC-O5djmCqb1HOp3ITaQE2LemC9PDY0KLyBv70fKI8dK35ldX5UtbriSJ5WVdcYm74Et7vs5SAvebAXJwK-qrf7vUy2SHlQ65LqZVPq0KGfvoI8Ao3M--SW6-h0xsHS-tfZ-y5v-1Hhh8f81sC-e5vFt4500uOwuRcbReg0FAoiwz9Go7YApdkpG7CRwTYmz5mVUKMgTeXG94s_hG_6zXDUVspTERDvAYkSRsBsPVZvD66hHWzWdQuWyHOnoHWjU3GYZYS_v02CFQ7edlbbZ_fNO645X-MJjcG8OP7MlMdmXBiDPB5cDTkORafSn48J8-lhnkDvqzERpYyHCBq-wBo0g_RiU-a_i6_tBS_N_xRknMxM3IPcVZQYp3lOewlGqdL7rN85SVXfmmh2d4kRZvkTkrae7rw4K1CySOleshyLNT-WiNwZnih-OZRKvbLn-RYL919Djb6EM1hdifMKNaKu2AsNWEu-VclXO_OWRPZi_iABxzXyK-RgQF-y7ejhpgzI-molqXBhwE_jOVJnkxm5F-OS-8QyRUspR4b_qb5z1N88ZHFQMuVKghRJU6-vgT79LGXCUBJ2naQj2l2DL6mE9CC4En-k__pPC-c1I2ncombJb6CEq46omV7aZ49jhH0eIkv2Gk0zhD6uazscn1Fr6uVRJld6lprfGMJW0eYATItc7fCLLcGvraWQ-bLf7CYbZvLRK9KQSPGU2MFKGJ0jbe_8oN7FdH_XV4GmwmRPzkwvQOmG6VZ3bEPSnUtCNFI6vAedGxKd4IK_YjSsA-8YGPge7M4xtBQcmJPFzf6UamBwxQ7BxvPskaY6YiV2O-i9Z3FMJteIIFD7vUKCshsX_GoARza4-ttesIXZwTVn9W5vDBOFEH6qd6fygpMcKKgu29UFaW6nbQ02hy0ge0ndkhh7KEaacvS0h-0hLI0iFzlRFwEJPc_mgNS0DBWqW1RHJn7f8LBBpVN5asVS-yE_EgdlO-sJ_TBJ2-1QQaEFRcRsvpWkHZw3dSzL1vQt4GiG69k089JXLe_ZqLIOv0c3iCiPWEPq4Xk50PoENok4R7eEnI1jtbrsKQpvS_0jHajKrU5b6jM_F44cVAcY2QoElW_mXwzm5_-nozzVLKa6TNeSzX2f7Nj9N_OXop3bODkaSTatIE2z_vxNVvfzwuj_-P7QX5p2qGOOshzPhMRKzx9d8PpbnWTgQxq1cHedwYn6DisTS9lX50ZigL0OPn4UOCc9MVjYvp0gKJRDGxY2wh2MPyM3uG3_98Ckz80H626KcoyTL3lNEHO1gmS9n1Iu-la90U37O83fQ711WzN6f_Dk3NOIu-GBzIVT3YBdP3hQBPkfu17g3kxX7nejUzlL8NvsDkhBrbXEWHHOt095omO9GeKy9zyK2g0LIQIpRz08aju8SZTNnuxYW3-5vr8pTedXdjxJyeDTV2n6u_3yMY_cqPGuR5syuLh4WS-u5M7mGct_z_MhznlXJr4-8kWDroJq64duANcINX1LcZmc5GPA6M73FMMXAjfLW6PCgJ5Him2m8Jev92PJ_eCw5m72mYLzXvfDBCpe7PRH5sG1OxNPJ1g-tFCLLT1FQXFMlCmOaaUy7sODYnoZgWUm91M-trlPsO9bQjEa05oDlzeou6GHqroxOcvIeSzbvXl_3lCQ2iWu3x7C7d78tCcwlQkbHQpY8H4ajYC_hvT5nX6-gV6Ritt5DnluG6SAvRqxfgcMVILZVIbCXaimORMQ3MYPfQmNVk61ivk2N2bkNO7plvQclDd9EgR9hkN0aj88f5MiwRbO_5tRpjxLcROxU9Kw_v5fWvMZqoRUi6xJCPsBUSQ-MoWl4SVAfpCOyUTN9lBjfIdheROpMgm4anmyvBquKMqfV_PMJsdtweXd1MJ9NHVyE8VAQPPzQyrnxuPtEJB3gV9dSNjdIL4U21LNIdSnOwdNRtBdQudlrkM5LGYVIdorKxmEd29ydWlWdxeyp-8Oid3avXTxiimpXN64W5CpLQe0t6xea4Uy3Hjgse-h6_vp6QGasqJmOXPpYHXQKC_v_p_BNA5RwlLKx8ofC7bZnvaWoV7MhSLmoltDO_tj3i187umJiht7WZOe-njGtSS_xT7gpXp8kr24itvV5G-1a9O3krgBH7i-LJFkYBsLtJ_iJsAkyud96FCbooAXq7cHgmpIjUmPnV5sSQ0mDUyV-cosnbGxMS2ZuPvN0sF_GNV4UiU7an5EV3TH_b5X5tDhlgieRI836AdLNGyex09JgIt9jUXOGuuJKyb6NWx5TmddCVDvHbmpjbHxuWnLEN-8h1dfNCaAhmJVKx10sQVmWqprTtYTXf4kxJMZLD_7YLDriIB__Dnj-wCAX6tf6LkT9AQZ0qMeRjssQCPlCC_8X4ekQUEJLy0Gpt0wuqCTa9RwzUOEu_-9mk0VCNwIw\\\\\\\",1]],[\\\\\\\"13FC1CFE-A1B2-46BB-AE26-DC4A69859A6C\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:32:40.678Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=2375791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:32:39.561Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=445517&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],529649083,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6dxggxKfo1Cmhmy7G2y9CjxOX9J8a3PFxztcO4_nkaM5h46xPimxT_i1MGHDF2banAHhTNf0465Q8QvvC6VGtb05CwyLImqg9_lk7Ti6wf9L1r62lyoJW7zNS8N8E2ZFV0HQU958vRzoVA2DwxMdybJ45IVHAF8tZ60PPsgq9rWtoo221iRuhgGnwHKtbPF0KVbZFx027QIj4QjNn3UivRimPtpa95V_2lLwkFMVdyNS6-W_5HP035U-i3Azr5fJLuIPRzCvF11R1PcEgWbEjOS3NcSgT-6K0bOf410KfLHTohphOTZo8iq_njsMM2cxBmHcX7Pkrw-6Mrs4H7ssGn-rOxu7D-t_naQl63U4azgwVA8Y4hXE0CWVrUQNIbiKmS2WLyrNRXI2OSPBiZ_BlIwFqkKm879KHa2NWar-jEUmtF_J5-c2xo-3GsZ9rDXVI7dd_hTODd8jeaOxNvAAyk7VT1KLNJlYqq3Co-7reHIFVXCWKEdh2NJoZyAPcn0zrTxjC6VaAxPb5L4LRgdD5f1zefLlTbFDXVefUd4_ITp9PyZlQKI7JB7HVJqqZDLN9c7JLZfC0UMcMgoaVbjHxcJzd9SX8og3ts_B9GF8zK5d6jsZGG_cNO7FktmXkyqEyzLibuxmDIDRuZ-RjAg5_7BpX6_pQ5wX_449POYvAK9ysuNkUodFQXCO_WEIIY7glJCp3RU5t6zgrIzU7ByWSY_7YW8LoushnljdKAhyMukD_VtlGMNSg7AdFp4HX0rxP7HNo1WdfsS5rHeTz443Zf2C6bPfZZ5MeYag-ZPJ-l9uZK9CA9CrUf2_IJrR6CXZI4jj892eoEqwc-mht8NhCvU2hEAKtfkA0GB49sIFr95Q-eQOhCt7ePbpsndTpI_TbwEll_MVHDyVmwG4KaUFLcfSsg1rkw5z4CfjQR0EzEMOwdxhWFk3h12dwTBbZXZjB2hnFdXgbY9csVqdazUgB2B7FETnqnj3i546Jd8i27kzwHAT3KGc2PUp706HYnBo7m4WLMvp4EyXE1kWpAHGiIHMhljXUwTTPrGelVkSNmH92C_ClEDCuWJ7m49tjRjLbp62fRRLGLuX8RUkK5Hc6Y4HnJucYqqujUZ5TVmjc8MQMg7O6OcP4lxSCIpQPRPvyStWnp2bVG4-Rg0O0H3Q-FVgJPlTKFHKvAxQF_JzwiJDiPingfK9CUi6Sbu_Lo1E0UWhKNxs9m_IOfGgWZ1Xf09pEyJnf0n4h1vUuY1oTFKoi7yfNYVw7rw1PYW8AnZrgMMiKKOsDM1B40pCGc7V7bvrHwm7CdnN7LGjSw4DgDYVRsf6xKMN2SMn4g0wPAYhAv6gjQQiraMGmEs9Wu8HCHg8waCjcESViTdPxndtm2VzxLqdaPX5b6Sq7ryTTgDajoguTNH5Vwkx9DS0Emv6NSdYLoMY5MrIbDxmUoY7FOd-rWN8y6T1jg9kcTWmZKfZmNsscaQec2xBOaSVGZG86IKNH0PVn8Sy6zeyxKLW_qbTebrVdiU4dxq2Y5g26D107ycznKHZkbPymlegvTZcRW5iBBQLdfT0adHbSgJ3xilhwDxcdqlu47E7Nw6rZ8Y7EIbxuUmtESpiRvDdM9U3kv3EAnBauBnCcSHrF-wujTE6kbVSGpAbeu801B43rQxEhpZfd9tkJgPFmh8O2J9B5vXa1Fxs79wkKohsT14jM7Vws3fIZbU-QfsgbuxAKZ8zQgK2bd2zbx3PkFuUidQN3TDSL6bfTbMngA-jCp3DgLr8iDTp983nweCgeQCTABKR9HzRRPlSEgCUWIFICpcopjIMvfB9UzEGT5malQUc-MYcgmpEj-h9eh3AiqZfp16gTLeKLR2zvCGU07p8bQauXSF7eKGObQBAFzH8y8HB5VYYqUb9r4KkBXN_xY_EaGytTxhqczTYHsHhmvYggdgo6jck1a1_euTCOP7hvwhkeusGxKc1tbp7Vtaei8BSzi5LLDRSVf8tuzKIVtthuF_kmhpRBabPFAf53zuL2lOh5T6iizBTddnxyXFI_3HC7Wno3S-nA3qMhY1m3VOlVOHQvDqJv41oOCr8fzmwJGpazQeKRIK9vCLm9xNK3GWpqCk54Y55HKvzY1yEoGppB9_BGrdRh9w9TlOZhdqaDqr5kLawUv6-VEC_rBY3Lc51PaCnhu9--a9yx6HzZ0EOty4ZthWFbORkQkaXaC1M_Gf1kNbpd531aE6YviWXrdFuf4yV9cqmFMvM-O_PwgCNWbJ9ealTCDrMIYLZJctHp5uXLda4M6QwpbPVTAPsC7sa9cSSj8hMdN9DnzvVpjD505zTC2idjHJErAgBlntlbd5dopi33yzD3uhw76VprRJQNYCZu1883VKqpxcd10FEqro3LONdBSvje3NTkRIKIJ3CRT6v8gq59MRo-nDBSkmDmsCOFG7meSOsOIA6uxYtDCSTe-YeWKkg\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"BBC48535-B107-4F71-9A61-3F0DEFE800E6\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6dxggxKfo1Cmhmy7G2y9CjxOX9J8a3PFxztcO4_nkaM5h46xPimxT_i1MGHDF2banAHhTNf0465Q8QvvC6VGtb05CwyLImqg9_lk7Ti6wf9L1r62lyoJW7zNS8N8E2ZFV0HQU958vRzoVA2DwxMdybJ45IVHAF8tZ60PPsgq9rWtoo221iRuhgGnwHKtbPF0KVbZFx027QIj4QjNn3UivRimPtpa95V_2lLwkFMVdyNS6-W_5HP035U-i3Azr5fJLuIPRzCvF11R1PcEgWbEjOS3NcSgT-6K0bOf410KfLHTohphOTZo8iq_njsMM2cxBmHcX7Pkrw-6Mrs4H7ssGn-rOxu7D-t_naQl63U4azgwVA8Y4hXE0CWVrUQNIbiKmS2WLyrNRXI2OSPBiZ_BlIwFqkKm879KHa2NWar-jEUmtF_J5-c2xo-3GsZ9rDXVI7dd_hTODd8jeaOxNvAAyk7VT1KLNJlYqq3Co-7reHIFVXCWKEdh2NJoZyAPcn0zrTxjC6VaAxPb5L4LRgdD5f1zefLlTbFDXVefUd4_ITp9PyZlQKI7JB7HVJqqZDLN9c7JLZfC0UMcMgoaVbjHxcJzd9SX8og3ts_B9GF8zK5d6jsZGG_cNO7FktmXkyqEyzLibuxmDIDRuZ-RjAg5_7BpX6_pQ5wX_449POYvAK9ysuNkUodFQXCO_WEIIY7glJCp3RU5t6zgrIzU7ByWSY_7YW8LoushnljdKAhyMukD_VtlGMNSg7AdFp4HX0rxP7HNo1WdfsS5rHeTz443Zf2C6bPfZZ5MeYag-ZPJ-l9uZK9CA9CrUf2_IJrR6CXZI4jj892eoEqwc-mht8NhCvU2hEAKtfkA0GB49sIFr95Q-eQOhCt7ePbpsndTpI_TbwEll_MVHDyVmwG4KaUFLcfSsg1rkw5z4CfjQR0EzEMOwdxhWFk3h12dwTBbZXZjB2hnFdXgbY9csVqdazUgB2B7FETnqnj3i546Jd8i27kzwHAT3KGc2PUp706HYnBo7m4WLMvp4EyXE1kWpAHGiIHMhljXUwTTPrGelVkSNmH92C_ClEDCuWJ7m49tjRjLbp62fRRLGLuX8RUkK5Hc6Y4HnJucYqqujUZ5TVmjc8MQMg7O6OcP4lxSCIpQPRPvyStWnp2bVG4-Rg0O0H3Q-FVgJPlTKFHKvAxQF_JzwiJDiPingfK9CUi6Sbu_Lo1E0UWhKNxs9m_IOfGgWZ1Xf09pEyJnf0n4h1vUuY1oTFKoi7yfNYVw7rw1PYW8AnZrgMMiKKOsDM1B40pCGc7V7bvrHwm7CdnN7LGjSw4DgDYVRsf6xKMN2SMn4g0wPAYhAv6gjQQiraMGmEs9Wu8HCHg8waCjcESViTdPxndtm2VzxLqdaPX5b6Sq7ryTTgDajoguTNH5Vwkx9DS0Emv6NSdYLoMY5MrIbDxmUoY7FOd-rWN8y6T1jg9kcTWmZKfZmNsscaQec2xBOaSVGZG86IKNH0PVn8Sy6zeyxKLW_qbTebrVdiU4dxq2Y5g26D107ycznKHZkbPymlegvTZcRW5iBBQLdfT0adHbSgJ3xilhwDxcdqlu47E7Nw6rZ8Y7EIbxuUmtESpiRvDdM9U3kv3EAnBauBnCcSHrF-wujTE6kbVSGpAbeu801B43rQxEhpZfd9tkJgPFmh8O2J9B5vXa1Fxs79wkKohsT14jM7Vws3fIZbU-QfsgbuxAKZ8zQgK2bd2zbx3PkFuUidQN3TDSL6bfTbMngA-jCp3DgLr8iDTp983nweCgeQCTABKR9HzRRPlSEgCUWIFICpcopjIMvfB9UzEGT5malQUc-MYcgmpEj-h9eh3AiqZfp16gTLeKLR2zvCGU07p8bQauXSF7eKGObQBAFzH8y8HB5VYYqUb9r4KkBXN_xY_EaGytTxhqczTYHsHhmvYggdgo6jck1a1_euTCOP7hvwhkeusGxKc1tbp7Vtaei8BSzi5LLDRSVf8tuzKIVtthuF_kmhpRBabPFAf53zuL2lOh5T6iizBTddnxyXFI_3HC7Wno3S-nA3qMhY1m3VOlVOHQvDqJv41oOCr8fzmwJGpazQeKRIK9vCLm9xNK3GWpqCk54Y55HKvzY1yEoGppB9_BGrdRh9w9TlOZhdqaDqr5kLawUv6-VEC_rBY3Lc51PaCnhu9--a9yx6HzZ0EOty4ZthWFbORkQkaXaC1M_Gf1kNbpd531aE6YviWXrdFuf4yV9cqmFMvM-O_PwgCNWbJ9ealTCDrMIYLZJctHp5uXLda4M6QwpbPVTAPsC7sa9cSSj8hMdN9DnzvVpjD505zTC2idjHJErAgBlntlbd5dopi33yzD3uhw76VprRJQNYCZu1883VKqpxcd10FEqro3LONdBSvje3NTkRIKIJ3CRT6v8gq59MRo-nDBSkmDmsCOFG7meSOsOIA6uxYtDCSTe-YeWKkg\\\\\\\",1]],[\\\\\\\"5D108930-A9DC-4B47-BCFB-3777EC2101F5\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:33:33.874Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=877763&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],275854649,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4xi_W9dEA6VWMhKDpjOjuJU842zdWXAYitUM9yT2bYZJNSB8OsAURjvBAQZWOflhaTryhcfvkzax8YuyInPOnI0fONiIFBFz7T-Tgkx51xg5X8xv4CEi7--8T3_-Qv9PfBervNe0A2RhKgl0DQQ0J8QWbsE1SgHOY-xctAt_2H2PxNKkcH5Sb-ZaNZoRsCYVDoN21AGX9zZM4BXSGxcloXaVMawExaQ83FlSZ6YM05rl_fSMmebgaAkupQwV8j9TC72_IsPFdPW__-yJEQng_yuwK8fGCMdAEtSquMf_bkXX298C1Om3YlGScIJWgtA0vWrqkZ4EpCMHc5_XT5lGF1t2RCQdh4scdlPs8JnUZIKoTgejcACbAoLLmqyVx4Iy4VJWde8g2JyoWYEotYKL9Xy29MSKLAMpTUxqCkizK0paQqsPi-GxGCzddHODtuRruigG25TwB6_dpNiDl_wlMBXAhpJePauyllTFBvUewuWuVmzbis-4agzh4WczNM_nM2EK7MneN2KF8hPH4pzU-voRJpAbZAMdY33Dt0HXlcbSZcmdgp6trEXgap0qiIMQxYPfwkKU_tt7MnjIP5ezQLta4G_xkn01Xp9iv0Hg5nVQ3DOuPizwwuX2MOjAPoKdEdOtzpSvDc_m9INJoRw6iU-49rpCAAVjF6XLNMz5pSFcSse5wyUF8ekLaE8dUbQsdb0s_FE_n7fYoLK7AWu7_cwHKV_FAjpX1igVfk7dGw3XkdOwHCCAuAT92DnXIQ2kBBSBvIYvO8AHiThfu3u7JF9B3gpSWE6rXprjJSR2V-AC_Qx4WN0HCbdWP0dSxb6yg3TRyspWGzkeyGB5ngKTCoHk8HRtH0v0OXOVhFt24Y5wEiNc9aax0dhbWLbQluirrR6M4n8yNxecL-YyZLdPayFkpe3FxtNElwKhVLcfhRBzZigdCb1ZgYbC6cWAGshkguNzy0CwHFtvL4ItsZHTtQDa8VoiVcyWwu3fR-4KR1Ah-fme7CPb7kiBBMqW3mk2F88kkUld5O-Wpbn58Go0DtcDxoblId89pjexveDJ7PaF-WbKvFrLAEOmwzxoNK1KaaBEDX2v98QrkU2s9zfcIyW4sI2un9gHCzCjv309PD28vWHx6IUo4Hhn2Y-DiTdCVV3LXqEV9JTcli8BWk4Gl3wP3ZmP8UcUWO8k0FGJdKA3SLodAqEKytx35uNOqw1JzB-ulwKPTcVoGhehJggJwUDXGamGMrnSDPGhYtRkUd2fNjCdzXUwBx_mQr5ZuhWEDE6nQmjpc4qTkHFwStuc56SXqQmauTDbXYlZL4ip4z_yrTWrjU1Zzc_zTXYHRzbbWdqxJIwE9lH19Ibw7Ofblg7y_wVASZ9HubAjXLWvYN-oJrU5VF2wKURm77uXCQH_-W1FjcdHr28BOfYF1uDc-07FkSmhMJ3Nw0Ib73MggkrufnFqie46-SgJZSYmzkHwWyUk1o-0Kegi-l-_bYBRPiiDE561LpnDjFM1N5eA5xAiXO-K4vFC8Reo6eb9MK3KQH8Fbc8y--OPsjr5EKl4pncZW0Dz-0bwkXpAt7qtk6blqweoXEv377EAVocQzsXq9LVVDPsS4reJzn9JHM9H59i33RgheKBCVcdJrV8NqpUfnhs5kVVMAZ5TD66o382-vo_lnxAVK_RbyBC29eBLmopfmmEofA4Y7ezKxb3Us20tPlNUAmZ9vRSsJZ5V2Z9KZDGCcfQpz19AqiJJaarpE2n75dxQO6c6GpxAU9oOi0uON9h6GjBAC-CmUB3cWXQYQBN1EHqGxRTqG28LTLI6uHEtuwXE5UNCbhH1OLNkh76tjyJjVdKu3U_BVJ3x43oAlnKHuz2r0euznyaYt8kmnQbEUCpdVFzlU3HExIIHrmEKcKsXabHFlzZpEXQgFRwVhR6eWEDud-j-yu02zGTb0Et-158vJ-1PlLagu6cTuCijA55J29BbDYyECkVYSBurmaEH3payFeHwMwJo8GKb-_XImoMzrtirJTouPiIKisAL-vf73boOGcuTbzqy2N5Lgek3wLgbZMeHOdEDVghuSAFoiRrqQYAKdI8SWezKwTG6sBbJxbH0l-nezkQVZTr2NUuh_q5CRhRaWcGAFtwDruR9WWZEU_Mplk0ILsjlnUcve-yH-H1bzjSrhokypYIY4Wx7w2COo-JpxmvPMDSrM8A6CR2AqzCI2Kzey6Uoo4FDKqpzzwwwrmEa_Zc6lvYha0ZQs0yzseN_OgCqYqalFzZsRi9XSZ07683NtBlsQ2zUuOyL9QVaJa3bETGK-O-6JdVuPZo56Brx_ELWe_TSzOz_o_h-cEq0RQhMgQZ3YW2YKYezS7YlhS0rIBkbGI6mnCd29fqCWXsSAG5S2vCIU1IyAgcwR_uoSLOgFAN37vSbmFALfVNy3O7wx-nAkC5ZGMuAf7YqEMiu865ll-0KjECbnC7A\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"AA74EDC9-428C-4B76-A2CC-A10BFF314455\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4xi_W9dEA6VWMhKDpjOjuJU842zdWXAYitUM9yT2bYZJNSB8OsAURjvBAQZWOflhaTryhcfvkzax8YuyInPOnI0fONiIFBFz7T-Tgkx51xg5X8xv4CEi7--8T3_-Qv9PfBervNe0A2RhKgl0DQQ0J8QWbsE1SgHOY-xctAt_2H2PxNKkcH5Sb-ZaNZoRsCYVDoN21AGX9zZM4BXSGxcloXaVMawExaQ83FlSZ6YM05rl_fSMmebgaAkupQwV8j9TC72_IsPFdPW__-yJEQng_yuwK8fGCMdAEtSquMf_bkXX298C1Om3YlGScIJWgtA0vWrqkZ4EpCMHc5_XT5lGF1t2RCQdh4scdlPs8JnUZIKoTgejcACbAoLLmqyVx4Iy4VJWde8g2JyoWYEotYKL9Xy29MSKLAMpTUxqCkizK0paQqsPi-GxGCzddHODtuRruigG25TwB6_dpNiDl_wlMBXAhpJePauyllTFBvUewuWuVmzbis-4agzh4WczNM_nM2EK7MneN2KF8hPH4pzU-voRJpAbZAMdY33Dt0HXlcbSZcmdgp6trEXgap0qiIMQxYPfwkKU_tt7MnjIP5ezQLta4G_xkn01Xp9iv0Hg5nVQ3DOuPizwwuX2MOjAPoKdEdOtzpSvDc_m9INJoRw6iU-49rpCAAVjF6XLNMz5pSFcSse5wyUF8ekLaE8dUbQsdb0s_FE_n7fYoLK7AWu7_cwHKV_FAjpX1igVfk7dGw3XkdOwHCCAuAT92DnXIQ2kBBSBvIYvO8AHiThfu3u7JF9B3gpSWE6rXprjJSR2V-AC_Qx4WN0HCbdWP0dSxb6yg3TRyspWGzkeyGB5ngKTCoHk8HRtH0v0OXOVhFt24Y5wEiNc9aax0dhbWLbQluirrR6M4n8yNxecL-YyZLdPayFkpe3FxtNElwKhVLcfhRBzZigdCb1ZgYbC6cWAGshkguNzy0CwHFtvL4ItsZHTtQDa8VoiVcyWwu3fR-4KR1Ah-fme7CPb7kiBBMqW3mk2F88kkUld5O-Wpbn58Go0DtcDxoblId89pjexveDJ7PaF-WbKvFrLAEOmwzxoNK1KaaBEDX2v98QrkU2s9zfcIyW4sI2un9gHCzCjv309PD28vWHx6IUo4Hhn2Y-DiTdCVV3LXqEV9JTcli8BWk4Gl3wP3ZmP8UcUWO8k0FGJdKA3SLodAqEKytx35uNOqw1JzB-ulwKPTcVoGhehJggJwUDXGamGMrnSDPGhYtRkUd2fNjCdzXUwBx_mQr5ZuhWEDE6nQmjpc4qTkHFwStuc56SXqQmauTDbXYlZL4ip4z_yrTWrjU1Zzc_zTXYHRzbbWdqxJIwE9lH19Ibw7Ofblg7y_wVASZ9HubAjXLWvYN-oJrU5VF2wKURm77uXCQH_-W1FjcdHr28BOfYF1uDc-07FkSmhMJ3Nw0Ib73MggkrufnFqie46-SgJZSYmzkHwWyUk1o-0Kegi-l-_bYBRPiiDE561LpnDjFM1N5eA5xAiXO-K4vFC8Reo6eb9MK3KQH8Fbc8y--OPsjr5EKl4pncZW0Dz-0bwkXpAt7qtk6blqweoXEv377EAVocQzsXq9LVVDPsS4reJzn9JHM9H59i33RgheKBCVcdJrV8NqpUfnhs5kVVMAZ5TD66o382-vo_lnxAVK_RbyBC29eBLmopfmmEofA4Y7ezKxb3Us20tPlNUAmZ9vRSsJZ5V2Z9KZDGCcfQpz19AqiJJaarpE2n75dxQO6c6GpxAU9oOi0uON9h6GjBAC-CmUB3cWXQYQBN1EHqGxRTqG28LTLI6uHEtuwXE5UNCbhH1OLNkh76tjyJjVdKu3U_BVJ3x43oAlnKHuz2r0euznyaYt8kmnQbEUCpdVFzlU3HExIIHrmEKcKsXabHFlzZpEXQgFRwVhR6eWEDud-j-yu02zGTb0Et-158vJ-1PlLagu6cTuCijA55J29BbDYyECkVYSBurmaEH3payFeHwMwJo8GKb-_XImoMzrtirJTouPiIKisAL-vf73boOGcuTbzqy2N5Lgek3wLgbZMeHOdEDVghuSAFoiRrqQYAKdI8SWezKwTG6sBbJxbH0l-nezkQVZTr2NUuh_q5CRhRaWcGAFtwDruR9WWZEU_Mplk0ILsjlnUcve-yH-H1bzjSrhokypYIY4Wx7w2COo-JpxmvPMDSrM8A6CR2AqzCI2Kzey6Uoo4FDKqpzzwwwrmEa_Zc6lvYha0ZQs0yzseN_OgCqYqalFzZsRi9XSZ07683NtBlsQ2zUuOyL9QVaJa3bETGK-O-6JdVuPZo56Brx_ELWe_TSzOz_o_h-cEq0RQhMgQZ3YW2YKYezS7YlhS0rIBkbGI6mnCd29fqCWXsSAG5S2vCIU1IyAgcwR_uoSLOgFAN37vSbmFALfVNy3O7wx-nAkC5ZGMuAf7YqEMiu865ll-0KjECbnC7A\\\\\\\",1]],[\\\\\\\"80C1FA03-ADB4-40CA-9951-38805F82B63D\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:33:56.661Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=482647&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1],[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1]],314608653,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7ckwhKx-bYZ4frukWjFRRGvjp4Hh8RuDJ3Mxn6PFwQEyPpzSi2YkTEXTID66RphZgqG6poKHTum42a6WzxKxzTSwVeAJ2iDqXai9ZagWkAeT0CrQTzs55iKo0-mSX81ttQuZDZmVyEpLNngE5--VZ5aJrsEt3NAl7fLaddxkOKNrWjUpMhrCOZQrLVGmfr-p7KIyn7V9KMmzdknEAnc4XULqvCazamiZVGCTd4iq0P6-Nl8Hh2_tqTCAXwr9Bsw_ughrEeEhGX3S5zIEPF3zphM7KOfWBZ-rsOIq9IWvTh9Tc9nShrIeE8FTlWl5Y4eM7eMbcYS35ZcNQGTTHns_kH-KcaX0cjDjOaPt4sGGn0-wY5rgLJlQ7Pg9iyySQA97V37CDxQUeeX7ecqoWVhv_ad33rGNtmYw2DNm1XQER70LulSDVZMq_zDDzCZG3nZ_vQLUe0WosAnYv2_nm96pOIR8UuyWwYFG8Fjx2TTNfMqhT1-PydNLXsNqiAHdzE_n8ZcGSGlsDyAszx7vu6GHDAi5RDzP3AUQtf70iSMVkhJNjY_BxyAd9e-kVL9ZN4crxQDZM2GIDF-ZnGB5HUdvJ5QXwvqdVEjDY73lFt753D0b2sNB0yqiQjTsOcDBi43DUB82x388IGxXNtBTdWiIRFzD-cPC0ibF0QGEKfsC_SFRDbrpBmPOfxgVY9AsqyGvZVPaYU5-8Nxliq1zLXqBuQMFLHJm9MdQWUuUHBkb9mmjuPkSroRpz_x7sJAQWtmS4URo0BEQlziTKfTnFi8H2NQuX285avBGTmgqGY2piKitsrJW_nK3YEcvlbQLMTh8iyNp71yE18pAfRRYa8l1BN690zP33Nbxdd9Ik1M-tmcvANu-niiGaD_eOs4DjPF5i5w0mLs_u3sju2juZZVqjENlrG93W177dLcEjGMXEpiaia12Tt3_-eW41AporjlwdWgwnG-PiZOqhZ7pAts_ENXU2W8SXL_SO2qbXjIqPliTL0ENtAl1lBCS8xgpWh3MGLLkhzu3fMyGZshpzxczOLXlf6qFB2t59XuIT78DGeNd3JA_A0Dtt5S9AXiXfMXnbJ1H248H1D71bgkZvD-128v4ewMpshQMpH8I3Gik9xivH20zX39f3Z_7GJcHk02uZL11ro8gSyOPQrmnjZRWLcWBX6bgIRKYegNdfsO8tEfdB0A64DiY4fYogczj9uoKHszfvFbiSY9_TMbuejUTbZ8PBHglEwuzTN4HTEgQ7bRZgv8dpCmbVOy6FDMvUwq1dH6hKHvidNcb5sq0qk-M8dDZ3i8dgLpgNeg9KtpshwvojcAoO6H1wgkrx61i9mq0r691UpgBa7xUNiN-p5azbKbDGPR0nyqHeRXjUCudcg4jYViT4pb6dESr_UDHc24BW-vMcfIsPTk6ABWWpyPhy4h0joGFDONlSvLBe6y7whDK_gyddNRLkJJtEYpGDHmRVL97EHaLKINqZtPzytvKDjJKilQrwUULvA7GHnFAVEfyyT2RNQQo4WI5ggx_AVU_AeHy4tJuyfTXXLRPc_SMqjMGINYGfEn18L5HF0jTX1PM8EBOKTzVMVsV7sFIw67De4vNeeZASiqiFxjUlVKm5hZ8Rtua7uDJ9_qfFe5_hebBrhoII3F3pf_3x72vtoq21MOtwFeKzBXIEyRcpSeflUytjeErdRBZNl_kKoFfPzsBpCgdihuQVOomcnjOhizyYrboVi_4fqpbhSBHmJ2SeYmiUtTk89QxRzsGCTvbo_EIIjMBup8WRkAcVoXbLgrXKQkljfh7ETzWCjJshB6Xseqh3z5cnN32wy1Dzc48TACHzl1sX9wHjP7oGLJc7Lvne6VN-X90Q3aBTGJo6SuHCKA1TczKSTJ_6hVU8yKy16zfVgweUMLL1bMKpXwYrIMn60GwhOlcblpD4v_0jKqG8BKMOqGISTrWvF3v4YD_yFxQBH49CZRlpx1lHL8KlOdfxFaXl87nb3MfR2zrkdiTGwLtC-USTtEs8VN-0ibWAgqFolwSh7MY-Jrqb1wXWJidbXy87jHqBWl9A2QiZwvxH2jtKeKzv8yEk-AoiCKm23KdQCELRWEbRm7TmP7mrigZfuXAOTR9yjYg9TDKpXCsYTo866Eua7knozrhw2h1e2BpfblHQyrMuczQiSAoZH_Z38b-lxn5QEvTs4kgxyfNQ1WmhB6CeFCx7niNTsoSFFdMXTaxC1Y86eb6CrFy46-zDwZDB9kdjbVhTc1L2liKt3QwhHhXA1YXzhawZwHQ3JiRtOJsaGpZ9YmHg4jZbRa8hKHWUoH15hFGHErAXgOcv9bZltLCUwEkO0oDXSBlP2At-Vh6WosezwwpFcwAJLSilIkLVYMxdp94kOXWHI4Kijj9NIcXZdCUWVGiNBQSdpJ-M57Qnv3CMhIY73De62vtj6Z5YTUY7oh798oqA8ycrr4kGzDQ\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot inside subterranean B3 basement parking at Me Tri during extreme heatwave. Le Quoc Tien slumps against a cracked concrete pillar in defeat beside a torn empty water pouch and heat-warped debris. Do Minh Kha looms over him in the background with a cold detached expression, silhouette backlit by an ominous beam of deep crimson sunlight piercing through a fractured ceiling fissure. Chiaroscuro high contrast cinematic lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"658FB113-ABCC-4436-899B-B885C9020EFE\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7ckwhKx-bYZ4frukWjFRRGvjp4Hh8RuDJ3Mxn6PFwQEyPpzSi2YkTEXTID66RphZgqG6poKHTum42a6WzxKxzTSwVeAJ2iDqXai9ZagWkAeT0CrQTzs55iKo0-mSX81ttQuZDZmVyEpLNngE5--VZ5aJrsEt3NAl7fLaddxkOKNrWjUpMhrCOZQrLVGmfr-p7KIyn7V9KMmzdknEAnc4XULqvCazamiZVGCTd4iq0P6-Nl8Hh2_tqTCAXwr9Bsw_ughrEeEhGX3S5zIEPF3zphM7KOfWBZ-rsOIq9IWvTh9Tc9nShrIeE8FTlWl5Y4eM7eMbcYS35ZcNQGTTHns_kH-KcaX0cjDjOaPt4sGGn0-wY5rgLJlQ7Pg9iyySQA97V37CDxQUeeX7ecqoWVhv_ad33rGNtmYw2DNm1XQER70LulSDVZMq_zDDzCZG3nZ_vQLUe0WosAnYv2_nm96pOIR8UuyWwYFG8Fjx2TTNfMqhT1-PydNLXsNqiAHdzE_n8ZcGSGlsDyAszx7vu6GHDAi5RDzP3AUQtf70iSMVkhJNjY_BxyAd9e-kVL9ZN4crxQDZM2GIDF-ZnGB5HUdvJ5QXwvqdVEjDY73lFt753D0b2sNB0yqiQjTsOcDBi43DUB82x388IGxXNtBTdWiIRFzD-cPC0ibF0QGEKfsC_SFRDbrpBmPOfxgVY9AsqyGvZVPaYU5-8Nxliq1zLXqBuQMFLHJm9MdQWUuUHBkb9mmjuPkSroRpz_x7sJAQWtmS4URo0BEQlziTKfTnFi8H2NQuX285avBGTmgqGY2piKitsrJW_nK3YEcvlbQLMTh8iyNp71yE18pAfRRYa8l1BN690zP33Nbxdd9Ik1M-tmcvANu-niiGaD_eOs4DjPF5i5w0mLs_u3sju2juZZVqjENlrG93W177dLcEjGMXEpiaia12Tt3_-eW41AporjlwdWgwnG-PiZOqhZ7pAts_ENXU2W8SXL_SO2qbXjIqPliTL0ENtAl1lBCS8xgpWh3MGLLkhzu3fMyGZshpzxczOLXlf6qFB2t59XuIT78DGeNd3JA_A0Dtt5S9AXiXfMXnbJ1H248H1D71bgkZvD-128v4ewMpshQMpH8I3Gik9xivH20zX39f3Z_7GJcHk02uZL11ro8gSyOPQrmnjZRWLcWBX6bgIRKYegNdfsO8tEfdB0A64DiY4fYogczj9uoKHszfvFbiSY9_TMbuejUTbZ8PBHglEwuzTN4HTEgQ7bRZgv8dpCmbVOy6FDMvUwq1dH6hKHvidNcb5sq0qk-M8dDZ3i8dgLpgNeg9KtpshwvojcAoO6H1wgkrx61i9mq0r691UpgBa7xUNiN-p5azbKbDGPR0nyqHeRXjUCudcg4jYViT4pb6dESr_UDHc24BW-vMcfIsPTk6ABWWpyPhy4h0joGFDONlSvLBe6y7whDK_gyddNRLkJJtEYpGDHmRVL97EHaLKINqZtPzytvKDjJKilQrwUULvA7GHnFAVEfyyT2RNQQo4WI5ggx_AVU_AeHy4tJuyfTXXLRPc_SMqjMGINYGfEn18L5HF0jTX1PM8EBOKTzVMVsV7sFIw67De4vNeeZASiqiFxjUlVKm5hZ8Rtua7uDJ9_qfFe5_hebBrhoII3F3pf_3x72vtoq21MOtwFeKzBXIEyRcpSeflUytjeErdRBZNl_kKoFfPzsBpCgdihuQVOomcnjOhizyYrboVi_4fqpbhSBHmJ2SeYmiUtTk89QxRzsGCTvbo_EIIjMBup8WRkAcVoXbLgrXKQkljfh7ETzWCjJshB6Xseqh3z5cnN32wy1Dzc48TACHzl1sX9wHjP7oGLJc7Lvne6VN-X90Q3aBTGJo6SuHCKA1TczKSTJ_6hVU8yKy16zfVgweUMLL1bMKpXwYrIMn60GwhOlcblpD4v_0jKqG8BKMOqGISTrWvF3v4YD_yFxQBH49CZRlpx1lHL8KlOdfxFaXl87nb3MfR2zrkdiTGwLtC-USTtEs8VN-0ibWAgqFolwSh7MY-Jrqb1wXWJidbXy87jHqBWl9A2QiZwvxH2jtKeKzv8yEk-AoiCKm23KdQCELRWEbRm7TmP7mrigZfuXAOTR9yjYg9TDKpXCsYTo866Eua7knozrhw2h1e2BpfblHQyrMuczQiSAoZH_Z38b-lxn5QEvTs4kgxyfNQ1WmhB6CeFCx7niNTsoSFFdMXTaxC1Y86eb6CrFy46-zDwZDB9kdjbVhTc1L2liKt3QwhHhXA1YXzhawZwHQ3JiRtOJsaGpZ9YmHg4jZbRa8hKHWUoH15hFGHErAXgOcv9bZltLCUwEkO0oDXSBlP2At-Vh6WosezwwpFcwAJLSilIkLVYMxdp94kOXWHI4Kijj9NIcXZdCUWVGiNBQSdpJ-M57Qnv3CMhIY73De62vtj6Z5YTUY7oh798oqA8ycrr4kGzDQ\\\\\\\",1]],[\\\\\\\"85FCAB29-DD00-4032-8AD2-15F7B36A484D\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:34:03.919Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=476601&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],785346768,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4PfOLAYyYtYTiDl5oPpG4VKwQ1N40yiI_2WEBcz-Twxgnr6BkmQmkFHtbnW2apZi89ctGksIEjVq3mU2MaZKFmQf3an-jGBDScmNVifAV40MxTtg9iABfPxluF1D2WGa2KoHb6ZgD6xA_iDQ9hw8wX7TwlnEnO2rGJb-zNyXYOcX_kWbiGLz_OpUmYqwp5coyICWUDmniqW7n9WVT87WNv3szVFjDwGRnnBHvYQBIjf2Qut6PbyU9392tzj0xCDpWh48sEfRo0Y__3_UPf3D56czuFq7kErXIYVgRpghjMUO3l6--QS5xdRD7j2aComCKMOLO0sQuCMSJuMx7kqBIZkJvtF7OxsFsa8g0iS6972eDpc0EplmmdMkmb5p1SRxJGIFnSMk_gYtHlwC3hkvg4EnJOhrpdDxrrkGVEr9_LqWcTO7vEYPM6s-ojX7uWJ2GmFYtu9uUPeLNb4mu34PG7EM92-Mi4R9L1EDHBvqcU2naXWg2Ukf77QlZCdq9OxhczeGxTARS6w78XtIWevHCFEikDqdmE0Up6nlifK1R5tjWYLxbHOw6xaj67rOqqgr8G6ln6ofSptQs5ODtwoWTPNGSlDgVEPcP9DG7sUOuBdMMrFEuDU6iyUwTys0h2kV6HOlFhb8zVQHtiFpa7YmYaaJRwgD9WdoHfQadMX-XvpacAafS0MfiVqShuR3r2sddr0n14w-9YROD3WWUszTukyDZIissyBdqNvfY20ZaeFcfTMBJeOklcWs1RhGfWNpPXbPC8Vp3zOOZbh5-a9HjMzPA0acbYyF3L9FCzL9koHiIXPcyJMK2m1ozCSpT6HhHqSrU6RvYuZ4cINTWygQe4GlZiTwmGhjQjs1WsmcGnOxtX-Jx5hKIh6MUrdjO0SVMlc-A_oUqawBGSSxnp1wC9OGmmbcC9bQDnrpiNo8A6r7OBZd6M3ubKif1QJ8nGy1B63oq2KozVvfiv-6uPTvxEHUGkLvUwJ_HoPsZYKD1uavHXNXom-ad0H2NPAURb38dOpitedthwV0czqOe0CRVpPkhTXxzH-A8zDh35eYA5s_rR1sasxi7tn0y8cKCnia3ZlTSQV7O24tFXR3YYyynC57LBpsEtDQ5LQ4P3XXhImzmFppEGgTMx8Y-ckPSVXYlTSBzealkQ_ZRYsGciDXblEKM5gk6hptu-BG1o8InZdfAcm9N5lqE89mO9iQuvOnmw4D1EQOOWhLMgXBAe35CW2Pyb8-i5v3X6tjibiuieyW7jNBgI7422hieUSmbm1wLx-hE-xafrmdUE0y7VjXzFABSoyohmAAOz7Ls4raHb2oPeJVf5wT8d9KVmhXAbwmC-3wWtYCcvLbUMNF1MCtLk1FE81AO9ALEc_8Jo6msssubOWjVnVaGyXLLKKKvQ8wLF9KcECd8vqd-f7t6a-N18YY5o_gAPosdwq8diyEIIocM6n9rRT6xQUGJ_aleyrWYSzb2LTqeP8pWwkxEGjcXHu2fV-fRKITQuOCKxmAlXKG-6xUHT4XJ38PsD6Vhc1WMLW93oum2zSfEm1gozvoagZAxZwoWPxb2WH1VFO5MpzATCDjxAXFfWQD3lejYNg6K0JpXjZtY6yn7bJJhbjnEdrA6s_EtB2I9W7k3WADPscOXNREWASpg7c6fV_KoiOf2QHhn3DQoGcyYAPsE5P000S6ZpotiEQRtA07oRgpZh-q8wzG72jndrmjc4lD3pZ3pf1GhMddzsYNx2K7P6h6nIdkqGe2sxLeYW7-J_qwA1BUJqQUWlwdJr6now7FWA9RVNRsH6SB6Fz8cH-d1dW4nYom96pDO9_mPKdp9tZ7NOJOoVJZ8LWkNtXl1LSYzHxXBunnisGvv35GgnMfjoEXhCsroHtItacHTxsnK09owgIOnX9K-P_ZVXPyWp18wB3eIKBZ-kewcQYN_gR_H9_VlDVKsGwfEmJ9GGvIsaMwWh1UUI_BhLLz4vA3aBhoRVq5zptyNe6bbt7QHK6R9mTXxcc3O8nG8pu6OCwguxhhaZz2dmmFpcoRe5hSlJQEF0OUHOvJPCYQ-kpp4Kt--vi-VO_gA9Pwh-LDdfHDUBBEYkuVqoodt2-9vIU0QXD8Pc5TSze7MNKiU2HDrVBQe981hknSHwZXTZ7sTYPb3cXwQFJDlP0KYuPGnas_jGFAuYdPhrETQQ49zrF_Q_g4EqZ-SVrbxMOiPaVOS4Hhc7VWZqjog3yRE8D4UGv7MTgIu2hwGGGeau-gFUtXL4YsHxpWFYVwMFimcQK-4aP9Ul0l67Q8Uo_zul5bENAkMKCAMRXR9vmy2o6By9WPiimqcJ8aF70Udlj1-bq_0sZ2aH85fSSx-ZW_rMbYmmyhxLFDeThQfMbdjiPpR9grxA--VkcOpMmcn1a01tOs3myDaV9D2UU18rhIb2ifDvJ2tg4xkdMDmTb_kJDjnLG9dQwuPcu30oESgY9A\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"2BE60259-0587-4B76-909B-A36EE82522F3\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4PfOLAYyYtYTiDl5oPpG4VKwQ1N40yiI_2WEBcz-Twxgnr6BkmQmkFHtbnW2apZi89ctGksIEjVq3mU2MaZKFmQf3an-jGBDScmNVifAV40MxTtg9iABfPxluF1D2WGa2KoHb6ZgD6xA_iDQ9hw8wX7TwlnEnO2rGJb-zNyXYOcX_kWbiGLz_OpUmYqwp5coyICWUDmniqW7n9WVT87WNv3szVFjDwGRnnBHvYQBIjf2Qut6PbyU9392tzj0xCDpWh48sEfRo0Y__3_UPf3D56czuFq7kErXIYVgRpghjMUO3l6--QS5xdRD7j2aComCKMOLO0sQuCMSJuMx7kqBIZkJvtF7OxsFsa8g0iS6972eDpc0EplmmdMkmb5p1SRxJGIFnSMk_gYtHlwC3hkvg4EnJOhrpdDxrrkGVEr9_LqWcTO7vEYPM6s-ojX7uWJ2GmFYtu9uUPeLNb4mu34PG7EM92-Mi4R9L1EDHBvqcU2naXWg2Ukf77QlZCdq9OxhczeGxTARS6w78XtIWevHCFEikDqdmE0Up6nlifK1R5tjWYLxbHOw6xaj67rOqqgr8G6ln6ofSptQs5ODtwoWTPNGSlDgVEPcP9DG7sUOuBdMMrFEuDU6iyUwTys0h2kV6HOlFhb8zVQHtiFpa7YmYaaJRwgD9WdoHfQadMX-XvpacAafS0MfiVqShuR3r2sddr0n14w-9YROD3WWUszTukyDZIissyBdqNvfY20ZaeFcfTMBJeOklcWs1RhGfWNpPXbPC8Vp3zOOZbh5-a9HjMzPA0acbYyF3L9FCzL9koHiIXPcyJMK2m1ozCSpT6HhHqSrU6RvYuZ4cINTWygQe4GlZiTwmGhjQjs1WsmcGnOxtX-Jx5hKIh6MUrdjO0SVMlc-A_oUqawBGSSxnp1wC9OGmmbcC9bQDnrpiNo8A6r7OBZd6M3ubKif1QJ8nGy1B63oq2KozVvfiv-6uPTvxEHUGkLvUwJ_HoPsZYKD1uavHXNXom-ad0H2NPAURb38dOpitedthwV0czqOe0CRVpPkhTXxzH-A8zDh35eYA5s_rR1sasxi7tn0y8cKCnia3ZlTSQV7O24tFXR3YYyynC57LBpsEtDQ5LQ4P3XXhImzmFppEGgTMx8Y-ckPSVXYlTSBzealkQ_ZRYsGciDXblEKM5gk6hptu-BG1o8InZdfAcm9N5lqE89mO9iQuvOnmw4D1EQOOWhLMgXBAe35CW2Pyb8-i5v3X6tjibiuieyW7jNBgI7422hieUSmbm1wLx-hE-xafrmdUE0y7VjXzFABSoyohmAAOz7Ls4raHb2oPeJVf5wT8d9KVmhXAbwmC-3wWtYCcvLbUMNF1MCtLk1FE81AO9ALEc_8Jo6msssubOWjVnVaGyXLLKKKvQ8wLF9KcECd8vqd-f7t6a-N18YY5o_gAPosdwq8diyEIIocM6n9rRT6xQUGJ_aleyrWYSzb2LTqeP8pWwkxEGjcXHu2fV-fRKITQuOCKxmAlXKG-6xUHT4XJ38PsD6Vhc1WMLW93oum2zSfEm1gozvoagZAxZwoWPxb2WH1VFO5MpzATCDjxAXFfWQD3lejYNg6K0JpXjZtY6yn7bJJhbjnEdrA6s_EtB2I9W7k3WADPscOXNREWASpg7c6fV_KoiOf2QHhn3DQoGcyYAPsE5P000S6ZpotiEQRtA07oRgpZh-q8wzG72jndrmjc4lD3pZ3pf1GhMddzsYNx2K7P6h6nIdkqGe2sxLeYW7-J_qwA1BUJqQUWlwdJr6now7FWA9RVNRsH6SB6Fz8cH-d1dW4nYom96pDO9_mPKdp9tZ7NOJOoVJZ8LWkNtXl1LSYzHxXBunnisGvv35GgnMfjoEXhCsroHtItacHTxsnK09owgIOnX9K-P_ZVXPyWp18wB3eIKBZ-kewcQYN_gR_H9_VlDVKsGwfEmJ9GGvIsaMwWh1UUI_BhLLz4vA3aBhoRVq5zptyNe6bbt7QHK6R9mTXxcc3O8nG8pu6OCwguxhhaZz2dmmFpcoRe5hSlJQEF0OUHOvJPCYQ-kpp4Kt--vi-VO_gA9Pwh-LDdfHDUBBEYkuVqoodt2-9vIU0QXD8Pc5TSze7MNKiU2HDrVBQe981hknSHwZXTZ7sTYPb3cXwQFJDlP0KYuPGnas_jGFAuYdPhrETQQ49zrF_Q_g4EqZ-SVrbxMOiPaVOS4Hhc7VWZqjog3yRE8D4UGv7MTgIu2hwGGGeau-gFUtXL4YsHxpWFYVwMFimcQK-4aP9Ul0l67Q8Uo_zul5bENAkMKCAMRXR9vmy2o6By9WPiimqcJ8aF70Udlj1-bq_0sZ2aH85fSSx-ZW_rMbYmmyhxLFDeThQfMbdjiPpR9grxA--VkcOpMmcn1a01tOs3myDaV9D2UU18rhIb2ifDvJ2tg4xkdMDmTb_kJDjnLG9dQwuPcu30oESgY9A\\\\\\\",1]],[\\\\\\\"E1EBBB69-0118-4F27-ADD1-F71D29C1C559\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:34:59.051Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=836687&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Low-angle tracking shot through heat-warped plastic debris and scorched concrete in subterranean B3 basement at Me Tri as Do Minh Kha walks slowly past motionless casualties, boots coated in red dust. 3-6s: Camera tilts down as Do Minh Kha crouches over Le Quoc Tien who slumps against a cracked concrete pillar beside a torn empty water pouch. Do Minh Kha speaks in a hoarse parched voice \\\\\\\\\\\\\\\"L\u00ea Qu\u1ed1c Ti\u1ebfn, m\u00e0y v\u1ed1n kh\u00f4ng n\u00ean s\u1ed1ng l\u00e2u \u0111\u1ebfn th\u1ebf.\\\\\\\\\\\\\\\" 6-8s: Close-up of Do Minh Kha raising a gleaming tactical blade reflecting the deep crimson sunlight bleeding through a fractured ceiling slab, then plunging the blade downward into pitch black darkness. Audio: Stifled gasping breath, slow crunching footsteps on gravel, hoarse menacing dialogue, sharp metallic blade unsheath, deep sub-bass cinematic hit. Negative: subtitles, watermark, text overlay.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"bdcbe55a-ee7b-497d-a414-25d22d04c096\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"ED10EBF6-DCFB-4D9F-A450-6E0B1AEEFCA5\\\\\\\",\\\\\\\"7C58CE0F-81E0-4079-944A-9F28392F5CE8\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7UoedpUZQQ9pVdbXQw18opVHeTxleUPvaQwIFTFbfTmys1ZH5_i-xR_hYnesuvf-XgDhHgbACVJ3SJ_8W6fjuY8dCxTLR-JJemy9B5dd0xB6_RpOrJPm4oy_E3Io_K_P5V4fOMuW46fhST0_pElCzQntwQSSxnE3MFBh7K_Loh4KAL2yxraH-JXyQ3bRXzwxZJXy5R4PUxMHLigCh4IoOShkxwpjj4ZwZjeyqgK1lrO3hT9ocHd-Ax-UWdDME-WTltiCVORyXLZQ6Vsasp8-NPsbcQnIglRCQu8hMmMGNB8gbxDz79cx0XNaPytVFw0HK3LZyzEY9hXsuf7JYESnOHqUoga3OyWKwpOF4Y6vy3pEeE3cpSJ5YWVqgezWhP8YMVeyFucV-kvhBIClwQMLJa2U2KZD4wLy-MiDmsJa3inHJ1qF-YgImGVXNU2s6FkREFebh53jISOjy-JDT2PQ3F7Ue7BY2_wFeJRrKEuX1Sxejh_eWCH5VcdVnNB9Xv4cwzN4YEVbts_6vtFzaaYD4utR0wfQJdXo4vUOB0BWUGU2-ZDlOJEgtI1323IOrx2WxUOMYfueT4EtGseOgrucogHLFmpjGilUiN3vdgXVjDPxAXxjgDdU2cDZg7UsVNtzMK6j7nfOvEDR9_QXxW97JuJvu94SQ5YSfmWW9y-xXkWbnwGPwZF74Y7YV9LM3xLu5j8J-b78FxA1F3fTXrVZ_uqe6SOeNNUVBmedBKGuEonMIttgYsc0bqR2wvDS2504lbQzIdCgjQkpS4uXhWHBz45YgkgCTKKm-MlPK5gjGAGIYTAqK3WLQi2QQHD8mzjKy0kFXktkVekYaDEOI3VBsyWDMVIwWTiJcdtLLuXKQP5gJm8uxUoKLsndv_b7gfEVYFQ-m8Mgxe4ThPMHrwxsPGRQ7ZGBx83seCGoO2SyLifxUrWwiu6gc5kxQvjZklbcdCudIuVcKK-DUDJcAJ2cnUkLh5ujmm5hT31bSPAtoOhXc2-vRuy9LFivxF-bx7QNjx4pcm4qXEsuOMyOkY-ObR2TLMqDyVpXJH1AY6EVJFCY06EIUQD5jllXFIcUQmpAUFpKApFs8XcT7M8lelBI4nHoTyTbg7m5HH_g8wpv-XouCk0YTHPIq3gs7FHtoaYOHOuLgIPA0w9ILZ-gr2Yw43gTZ3zCET6rL4mSYm0nSrSM87kakPfNnt8ADk841k0oVqSkL2xp0t357rO_z1j5gUZcHJ6zD13pHM8l2xoc_SPDqwwNCk8sWl_6xQ8_MxSN0RyD3tGmsDQsGDQrFupG1DnEUnSN8xhsJ8Wzm2v-ZjAbbeB613JsKecqivpsmh3QU_jCqHJdcdhjioPorEXl_iMvh6zJykI2iVchg11Ko6q46WdSMcTb1KRuKDQxaDtPR1f_fJkIiguukPYc840JOM9OSy-ICekyvk8Id_ybdlNjTgPiLmjLaJU8jR5sKDuslRsawpFQjg8ZDTBYHs-dy2JBmHGNfT63wCKg-EUG27on0sbRQ_eqR1e3kz-Jidz0eoP3Sknoh1ax4p8TSBbcZ21KqlThhJXNSe5HXW__Tab8wIOKaU-FT0s832VQY3aBQ4gmyXpoiS3D7pFM1nXzGDyeNTpqnnP-YyEFtY7SZx5hMuniW-hywDGETHlTb9CjxXjUXgIso0C3oQpSru2eVkWX4d0NxAAupYxYWqe2HDGIP0wFWI1GLVONZIny6uNypI_W5nuQt0pmuXnK0Ta3fAq-PtDXah1jyv5YLkPtYHYSoD3WZeN2qY4Y-kytKDKZKEYUmCuhvx7JbgMX68xeSzmL9oCX8lvi2H4cJJ6psXnukSfuJwGcud8dar-6MDI0D2k-ydlih3g0_vKzfnJIg59NXJ-yTM_DBwNayA9okEIaCok5gh9l8iy64E8256JxPDtUzDTswQSCkrEW3oN5-Ktrcw4dsNlL8x4k9tpYkySOk22C5-QYaaYZgy9R-PnJd6eeGH9k3XOD9Q6J6bcDWhwHPuYOyzIvW7CM0AMXbSO_yltFUJwdT_XlwHPKlfiHlS1LODOYtlL5cpHkLumcusF-AESq-RbiNEtFWFvsBgoR9BUMzmVGWhU8ERwJNO7j5P7XqVZM2coT4hXotdQ7fsSCNKTCv8bHvmYSa0zEsL22x9GLMjPJHXYldyQM-ujiG8vZqd09GJx4Ac2Sq6WyxLDUQcn9vXLHzhTiwOcBxXlL77oETNOa4-5oSviT-3L3Czi6l989g25CslxJ8Un2Z8lBsVocDCadl4fHQW7khgNMby9nHj6M50Lk0uG0bl65TuDedaca8Afk31LpniczWKco2-nT6EaZFvNf9rw1-6P69YS2aSuAlfPSBcHzDiKPqXA5s4Rjb3D881nVboJ3XEPjIixd3lWXpqM66o7Ml1GYSKZqX90QYK0ugNz4AJ1uhIHQkb1MyC2wOz2-nB3EkXzF83BG0v8AUS2hU1gCKtdF6eqkBnT6omxSi8wfgP0nNbjndK\\\\\\\",1]],[\\\\\\\"431391A8-8AD9-495B-B597-B48EFC110EE1\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:35:13.860Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=120836&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:35:14.419Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=519275&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:35:15.657Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=767004&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"acfab455-1ea6-4342-9f77-6980931191e9\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:35:26.075Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=881040&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"acfab455-1ea6-4342-9f77-6980931191e9\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:35:36.511Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=793277&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"acfab455-1ea6-4342-9f77-6980931191e9\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:35:47.011Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=507785&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"acfab455-1ea6-4342-9f77-6980931191e9\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:35:57.400Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=484103&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"acfab455-1ea6-4342-9f77-6980931191e9\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:36:07.776Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=133832&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:36:08.354Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=687365&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:36:19.507Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=846490&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:36:20.039Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=307656&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:36:31.240Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=204772&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:36:31.846Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=126862&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:36:43.128Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=274645&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:36:43.672Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=550696&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:36:54.917Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=902395&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:36:55.524Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=735343&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:37:06.579Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=732662&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:37:07.164Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=428849&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:37:18.297Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=403016&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:37:18.869Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=482869&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:37:30.407Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=943611&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:37:30.968Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=635711&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:37:42.333Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=130904&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:37:42.906Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=449576&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:37:54.021Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=141389&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:37:54.709Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=662206&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:38:05.860Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=514666&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:38:06.478Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=672489&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:38:17.674Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=284421&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:38:18.310Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=672217&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:38:29.476Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=830575&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:38:30.038Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=228952&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:38:41.240Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=869891&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:38:41.801Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=903508&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:38:52.908Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=635587&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:38:53.481Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=281464&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:39:05.251Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=982190&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:39:05.857Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=713378&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:39:16.987Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=514501&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:39:17.587Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=212790&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:39:29.907Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=220095&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:39:30.555Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=573135&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:39:41.677Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=842271&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:39:42.269Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=979840&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:39:53.451Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=598114&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:39:54.002Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=429825&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:40:05.147Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=129932&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:40:05.720Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=377093&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:40:16.777Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=589057&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:40:17.422Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=332572&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:40:28.494Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=573674&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:40:29.087Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=126423&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:40:40.207Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=875866&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:40:40.764Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=482156&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:40:47.463Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=331165&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:40:51.932Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=714688&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:40:52.506Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=253399&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:41:03.532Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=358774&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:41:04.158Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=999531&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:41:15.352Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=356379&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:41:15.954Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=234202&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:41:27.269Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=385323&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:41:27.886Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=232235&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:41:38.907Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=310126&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:41:39.479Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=788694&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:41:50.598Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=516710&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:41:51.184Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=776562&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:42:02.437Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=319540&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:42:03.037Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=915775&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:42:14.103Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=752966&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:42:14.666Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=653216&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:42:25.704Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=152111&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:42:26.299Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=990870&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:42:37.372Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=583673&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:42:38.046Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=933835&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:42:49.540Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=547072&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:42:50.132Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=158498&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:01.243Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=927915&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:01.906Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=233382&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:13.175Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=670629&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:13.762Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=249295&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:15.488Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=maseQ&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=377839&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"maseQ\\\",\\\"[[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5sSvd8B977BDkEJiTttL1GNyyHbcqoTKrV-qQDVafR-aA1XD9xGEBapDM_0Bq88_NE7WOdRjCNto6fvEz6Ndk6LRuSx_fyc2Bpgf7YNN00EzmqJCqS_Sci0-PCiki9s8D8xcFA0LH1Cz5X_jlRpVaOIYcbZ3BCBsFxGgBZJuYo0B0QFuzbhwl8vstyW4qjAQfen9-TRAXdQz_mxnwW-v8qOrJUUpgBqktV0jUcmPMC0x71Lgv8YSCVbLIKA0s2WWuPEPc9t4w7pYB3oz158No18L09LdwT5xj2LkVLrlmCId45zO-QVF1JxlpjUabO6O5_VSNzlnHXc2EMC__ig0cYtIc6jJOpkFYpl1OT_F6eZ_YJzuB7Q3qY4aya3yso-7U4mcnBz01qG7B5hOjOgk0XV2E_O6OV6vfQEoEfodZFg-tm9DpQ0vjS8xrFfsR67OaWG_lk-LrBHDPuAuEwQife5EJIUG-4QRvhELIDja6nUZtZJmIbf8-l-u-JB-edWgooTUIOoDEan41sTXp9GZgI0gt6EB-yzJcTSsVc4omHAh_OyzCds_qrOwa5awYBhCcdMpV-PbV49ZoQizBYTcTEzb9S3b_gplfIgkAHdii5jNSBqoAHWYE_h2wSsGBISB5uuan6bnLpaKOJpHRZFx9dv8bXtlF92BO-BuFUv-zSt-I8XEUISv8qUkB6xef5t9ErNh92ZBcHX9adkVSVTB9jq2QWS5VQrtD5wJz30pvOhTcRiQPabJu_8fz7U8gEYMrQm_oEEYr2LqIIskllksoevrzQhMsSxjjp-kiV87a4B8nJJuvWvliaPImcxb0sJDN4F4knDcs_N7RpAEUSXS6UL6-NGs0HyRKpmQ4Ant73haBmGMehmlKANKJLygOpuTkP9jaY9kkH2kgSFVlKHN-oDVd0WhzOMqE2IWpza5uZD_W5f_7VgMN2LdRwUB-1OCO_5NGBjkFRXeK7CPinyJ44Ol0iT4UT_vvnmxUTIzHIQswIE7EV5VLSf38td9DNilDvzyDNnaIM-smxQRxFZ9wMddQIxoVye7WbYGzoW0G2pBXfjG-kOM505K-sei-bPbRTugfqHx6EzuIEkILkPHgi0L97JL6s12leIYXcj4QrfHy8wjG2yud62R-kIKsE_5O06oGuXimbRHgTwJbfbg5Jxbs29RRed6gh6LyDOjgXSO9VcvvmKRvJZ3Wn_l-kj7j1wrBNf2-20n_CIhH6qjmVUxT1tjGR8Eb2sUEnoOiPib8GRiBe67e639bKFSISFoFlitq-Wg9fpxBMM1K0UCA8E21G-e6PdtVFnRAtrfm5Rr1iuw8Np3uWNmO2lGQK9Gs8KGYnUO77oSdLYDU6itNhyZCFgn-gzxocjlLFtEvBgPq1AAR7-l3p4P--EJrY9XsF6hAHimudCxTYtA-MlxYE2x9YeHip_WCeN0HteRt0nphPGVihLpKMu8GzX-IMJyHa2ckxkOZpqMtSlXZEmPtjRZnGmEKeuL4G_khynDY_cHWueR7X-1M8duVOERwPkmo4roXWp21pufR9DhPEbTGis-4d0ZnWxuX_-4Vq_AMOLaX6gF6H8jFqf7OWWaOwC0DlXQIx5uQbwL2dPapG4Nq4jRHyzZFMhb_eIP4lhh09Gw5fMTLQzsBR7PzHVvkjfLmAP6P2q_obz59Bar11PN9cwd2vwIHhH032c-CGGE8S-Y9VLSgzq8rk2e8qJ17n14c2bidUozetXk3peR6BXl3YfsWtc_c_puZnCDWnGk5ekLqd8Re1lBWQLb0p3cZaUDJk7ZrvNtcyZpHjcyZu_nWnSVcvMAkfR2nJ1DhGeOVdeQm3FVY_fbhsqwFqHDbfxTAulrWZ0kf89cvhFndBjC5xl_t0gXCRHirnw8hVrK7HPVMPrF5XREZE4OGYRGrXInuRc5jcOxexMyG-8uMl789GE2P1Fzs8CjFd4-c87YjmW4ZmZCdRKg2kfhOpg1DZ88eu0cNEjvDv8T7I72cxRLqPlnTc8qRKBzkElscAazsBe0ngZ4g0mjt4SVk_TyvSn1wYNbVzlA-L_zHvE_shJiN5JqHHKMPiZKULCBF7D-DHP0ss7-HZDvxe27-tyi6IuWAPIYOFnerY-JDYL-tHvHHKj4nb2jNhbbEM_0OAWmaoAgEVylGokC8S3fu-C8mofWQXCHAJGQ6zmaV8zOrfrMMjHEBUEeUdNrsI6omcdBfQ9JR2fCMs3y7P5_JwpFvE5fDOoL_1L89P-pPj1jmgYPqTy7lMDfSvy7MAkdWDcvqVaiMuwIeciva2-JsJIXfLIQy8nxS1yAMinOwp_qlwos46mZf7Kopkx6gIQ5O9EzPODcd8beyQNiZsJG_QJx8eQtfJPDvOOSPb07vbESA6dW9899sCuDqfJ6dWkuEk-OkBbY9aA9vuMe_S3CNnT9ot1isAlnYrabTVk5A0lKMKP3oYb-8-OUfWPU72eFryQCDDtEEVetE\\\\\\\",1]],\\\\\\\"/9j/4AAQSkZJRgABAQAAAQABAAD/7QBQUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAABgcAm4AE01hZGUgd2l0aCBHb29nbGUgQUk4QklNBCUAAAAAABDIs4lltEU3qRin51mYyOP2/+EDAWh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNy4wLWMwMDAiPgo8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIgeG1sbnM6eG1sPSJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiIHhtbG5zOklwdGM0eG1wRXh0PSJodHRwOi8vaXB0Yy5vcmcvc3RkL0lwdGM0eG1wRXh0LzIwMDgtMDItMjkvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIElwdGM0eG1wRXh0OkRpZ2l0YWxTb3VyY2VGaWxlVHlwZT0iaHR0cDovL2N2LmlwdGMub3JnL25ld3Njb2Rlcy9kaWdpdGFsc291cmNldHlwZS90cmFpbmVkQWxnb3JpdGhtaWNNZWRpYSIgSXB0YzR4bXBFeHQ6RGlnaXRhbFNvdXJjZVR5cGU9Imh0dHA6Ly9jdi5pcHRjLm9yZy9uZXdzY29kZXMvZGlnaXRhbHNvdXJjZXR5cGUvdHJhaW5lZEFsZ29yaXRobWljTWVkaWEiIHBob3Rvc2hvcDpDcmVkaXQ9Ik1hZGUgd2l0aCBHb29nbGUgQUkiLz4KPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4K/+sZ90pQAAEAAAABAAAZ7Wp1bWIAAAAeanVt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L2MycGEuYWN0aW9ucy52MmRoYXNoWCB5q0Xq9rF01iglhf65S6khCMK+kydWOnLL1OvmXsVMqqJjdXJseClzZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmhhc2guZGF0YWRoYXNoWCAPSDdU4ZjgSfyxw66Idj7Rtq7EMYqf+6moerr73uH0gmlzaWduYXR1cmV4GXNlbGYjanVtYmY9YzJwYS5zaWduYXR1cmVjYWxnZnNoYTI1NgAABAhqdW1iAAAAKWp1bWRjMmFzABEAEIAAAKoAOJtxA2MycGEuYXNzZXJ0aW9ucwAAAACcanVtYgAAAChqdW1kY2JvcgARABCAAACqADibcQNjMnBhLmhhc2guZGF0YQAAAABsY2JvcqRqZXhjbHVzaW9uc4GiZXN0YXJ0GQNpZmxlbmd0aBkZ+WNhbGdmc2hhMjU2ZGhhc2hYIId95Tk+Ud8rnWXsew1hnNIjvKmUVOhx9o9/rY0j6vGHY3BhZEwAAAAAAAAAAAAAAAAAAAJWanVtYgAAAClqdW1kY2JvcgARABCAAACqADibcQNjMnBhLmFjdGlvbnMudjIAAAACJWNib3KhZ2FjdGlvbnOCpGZhY3Rpb25sYzJwYS5jcmVhdGVka2Rlc2NyaXB0aW9ueCBDcmVhdGVkIGJ5IEdvb2dsZSBHZW5lcmF0aXZlIEFJLnFkaWdpdGFsU291cmNlVHlwZXhGaHR0cDovL2N2LmlwdGMub3JnL25ld3Njb2Rlcy9kaWdpdGFsc291cmNldHlwZS90cmFpbmVkQWxnb3JpdGhtaWNNZWRpYWpwYXJhbWV0ZXJzoWtpbmdyZWRpZW50c4KiY3VybHgtc2VsZiNqdW1iZj1jMnBhLmFzc2VydGlvbnMvYzJwYS5pbmdyZWRpZW50LnYzZGhhc2hYIEPPQQUmfu68wdIEHLdRNcwvAGFseCftiCe5+857WDmWomN1cmx4MHNlbGYjanVtYmY9YzJwYS5hc3NlcnRpb25zL2MycGEuaW5ncmVkaWVudC52M19fMWRoYXNoWCAVclPWZvmGvl1yJJJFIKVjMTldBPijflMgnfw2JSGnp6NmYWN0aW9ua2MycGEuZWRpdGVka2Rlc2NyaXB0aW9ueChBcHBsaWVkIGltcGVyY2VwdGlibGUgU3ludGhJRCB3YXRlcm1h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\\\\\\\",\\\\\\\"image/jpeg\\\\\\\",1,null,null,null,null,\\\\\\\"image.jpg\\\\\\\",null,\\\\\\\"DDE5D2A5-FE61-45F0-8DEB-644FD661D8FE\\\\\\\",\\\\\\\"32984960-0203-4A83-A40A-38AA1CB72B49\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:30.002Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=516290&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:34.708Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=457940&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:35.371Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=836706&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:46.411Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=712321&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:47.045Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=679753&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:46.993Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=270832&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:58.096Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=348558&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:43:58.651Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=850002&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:44:09.691Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=941613&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:44:10.325Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=763002&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:44:21.404Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=249676&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:44:21.924Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=226901&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:44:33.059Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=351509&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:44:33.716Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=731350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:44:44.837Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=761095&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:44:45.421Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=649427&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:44:56.580Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=234206&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:44:57.218Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=505695&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:44:58.925Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=693767&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:45:08.375Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=216527&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:45:08.960Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=864349&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:45:20.042Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=598093&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:45:20.593Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=459315&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:45:44.892Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=326329&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:45:55.470Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=160041&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:46:06.184Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=538126&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:46:16.785Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=425860&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:46:27.392Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=882427&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:46:37.972Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=896469&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:46:48.558Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=654551&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:46:59.105Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=437717&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:47:09.662Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=820538&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:47:20.258Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=224749&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:47:30.891Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=997797&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:47:41.499Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=447250&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:47:52.175Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=613362&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:48:02.794Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=130278&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:48:13.370Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=954209&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:48:24.046Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=128013&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:48:34.673Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=419970&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:48:45.209Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=678757&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:48:55.800Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=922184&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:49:06.369Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=949639&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:49:26.737Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=664766&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:49:37.403Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=170642&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:49:47.947Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=716638&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:49:59.396Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=491729&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:50:09.951Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=838757&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:50:20.534Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=868651&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:50:31.102Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=136891&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:50:41.704Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=755022&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:50:52.273Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=364569&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:51:02.831Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=643020&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:51:13.402Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=262067&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:51:23.981Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=302529&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:51:34.540Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=176657&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:51:45.141Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=198295&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:51:55.784Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=387145&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:52:06.364Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=729924&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:52:16.960Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=789506&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:52:27.561Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=272150&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:52:38.115Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=796219&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:52:48.727Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=287705&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:52:59.272Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=451205&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:53:09.891Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=546454&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:53:20.734Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=651180&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:53:31.365Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=455957&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:53:41.988Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=722873&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:53:52.602Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=572083&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:54:03.210Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=796153&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:54:13.775Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=534261&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:54:24.368Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=595405&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:54:34.934Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=987190&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:54:45.501Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=183779&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:54:56.107Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=220694&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:55:06.711Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=152543&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:55:17.278Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=326182&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:55:27.881Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=817338&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:55:38.445Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=621124&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:55:49.045Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=461769&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:55:59.639Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=513854&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:56:10.277Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=546890&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:56:20.892Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=386300&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:56:31.569Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=119744&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:56:42.098Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=661519&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:56:52.662Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=827093&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:57:03.253Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=733686&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:57:13.808Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=902402&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:57:24.390Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=583328&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:57:34.981Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=592196&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:57:45.570Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=962876&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:57:56.224Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=330832&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:58:06.828Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=749968&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:58:17.450Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=256317&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:58:28.051Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=133287&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:58:38.594Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=190807&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:58:49.208Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=549301&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:58:59.787Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=876609&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:59:10.396Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=424315&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:59:20.988Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=891089&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:59:31.632Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=172988&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:59:42.174Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=566179&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T14:59:52.741Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=502020&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:00:03.320Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=568950&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:00:17.227Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=108961&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:00:30.621Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=697403&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:00:41.291Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=906598&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:00:56.513Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=930311&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:01:07.132Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=659070&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:01:17.723Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=489037&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:01:28.348Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=788214&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:01:38.911Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=201581&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:01:49.542Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=567273&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:02:00.179Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=704154&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:02:10.776Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=807511&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:02:21.418Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=584917&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:02:32.114Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=497819&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:02:42.684Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=860563&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:02:53.329Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=891712&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:03:03.932Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=577369&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:03:14.519Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=666831&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:03:25.158Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=309121&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:03:35.767Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=343200&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:03:46.364Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=453303&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:03:56.924Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=644318&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} +{"ts": "2026-09-23T15:04:07.617Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=395220&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} diff --git a/scratch/check_chars.py b/scratch/check_chars.py new file mode 100644 index 000000000..d917789a3 --- /dev/null +++ b/scratch/check_chars.py @@ -0,0 +1,7 @@ +import sqlite3 + +conn = sqlite3.connect('flow_agent.db') +chars = conn.execute('SELECT id, name, entity_type, media_id FROM character').fetchall() +print(f"Total characters: {len(chars)}") +for ch in chars: + print(f"ID: {ch[0]} | Name: {ch[1]} | Type: {ch[2]} | media_id: {ch[3]}") diff --git a/scratch/check_db.py b/scratch/check_db.py new file mode 100644 index 000000000..2df54e0cd --- /dev/null +++ b/scratch/check_db.py @@ -0,0 +1,18 @@ +import sqlite3 + +con = sqlite3.connect('flow_agent.db') +print("--- SCENES ---") +for row in con.execute("SELECT id, display_order, prompt, video_prompt, narrator_text, horizontal_image_media_id, horizontal_video_media_id, horizontal_image_url, horizontal_video_url FROM scene ORDER BY display_order").fetchall(): + print(f"Scene #{row[1]}: id={row[0]}") + print(f" prompt={row[2]}") + print(f" video_prompt={row[3]}") + print(f" narrator_text={row[4]}") + print(f" image_mid={row[5]}") + print(f" video_mid={row[6]}") + print(f" image_url={row[7]}") + print(f" video_url={row[8]}") + print() + +print("--- CHARACTERS / ENTITIES ---") +for row in con.execute("SELECT id, name, media_id, image_url FROM character").fetchall(): + print(f"Character: {row[1]} (id={row[0]}) mid={row[2]} url={row[3]}") diff --git a/scratch/check_hijack.py b/scratch/check_hijack.py new file mode 100644 index 000000000..9a0d445ec --- /dev/null +++ b/scratch/check_hijack.py @@ -0,0 +1,4 @@ +import requests + +resp = requests.get("http://127.0.0.1:8100/api/ext/find-actions") +print(resp.json()) diff --git a/scratch/check_netlog.py b/scratch/check_netlog.py new file mode 100644 index 000000000..4003814b9 --- /dev/null +++ b/scratch/check_netlog.py @@ -0,0 +1,8 @@ +import json + +with open('scratch/captured_netlog.jsonl', encoding='utf-8') as f: + for i, line in enumerate(f): + d = json.loads(line) + url = d.get('url', '') + if any(k in url for k in ['Video', 'video', 'eb1hJf', 'StreamChat']): + print(f"Line {i+1}: {url[:100]} status={d.get('statusCode')}") diff --git a/scratch/check_new_media.py b/scratch/check_new_media.py new file mode 100644 index 000000000..5d78c2837 --- /dev/null +++ b/scratch/check_new_media.py @@ -0,0 +1,18 @@ +import sys +sys.path.insert(0, '.') +import asyncio +from agent.services.flow_client import get_flow_client +from agent.services import flow_batch as fb + +async def main(): + client = get_flow_client() + mid = "666bc47c-1fa1-4167-83cc-3088840b3146" + freq = fb.media_request(mid) + res = await client.batch_rpc(fb.RPC_MEDIA, freq) + print("as29s status:", res.get("status")) + print("as29s data:", res.get("data")[:300] if res.get("data") else None) + urls = fb.read_media_urls(res.get("data", "")) if res.get("data") else None + print("urls:", urls) + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/scratch/check_recent_assets.py b/scratch/check_recent_assets.py new file mode 100644 index 000000000..393162a46 --- /dev/null +++ b/scratch/check_recent_assets.py @@ -0,0 +1,32 @@ +import sys +sys.path.insert(0, ".") +import urllib.request +import json +import re + +with urllib.request.urlopen("http://127.0.0.1:8100/api/ext/test-project-media") as resp: + data = json.loads(resp.read().decode("utf-8")) + +with open("scratch/project_media_dump.txt", "r", encoding="utf-8") as f: + text = f.read() + +from agent.services import flow_batch as fb +payload = fb.first_payload(text, fb.RPC_PROJECT_MEDIA) +items = payload[1] if len(payload) > 1 and isinstance(payload[1], list) else [] + +print(f"Total items in payload[1]: {len(items)}") + +# Print all items created in the last 15 minutes (since 21:30) +# Epoch ~ 1790173800 +for it in items: + try: + details = it[3] + ts = details[1][0] + title = details[0] + is_video = bool(details[2]) + media_id = details[4] + op_id = details[5] if len(details) > 5 else None + if ts > 1790173500: # recent + print(f"RECENT: TS={ts} | Video={is_video} | Title='{title}' | MediaID={media_id} | OpID={op_id}") + except Exception as e: + pass diff --git a/scratch/check_requests.py b/scratch/check_requests.py new file mode 100644 index 000000000..1eab5d464 --- /dev/null +++ b/scratch/check_requests.py @@ -0,0 +1,8 @@ +import sqlite3 + +con = sqlite3.connect('flow_agent.db') +cur = con.cursor() +rows = cur.execute("SELECT id, type, scene_id, status, error, created_at, updated_at FROM request ORDER BY created_at DESC LIMIT 15").fetchall() +print(f"Total requests: {len(rows)}") +for r in rows: + print(r) diff --git a/scratch/compare_stream_chat.py b/scratch/compare_stream_chat.py new file mode 100644 index 000000000..ae892db35 --- /dev/null +++ b/scratch/compare_stream_chat.py @@ -0,0 +1,30 @@ +import json +import sys +sys.path.insert(0, ".") +from agent.services import flow_batch as fb + +with open("scratch/captured_netlog.jsonl", "r", encoding="utf-8") as f: + lines = [l for l in f if l.strip()] + +entry31 = json.loads(lines[31]) +b31 = json.loads(entry31["body"]) +outer = json.loads(b31["f.req"][0]) +req31 = json.loads(outer[1]) + +print("Entry 31 payload structure:") +print("Type:", type(req31), "Len:", len(req31)) +print("Item 0:", req31[0]) +print("Item 1:", req31[1]) +print("Item 2:", req31[2]) + +# Now generate from flow_batch +our_freq = fb.stream_chat_request("tạo 1 ảnh nhân vật", "594758cc-11f5-4f92-8b3c-1213686591f4") +print("\nOur freq:") +print(our_freq[:300]) + +# Compare our parsed freq with req31 +our_parsed = json.loads(our_freq) +print("\nOur parsed structure:") +print("Item 0:", our_parsed[0]) +print("Item 1:", our_parsed[1]) +print("Item 2 (minus token):", [our_parsed[2][0], our_parsed[2][1], "..."]) diff --git a/scratch/inspect_28_31.py b/scratch/inspect_28_31.py new file mode 100644 index 000000000..b91e8b348 --- /dev/null +++ b/scratch/inspect_28_31.py @@ -0,0 +1,14 @@ +import json + +with open("scratch/captured_netlog.jsonl", "r", encoding="utf-8") as f: + lines = [l for l in f if l.strip()] + +entry28 = json.loads(lines[28]) +print("Entry 28 URL:", entry28.get("url")) +print("Entry 28 Body:") +print(entry28.get("body")) + +entry31 = json.loads(lines[31]) +print("\nEntry 31 URL:", entry31.get("url")) +print("Entry 31 Body:") +print(entry31.get("body")) diff --git a/scratch/inspect_as29s.py b/scratch/inspect_as29s.py new file mode 100644 index 000000000..b1e51ab9f --- /dev/null +++ b/scratch/inspect_as29s.py @@ -0,0 +1,13 @@ +import json +import urllib.request + +req = urllib.request.Request( + 'http://127.0.0.1:8100/api/ext/media-url?media_id=666bc47c-1fa1-4167-83cc-3088840b3146' +) +# Wait, let's call the ext directly or fetch from main +res = urllib.request.urlopen('http://127.0.0.1:8100/api/ext/netlog') +data = json.loads(res.read().decode()) +for c in data.get('captures', []): + if 'as29s' in c.get('url', ''): + print("as29s capture:", c['url']) + print("f.req:", c.get('body')) diff --git a/scratch/inspect_assets.py b/scratch/inspect_assets.py new file mode 100644 index 000000000..901717580 --- /dev/null +++ b/scratch/inspect_assets.py @@ -0,0 +1,14 @@ +import sys +sys.path.insert(0, '.') +import json +from agent.services import flow_batch as fb + +s = open('scratch/project_media_dump.txt', encoding='utf-8').read() +results = fb.parse_envelope(s) +data = results[0].data +assets = data[1] +print(f"Total assets: {len(assets)}") +for i, a in enumerate(assets[:10]): + aid = a[0] if len(a) > 0 else None + prompt_info = a[3] if len(a) > 3 else None + print(f"Asset #{i}: id={aid} prompt={prompt_info[0] if isinstance(prompt_info, list) else prompt_info}") diff --git a/scratch/inspect_c31.py b/scratch/inspect_c31.py new file mode 100644 index 000000000..ebfc04abb --- /dev/null +++ b/scratch/inspect_c31.py @@ -0,0 +1,22 @@ +import json + +lines = open('scratch/captured_netlog.jsonl', encoding='utf-8').read().splitlines() +c31 = json.loads(lines[31]) +print("URL:", c31['url']) +print("StatusCode:", c31['statusCode']) +body_dict = json.loads(c31['body']) +print("Keys:", list(body_dict.keys())) +freq_list = body_dict.get('f.req', []) +print("f.req len:", len(freq_list)) +inner_str = freq_list[0] +print("f.req[0]:", inner_str[:300]) +# parse json if possible +try: + parsed = json.loads(inner_str) + print("parsed type:", type(parsed), len(parsed)) + print("parsed[0]:", parsed[0]) + print("parsed[1] type:", type(parsed[1])) + inner_payload = json.loads(parsed[1]) + print("inner_payload:", json.dumps(inner_payload, indent=2)[:1000]) +except Exception as e: + print("Error parsing:", e) diff --git a/scratch/inspect_dump.py b/scratch/inspect_dump.py new file mode 100644 index 000000000..2c1ae0333 --- /dev/null +++ b/scratch/inspect_dump.py @@ -0,0 +1,36 @@ +import sys +sys.path.insert(0, ".") +import json +from agent.services import flow_batch as fb + +with open('scratch/project_media_dump.txt', 'r', encoding='utf-8') as f: + text = f.read() + +payload = fb.first_payload(text, fb.RPC_PROJECT_MEDIA) +items = payload[1] if len(payload) > 1 and isinstance(payload[1], list) else [] + +parsed = [] +for it in items: + try: + asset_id = it[0] + details = it[3] if len(it) > 3 else None + title = details[0] if details else None + ts = details[1][0] if details and details[1] else 0 + media_id = details[4] if details and len(details) > 4 else None + is_video = bool(details[2]) if details and len(details) > 2 else False + parsed.append({ + "asset_id": asset_id, + "title": title, + "ts": ts, + "media_id": media_id, + "is_video": is_video, + "raw": it + }) + except Exception as e: + pass + +parsed.sort(key=lambda x: x["ts"], reverse=True) + +print(f"Total parsed items: {len(parsed)}") +for i, p in enumerate(parsed): + print(f"[{i}] TS: {p['ts']} | Type: {'VIDEO' if p['is_video'] else 'IMAGE'} | MediaID: {p['media_id']} | Title: {p['title']}") diff --git a/scratch/inspect_items.py b/scratch/inspect_items.py new file mode 100644 index 000000000..035bfcfec --- /dev/null +++ b/scratch/inspect_items.py @@ -0,0 +1,16 @@ +import sys +sys.path.insert(0, '.') +import json +from agent.services import flow_batch as fb + +s = open('scratch/project_media_dump.txt', encoding='utf-8').read() +results = fb.parse_envelope(s) +data = results[0].data +media_list = data[0] +print(f"Total media items in project: {len(media_list)}") +for item in media_list[:10]: + # inspect item structure + mid = item[0] if len(item) > 0 else None + meta = item[1] if len(item) > 1 else None + extra = item[2] if len(item) > 2 else None + print(f"Item: mid={mid} type={type(meta)} extra={extra}") diff --git a/scratch/inspect_new_asset.py b/scratch/inspect_new_asset.py new file mode 100644 index 000000000..47581570b --- /dev/null +++ b/scratch/inspect_new_asset.py @@ -0,0 +1,18 @@ +import sys +sys.path.insert(0, '.') +from agent.services import flow_batch as fb + +s = open('scratch/project_media_dump.txt', encoding='utf-8').read() +results = fb.parse_envelope(s) +data = results[0].data +assets = data[1] +print(f"Total assets in project: {len(assets)}") +for i, a in enumerate(assets): + # check prompt or timestamp + aid = a[0] if len(a) > 0 else None + meta = a[1] if len(a) > 1 else None + prompt_info = a[3] if len(a) > 3 else None + media_info = a[2] if len(a) > 2 else None + print(f"Asset #{i}: id={aid}") + print(f" prompt={prompt_info}") + print(f" media_info={str(media_info)[:160]}") diff --git a/scratch/inspect_video.py b/scratch/inspect_video.py new file mode 100644 index 000000000..249618baa --- /dev/null +++ b/scratch/inspect_video.py @@ -0,0 +1,18 @@ +import sqlite3 + +conn = sqlite3.connect('flow_agent.db') +c = conn.cursor() +vid = '945ad6d4-5d79-4790-80db-1bff16ed7255' +scenes = c.execute( + 'SELECT id, display_order, horizontal_image_media_id, horizontal_video_media_id, prompt, video_prompt, narrator_text ' + 'FROM scene WHERE video_id = ? ORDER BY display_order', (vid,) +).fetchall() + +print(f"Total scenes: {len(scenes)}") +for s in scenes: + print(f"#{s[1]}: id={s[0]}") + print(f" img={s[2]}") + print(f" vid={s[3]}") + print(f" prompt={s[4][:70]}...") + print(f" vid_prompt={s[5][:70] if s[5] else None}...") + print(f" narrator={s[6]}") diff --git a/scratch/inspect_video_op.py b/scratch/inspect_video_op.py new file mode 100644 index 000000000..ee7d602b0 --- /dev/null +++ b/scratch/inspect_video_op.py @@ -0,0 +1,16 @@ +import sys +sys.path.insert(0, ".") +import asyncio +import json +from agent.services.flow_client import get_flow_client + +async def main(): + client = get_flow_client() + op_id = "ec675e90-a9e3-4c4a-b64f-77672c87d1d0" + print(f"Checking status for op {op_id}...") + ops = [{"operation": {"name": op_id}}] + res = await client.check_video_status(ops) + print("Status result:") + print(json.dumps(res, indent=2)) + +asyncio.run(main()) diff --git a/scratch/inspect_zzl.py b/scratch/inspect_zzl.py new file mode 100644 index 000000000..8486281c6 --- /dev/null +++ b/scratch/inspect_zzl.py @@ -0,0 +1,10 @@ +import urllib.request +import json +import re + +req = urllib.request.urlopen("http://127.0.0.1:8100/api/ext/netlog") +data = json.loads(req.read().decode()) +for c in data.get("captures", []): + if "Zzl0ze" in c.get("url", ""): + print("Found Zzl0ze capture:") + print(c["url"]) diff --git a/scratch/list_captures.py b/scratch/list_captures.py new file mode 100644 index 000000000..a50ac196b --- /dev/null +++ b/scratch/list_captures.py @@ -0,0 +1,16 @@ +import json + +lines = open('scratch/captured_netlog.jsonl', encoding='utf-8').read().splitlines() +print(f"Total lines captured: {len(lines)}") +for i, line in enumerate(lines): + if not line.strip(): continue + d = json.loads(line) + ts = d.get('ts') + url = d.get('url') + # extract rpcids from url + rpcids = "unknown" + if "rpcids=" in url: + rpcids = url.split("rpcids=")[1].split("&")[0] + status = d.get('statusCode') + body_len = len(d.get('body') or '') + print(f"#{i} [{ts}] rpcid={rpcids} status={status} body_len={body_len}") diff --git a/scratch/orig_background.js b/scratch/orig_background.js new file mode 100644 index 000000000..56e2ed47c --- /dev/null +++ b/scratch/orig_background.js @@ -0,0 +1,1010 @@ +/** + * Flow Kit — Chrome Extension Background Service Worker + * + * Connects to local Python agent via WebSocket (agent runs WS server). + * Mints reCAPTCHA and runs Flow's batchexecute RPCs inside the Flow tab. + * + * Flow moved to flow.google.com in September 2026 and stopped minting the + * `Bearer ya29.…` the old REST host needed. The current path is `batch_rpc`: + * the agent builds an `f.req` envelope, this worker mints a captcha for it and + * runs the POST in the page's MAIN world, where the `at` CSRF token lives. + * The bearer capture and the `api_request` / `trpc_request` proxies below are + * the pre-migration path. The agent no longer sends either — it speaks only + * `batch_rpc`. They stay so an extension updated ahead of its agent keeps + * serving an older one; remove them once no agent in the wild sends them. + */ + +const AGENT_WS_URL = 'ws://127.0.0.1:9222'; +// NOTE: This is a browser-restricted public API key — safe to ship in extension bundles. +const API_KEY = 'AIzaSyBtrm0o5ab1c-Ec8ZuLcGt3oJAA5VWt3pY'; + +// labs.google/fx/tools/flow still resolves but redirects here, so in practice a +// signed-in tab is only ever flow.google.com/*. The legacy patterns stay for an +// old pinned tab. Every tab lookup in this file goes through this list. +const flowUrls = [ + 'https://flow.google.com/*', + 'https://labs.google/fx/tools/flow*', + 'https://labs.google/fx/*/tools/flow*', +]; +const FLOW_TAB_URL = 'https://flow.google.com/'; + +let ws = null; +let flowKey = null; +let callbackSecret = null; // Auth secret for HTTP callback, received from server on WS connect +let state = 'off'; // off | idle | running +let manualDisconnect = false; +let metrics = { + tokenCapturedAt: null, + requestCount: 0, // captcha-consuming requests only (gen image/video/upscale) + successCount: 0, + failedCount: 0, + lastError: null, +}; + +// ─── URL → Log Type Classifier ───────────────────────────── + +// Visible log types — only these appear in the request log +const _VISIBLE_TYPES = new Set(['GEN_IMG', 'GEN_VID', 'GEN_VID_REF', 'UPSCALE', 'TRACKING', 'URL_REFRESH']); + +function _classifyApiUrl(url) { + if (url.includes('uploadImage')) return 'UPLOAD'; + if (url.includes('batchGenerateImages')) return 'GEN_IMG'; + if (url.includes('UpsampleVideo')) return 'UPSCALE'; + if (url.includes('ReferenceImages')) return 'GEN_VID_REF'; + if (url.includes('batchAsyncGenerateVideo')) return 'GEN_VID'; + if (url.includes('batchCheckAsync')) return 'POLL'; + if (url.includes('upsampleImage')) return 'UPS_IMG'; + if (url.includes('/media/')) return 'MEDIA'; + if (url.includes('/credits')) return 'CREDITS'; + return 'API'; +} + +// ─── Request Log ──────────────────────────────────────────── + +let requestLog = []; + +function addRequestLog(entry) { + requestLog.unshift(entry); + if (requestLog.length > 100) requestLog.pop(); + broadcastRequestLog(); +} + +function updateRequestLog(id, updates) { + const entry = requestLog.find((e) => e.id === id); + if (entry) Object.assign(entry, updates); + broadcastRequestLog(); +} + +function broadcastRequestLog() { + chrome.runtime.sendMessage({ type: 'REQUEST_LOG_UPDATE', log: requestLog }).catch(() => {}); +} + +// ─── Startup ──────────────────────────────────────────────── + +let initializationPromise = null; + +chrome.runtime.onInstalled.addListener(() => { + void ensureInitialized(); +}); +chrome.runtime.onStartup.addListener(() => { + void ensureInitialized(); +}); +chrome.alarms.onAlarm.addListener(async (alarm) => { + await ensureInitialized(); + if (alarm.name === 'reconnect') connectToAgent(); + if (alarm.name === 'keepAlive') keepAlive(); + if (alarm.name === 'token-refresh') { + // Passive maintenance must never create browser tabs. If the user has no + // Flow tab open, wait for an explicit action or an actual RPC to open one. + await captureTokenFromFlowTab({ createIfMissing: false }); + } +}); + +function ensureInitialized() { + if (!initializationPromise) { + initializationPromise = initialize().catch((error) => { + initializationPromise = null; + console.error('[FlowAgent] Initialization failed', error); + throw error; + }); + } + return initializationPromise; +} + +async function initialize() { + const data = await chrome.storage.local.get(['flowKey', 'metrics', 'callbackSecret']); + if (data.flowKey) flowKey = data.flowKey; + if (data.metrics) Object.assign(metrics, data.metrics); + if (data.callbackSecret) callbackSecret = data.callbackSecret; + connectToAgent(); + chrome.alarms.create('keepAlive', { periodInMinutes: 0.4 }); +} + +// MV3 workers can be suspended and restarted without onStartup firing. +// Rehydrate the persisted Flow key on every worker start. +void ensureInitialized(); + +// ─── Token Capture ────────────────────────────────────────── + +chrome.webRequest.onBeforeSendHeaders.addListener( + (details) => { + if (!details?.requestHeaders?.length) return; + const authHeader = details.requestHeaders.find( + (h) => h.name?.toLowerCase() === 'authorization', + ); + const value = authHeader?.value || ''; + if (!value.startsWith('Bearer ya29.')) return; + + const token = value.replace(/^Bearer\s+/i, '').trim(); + if (!token) return; + + // Always update — even if same token string, refresh the timestamp + flowKey = token; + metrics.tokenCapturedAt = Date.now(); + chrome.storage.local.set({ flowKey, metrics }); + console.log('[FlowAgent] Bearer token captured'); + + // Notify agent + if (ws?.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ type: 'token_captured', flowKey })); + } + }, + { urls: ['https://aisandbox-pa.googleapis.com/*', 'https://labs.google/*'] }, + ['requestHeaders', 'extraHeaders'], +); + +let _openingFlowTab = false; + +async function captureTokenFromFlowTab({ createIfMissing = false } = {}) { + let tabs = await chrome.tabs.query({ url: flowUrls }); + if (!tabs.length) { + if (!createIfMissing) { + console.log('[FlowAgent] No Flow tab found — passive refresh skipped'); + return { skipped: 'NO_FLOW_TAB' }; + } + if (_openingFlowTab) { + console.log('[FlowAgent] Flow tab already opening, skipping'); + return; + } + _openingFlowTab = true; + try { + console.log('[FlowAgent] No Flow tab found — opening one for explicit refresh'); + const opened = await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); + await sleep(3000); + const target = opened?.id ? await chrome.tabs.get(opened.id).catch(() => null) : null; + if (!target) { + console.log('[FlowAgent] Flow tab not ready yet after open'); + return; + } + await chrome.scripting.executeScript({ + target: { tabId: target.id }, + files: ['content.js'], + }); + console.log('[FlowAgent] Token refresh triggered on newly opened Flow tab'); + } catch (e) { + console.error('[FlowAgent] Token refresh failed after opening tab:', e); + } finally { + _openingFlowTab = false; + } + return; + } + try { + await chrome.scripting.executeScript({ + target: { tabId: tabs[0].id }, + files: ['content.js'], + }); + console.log('[FlowAgent] Token refresh triggered on Flow tab'); + } catch (e) { + console.error('[FlowAgent] Token refresh failed:', e); + } +} + +// ─── WebSocket to Agent ───────────────────────────────────── + +function connectToAgent() { + if (manualDisconnect) return; + if (ws?.readyState === WebSocket.CONNECTING) return; + if (ws?.readyState === WebSocket.OPEN) return; + + try { + ws = new WebSocket(AGENT_WS_URL); + } catch (e) { + console.error('[FlowAgent] WS connect error:', e); + scheduleReconnect(); + return; + } + + ws.onopen = () => { + console.log('[FlowAgent] Connected to agent'); + chrome.alarms.clear('reconnect'); + setState('idle'); + + // Token refresh alarm — 45 min gives buffer before ~60 min expiry + chrome.alarms.create('token-refresh', { periodInMinutes: 45 }); + + // Send current state + resend token if we have one + ws.send(JSON.stringify({ + type: 'extension_ready', + flowKeyPresent: !!flowKey, + extensionVersion: chrome.runtime.getManifest().version, + flowUrlSupported: chrome.runtime.getManifest().host_permissions?.includes('https://flow.google.com/*') === true, + tokenAge: flowKey && metrics.tokenCapturedAt ? Date.now() - metrics.tokenCapturedAt : null, + })); + if (flowKey) { + ws.send(JSON.stringify({ type: 'token_captured', flowKey })); + } + }; + + ws.onmessage = async ({ data }) => { + try { + const msg = JSON.parse(data); + + if (msg.method === 'batch_rpc') { + await handleBatchRpc(msg); + } else if (msg.method === 'api_request') { + await handleApiRequest(msg); + } else if (msg.method === 'trpc_request') { + await handleTrpcRequest(msg); + } else if (msg.method === 'solve_captcha') { + await handleSolveCaptcha(msg); + } else if (msg.method === 'get_status') { + sendToAgent({ + id: msg.id, + result: { + state, + flowKeyPresent: !!flowKey, + manualDisconnect, + tokenAge: metrics.tokenCapturedAt ? Date.now() - metrics.tokenCapturedAt : null, + metrics, + }, + }); + } else if (msg.type === 'callback_secret') { + callbackSecret = msg.secret; + chrome.storage.local.set({ callbackSecret: msg.secret }); + console.log('[FlowAgent] Received callback secret'); + } else if (msg.type === 'pong') { + // keepalive response + } + } catch (e) { + console.error('[FlowAgent] Message error:', e); + } + }; + + ws.onclose = () => { + setState('off'); + chrome.alarms.clear('token-refresh'); + if (!manualDisconnect) scheduleReconnect(); + }; + + ws.onerror = (e) => { + console.error('[FlowAgent] WS error:', e); + metrics.lastError = 'WS_ERROR'; + chrome.storage.local.set({ metrics }); + }; +} + +function scheduleReconnect() { + chrome.alarms.create('reconnect', { delayInMinutes: 0.083 }); // ~5s +} + +function keepAlive() { + if (ws?.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ type: 'ping' })); + } else { + connectToAgent(); + } +} + +function sendToAgent(msg) { + // API responses (with msg.id) go via HTTP — immune to WS disconnect + if (msg.id) { + const headers = { 'Content-Type': 'application/json' }; + if (callbackSecret) { + headers['X-Callback-Secret'] = callbackSecret; + } + fetch('http://127.0.0.1:8100/api/ext/callback', { + method: 'POST', + headers, + body: JSON.stringify(msg), + }).catch(() => { + // HTTP failed — fallback to WS + if (ws?.readyState === WebSocket.OPEN) ws.send(JSON.stringify(msg)); + }); + return; + } + // Non-response messages (ping, status) or no secret yet — use WS + if (ws?.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify(msg)); + } +} + +// ─── reCAPTCHA Solving ────────────────────────────────────── + +async function requestCaptchaFromTab(tabId, requestId, pageAction) { + try { + return await chrome.tabs.sendMessage(tabId, { + type: 'GET_CAPTCHA', + requestId, + pageAction, + }); + } catch (error) { + const msg = error?.message || ''; + const shouldInject = + msg.includes('Receiving end does not exist') || + msg.includes('Could not establish connection'); + if (!shouldInject) throw error; + + // Inject content script and retry + await chrome.scripting.executeScript({ + target: { tabId }, + files: ['content.js'], + }); + await sleep(200); + return await chrome.tabs.sendMessage(tabId, { + type: 'GET_CAPTCHA', + requestId, + pageAction, + }); + } +} + +/** Try to wake a discarded Flow tab so `sendMessage` can reach it. + * Chrome auto-discards backgrounded tabs to save memory; the tab still shows + * up in `chrome.tabs.query` but cross-context calls fail with "No current + * window" / "No tab with id". A reload re-hydrates it. */ +async function reviveTabIfNeeded(tab) { + if (!tab?.discarded) return tab; + try { + await chrome.tabs.reload(tab.id); + await sleep(2500); + return await chrome.tabs.get(tab.id); + } catch { + return null; + } +} + +function captchaFromTab(tabId, requestId, captchaAction) { + return Promise.race([ + requestCaptchaFromTab(tabId, requestId, captchaAction), + new Promise((_, rej) => setTimeout(() => rej(new Error('CAPTCHA_TIMEOUT')), 30000)), + ]); +} + +async function solveCaptcha(requestId, captchaAction) { + let tabs = await chrome.tabs.query({ url: flowUrls }); + + // No Flow tab at all — spawn one and let it settle. Keep the exact tab id: + // a redirected or stale tab must not make us select some older candidate. + if (!tabs.length) { + let opened; + try { + opened = await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); + await sleep(3000); + } catch (e) { + return { error: e.message || 'NO_FLOW_TAB' }; + } + const target = opened?.id ? await chrome.tabs.get(opened.id).catch(() => null) : null; + if (!target) return { error: 'NO_FLOW_TAB' }; + tabs = [target]; + } + + // Try each Flow tab in turn. A tab that answers "no grecaptcha" is a tab + // sitting on a page that never loaded it — another Flow tab may well be + // fine. Returning on the first one let one stale tab veto every generation. + const errors = []; + for (const candidate of tabs) { + const tab = await reviveTabIfNeeded(candidate); + if (!tab) continue; + try { + const resp = await captchaFromTab(tab.id, requestId, captchaAction); + if (!resp?.token) { + errors.push(resp?.error || 'NO_TOKEN'); + continue; + } + return resp; + } catch (e) { + const msg = e?.message || ''; + errors.push(msg); + // Tab evaporated mid-call (window closed, discarded again, navigated + // away). Move on to the next candidate rather than failing the job. + if ( + msg.includes('No current window') || + msg.includes('No tab with id') || + msg.includes('Receiving end does not exist') + ) { + continue; + } + return { error: msg }; + } + } + + // Every candidate failed — last-ditch, spawn a fresh temporary tab and + // target THAT exact tab. Previously we re-queried all Flow tabs and picked + // fresh[0], which could select the same stale tab again while leaking the + // newly-created one on every retry. + let recoveryTab = null; + try { + recoveryTab = await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); + await sleep(3000); + const target = await chrome.tabs.get(recoveryTab.id); + if (!target || target.discarded) return { error: 'NO_FLOW_TAB' }; + return await captchaFromTab(target.id, requestId, captchaAction); + } catch (e) { + return { error: e?.message || errors[0] || 'NO_FLOW_TAB' }; + } finally { + // A recovery tab is disposable: there were already Flow tabs available + // for the signed RPC. Do not let CAPTCHA retries accumulate root tabs. + if (recoveryTab?.id) { + try { await chrome.tabs.remove(recoveryTab.id); } catch { /* already gone */ } + } + } +} + +async function handleSolveCaptcha(msg) { + const { id, params } = msg; + const result = await solveCaptcha(id, params?.captchaAction || 'VIDEO_GENERATION'); + + // Standalone captcha solve counts as captcha-consuming + metrics.requestCount++; + if (result?.token) { + metrics.successCount++; + } else { + metrics.failedCount++; + metrics.lastError = result?.error || 'NO_TOKEN'; + } + chrome.storage.local.set({ metrics }); + + sendToAgent({ id, result }); +} + +// ─── Page-context RPC runner (the current path) ───────────── +// +// Flow's frontend signs its calls with cookies and a per-page `at` token, and +// every generate carries a single-use reCAPTCHA. None of that can be replayed +// from the service worker, so the request has to be issued by the Flow page +// itself: mint a fresh captcha through the grecaptcha bridge, then run the +// batchexecute POST in the page's MAIN world, where at / f.sid / bl live. + +const CAPTCHA_SLOT = '__CAPTCHA__'; +const MAX_RPC_TEXT = 32000000; // the project listing alone is past 17 MB + +async function runBatchRpc(cmd) { + const tabs = await chrome.tabs.query({ url: flowUrls }); + let candidate = tabs.find((t) => !t.discarded) || tabs[0]; + if (!candidate) { + // No Flow tab — open one and give the app a moment to boot, otherwise + // WIZ_global_data is not on the page yet and `at` comes back empty. Keep + // the exact created tab id so redirects/stale tabs cannot hijack recovery. + let opened; + try { + opened = await chrome.tabs.create({ url: FLOW_TAB_URL, active: false }); + await sleep(5000); + candidate = opened?.id ? await chrome.tabs.get(opened.id).catch(() => null) : null; + } catch (e) { + return { error: e?.message || 'NO_FLOW_TAB' }; + } + if (!candidate) return { error: 'NO_FLOW_TAB' }; + } + // Chrome discards backgrounded tabs; executeScript throws on a dead one. + const tab = await reviveTabIfNeeded(candidate); + if (!tab) return { error: 'FLOW_TAB_DISCARDED' }; + + let freq = cmd.freq; + if (cmd.captchaAction) { + const solved = await solveCaptcha(cmd.id, cmd.captchaAction); + if (!solved?.token) return { error: `CAPTCHA_FAILED: ${solved?.error || 'no token'}` }; + freq = freq.split(CAPTCHA_SLOT).join(solved.token); + } + + const [injected] = await chrome.scripting.executeScript({ + target: { tabId: tab.id }, + world: 'MAIN', + args: [cmd.rpcid, freq, MAX_RPC_TEXT, cmd.match || null], + func: async (rpcid, freqStr, maxText, match) => { + const wiz = globalThis.WIZ_global_data || {}; + const at = wiz.SNlM0e; + const sid = wiz.FdrFJe; + const bl = wiz.cfb2h; + if (!at) return { error: 'NO_AT_TOKEN' }; + const reqid = Math.floor(Math.random() * 900000) + 100000; + // Match Flow's own WIZ metadata. GEM_PIX_2 (Nano Banana Pro) rejects + // image generation when source-path is missing even though Lite may not. + const sourcePath = location.pathname || '/'; + const hl = (document.documentElement.lang || navigator.language || 'en').split('-')[0]; + const url = + `/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=${encodeURIComponent(rpcid)}` + + `&source-path=${encodeURIComponent(sourcePath)}` + + `&bl=${encodeURIComponent(bl || '')}&f.sid=${encodeURIComponent(sid || '')}` + + `&hl=${encodeURIComponent(hl)}&_reqid=${reqid}&rt=c`; + const resp = await fetch(url, { + method: 'POST', + credentials: 'include', + headers: { + 'content-type': 'application/x-www-form-urlencoded;charset=UTF-8', + 'x-same-domain': '1', + }, + body: new URLSearchParams({ 'f.req': freqStr, at }), + }); + const text = await resp.text(); + // The project listing is tens of megabytes and all we ever want from it + // is one entry. Cutting it down here keeps that payload inside the tab + // instead of pushing it through the bridge on every poll. + if (match) { + const found = text.indexOf(match); // not `at` — that is the CSRF token above + return { + status: resp.status, + matched: found !== -1, + text: found === -1 ? '' : text.slice(found, found + 800), + }; + } + return { status: resp.status, text: text.slice(0, maxText) }; + }, + }); + + return injected?.result || { error: 'NO_INJECTION_RESULT' }; +} + +async function handleBatchRpc(msg) { + const { id, params } = msg; + const { rpcid, freq, captchaAction, match } = params || {}; + if (!rpcid || !freq) { + sendToAgent({ id, status: 400, error: 'INVALID_BATCH_RPC' }); + return; + } + + setState('running'); + const hasCaptcha = !!captchaAction; + if (hasCaptcha) metrics.requestCount++; + // Polls and listing lookups run constantly; only the generates are worth + // a row in the log the popup shows. + const visible = hasCaptcha; + if (visible) { + addRequestLog({ + id, type: `RPC:${rpcid}`, time: new Date().toISOString(), + status: 'processing', error: null, outputUrl: null, url: rpcid, + payloadSummary: freq.slice(0, 200), + }); + } + + try { + const out = await runBatchRpc({ id, rpcid, freq, captchaAction, match }); + if (out.error) { + if (hasCaptcha) { metrics.failedCount++; metrics.lastError = out.error; } + if (visible) updateRequestLog(id, { status: 'failed', error: out.error }); + sendToAgent({ id, status: 502, error: out.error }); + } else { + if (hasCaptcha) { metrics.successCount++; metrics.lastError = null; } + if (visible) { + updateRequestLog(id, { + status: 'success', httpStatus: out.status, + responseSummary: (out.text || '').slice(0, 300), + }); + } + sendToAgent({ id, status: out.status, data: out.text }); + } + } catch (e) { + const err = e?.message || 'BATCH_RPC_FAILED'; + if (hasCaptcha) { metrics.failedCount++; metrics.lastError = err; } + if (visible) updateRequestLog(id, { status: 'failed', error: err }); + sendToAgent({ id, status: 500, error: err }); + } + + chrome.storage.local.set({ metrics }); + setState('idle'); +} + +// ─── API Request Proxy ────────────────────────────────────── + +async function handleTrpcRequest(msg) { + const { id, params } = msg; + const { url, method = 'POST', headers = {}, body, responseMode = 'json' } = params; + + if (!url || !url.startsWith('https://labs.google/')) { + sendToAgent({ id, error: 'INVALID_TRPC_URL' }); + return; + } + + setState('running'); + // TRPC calls don't consume captcha — don't count in metrics + + const logId = id; + const logType = url.includes('createProject') ? 'CREATE_PROJECT' : 'TRPC'; + // TRPC calls are silent — don't show in request log + + const fetchHeaders = { 'Content-Type': 'application/json', ...headers }; + if (flowKey) { + fetchHeaders['authorization'] = `Bearer ${flowKey}`; + } + + try { + const resp = await fetch(url, { + method, + headers: fetchHeaders, + body: body ? JSON.stringify(body) : undefined, + credentials: 'include', + }); + let data; + if (responseMode === 'url') { + // fetch() has already followed the authenticated Flow redirect. Return + // only the final signed URL and cancel the body so large videos are not + // buffered in the extension or copied through the WebSocket bridge. + data = { + url: resp.url, + contentType: resp.headers.get('content-type'), + }; + await resp.body?.cancel(); + } else { + data = await resp.json(); + } + chrome.storage.local.set({ metrics }); + updateRequestLog(logId, { status: 'success' }); + sendToAgent({ id, status: resp.status, data }); + } catch (e) { + console.error('[FlowAgent] tRPC request failed:', e); + chrome.storage.local.set({ metrics }); + updateRequestLog(logId, { status: 'failed', error: e.message || 'TRPC_FETCH_FAILED' }); + sendToAgent({ id, error: e.message || 'TRPC_FETCH_FAILED' }); + } finally { + setState('idle'); + } +} + +// Legacy REST proxy against aisandbox-pa. No current agent sends `api_request`; +// kept only so an extension updated ahead of its agent still serves an older +// one. It needs a `Bearer ya29.…` that Flow stopped minting, so it 401s on any +// post-migration profile — as does sendTelemetry below, which early-returns +// without a flowKey. Nothing here reaches aisandbox-pa any more; when the +// oldest agent in the wild speaks batch_rpc, this and the host permission go. +async function handleApiRequest(msg) { + const { id, params } = msg; + const { url, method, headers, body, captchaAction } = params; + + if (!url) { + sendToAgent({ id, error: 'MISSING_URL' }); + return; + } + + if (!url.startsWith('https://aisandbox-pa.googleapis.com/')) { + sendToAgent({ id, error: 'INVALID_URL' }); + return; + } + + setState('running'); + const hasCaptcha = !!captchaAction; + if (hasCaptcha) metrics.requestCount++; + + const logId = id; + const logType = _classifyApiUrl(url); + if (_VISIBLE_TYPES.has(logType)) { + const payloadSummary = body ? JSON.stringify(body).slice(0, 200) : null; + addRequestLog({ id: logId, type: logType, time: new Date().toISOString(), status: 'processing', error: null, outputUrl: null, url, payloadSummary }); + } + + try { + // Step 1: Solve captcha if needed + let captchaToken = null; + if (captchaAction) { + const captchaResult = await solveCaptcha(id, captchaAction); + captchaToken = captchaResult?.token || null; + if (!captchaToken) { + // Cannot proceed without captcha — API will 403 + const err = captchaResult?.error || 'CAPTCHA_FAILED'; + console.error(`[FlowAgent] Captcha failed for ${captchaAction}: ${err}`); + sendToAgent({ id, status: 403, error: `CAPTCHA_FAILED: ${err}` }); + if (hasCaptcha) { metrics.failedCount++; metrics.lastError = `CAPTCHA_FAILED: ${err}`; } + chrome.storage.local.set({ metrics }); + updateRequestLog(logId, { status: 'failed', error: `CAPTCHA_FAILED: ${err}` }); + setState('idle'); + return; + } + } + + // Step 2: Inject captcha token into body + let finalBody = body; + if (captchaToken && finalBody) { + finalBody = JSON.parse(JSON.stringify(finalBody)); // deep clone + if (finalBody.clientContext?.recaptchaContext) { + finalBody.clientContext.recaptchaContext.token = captchaToken; + } + if (finalBody.requests && Array.isArray(finalBody.requests)) { + for (const req of finalBody.requests) { + if (req.clientContext?.recaptchaContext) { + req.clientContext.recaptchaContext.token = captchaToken; + } + } + } + } + + // Step 3: Use flowKey for auth + const activeFlowKey = flowKey; + if (!activeFlowKey) { + sendToAgent({ id, status: 503, error: 'NO_FLOW_KEY' }); + if (hasCaptcha) { metrics.failedCount++; metrics.lastError = 'NO_FLOW_KEY'; } + chrome.storage.local.set({ metrics }); + updateRequestLog(logId, { status: 'failed', error: 'NO_FLOW_KEY' }); + setState('idle'); + return; + } + + const fetchHeaders = { ...(headers || {}) }; + fetchHeaders['authorization'] = `Bearer ${activeFlowKey}`; + + // Step 4: Make the API call from browser context + const response = await fetch(url, { + method: method || 'POST', + headers: fetchHeaders, + credentials: 'include', + body: method === 'GET' ? undefined : JSON.stringify(finalBody), + }); + + let responseData; + const responseText = await response.text(); + try { + responseData = JSON.parse(responseText); + } catch { + responseData = responseText; + } + + sendToAgent({ + id, + status: response.status, + data: responseData, + }); + + const responseSummary = responseText ? responseText.slice(0, 300) : null; + if (response.ok) { + if (hasCaptcha) { metrics.successCount++; metrics.lastError = null; } + updateRequestLog(logId, { status: 'success', httpStatus: response.status, responseSummary }); + } else { + if (hasCaptcha) { metrics.failedCount++; metrics.lastError = `API_${response.status}`; } + updateRequestLog(logId, { status: 'failed', error: `API_${response.status}`, httpStatus: response.status, responseSummary }); + } + } catch (e) { + sendToAgent({ + id, + status: 500, + error: e.message || 'API_REQUEST_FAILED', + }); + if (hasCaptcha) { metrics.failedCount++; metrics.lastError = e.message; } + updateRequestLog(logId, { status: 'failed', error: e.message || 'API_REQUEST_FAILED' }); + } + + chrome.storage.local.set({ metrics }); + setState('idle'); +} + +// ─── State & Popup ────────────────────────────────────────── + +function setState(newState) { + state = newState; + const badges = { idle: '●', running: '▶', off: '○' }; + const colors = { idle: '#22c55e', running: '#f59e0b', off: '#6b7280' }; + chrome.action.setBadgeText({ text: badges[state] || '' }); + chrome.action.setBadgeBackgroundColor({ color: colors[state] || '#000' }); + broadcastStatus(); +} + +function broadcastStatus() { + chrome.runtime.sendMessage({ type: 'STATUS_PUSH' }).catch(() => {}); +} + +chrome.runtime.onMessage.addListener((msg, _, reply) => { + if (msg.type === 'STATUS') { + reply({ + connected: ws?.readyState === WebSocket.OPEN, + agentConnected: ws?.readyState === WebSocket.OPEN, + flowKeyPresent: !!flowKey, + manualDisconnect, + tokenAge: metrics.tokenCapturedAt ? Date.now() - metrics.tokenCapturedAt : null, + metrics: { + requestCount: metrics.requestCount, + successCount: metrics.successCount, + failedCount: metrics.failedCount, + lastError: metrics.lastError, + }, + state, + }); + } + + if (msg.type === 'DISCONNECT') { + manualDisconnect = true; + if (ws) ws.close(); + reply({ ok: true }); + return true; + } + + if (msg.type === 'RECONNECT') { + manualDisconnect = false; + connectToAgent(); + reply({ ok: true }); + return true; + } + + if (msg.type === 'REQUEST_LOG') { + reply({ log: requestLog }); + return true; + } + + if (msg.type === 'OPEN_FLOW_TAB') { + chrome.tabs.query({ url: flowUrls }).then((tabs) => { + if (tabs.length) { + chrome.tabs.update(tabs[0].id, { active: true }); + reply({ ok: true, tabId: tabs[0].id }); + } else { + chrome.tabs.create({ url: FLOW_TAB_URL }) + .then((tab) => reply({ ok: true, tabId: tab.id })) + .catch((e) => reply({ error: e.message })); + } + }).catch((e) => reply({ error: e.message })); + return true; + } + + if (msg.type === 'REFRESH_TOKEN') { + captureTokenFromFlowTab({ createIfMissing: true }) + .then(() => reply({ ok: true })) + .catch((e) => reply({ error: e.message })); + return true; + } + + if (msg.type === 'TEST_CAPTCHA') { + solveCaptcha(`test-${Date.now()}`, msg.pageAction || 'IMAGE_GENERATION') + .then((r) => reply(r)) + .catch((e) => reply({ error: e.message })); + return true; + } + + if (msg.type === 'TRPC_MEDIA_URLS') { + handleTrpcMediaUrls(msg.trpcUrl, msg.body); + reply({ ok: true }); + return true; + } + + return true; +}); + +// ─── TRPC Media URL Extractor ────────────────────────────── + +function handleTrpcMediaUrls(trpcUrl, bodyText) { + try { + // Extract all fresh GCS signed URLs + const urlRegex = /https:\/\/storage\.googleapis\.com\/ai-sandbox-videofx\/(?:image|video)\/[0-9a-f-]{36}\?[^"'\s]+/g; + const matches = bodyText.match(urlRegex) || []; + if (!matches.length) return; + + // Deduplicate and parse + const urlMap = {}; + for (const rawUrl of matches) { + // Unescape JSON-escaped URLs + const url = rawUrl.replace(/\\u0026/g, '&').replace(/\\/g, ''); + const mediaMatch = url.match(/\/(image|video)\/([0-9a-f-]{36})\?/); + if (mediaMatch) { + const [, mediaType, mediaId] = mediaMatch; + // Keep last occurrence (freshest) + urlMap[mediaId] = { mediaType, url, mediaId }; + } + } + + const entries = Object.values(urlMap); + if (!entries.length) return; + + console.log(`[FlowAgent] Captured ${entries.length} fresh media URLs from TRPC`); + // URL refresh is silent — don't show in request log + + // Forward to agent for DB update + if (ws?.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ + type: 'media_urls_refresh', + urls: entries, + })); + } + } catch (e) { + console.error('[FlowAgent] Failed to extract TRPC media URLs:', e); + } +} + +function sleep(ms) { + return new Promise((r) => setTimeout(r, ms)); +} + +// ─── Human-like Telemetry ────────────────────────────────── +// Periodically send tracking events to Google's analytics endpoints +// to mimic normal browser behavior. + +const _UA = navigator.userAgent; +let _telemetrySessionId = `;${Date.now()}`; + +function _rand(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } + +function _buildBatchLogPayload() { + const events = []; + const types = ['FLOW_IMAGE_LATENCY', 'FLOW_VIDEO_LATENCY']; + const count = _rand(1, 3); + for (let i = 0; i < count; i++) { + events.push({ + event: types[_rand(0, types.length - 1)], + eventProperties: [ + { key: 'CURRENT_TIME_MS', doubleValue: Date.now() }, + { key: 'DURATION_MS', doubleValue: _rand(150, 800) }, + { key: 'USER_AGENT', stringValue: _UA }, + { key: 'IS_DESKTOP', booleanValue: true }, + ], + eventMetadata: { sessionId: _telemetrySessionId }, + eventTime: new Date().toISOString(), + }); + } + return { appEvents: events }; +} + +function _buildFrontendEventsPayload() { + const eventTypes = [ + 'FLOW_IMAGE_LATENCY', 'FLOW_VIDEO_LATENCY', 'GRID_SCROLL_DEPTH', + 'FLOW_PROJECT_OPEN', 'FLOW_SCENE_VIEW', + ]; + const count = _rand(1, 4); + const events = []; + for (let i = 0; i < count; i++) { + const et = eventTypes[_rand(0, eventTypes.length - 1)]; + const params = { + USER_AGENT: { '@type': 'type.googleapis.com/google.protobuf.StringValue', value: _UA }, + IS_DESKTOP: { '@type': 'type.googleapis.com/google.protobuf.StringValue', value: 'true' }, + }; + if (et.includes('LATENCY')) { + params.CURRENT_TIME_MS = { '@type': 'type.googleapis.com/google.protobuf.StringValue', value: String(Date.now()) }; + params.DURATION_MS = { '@type': 'type.googleapis.com/google.protobuf.StringValue', value: String(_rand(100, 600)) }; + } + if (et === 'GRID_SCROLL_DEPTH') { + params.MEDIA_GENERATION_PAYGATE_TIER = { '@type': 'type.googleapis.com/google.protobuf.StringValue', value: 'PAYGATE_TIER_TWO' }; + } + events.push({ + eventType: et, + metadata: { + sessionId: _telemetrySessionId, + createTime: new Date().toISOString(), + additionalParams: params, + }, + }); + } + return { events }; +} + +async function sendTelemetry() { + // Legacy-path camouflage: these endpoints want the bearer Flow no longer + // mints, so on the batch path there is no flowKey and this is a no-op. + if (!flowKey || state === 'off') return; + + const headers = { + 'Content-Type': 'text/plain;charset=UTF-8', + 'authorization': `Bearer ${flowKey}`, + }; + + // Telemetry is silent — don't show in request log + try { + if (Math.random() < 0.5) { + await fetch(`https://aisandbox-pa.googleapis.com/v1:batchLog`, { + method: 'POST', headers, credentials: 'include', + body: JSON.stringify(_buildBatchLogPayload()), + }); + } else { + await fetch(`https://aisandbox-pa.googleapis.com/v1/flow:batchLogFrontendEvents`, { + method: 'POST', headers, credentials: 'include', + body: JSON.stringify(_buildFrontendEventsPayload()), + }); + } + } catch {} +} + +// Send telemetry at random intervals (45-120s) to look organic +function scheduleTelemetry() { + const delay = _rand(45, 120) * 1000; + setTimeout(async () => { + await sendTelemetry(); + scheduleTelemetry(); // reschedule with new random interval + }, delay); +} + +// Refresh session ID every ~30min like a real user +setInterval(() => { _telemetrySessionId = `;${Date.now()}`; }, _rand(25, 35) * 60 * 1000); + +scheduleTelemetry(); + +console.log('[FlowAgent] Extension loaded'); diff --git a/scratch/parse_dump.py b/scratch/parse_dump.py new file mode 100644 index 000000000..f929bd258 --- /dev/null +++ b/scratch/parse_dump.py @@ -0,0 +1,13 @@ +import re +import json + +s = open('scratch/project_media_dump.txt', encoding='utf-8').read() +uuids = set(re.findall(r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}', s)) +print(f"Total UUIDs in dump: {len(uuids)}") +for u in sorted(uuids): + print("UUID:", u) + +urls = re.findall(r'https?://[^\s\"\'\\]+', s) +print(f"Total URLs in dump: {len(urls)}") +for u in urls[:10]: + print("URL:", u) diff --git a/scratch/parse_envelopes.py b/scratch/parse_envelopes.py new file mode 100644 index 000000000..e417d0d1a --- /dev/null +++ b/scratch/parse_envelopes.py @@ -0,0 +1,17 @@ +import sys +sys.path.insert(0, '.') +import json +from agent.services import flow_batch as fb + +s = open('scratch/project_media_dump.txt', encoding='utf-8').read() +results = fb.parse_envelope(s) +print(f"Total results envelopes: {len(results)}") +for r in results: + print("rpcid:", r.rpcid, "ok:", r.ok) + if r.ok and r.data: + # inspect r.data + if isinstance(r.data, list) and len(r.data) > 0: + print("data len:", len(r.data)) + # print top-level fields + for i, item in enumerate(r.data[:5]): + print(f" [{i}]: type={type(item)} preview={str(item)[:120]}") diff --git a/scratch/parse_media.py b/scratch/parse_media.py new file mode 100644 index 000000000..378abfd1c --- /dev/null +++ b/scratch/parse_media.py @@ -0,0 +1,17 @@ +import urllib.request +import json +import asyncio + +req = urllib.request.Request('http://127.0.0.1:8100/api/flow/debug-project-media?project_id=594758cc-11f5-4f92-8b3c-1213686591f4') +with urllib.request.urlopen(req) as resp: + data = json.loads(resp.read().decode()) + +# Check recent image media in DB for this video +import sqlite3 +conn = sqlite3.connect('flow_agent.db') +cursor = conn.cursor() +cursor.execute('SELECT id, display_order, horizontal_image_media_id, horizontal_video_media_id FROM scene WHERE video_id = ? ORDER BY display_order', ('945ad6d4-5d79-4790-80db-1bff16ed7255',)) +scenes = cursor.fetchall() +print("Scenes in DB:") +for s in scenes: + print(f"Scene #{s[1]} (id: {s[0]}): img={s[2]} vid={s[3]}") diff --git a/scratch/parse_netlog.py b/scratch/parse_netlog.py new file mode 100644 index 000000000..fbaf45a43 --- /dev/null +++ b/scratch/parse_netlog.py @@ -0,0 +1,26 @@ +import json + +with open("scratch/captured_netlog.jsonl", "r", encoding="utf-8") as f: + lines = f.readlines() + +print(f"Total netlog entries: {len(lines)}") +for i, line in enumerate(lines): + if not line.strip(): continue + try: + data = json.loads(line) + url = data.get("url", "").split("?")[0].split("/")[-1] + status = data.get("statusCode") + ts = data.get("ts") + body = data.get("body", "") + # search for prompt in body + print(f"[{i}] {ts} | {url} | Status: {status} | Body len: {len(body)}") + if "f.req" in body or "ProseMirror" in body or "StreamChat" in line or "Tạo" in body or "knife" in body: + # try to decode json body + try: + bjson = json.loads(body) + freq = bjson.get("f.req", [""])[0] + print(f" f.req snippet: {freq[:180]}...") + except: + print(f" body snippet: {body[:180]}...") + except Exception as e: + print(f"[{i}] error: {e}") diff --git a/scratch/patch_scene_0.py b/scratch/patch_scene_0.py new file mode 100644 index 000000000..15f08861a --- /dev/null +++ b/scratch/patch_scene_0.py @@ -0,0 +1,38 @@ +import urllib.request +import json + +sid = "02f6d29e-be27-491a-b1ad-baa944964890" + +update_data = { + "character_names": ["Le Quoc Tien", "Do Minh Kha"], + "prompt": ( + "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. " + "Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. " + "Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. " + "In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. " + "Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph." + ), + "video_prompt": ( + "0-3s: Low-angle tracking shot through heat-warped plastic debris and scorched concrete in subterranean B3 basement at Me Tri as Do Minh Kha walks slowly past motionless casualties, boots coated in red dust. " + "3-6s: Camera tilts down as Do Minh Kha crouches over Le Quoc Tien, who clutches a bleeding abdominal wound beside a torn empty water pouch. Do Minh Kha speaks in a hoarse parched voice \"Lê Quốc Tiến, mày vốn không nên sống lâu đến thế.\" " + "6-8s: Close-up of Do Minh Kha raising a gleaming tactical knife reflecting the deep crimson sunlight bleeding through a fractured ceiling slab, then plunging the blade downward into pitch black darkness. " + "Audio: Stifled gasping breath, slow crunching footsteps on gravel, hoarse menacing dialogue, sharp metallic blade unsheath, deep sub-bass cinematic hit. Negative: subtitles, watermark, text overlay." + ), + "narrator_text": "Tầng hầm B3 Mễ Trì, năm 2031. Dưới ánh Hồng Nhật thiêu đốt, lưỡi dao của Đỗ Minh Kha đã kết thúc ba năm sinh tồn của tôi." +} + +req = urllib.request.Request( + f"http://127.0.0.1:8100/api/scenes/{sid}", + data=json.dumps(update_data).encode("utf-8"), + headers={"Content-Type": "application/json"}, + method="PATCH" +) + +with urllib.request.urlopen(req) as resp: + res = json.loads(resp.read().decode("utf-8")) + print("Patched Scene #0:") + print("ID:", res["id"]) + print("Character names:", res["character_names"]) + print("Prompt:", res["prompt"][:80], "...") + print("Video prompt:", res["video_prompt"][:80], "...") + print("Narrator text:", res["narrator_text"]) diff --git a/scratch/pause_requests.py b/scratch/pause_requests.py new file mode 100644 index 000000000..5e55b021c --- /dev/null +++ b/scratch/pause_requests.py @@ -0,0 +1,6 @@ +import sqlite3 + +conn = sqlite3.connect('flow_agent.db') +conn.execute("UPDATE request SET status = 'FAILED' WHERE status IN ('PENDING', 'PROCESSING')") +conn.commit() +print("Cancelled all active requests.") diff --git a/scratch/poll_media.py b/scratch/poll_media.py new file mode 100644 index 000000000..a40032ada --- /dev/null +++ b/scratch/poll_media.py @@ -0,0 +1,39 @@ +import sys +sys.path.insert(0, ".") +import urllib.request +import json +import time + +print("Polling project media for new assets...") +for i in range(12): + time.sleep(5) + try: + with urllib.request.urlopen("http://127.0.0.1:8100/api/ext/test-project-media") as resp: + data = json.loads(resp.read().decode("utf-8")) + raw_len = data.get("data_len", 0) + + with open("scratch/project_media_dump.txt", "r", encoding="utf-8") as f: + raw = f.read() + + from agent.services import flow_batch as fb + payload = fb.first_payload(raw, fb.RPC_PROJECT_MEDIA) + items = payload[1] if len(payload) > 1 and isinstance(payload[1], list) else [] + + # find items created in the last 200 seconds + recent = [] + now_approx = 1790172189 # current epoch order + for it in items: + details = it[3] if len(it) > 3 else None + ts = details[1][0] if details and details[1] else 0 + title = details[0] if details else "" + media_id = details[4] if details and len(details) > 4 else None + if ts > 1790169824: # after the workshop man + recent.append((ts, title, media_id)) + + print(f"[{i*5}s] Total items: {len(items)}, Recent new items: {len(recent)}") + if recent: + for r in recent: + print(f" >>> NEW ASSET: TS={r[0]}, Title='{r[1]}', MediaID={r[2]}") + break + except Exception as e: + print(f"[{i*5}s] Error: {e}") diff --git a/scratch/print_c31.py b/scratch/print_c31.py new file mode 100644 index 000000000..1c5002b2a --- /dev/null +++ b/scratch/print_c31.py @@ -0,0 +1,9 @@ +import json + +lines = open('scratch/captured_netlog.jsonl', encoding='utf-8').read().splitlines() +c31 = json.loads(lines[31]) +body_dict = json.loads(c31['body']) +inner_str = body_dict['f.req'][0] +parsed = json.loads(inner_str) +inner_payload = json.loads(parsed[1]) +print(json.dumps(inner_payload, indent=2)) diff --git a/scratch/project_media_dump.txt b/scratch/project_media_dump.txt new file mode 100644 index 000000000..cd27a6d3b --- /dev/null +++ b/scratch/project_media_dump.txt @@ -0,0 +1,8 @@ +)]}' + +163908 +[["wrb.fr","Zzl0ze","[[[\"0a42ed66-8a7f-4b28-abfb-4586a39f4b52\",\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",[\"03_APPROVED\",null,null,[1784529350,72144000],null,[1784529355,462807000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"0c211a47-5991-43e8-8142-a390e0daa4a8\",null,[\"03_PROPS_TECH\",null,null,[1784529293,146542000],null,[1784529297,460541000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"1139ff90-563d-4843-92ac-3a35fbecae86\",null,[\"09_ARCHIVE\",null,null,[1784529463,78960000],null,[1784529475,558401000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"1845d995-1a46-48ed-8c43-c91c9cc28ef2\",\"ccd7cdd3-bb43-4ba5-8cbc-0c7b75381109\",[\"99_REJECTED\",null,null,[1784529240,97665000],null,[1784529245,759339000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"1fdfac50-bbad-4622-b43b-0ab2d15d37ff\",\"d57bfef1-e345-42be-8be5-244c58752988\",[\"02_SELECT\",null,null,[1784529418,744451000],null,[1784529428,627263000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"4b8dcbae-1bbe-484f-9459-708233502798\",\"95d2e37f-c851-4122-8825-e4b4d7d71e8e\",[\"01_VARIANTS\",null,null,[1784529272,754511000],null,[1784529277,491788000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"5500f781-66f4-44f1-9ce5-47f0a90c04d0\",\"d57bfef1-e345-42be-8be5-244c58752988\",[\"03_APPROVED\",null,null,[1784529420,112190000],null,[1784529432,949574000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"881fa2e3-3396-4c33-ab58-941204d5a869\",\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",[\"00_FRAMES\",null,null,[1784529320,39941000],null,[1784529323,799385000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"909ad3fe-a510-4d46-9a35-641144cc276e\",\"95d2e37f-c851-4122-8825-e4b4d7d71e8e\",[\"99_REJECTED\",null,null,[1784529282,196777000],null,[1784529287,686348000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"95d2e37f-c851-4122-8825-e4b4d7d71e8e\",null,[\"02_LOCATIONS\",null,null,[1784529252,245818000],null,[1784529256,242132000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"a55a169d-3f7e-40d7-b9be-50a3abe4182a\",null,[\"04_STYLE_LOCK\",null,null,[1784529301,392131000],null,[1784529305,947850000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"adf37d8f-38a0-4198-b1e4-26efbf46bcf0\",null,[\"00_CANON\",null,null,[1784529050,206104000],null,[1784529171,248849000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"b6e65c65-d1f0-46e0-899e-91a442806fc9\",\"ccd7cdd3-bb43-4ba5-8cbc-0c7b75381109\",[\"02_VOICE_MASTERS\",null,null,[1784529231,661607000],null,[1784529237,672168000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"b9f3fb92-e22b-4a39-b126-f0ca914eca14\",\"d57bfef1-e345-42be-8be5-244c58752988\",[\"00_FRAMES\",null,null,[1784529405,117346000],null,[1784529411,260369000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"bcb1aa9b-b47a-4ff3-9c09-92369ca02355\",\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",[\"01_DRAFT\",null,null,[1784529328,990912000],null,[1784529333,198253000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"be966234-d647-4699-bc33-a0e13177c153\",\"ccd7cdd3-bb43-4ba5-8cbc-0c7b75381109\",[\"01_VARIANTS\",null,null,[1784529217,532896000],null,[1784529228,620221000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"c3e324f9-e875-4284-a2cc-357b31c22d31\",\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",[\"02_SELECT\",null,null,[1784529339,230340000],null,[1784529344,560943000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",null,[\"05_TRAILER\",null,null,[1784529311,526839000],null,[1784529316,590851000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"ccd7cdd3-bb43-4ba5-8cbc-0c7b75381109\",null,[\"01_CHARACTERS\",null,null,[1784529188,643203000],null,[1784529196,685227000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"cf1a4e1e-0b55-4944-89b6-f019381d74d6\",\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",[\"04_SCENE\",null,null,[1784529360,286453000],null,[1784529376,577028000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d4b9f61e-164e-41bc-ab33-73533207a219\",\"d57bfef1-e345-42be-8be5-244c58752988\",[\"04_SCENE\",null,null,[1784529438,238663000],null,[1784529444,283791000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d57bfef1-e345-42be-8be5-244c58752988\",null,[\"06_EP01\",null,null,[1784529394,651678000],null,[1784529400,751158000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"eae3b1f7-5964-4041-a509-c289180d05eb\",\"d57bfef1-e345-42be-8be5-244c58752988\",[\"01_DRAFT\",null,null,[1784529416,61894000],null,[1784529423,404539000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"ebfe3ef1-604d-4ba0-8f17-c4f18b0e3dc7\",\"ccd7cdd3-bb43-4ba5-8cbc-0c7b75381109\",[\"00_FACE_MASTERS\",null,null,[1784529204,622353000],null,[1784529212,77567000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"f07fddb4-950f-4b09-9b45-c534be4b10c8\",null,[\"08_POST_REFERENCES\",null,null,[1784529461,149740000],null,[1784529469,73331000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"f859aae4-e394-4924-bb6d-12b9eaa93663\",null,[\"07_EPISODES\",null,null,[1784529450,853966000],null,[1784529457,442839000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"fc0eb04a-aa2c-4556-8852-45f034b9f232\",\"95d2e37f-c851-4122-8825-e4b4d7d71e8e\",[\"00_MASTERS\",null,null,[1784529262,28805000],null,[1784529268,688191000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"]],[[\"18462c7e-40cf-4217-964d-980db21dac35\",null,null,[\"Train gliding over Hanoi traffic\",[1790099234,21793000],null,null,\"a029279b-cc59-465f-98d5-0fa8b78187ba\",\"DDD5C8EB-ECF1-4A0F-BB97-8EF2A1FDF396\",[1790099256,112919000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"23070ed9-c3a8-4070-a111-318ef1ed4f3a\",null,null,[\"image.jpg\",[1790174596,878212000],null,null,\"c436b109-dd00-498d-806d-b6bddc9a3bbf\",null,[1790174602,244051000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"2c817534-e7d9-4711-ba06-8da52e020080\",null,null,[\"Camera pans cracked asphalt sun\",[1790099773,817655000],true,null,\"c8939cac-021c-4000-a355-ec23628e5ea0\",\"649876A2-0594-4ACD-80A2-35CC61E50C6B\",[1790103884,48657000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"3197d46b-0a13-463c-8aaf-9dd5f1416e6e\",null,null,[\"Hands slamming against glass doors\",[1790099933,333177000],null,null,\"c86e9fac-57bb-4fc3-a85f-d751ecefdcc8\",\"2CAEE570-CE42-462F-A46F-D5731297D999\",[1790099941,95849000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"337d7d27-bc09-4ca1-9f11-1b9253d15cbb\",null,null,[\"Overgrown bridge over river\",[1790104423,640950000],null,null,\"3d1052dd-2332-48f6-81c3-73adb6d4ff09\",\"c3a99ab1-0f8d-4d1b-ba0c-8f354bd9fc13\",[1790104447,312420000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"3ab07549-ccbb-410a-a97d-08b8a4627f84\",null,null,[\"Vietnamese engineer with abdomen…\",[1784546411,930438000],null,true,\"684e27a9-a16c-480e-95ce-8cb540798659\",\"a5f6c049-2f1d-40d4-b16f-3d96f24b1fe8\",[1784546442,385675000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"3bd39545-26f0-4165-883c-528e119207fc\",null,null,[\"Woman standing in ruins\",[1790105718,172947000],true,null,\"03bb0401-4b95-485b-906c-f5f8b0195547\",null,[1790105731,783423000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"3ddd6fbc-8834-4868-a7fa-5e1dc68d04d7\",null,null,[\"Sun shining over cracked asphalt\",[1790099782,85545000],null,null,\"d9a829c4-cd2d-491c-8773-7bee1eeb0aba\",\"0CCA1636-A823-4656-9E94-3234A72452ED\",[1790099861,528437000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"420931e8-d444-4a59-8ba8-a745cbeead17\",\"ebfe3ef1-604d-4ba0-8f17-c4f18b0e3dc7\",null,[\"HNTL_CHR_TIEN_2028_FACE_MASTER_v001_APPROVED\",[1784545966,119130000],null,null,\"cd20c077-1f3e-4432-9bbc-6d19af7a5a16\",null,[1784545986,933851000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"431da3f0-96a9-4cc7-8384-937287b72c6e\",null,null,[\"Commander standing facing camera\",[1790098978,830949000],null,null,\"78e46231-e6cf-43fb-99bc-a4cb96196e24\",\"389D74E5-56CC-4283-B7BE-E20A2DCA261B\",[1790099002,862715000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"482b99b0-f4ee-40f9-a31b-c4f76ddd2af7\",null,null,[\"Man standing over exhausted man\",[1790174045,451631000],null,null,\"25704835-1c43-4c10-a718-9f77ab2e9cd6\",\"E1EBBB69-0118-4F27-ADD1-F71D29C1C559\",[1790174068,910540000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"4b6e1f6c-ad29-4c79-ac8b-840e0ff929c4\",null,null,[\"Bustling open-air market with la…\",[1790098607,247715000],true,null,\"dc6cb5cb-1515-4607-8d63-35b7d4c79df9\",\"33C47DC5-F835-4F3A-94CA-0BA140F9EF51\",[1790103911,506021000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"4fb9e862-d995-4f49-9eb6-d00b1f2ee767\",null,null,[\"Vietnamese engineer with abdomen…\",[1784546541,545693000],null,null,\"9aea7396-dc22-4b69-947f-7d1dcc5c1e3c\",null,[1784546548,573950000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"ad4b3ad9-a282-478e-957e-6fcc47a2b5e4\"],[\"50ce51e4-768e-4eb0-abce-1df3f94acae6\",null,null,[\"Wooden market stall with scale\",[1790098627,137046000],true,null,\"deb54d26-dbdb-4351-99f5-04400fef123c\",\"6D44D38D-F81B-4CC1-9ED4-5CC9C5A58E57\",[1790103919,140646000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"52274337-3f1e-499b-b404-022ff18196d3\",null,null,[\"Metallic structures rising from …\",[1790099028,206353000],null,null,\"9daace9a-a99c-4a5a-bce5-e9aaedcb1980\",\"836A8983-2CBB-4570-B679-C6E43A2EBE73\",[1790099051,404977000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"6ddbd597-0a88-4e3c-b31a-7d20443c0dab\",null,null,[\"Engineer standing facing camera\",[1790098968,283242000],null,null,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\",\"D690B37C-62E0-4E9D-A68E-D0B96D91BCDB\",[1790098990,362027000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,null,[\"Woman standing in ruins\",[1790105368,68953000],true,null,\"2e1227e3-7cb3-4213-8574-503bc667c75e\",\"dc42af28-a7ef-440d-81ab-ca9d701c8e7f\",[1790105725,873145000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",null,null,[\"Woman sitting near cooling fan\",[1790106045,1406000],true,null,\"567984bd-c3ff-46de-ad25-353be60e6188\",\"1a289c4e-464f-4aee-9114-f9d9cd93c6ff\",[1790106200,882061000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"82ddef0b-fced-4a18-a039-240a66c111d2\",null,null,[\"Woman wearing coat in sun\",[1790105368,716850000],true,null,\"78266bba-b106-47e7-80e3-c152822e1ca9\",\"3df1fee0-6b2c-447a-b83a-5a4fded17d43\",[1790105435,349518000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"87cfaa04-a192-405e-aa3b-137fa3d20ccb\",null,null,[\"Journalist standing for referenc…\",[1790098988,593315000],null,null,\"65993027-0037-4f25-9fb7-7bd4d301ee7b\",\"1A445D6E-8380-4BBC-AE96-FA2C39BB7DBB\",[1790099012,265973000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"8a636ea0-c501-40c7-b8a3-74ebcb14ba74\",null,null,[\"tạo video intro\",[1789492421,692307000],true,null,\"1b832287-df4c-429a-b3b2-46d8f818d284\",\"e2e9ea1a-0fed-4c90-9ab3-1cd282ba672b\",[1790103876,68469000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"9139a337-e6df-474c-90f1-e4e48dca69a9\",null,null,[\"Man holding knife over seated ma…\",[1790099323,542997000],null,null,\"a6010398-57c9-4e27-a89f-31ed0ddf2d1a\",\"B3178C0F-6E72-49C4-9912-0EC1B6A0AB7A\",[1790099346,133587000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"99a9b9fa-2091-4429-b192-476892fad1e8\",null,null,[\"Mountain landscape in northern V…\",[1790104961,385705000],null,null,\"1fa5e13c-e74f-45da-adc7-311e9e27c140\",\"c48a378f-6f86-4a32-8bb4-6c0c236fa92f\",[1790104983,162792000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"9c487a71-fc76-4e0e-bdc3-98eee2bc25da\",null,null,[\"Man jolting awake in bed\",[1790099223,430583000],null,null,\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\",\"A08F6255-349C-4E2F-9AC3-1577284BBC2F\",[1790099244,889973000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"9e8ede1b-4f8f-4354-aecb-a7759421bf13\",null,null,[\"Person shining flashlight on hatch\",[1790099253,589865000],null,null,\"30b5f32e-3918-4b68-acf8-7f7b0afafd0d\",\"55BC5782-6E26-45E4-AC92-44BBAEFAA7D2\",[1790099279,51856000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"a5fbb9e9-b0d0-48f4-89ea-277444ec27c4\",null,null,[\"Deserted street with abandoned s…\",[1790104424,188616000],null,null,\"76a03ec4-6340-4e25-9e8a-5009942893b9\",\"821131e5-6a0a-498b-9215-628a6f727127\",[1790104446,58271000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"ad778284-c548-4428-9386-24491b893682\",null,null,[\"Cat peering through rainy window\",[1790098625,39575000],true,null,\"310d92fb-dd8e-4e33-b061-4750fcbeeeaa\",\"7fe69dc0-a68f-4e64-bad1-877baf14334e\",[1790103909,73177000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"b00ceb65-a125-49c4-91ff-49f0af1e2356\",null,null,[\"HNTL_CHR_TIEN_2028_FACE_MASTER_v001_APPROVED\",[1784545698,613155000],null,true,\"ac5f92cb-b55e-4db9-b800-0dd1dbe759ef\",\"74c99d95-363a-4479-b0b2-35b92c0e44b6\",[1784545880,528045000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"b58780b6-8218-433c-bdca-6fb13f9e9cd6\",null,null,[\"Vietnamese engineer character re…\",[1784545738,781156000],true,null,\"acf87cab-c8f4-46c4-b305-5d57a5be19fa\",\"c1a2084f-d5ca-42f0-8070-1031049fb44f\",[1784545790,489539000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"b84f96ab-d2b2-414b-b4ed-912a9e3e2859\",null,null,[\"Concrete warehouse with metal hatch\",[1790099018,2158000],null,null,\"5a919b50-566c-4cfb-97b6-4e481650dc0a\",\"D4B2CCDB-02A8-4678-9613-0A507F273D92\",[1790099039,863469000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"bba71aa9-a24c-43bc-a42e-e0f140a426e3\",null,null,[\"Cat wearing apron walking upright\",[1790098596,970493000],true,null,\"c6bef467-362b-4d7d-86bd-7734cf16379f\",\"64A9C999-320D-43D0-A3FB-DB954A6CEADA\",[1790103914,136184000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"bd7eacf9-d385-4561-bf0b-62e3e8a253dc\",null,null,[\"Commuter traffic on urban avenue\",[1790098998,48960000],null,null,\"e12021b9-1f91-4a65-a9e2-f1ddbffbf42d\",\"DD98F4BD-09EF-4A49-8064-8F684F842216\",[1790099021,546266000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"be5c73e8-269a-4fdf-a1a5-d2265179a8be\",null,null,[\"Vietnamese engineer with abdomen…\",[1784546459,807750000],true,null,\"732c7e1a-7267-462f-8f58-1bf43694428e\",\"8814c820-2648-41d8-8971-f12d6ef4992c\",[1784565183,289884000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"c3b02b33-da87-410c-88ce-c3896028c8a6\",null,null,[\"Green metro train and commuters\",[1790099923,331786000],null,null,\"1d72b8c7-7c9f-477c-bbf2-0f3a24cdc9a1\",\"44483D79-04FD-487B-AEAF-CB7269FA6C44\",[1790099930,87223000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"c7fee095-6829-4801-94c8-3eb9bcaf060f\",null,null,[\"Le Quoc Tien.png\",[1785255350,725479000],null,null,\"4630aeab-cd27-4457-96b6-24045de2504e\",null,[1785255359,823385000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"11a89444-ca45-45a2-a890-feab388ba4ae\"],[\"d0e3e32c-df9c-4641-bce4-dd9ca73a4f9b\",null,null,[\"Industrial outpost on mountain r…\",[1790104962,53428000],null,null,\"ca9eac0a-7816-4104-af03-8f98001f2915\",\"ae1cd228-257c-4806-8c6e-865d878e4140\",[1790104983,167759000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d19f6811-455b-4838-bdc2-b908aeb7bd36\",null,null,[\"Man standing in workshop\",[1790169824,340307000],null,null,\"666bc47c-1fa1-4167-83cc-3088840b3146\",\"119296d0-39e6-4e6c-96a9-b713a2e3d50d\",[1790169845,203797000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d5719db7-7c9a-42eb-a9dc-a13028690a3b\",null,null,[\"People standing near metallic ruins\",[1790099263,649996000],null,null,\"2c14fdf3-bb10-4603-bb76-ca483c23db87\",\"AABC7A39-2CBE-469B-B9DF-A97AAC85E9EC\",[1790099288,639522000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d6e35829-f7a1-43aa-b12c-7172309cf84c\",null,null,[\"Golden koi fish swimming\",[1790098617,113716000],true,null,\"a661bfc5-873f-4f71-862b-b76958cdda91\",\"47A1B759-7F96-4085-ADC3-5E648AD69AAE\",[1790103915,929616000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d7c54686-02ce-4344-ac22-2888ccf9c76e\",null,null,[\"HNTL_CHR_TIEN_2028_FACE_MASTER_v001_APPROVED\",[1784546032,956328000],null,null,\"6aa915c7-1123-4e12-b75f-6d5e6d40d0fe\",null,[1784546039,629998000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"f4d9c731-41f2-4b51-9dd2-edd20c1dc7f1\"],[\"d9102dd3-bb7b-4a6b-8135-90e9e3455f30\",null,null,[\"Heatwave apocalypse in Hanoi\",[1790104505,133221000],null,null,\"b5b2415a-b104-4e53-bf22-1bd940d2186b\",\"7310a95b-660a-402a-b3cd-58af71069ea2\",[1790104527,311732000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"da045c4a-d318-46ce-9d05-2b902878dc90\",null,null,[\"Abandoned vehicles at Hanoi inte…\",[1790104504,482062000],null,null,\"27cf3d47-aae9-4035-9324-32bb65509721\",\"ec0e0a52-b4dd-4102-a4e8-b468c857b069\",[1790104524,768009000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"e03db69f-0402-4e01-8d10-20a700e1d064\",null,null,[\"Cat sitting on wooden stool\",[1790098624,387715000],true,null,\"ffd129ac-2cb2-4c5d-a059-e37be9782118\",\"a72a8dac-99eb-4daa-8359-511e4239b0c8\",[1790103906,77570000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"e2367807-01e9-4bf4-a522-1f8549998e20\",null,null,[\"Modern shopping mall under red s…\",[1790099008,171508000],null,null,\"c38a6066-9d26-44da-8a14-8c7e260f7f8d\",\"2035D763-8320-4737-8083-E9AA31E42FF4\",[1790099030,317790000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"e516fce6-a049-4a7f-b414-5db3660b52fc\",null,null,[\"Man slumps against concrete pillar\",[1790174038,296806000],null,null,\"bdcbe55a-ee7b-497d-a414-25d22d04c096\",\"85FCAB29-DD00-4032-8AD2-15F7B36A484D\",[1790174057,857105000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"f69d66c7-9cd6-459d-a883-753390a8cb25\",null,null,[\"Woman standing in post-apocalypt…\",[1790106044,585720000],true,null,\"b6900ed9-ed42-4b6c-80c1-74db6fc6132d\",\"b2676050-a010-4f75-be4c-ee62a94baae3\",[1790106099,407867000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"fb28016d-5ed3-47b0-9a38-6f98eaa8b439\",null,null,[\"Crowd escaping heat trap\",[1790099243,507045000],null,null,\"ce812adb-5fef-42cb-9a38-97b2e1bac60b\",\"E1B67B78-288F-4B11-8704-AFA083A24D40\",[1790099265,47155000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"]],[[\"03bb0401-4b95-485b-906c-f5f8b0195547\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"3bd39545-26f0-4165-883c-528e119207fc\",\"CAE\",null,[[1790105718,172947000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaXm49Rdt0OZndhpTMPGANW864qQpmzS_pSUrYkrucaLudt-rN0ShHnS-M-QNIG-4Qz4sgOdUl3Xdmhii8QZ_8qjXlSyq-vwEbLdl7Y0ZoqpSGEwyjBPn2jf0upCg2b7KcOsuH3E-DIyv0v7YJnXWi3LulKmDegyPxS4tfzsg\",[null,null,[[\"Large breasts, subtly revealed.\",null,[[[\"ngực to, lộ một cách tinh tế\"]]]]],[[[null,2,\"6e6be6ca-d2c5-477c-b025-8ceac859aa54\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUaXm49Rdt0OZndhpTMPGANW864qQpmzS_pSUrYkrucaLudt-rN0ShHnS-M-QNIG-4Qz4sgOdUl3Xdmhii8QZ_8qjXlSyq-vwEbLdl7Y0ZoqpSGEwyjBPn2jf0upCg2b7KcOsuH3E-DIyv0v7YJnXWi3LulKmDegyPxS4tfzsg\"],[[null,1786455158,null,null,null,null,null,\"Large breasts, subtly revealed.\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUaXm49Rdt0OZndhpTMPGANW864qQpmzS_pSUrYkrucaLudt-rN0ShHnS-M-QNIG-4Qz4sgOdUl3Xdmhii8QZ_8qjXlSyq-vwEbLdl7Y0ZoqpSGEwyjBPn2jf0upCg2b7KcOsuH3E-DIyv0v7YJnXWi3LulKmDegyPxS4tfzsg\",3],null,[1376,768]]],[\"07f97f41-209d-458b-ad17-55606514eb6a\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAI\",null,[[1790105455,367014000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUY-2d81GEQpaR39zIjXEN0Qf5BJONrNE_elkcl7eS4oOY_qd5T8WxpFbwNOowomiZHprFvFxce8dHYOacQn-XE5qj-m_zL5h9gTeuAAw7zTU5Y80OEuwDM16UCPB9eQcCwu1GlRll_QEtosdSd_HSZ6k6iis1w7jUVzKrdFGQ\",[null,null,[[\"sexier\",null,[[[\"sexy hơn\"]]]]],[[[null,2,\"e0ca950b-db30-416a-b2d2-fe98a9bf1344\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUY-2d81GEQpaR39zIjXEN0Qf5BJONrNE_elkcl7eS4oOY_qd5T8WxpFbwNOowomiZHprFvFxce8dHYOacQn-XE5qj-m_zL5h9gTeuAAw7zTU5Y80OEuwDM16UCPB9eQcCwu1GlRll_QEtosdSd_HSZ6k6iis1w7jUVzKrdFGQ\",null,null,205489],[[null,1851291174,null,null,null,null,null,\"sexier\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUY-2d81GEQpaR39zIjXEN0Qf5BJONrNE_elkcl7eS4oOY_qd5T8WxpFbwNOowomiZHprFvFxce8dHYOacQn-XE5qj-m_zL5h9gTeuAAw7zTU5Y80OEuwDM16UCPB9eQcCwu1GlRll_QEtosdSd_HSZ6k6iis1w7jUVzKrdFGQ\",3],null,[1376,768]]],[\"1b832287-df4c-429a-b3b2-46d8f818d284\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"8a636ea0-c501-40c7-b8a3-74ebcb14ba74\",\"CAE\",null,[[1789492421,692307000],\"tạo video intro\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZE4T_NKjDNPXQs7RqIQ9p_8tFB4mf1_97DodcibQfzOWTgqgWPIlVw2rkG_10HP7LmxYCNI_NZH3JZb3CkZ4pNpySGBZG1oZRB7CRdGIj3u0Xcib07jGNzZFpdqLKCUBYNv_PXHIy-SFW56O3R3r790U3XfsvC1dgFuCSE\",[null,[[\"abra_t2v_10s\",1,null,null,1,1]],[[null,null,[[[\"tạo video intro\"]]]]],null,3],null,[3],1,\"https://lh3.googleusercontent.com/asb/AB-nOUZE4T_NKjDNPXQs7RqIQ9p_8tFB4mf1_97DodcibQfzOWTgqgWPIlVw2rkG_10HP7LmxYCNI_NZH3JZb3CkZ4pNpySGBZG1oZRB7CRdGIj3u0Xcib07jGNzZFpdqLKCUBYNv_PXHIy-SFW56O3R3r790U3XfsvC1dgFuCSE\",null,null,4851883],null,[[null,362440,null,null,null,null,null,\"create intro video\",\"https://lh3.googleusercontent.com/asb/AB-nOUZE4T_NKjDNPXQs7RqIQ9p_8tFB4mf1_97DodcibQfzOWTgqgWPIlVw2rkG_10HP7LmxYCNI_NZH3JZb3CkZ4pNpySGBZG1oZRB7CRdGIj3u0Xcib07jGNzZFpdqLKCUBYNv_PXHIy-SFW56O3R3r790U3XfsvC1dgFuCSE\",null,null,null,\"abra_t2v_10s\",\"\",null,false,1],[null,null,[10]],[\"1b832287-df4c-429a-b3b2-46d8f818d284\"]]],[\"1d72b8c7-7c9f-477c-bbf2-0f3a24cdc9a1\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"c3b02b33-da87-410c-88ce-c3896028c8a6\",\"CAE\",null,[[1790099923,331786000],\"0-3s: Elevated wide cinematic shot following the green metro train gliding on concrete viaducts. 3-6s: Camera cranes down toward dense streams of morning motorbike commuters on Nguyen Trai Avenue. 6-8s: Golden sunlight reflects brilliantly off modern glass skyscrapers under a blue sky. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZqIAmzmzMR_fmc351j70xfMg5cfzXWRb4LV5TceF0Cn_GHe5N0D5N6095ca207VHFVchQ3VclIyqZffsLTSsU3Ll2XmhUxXMllVI9XIj6QesNqFTh_iimSNkOx_WES37vQLZeEvaL7OnmtAsHl3m6AeRJmI1DZhFwjeXiuvQ\",[null,[[\"veo_3_1_i2v_lite\",2,[1],null,2,1],[[null,1,\"a029279b-cc59-465f-98d5-0fa8b78187ba\",[null,0.0038759689922481244,1,0.9961240310077519]]]],[[null,null,[[[\"0-3s: Elevated wide cinematic shot following the green metro train gliding on concrete viaducts. 3-6s: Camera cranes down toward dense streams of morning motorbike commuters on Nguyen Trai Avenue. 6-8s: Golden sunlight reflects brilliantly off modern glass skyscrapers under a blue sky. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\"]]]]],null,1],null,[3],1,\"https://lh3.googleusercontent.com/asb/AB-nOUZqIAmzmzMR_fmc351j70xfMg5cfzXWRb4LV5TceF0Cn_GHe5N0D5N6095ca207VHFVchQ3VclIyqZffsLTSsU3Ll2XmhUxXMllVI9XIj6QesNqFTh_iimSNkOx_WES37vQLZeEvaL7OnmtAsHl3m6AeRJmI1DZhFwjeXiuvQ\",null,null,7171738],null,[[null,916049,null,null,null,null,null,\"\\u003croot\\u003e\\n \\u003ccontext\\u003e\\n \\u003c/context\\u003e\\n \\u003cinstruction\\u003e\\n \\u003cprompt\\u003e0-3s: Elevated wide cinematic shot following the green metro train gliding on concrete viaducts. 3-6s: Camera cranes down toward dense streams of morning motorbike commuters on Nguyen Trai Avenue. 6-8s: Golden sunlight reflects brilliantly off modern glass skyscrapers under a blue sky. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\u003c/prompt\\u003e\\n \\u003c/instruction\\u003e\\n\\u003c/root\\u003e\",\"https://lh3.googleusercontent.com/asb/AB-nOUZqIAmzmzMR_fmc351j70xfMg5cfzXWRb4LV5TceF0Cn_GHe5N0D5N6095ca207VHFVchQ3VclIyqZffsLTSsU3Ll2XmhUxXMllVI9XIj6QesNqFTh_iimSNkOx_WES37vQLZeEvaL7OnmtAsHl3m6AeRJmI1DZhFwjeXiuvQ\",null,null,null,\"veo_3_1_i2v_lite\",\"\",null,false,2],[null,null,[8]],[\"1d72b8c7-7c9f-477c-bbf2-0f3a24cdc9a1\"]]],[\"1fa5e13c-e74f-45da-adc7-311e9e27c140\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"99a9b9fa-2091-4429-b192-476892fad1e8\",\"CAE\",null,[[1790104961,385705000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaXPOuTcr9v1Xh6abZRqn2Ql8xcTpW82xihiklrDHB8VhvQETdxL8CzVnM9FdQQqzonyyRegb8I8y7157a2asZfRJcj4tQHIcvoreX4HDwKESDAs8CRggLZawu_RjK81UwnVa6ySOYqcwXcmjMIqp1Pb1e-F1zRn35qU3s_\",[null,null,[[\"Grounded cinematic realism, a scenic mountain landscape in northern Vietnam near the border. Towering limestone karsts rise sharply from a parched, dusty valley under a harsh, scorching 2028 sun. Visible heat haze shimmers across the rugged terrain. Authentic northern Vietnamese vegetation, parched and withered. Near-future techno-thriller atmosphere, muted high-contrast color palette, subtle film grain, natural harsh lighting. No fantasy elements.\",null,[[[\"Grounded cinematic realism, a scenic mountain landscape in northern Vietnam near the border. Towering limestone karsts rise sharply from a parched, dusty valley under a harsh, scorching 2028 sun. Visible heat haze shimmers across the rugged terrain. Authentic northern Vietnamese vegetation, parched and withered. Near-future techno-thriller atmosphere, muted high-contrast color palette, subtle film grain, natural harsh lighting. No fantasy elements.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUaXPOuTcr9v1Xh6abZRqn2Ql8xcTpW82xihiklrDHB8VhvQETdxL8CzVnM9FdQQqzonyyRegb8I8y7157a2asZfRJcj4tQHIcvoreX4HDwKESDAs8CRggLZawu_RjK81UwnVa6ySOYqcwXcmjMIqp1Pb1e-F1zRn35qU3s_\",null,null,334094],[[null,567356,null,null,null,null,null,\"Grounded cinematic realism, a scenic mountain landscape in northern Vietnam near the border. Towering limestone karsts rise sharply from a parched, dusty valley under a harsh, scorching 2028 sun. Visible heat haze shimmers across the rugged terrain. Authentic northern Vietnamese vegetation, parched and withered. Near-future techno-thriller atmosphere, muted high-contrast color palette, subtle film grain, natural harsh lighting. No fantasy elements.\",25,\"\",null,\"99a9b9fa-2091-4429-b192-476892fad1e8\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUaXPOuTcr9v1Xh6abZRqn2Ql8xcTpW82xihiklrDHB8VhvQETdxL8CzVnM9FdQQqzonyyRegb8I8y7157a2asZfRJcj4tQHIcvoreX4HDwKESDAs8CRggLZawu_RjK81UwnVa6ySOYqcwXcmjMIqp1Pb1e-F1zRn35qU3s_\",3],null,[1376,768]]],[\"25704835-1c43-4c10-a718-9f77ab2e9cd6\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"482b99b0-f4ee-40f9-a31b-c4f76ddd2af7\",\"CAE\",null,[[1790174045,451631000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbv96PVxcN2PbifMQLbnfBljuWf4Xiu5nDiPGArpO0tyJYXHdrObt1q-0gOdtpRBQDoTJoVFo676vQBLUKK7WbuzryMkfcJSs9xB7ZWWKW8qfp2Nxu4OrbxkHjMCKlHYF_0t5UqhdHWoG3gINiTcdb13Wsssk-KF_FjORBFaQ\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\"]]]]],[[[null,1,\"78e46231-e6cf-43fb-99bc-a4cb96196e24\"],[null,1,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbv96PVxcN2PbifMQLbnfBljuWf4Xiu5nDiPGArpO0tyJYXHdrObt1q-0gOdtpRBQDoTJoVFo676vQBLUKK7WbuzryMkfcJSs9xB7ZWWKW8qfp2Nxu4OrbxkHjMCKlHYF_0t5UqhdHWoG3gINiTcdb13Wsssk-KF_FjORBFaQ\",null,null,194645],[[null,785346768,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\",25,\"\",null,\"482b99b0-f4ee-40f9-a31b-c4f76ddd2af7\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbv96PVxcN2PbifMQLbnfBljuWf4Xiu5nDiPGArpO0tyJYXHdrObt1q-0gOdtpRBQDoTJoVFo676vQBLUKK7WbuzryMkfcJSs9xB7ZWWKW8qfp2Nxu4OrbxkHjMCKlHYF_0t5UqhdHWoG3gINiTcdb13Wsssk-KF_FjORBFaQ\",3],null,[1376,768]]],[\"279b944e-5348-4ecc-91d4-f356b9271132\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAQ\",null,[[1790105556,47573000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZvnfLi4e_wIQIorBBWTJ68UhPPAGCGyMM1bGCslA4p0p3FPmZaErkcCJYOWZAU45AtW9O6ltyL0rvw2djSHFrWD5qQSNo0YvIoExryJLJri_WXrIastNeDraPmM1lNKPSF3KgOHu71rkSRSh_Dczg-c1R657r9-mQNa93KkQ\",[null,null,[[\"deep cut-out top, revealing cleavage\",null,[[[\"áo khoét sâu, lộ ngực\"]]]]],[[[null,2,\"cea6d7a9-29a2-4b36-aa89-60358b4998b5\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZvnfLi4e_wIQIorBBWTJ68UhPPAGCGyMM1bGCslA4p0p3FPmZaErkcCJYOWZAU45AtW9O6ltyL0rvw2djSHFrWD5qQSNo0YvIoExryJLJri_WXrIastNeDraPmM1lNKPSF3KgOHu71rkSRSh_Dczg-c1R657r9-mQNa93KkQ\",null,null,181343],[[null,2021215439,null,null,null,null,null,\"deep cut-out top, revealing cleavage\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZvnfLi4e_wIQIorBBWTJ68UhPPAGCGyMM1bGCslA4p0p3FPmZaErkcCJYOWZAU45AtW9O6ltyL0rvw2djSHFrWD5qQSNo0YvIoExryJLJri_WXrIastNeDraPmM1lNKPSF3KgOHu71rkSRSh_Dczg-c1R657r9-mQNa93KkQ\",3],null,[1376,768]]],[\"27cf3d47-aae9-4035-9324-32bb65509721\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"da045c4a-d318-46ce-9d05-2b902878dc90\",\"CAE\",null,[[1790104504,482062000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaFSHfD2PqGyT1oHU6O0EbyvRHBQu_z7dP3bo91wcegBn8L2viTM_ntW_NoGAq0eebQ8yYP2V-H_P4AsXf_55A1NCdBuJPm9nEi6JyjvG_OGCPVk4McB5eeTavReqR7FdSnH6SaY61Zueutr1LWVRHArV8DgqyHVX_3ZRkEMQ\",[null,null,[[\"A post-apocalyptic Hanoi intersection under a blistering, golden-hour sun that feels oppressive. The air is thick with dust and heat haze. Abandoned 2028 industrial equipment and vehicles sit on parched, sun-baked earth where a road once was. Authentic Vietnamese infrastructure, weathered and worn by extreme temperatures. Cinematic realism, high dynamic range, natural harsh lighting, restrained motion.\",null,[[[\"A post-apocalyptic Hanoi intersection under a blistering, golden-hour sun that feels oppressive. The air is thick with dust and heat haze. Abandoned 2028 industrial equipment and vehicles sit on parched, sun-baked earth where a road once was. Authentic Vietnamese infrastructure, weathered and worn by extreme temperatures. Cinematic realism, high dynamic range, natural harsh lighting, restrained motion.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUaFSHfD2PqGyT1oHU6O0EbyvRHBQu_z7dP3bo91wcegBn8L2viTM_ntW_NoGAq0eebQ8yYP2V-H_P4AsXf_55A1NCdBuJPm9nEi6JyjvG_OGCPVk4McB5eeTavReqR7FdSnH6SaY61Zueutr1LWVRHArV8DgqyHVX_3ZRkEMQ\",null,null,263504],[[null,92604,null,null,null,null,null,\"A post-apocalyptic Hanoi intersection under a blistering, golden-hour sun that feels oppressive. The air is thick with dust and heat haze. Abandoned 2028 industrial equipment and vehicles sit on parched, sun-baked earth where a road once was. Authentic Vietnamese infrastructure, weathered and worn by extreme temperatures. Cinematic realism, high dynamic range, natural harsh lighting, restrained motion.\",25,\"\",null,\"da045c4a-d318-46ce-9d05-2b902878dc90\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUaFSHfD2PqGyT1oHU6O0EbyvRHBQu_z7dP3bo91wcegBn8L2viTM_ntW_NoGAq0eebQ8yYP2V-H_P4AsXf_55A1NCdBuJPm9nEi6JyjvG_OGCPVk4McB5eeTavReqR7FdSnH6SaY61Zueutr1LWVRHArV8DgqyHVX_3ZRkEMQ\",3],null,[1376,768]]],[\"2c14fdf3-bb10-4603-bb76-ca483c23db87\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d5719db7-7c9a-42eb-a9dc-a13028690a3b\",\"CAE\",null,[[1790099263,649996000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYqNeb67_wZna9RODkkM_u9IGAIMApuPePBoUySVzv1CL88DZu91GdGX6ncOx5U93Kjx5ZunD20cJgcr6M6YUnE2PhN6IAYuvVSdNQKQccEtHXu2lFcFkLeJJR2svbQWzb4RiihDKCpJQ_gPZ-1ZJISs6lIw2Xvu7Ei7rufVA\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Epic cinematic wide shot of Dried West Lake Colossus in Hanoi under a dark apocalyptic red sun. Cracked black mud lakebed exposes colossal ancient dark metallic ribbed structures resembling giant dragon bones protruding from the earth. Tran Thanh Thuy and Do Minh Kha stand on the distant embankment silhouetted against the colossal metallic ruins and crimson haze. Masterpiece cinematic photography, 16:9 ultra-wide, atmospheric scale.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Epic cinematic wide shot of Dried West Lake Colossus in Hanoi under a dark apocalyptic red sun. Cracked black mud lakebed exposes colossal ancient dark metallic ribbed structures resembling giant dragon bones protruding from the earth. Tran Thanh Thuy and Do Minh Kha stand on the distant embankment silhouetted against the colossal metallic ruins and crimson haze. Masterpiece cinematic photography, 16:9 ultra-wide, atmospheric scale.\"]]]]],[[[null,1,\"65993027-0037-4f25-9fb7-7bd4d301ee7b\"],[null,1,\"78e46231-e6cf-43fb-99bc-a4cb96196e24\"],[null,1,\"9daace9a-a99c-4a5a-bce5-e9aaedcb1980\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYqNeb67_wZna9RODkkM_u9IGAIMApuPePBoUySVzv1CL88DZu91GdGX6ncOx5U93Kjx5ZunD20cJgcr6M6YUnE2PhN6IAYuvVSdNQKQccEtHXu2lFcFkLeJJR2svbQWzb4RiihDKCpJQ_gPZ-1ZJISs6lIw2Xvu7Ei7rufVA\",null,null,176367],[[null,434962038,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Epic cinematic wide shot of Dried West Lake Colossus in Hanoi under a dark apocalyptic red sun. Cracked black mud lakebed exposes colossal ancient dark metallic ribbed structures resembling giant dragon bones protruding from the earth. Tran Thanh Thuy and Do Minh Kha stand on the distant embankment silhouetted against the colossal metallic ruins and crimson haze. Masterpiece cinematic photography, 16:9 ultra-wide, atmospheric scale.\",25,\"\",null,\"d5719db7-7c9a-42eb-a9dc-a13028690a3b\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYqNeb67_wZna9RODkkM_u9IGAIMApuPePBoUySVzv1CL88DZu91GdGX6ncOx5U93Kjx5ZunD20cJgcr6M6YUnE2PhN6IAYuvVSdNQKQccEtHXu2lFcFkLeJJR2svbQWzb4RiihDKCpJQ_gPZ-1ZJISs6lIw2Xvu7Ei7rufVA\",3],null,[1376,768]]],[\"2e1227e3-7cb3-4213-8574-503bc667c75e\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAg\",null,[[1790105692,921386000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbmtaLvJBYFzG_Nu8SGXyCkpETTdaEe-GEQdQcMp6ZwhV0aup7aSHYh_yQZgOAFFIeivnJODySrIpprwMd1_VwH8racXWFZI7_sHEgex2j0TlCMr6upaH5hmazd5AjtL_JTn2dAR4NTD8WmRxiiwg31GI2Px3pPZQ1BoHnpyw\",[null,null,[[\"Large breasts, subtly revealed.\",null,[[[\"ngực to, lộ một cách tinh tế\"]]]]],[[[null,2,\"6e6be6ca-d2c5-477c-b025-8ceac859aa54\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbmtaLvJBYFzG_Nu8SGXyCkpETTdaEe-GEQdQcMp6ZwhV0aup7aSHYh_yQZgOAFFIeivnJODySrIpprwMd1_VwH8racXWFZI7_sHEgex2j0TlCMr6upaH5hmazd5AjtL_JTn2dAR4NTD8WmRxiiwg31GI2Px3pPZQ1BoHnpyw\",null,null,180851],[[null,1786455158,null,null,null,null,null,\"Large breasts, subtly revealed.\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbmtaLvJBYFzG_Nu8SGXyCkpETTdaEe-GEQdQcMp6ZwhV0aup7aSHYh_yQZgOAFFIeivnJODySrIpprwMd1_VwH8racXWFZI7_sHEgex2j0TlCMr6upaH5hmazd5AjtL_JTn2dAR4NTD8WmRxiiwg31GI2Px3pPZQ1BoHnpyw\",3],null,[1376,768]]],[\"30b5f32e-3918-4b68-acf8-7f7b0afafd0d\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"9e8ede1b-4f8f-4354-aecb-a7759421bf13\",\"CAE\",null,[[1790099253,589865000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUalNn_NTUPRfEuX9bDo48haCw-YN8O0Sswn60OUCB8dMrwu1yeFAx3Cnj7659Olp76dD9_IrOClicqzqKt7N0wH4Zz1tGyQYc9I9Uu7EQy4bZpcwkPEXYU3fQ3-u6CW8eVS5Ix8h_J2Zq697efFTosxZWK0d-aBd1q415_TYQ\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Atmospheric cinematic shot inside Ngoc Truc Warehouse. Le Quoc Tien shines a flashlight onto a heavy dark metal hatch embedded in the concrete floor. The circular sun emblem with twelve rays on the hatch glows with an ominous deep red bioluminescent light. Dense cold vapor rising from the metallic seams. 35mm cinematic photograph, moody volumetric shadows.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Atmospheric cinematic shot inside Ngoc Truc Warehouse. Le Quoc Tien shines a flashlight onto a heavy dark metal hatch embedded in the concrete floor. The circular sun emblem with twelve rays on the hatch glows with an ominous deep red bioluminescent light. Dense cold vapor rising from the metallic seams. 35mm cinematic photograph, moody volumetric shadows.\"]]]]],[[[null,1,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\"],[null,1,\"5a919b50-566c-4cfb-97b6-4e481650dc0a\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUalNn_NTUPRfEuX9bDo48haCw-YN8O0Sswn60OUCB8dMrwu1yeFAx3Cnj7659Olp76dD9_IrOClicqzqKt7N0wH4Zz1tGyQYc9I9Uu7EQy4bZpcwkPEXYU3fQ3-u6CW8eVS5Ix8h_J2Zq697efFTosxZWK0d-aBd1q415_TYQ\",null,null,222634],[[null,91251415,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Atmospheric cinematic shot inside Ngoc Truc Warehouse. Le Quoc Tien shines a flashlight onto a heavy dark metal hatch embedded in the concrete floor. The circular sun emblem with twelve rays on the hatch glows with an ominous deep red bioluminescent light. Dense cold vapor rising from the metallic seams. 35mm cinematic photograph, moody volumetric shadows.\",25,\"\",null,\"9e8ede1b-4f8f-4354-aecb-a7759421bf13\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUalNn_NTUPRfEuX9bDo48haCw-YN8O0Sswn60OUCB8dMrwu1yeFAx3Cnj7659Olp76dD9_IrOClicqzqKt7N0wH4Zz1tGyQYc9I9Uu7EQy4bZpcwkPEXYU3fQ3-u6CW8eVS5Ix8h_J2Zq697efFTosxZWK0d-aBd1q415_TYQ\",3],null,[1376,768]]],[\"310d92fb-dd8e-4e33-b061-4750fcbeeeaa\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"ad778284-c548-4428-9386-24491b893682\",\"CAE\",null,[[1790098625,39575000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUa_gg6Ycay8_6RD99svCFCHJYSmlGmV8rQw6rG5cSWSwG7uND9QTQa1Ehcv6ZyyJTetHv_LnKZyDs_NcAa1OoH-AuPdDUnRcXBtHFNiBESXr2Kq-n1shgnzI2s11MABmqWSQmKnrTqIyG_3EvOJvhMRAFhWn0kDrLllaK0rdA\",[null,null,[[\"Close-up of a cute, fluffy cat peering through a rainy window overlooking a busy Hanoi street at dusk. Grounded cinematic realism, natural skin and fur texture, physically believable rain droplets on glass. Near-future techno-thriller mood, muted color palette, high dynamic range.\",null,[[[\"Close-up of a cute, fluffy cat peering through a rainy window overlooking a busy Hanoi street at dusk. Grounded cinematic realism, natural skin and fur texture, physically believable rain droplets on glass. Near-future techno-thriller mood, muted color palette, high dynamic range.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUa_gg6Ycay8_6RD99svCFCHJYSmlGmV8rQw6rG5cSWSwG7uND9QTQa1Ehcv6ZyyJTetHv_LnKZyDs_NcAa1OoH-AuPdDUnRcXBtHFNiBESXr2Kq-n1shgnzI2s11MABmqWSQmKnrTqIyG_3EvOJvhMRAFhWn0kDrLllaK0rdA\",null,null,296927],[[null,132288,null,null,null,null,null,\"Close-up of a cute, fluffy cat peering through a rainy window overlooking a busy Hanoi street at dusk. Grounded cinematic realism, natural skin and fur texture, physically believable rain droplets on glass. Near-future techno-thriller mood, muted color palette, high dynamic range.\",25,\"\",null,\"ad778284-c548-4428-9386-24491b893682\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUa_gg6Ycay8_6RD99svCFCHJYSmlGmV8rQw6rG5cSWSwG7uND9QTQa1Ehcv6ZyyJTetHv_LnKZyDs_NcAa1OoH-AuPdDUnRcXBtHFNiBESXr2Kq-n1shgnzI2s11MABmqWSQmKnrTqIyG_3EvOJvhMRAFhWn0kDrLllaK0rdA\",3],null,[1376,768]]],[\"3d1052dd-2332-48f6-81c3-73adb6d4ff09\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"337d7d27-bc09-4ca1-9f11-1b9253d15cbb\",\"CAE\",null,[[1790104423,640950000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUY6KFmaKl70oB4q2qP1ELQeDAA8KXk9MyYhaeYv76CDntBP943rdON5zdngOz1at2IiBnKsjqI7820q-FrpHiUnR5-Ub9vrGSqaQMYxLtCYvPgV-0tpDcgftURMYtur9WCj3PDKwtSd3pASvjZk6Ta3QiPOcSLaJKKq1d5JPQ\",[null,null,[[\"Grounded cinematic realism, post-apocalyptic Hanoi in 2028. An overgrown, crumbling Long Bien Bridge spans the Red River under a heavy, ash-colored sky. Distant skeletal skyscrapers of the city are shrouded in thick mist. The scene is quiet, devoid of life, featuring authentic Vietnamese architecture and infrastructure. Muted color palette, subtle film grain, physically believable heat haze. No generic cyberpunk neon or glowing holograms.\",null,[[[\"Grounded cinematic realism, post-apocalyptic Hanoi in 2028. An overgrown, crumbling Long Bien Bridge spans the Red River under a heavy, ash-colored sky. Distant skeletal skyscrapers of the city are shrouded in thick mist. The scene is quiet, devoid of life, featuring authentic Vietnamese architecture and infrastructure. Muted color palette, subtle film grain, physically believable heat haze. No generic cyberpunk neon or glowing holograms.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUY6KFmaKl70oB4q2qP1ELQeDAA8KXk9MyYhaeYv76CDntBP943rdON5zdngOz1at2IiBnKsjqI7820q-FrpHiUnR5-Ub9vrGSqaQMYxLtCYvPgV-0tpDcgftURMYtur9WCj3PDKwtSd3pASvjZk6Ta3QiPOcSLaJKKq1d5JPQ\",null,null,210059],[[null,14483,null,null,null,null,null,\"Grounded cinematic realism, post-apocalyptic Hanoi in 2028. An overgrown, crumbling Long Bien Bridge spans the Red River under a heavy, ash-colored sky. Distant skeletal skyscrapers of the city are shrouded in thick mist. The scene is quiet, devoid of life, featuring authentic Vietnamese architecture and infrastructure. Muted color palette, subtle film grain, physically believable heat haze. No generic cyberpunk neon or glowing holograms.\",25,\"\",null,\"337d7d27-bc09-4ca1-9f11-1b9253d15cbb\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUY6KFmaKl70oB4q2qP1ELQeDAA8KXk9MyYhaeYv76CDntBP943rdON5zdngOz1at2IiBnKsjqI7820q-FrpHiUnR5-Ub9vrGSqaQMYxLtCYvPgV-0tpDcgftURMYtur9WCj3PDKwtSd3pASvjZk6Ta3QiPOcSLaJKKq1d5JPQ\",3],null,[1376,768]]],[\"41627dd9-5c3f-427f-845c-d83fc277b5e9\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",\"CAU\",null,[[1790173506,107885000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYFcUMTsOE6AhppE7lm8Km-427PJN-lzcsRm9dXuzxq_Oz2csumv9AW2j7tWm26WKmuyj0EcwC1p66xonLxbGvi_eMfuNxdJ3MGkOzXrVF98hzfJgvKPgbio2koOurKIkqXyyX13neV96slX51nSH_SEU_b9bWQ4Q8T2vS2uQ\",[null,null,[[\"A dramatic cinematic shot of a young man in subterranean B3 basement parking at Me Tri under extreme heat, 35mm RAW photograph\",null,[[[\"A dramatic cinematic shot of a young man in subterranean B3 basement parking at Me Tri under extreme heat, 35mm RAW photograph\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYFcUMTsOE6AhppE7lm8Km-427PJN-lzcsRm9dXuzxq_Oz2csumv9AW2j7tWm26WKmuyj0EcwC1p66xonLxbGvi_eMfuNxdJ3MGkOzXrVF98hzfJgvKPgbio2koOurKIkqXyyX13neV96slX51nSH_SEU_b9bWQ4Q8T2vS2uQ\",null,null,135878],[[null,981155251,null,null,null,null,null,\"A dramatic cinematic shot of a young man in subterranean B3 basement parking at Me Tri under extreme heat, 35mm RAW photograph\",25,\"\",null,\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYFcUMTsOE6AhppE7lm8Km-427PJN-lzcsRm9dXuzxq_Oz2csumv9AW2j7tWm26WKmuyj0EcwC1p66xonLxbGvi_eMfuNxdJ3MGkOzXrVF98hzfJgvKPgbio2koOurKIkqXyyX13neV96slX51nSH_SEU_b9bWQ4Q8T2vS2uQ\",3],null,[1376,768]]],[\"4630aeab-cd27-4457-96b6-24045de2504e\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"c7fee095-6829-4801-94c8-3eb9bcaf060f\",\"CAE\",null,[[1785255350,725479000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYvD5DO21C7peFe1MSdZ6wqPFz5qUEGBLbNmQua_4kKt72r5w1J1pTtaEVZkZHRJuymy5QmAZbcuUlPtLKMfNspIFve3bv0wBudRZKXFkpzeNWXjBaLce4BsfYKnfBjOL39eT2dqSe0O-omDru0BPOWjUKobLnXTNFht_Mo\",[null,null,null,null,1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYvD5DO21C7peFe1MSdZ6wqPFz5qUEGBLbNmQua_4kKt72r5w1J1pTtaEVZkZHRJuymy5QmAZbcuUlPtLKMfNspIFve3bv0wBudRZKXFkpzeNWXjBaLce4BsfYKnfBjOL39eT2dqSe0O-omDru0BPOWjUKobLnXTNFht_Mo\",null,null,521906],[null,[null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYvD5DO21C7peFe1MSdZ6wqPFz5qUEGBLbNmQua_4kKt72r5w1J1pTtaEVZkZHRJuymy5QmAZbcuUlPtLKMfNspIFve3bv0wBudRZKXFkpzeNWXjBaLce4BsfYKnfBjOL39eT2dqSe0O-omDru0BPOWjUKobLnXTNFht_Mo\",0],[1448,1086]]],[\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"9c487a71-fc76-4e0e-bdc3-98eee2bc25da\",\"CAE\",null,[[1790099223,430583000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUba9TAxJHa3p4QWzvlYmJ5i7dpuV6jEiNtC564dOPzPAw7dW9NGpUqfzrn_6Ivz6G4P_bL5YXozCmEzILHaVB1zttr6ECAC07TOmehktY-El0n-bkrD_5vuWlUntB7Txd6R0cYh8IDxUttuP1KdAXF_hs2zzKOeNt2LghGpUA\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Cinematic close-up of Le Quoc Tien jolting awake in bed, eyes wide with intense shock and cold sweat on his face. In background, a desktop setup with multiple glowing monitors and a digital clock displaying 07:13 AM. Soft morning golden sunlight streaming through half-open blinds. Photorealistic RAW photograph, Canon EOS R5, shallow depth of field.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Cinematic close-up of Le Quoc Tien jolting awake in bed, eyes wide with intense shock and cold sweat on his face. In background, a desktop setup with multiple glowing monitors and a digital clock displaying 07:13 AM. Soft morning golden sunlight streaming through half-open blinds. Photorealistic RAW photograph, Canon EOS R5, shallow depth of field.\"]]]]],[[[null,1,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUba9TAxJHa3p4QWzvlYmJ5i7dpuV6jEiNtC564dOPzPAw7dW9NGpUqfzrn_6Ivz6G4P_bL5YXozCmEzILHaVB1zttr6ECAC07TOmehktY-El0n-bkrD_5vuWlUntB7Txd6R0cYh8IDxUttuP1KdAXF_hs2zzKOeNt2LghGpUA\",null,null,122156],[[null,658411800,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Cinematic close-up of Le Quoc Tien jolting awake in bed, eyes wide with intense shock and cold sweat on his face. In background, a desktop setup with multiple glowing monitors and a digital clock displaying 07:13 AM. Soft morning golden sunlight streaming through half-open blinds. Photorealistic RAW photograph, Canon EOS R5, shallow depth of field.\",25,\"\",null,\"9c487a71-fc76-4e0e-bdc3-98eee2bc25da\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUba9TAxJHa3p4QWzvlYmJ5i7dpuV6jEiNtC564dOPzPAw7dW9NGpUqfzrn_6Ivz6G4P_bL5YXozCmEzILHaVB1zttr6ECAC07TOmehktY-El0n-bkrD_5vuWlUntB7Txd6R0cYh8IDxUttuP1KdAXF_hs2zzKOeNt2LghGpUA\",3],null,[1376,768]]],[\"567984bd-c3ff-46de-ad25-353be60e6188\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",\"CAQ\",null,[[1790106174,785955000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUY3VK7qOJVbMaIhPKY_538QExrPFVsUwang-UkP9AxM4VJ0zZqmSIQrj94nZEGslM812hnfTt7kaMwBDwxw-zuRAcwNIB56Ar5VZvOZSt6vshgGNvwiLFL86HzoaNBeqnjCV2Vrtq6EHz3TM6xejHsV95G-JZI5XnUdnX7WEg\",[null,null,[[\"\\\"Front-facing person, posing, sensual face\\\"\",null,[[[\"quy người chính diện, tạo dáng , khuôn mặt gợi cảm\"]]]]],[[[null,2,\"b4d91c90-5b01-4472-aab2-1bcacb892fa4\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUY3VK7qOJVbMaIhPKY_538QExrPFVsUwang-UkP9AxM4VJ0zZqmSIQrj94nZEGslM812hnfTt7kaMwBDwxw-zuRAcwNIB56Ar5VZvOZSt6vshgGNvwiLFL86HzoaNBeqnjCV2Vrtq6EHz3TM6xejHsV95G-JZI5XnUdnX7WEg\",null,null,119798],[[null,1871434922,null,null,null,null,null,\"\\\"Front-facing person, posing, sensual face\\\"\",25,\"\",null,\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUY3VK7qOJVbMaIhPKY_538QExrPFVsUwang-UkP9AxM4VJ0zZqmSIQrj94nZEGslM812hnfTt7kaMwBDwxw-zuRAcwNIB56Ar5VZvOZSt6vshgGNvwiLFL86HzoaNBeqnjCV2Vrtq6EHz3TM6xejHsV95G-JZI5XnUdnX7WEg\",3],null,[1376,768]]],[\"5a919b50-566c-4cfb-97b6-4e481650dc0a\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"b84f96ab-d2b2-414b-b4ed-912a9e3e2859\",\"CAE\",null,[[1790099018,2158000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbwQe77Y4OkTtNco2H0sStQ2-qp7379h4bZeORSYvXZ-589lAjp7xPmFYzHFU1vG90yU_ywYBY5mO31QkaIeR3nixA7xpN2X20jzDi-VLeGn4-WvG4lHkMtVu1SDjQHnbwmluL1DkulB8QpEx7KDLTaQTsuVVKGTZmN7ZCu\",[null,null,[[\"Single reference image of Secluded industrial concrete warehouse on Hanoi outskirts, weathered corrugated metal roof, dusty grey concrete floor with faint cracks, heavy circular dark metal floor hatch with an etched twelve-ray sun emblem hidden beneath metal shelving. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of Secluded industrial concrete warehouse on Hanoi outskirts, weathered corrugated metal roof, dusty grey concrete floor with faint cracks, heavy circular dark metal floor hatch with an etched twelve-ray sun emblem hidden beneath metal shelving. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbwQe77Y4OkTtNco2H0sStQ2-qp7379h4bZeORSYvXZ-589lAjp7xPmFYzHFU1vG90yU_ywYBY5mO31QkaIeR3nixA7xpN2X20jzDi-VLeGn4-WvG4lHkMtVu1SDjQHnbwmluL1DkulB8QpEx7KDLTaQTsuVVKGTZmN7ZCu\",null,null,175386],[[null,288261536,null,null,null,null,null,\"Single reference image of Secluded industrial concrete warehouse on Hanoi outskirts, weathered corrugated metal roof, dusty grey concrete floor with faint cracks, heavy circular dark metal floor hatch with an etched twelve-ray sun emblem hidden beneath metal shelving. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"b84f96ab-d2b2-414b-b4ed-912a9e3e2859\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbwQe77Y4OkTtNco2H0sStQ2-qp7379h4bZeORSYvXZ-589lAjp7xPmFYzHFU1vG90yU_ywYBY5mO31QkaIeR3nixA7xpN2X20jzDi-VLeGn4-WvG4lHkMtVu1SDjQHnbwmluL1DkulB8QpEx7KDLTaQTsuVVKGTZmN7ZCu\",3],null,[1376,768]]],[\"65993027-0037-4f25-9fb7-7bd4d301ee7b\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"87cfaa04-a192-405e-aa3b-137fa3d20ccb\",\"CAE\",null,[[1790098988,593315000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYuW_MBkm_rvBXuqLf9k9WJJNEP4pGgLOd-2Jqy0aTRKvG65KC4qe8iDn4enPIs9r4yCr_21dXJQBparb-V7KAeIvF5wNzz3-SnX9PX1KZ7hrQhzwo-pBD3coVHYYvCoqLjMy1IFs_fBWo8e_GTg2Iyb9o6dypoboRnDId8jA\",[null,null,[[\"Single reference image of 27-year-old Vietnamese investigative journalist, smart analytical expression, hair tied back in a neat ponytail, wearing a light beige utility shirt, olive multi-pocket reporter vest, canvas shoulder bag carrying a compact camera, intelligent perceptive dark eyes. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of 27-year-old Vietnamese investigative journalist, smart analytical expression, hair tied back in a neat ponytail, wearing a light beige utility shirt, olive multi-pocket reporter vest, canvas shoulder bag carrying a compact camera, intelligent perceptive dark eyes. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYuW_MBkm_rvBXuqLf9k9WJJNEP4pGgLOd-2Jqy0aTRKvG65KC4qe8iDn4enPIs9r4yCr_21dXJQBparb-V7KAeIvF5wNzz3-SnX9PX1KZ7hrQhzwo-pBD3coVHYYvCoqLjMy1IFs_fBWo8e_GTg2Iyb9o6dypoboRnDId8jA\",null,null,138007],[[null,998613419,null,null,null,null,null,\"Single reference image of 27-year-old Vietnamese investigative journalist, smart analytical expression, hair tied back in a neat ponytail, wearing a light beige utility shirt, olive multi-pocket reporter vest, canvas shoulder bag carrying a compact camera, intelligent perceptive dark eyes. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"87cfaa04-a192-405e-aa3b-137fa3d20ccb\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYuW_MBkm_rvBXuqLf9k9WJJNEP4pGgLOd-2Jqy0aTRKvG65KC4qe8iDn4enPIs9r4yCr_21dXJQBparb-V7KAeIvF5wNzz3-SnX9PX1KZ7hrQhzwo-pBD3coVHYYvCoqLjMy1IFs_fBWo8e_GTg2Iyb9o6dypoboRnDId8jA\",2],null,[768,1376]]],[\"666bc47c-1fa1-4167-83cc-3088840b3146\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d19f6811-455b-4838-bdc2-b908aeb7bd36\",\"CAE\",null,[[1790169824,340307000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbpaVpfKL6IfiRICiDfApjUpVXD_I6HbglLUIxQbvzERuEEQErKZyuIkr9BWioME_zJXXY3Ot16fKfEw5YoALNDuctrP6QFnojDlP16MlfiJR2OObhXloM4hGy7Qi8x2C8XZpNwApq_plSPJXSAZjcsavE6mbTYYlSRQxiaMQ\",[null,null,[[\"Grounded cinematic realism, an older Vietnamese male character in post-apocalyptic Hanoi 2028. He has rugged, weathered features, short grey hair, and intense eyes. He is wearing a practical, sweat-stained industrial worker's jumpsuit with tech-utility pouches. Natural skin texture, visible sweat and grime from the extreme heatwave. He stands in a dim, cluttered workshop filled with high-tech salvage. Near-future techno-thriller style, restrained acting, subtle film grain, natural lighting, high dynamic range. No fantasy spectacle.\",null,[[[\"Grounded cinematic realism, an older Vietnamese male character in post-apocalyptic Hanoi 2028. He has rugged, weathered features, short grey hair, and intense eyes. He is wearing a practical, sweat-stained industrial worker's jumpsuit with tech-utility pouches. Natural skin texture, visible sweat and grime from the extreme heatwave. He stands in a dim, cluttered workshop filled with high-tech salvage. Near-future techno-thriller style, restrained acting, subtle film grain, natural lighting, high dynamic range. No fantasy spectacle.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbpaVpfKL6IfiRICiDfApjUpVXD_I6HbglLUIxQbvzERuEEQErKZyuIkr9BWioME_zJXXY3Ot16fKfEw5YoALNDuctrP6QFnojDlP16MlfiJR2OObhXloM4hGy7Qi8x2C8XZpNwApq_plSPJXSAZjcsavE6mbTYYlSRQxiaMQ\",null,null,169345],[[null,707997,null,null,null,null,null,\"Grounded cinematic realism, an older Vietnamese male character in post-apocalyptic Hanoi 2028. He has rugged, weathered features, short grey hair, and intense eyes. He is wearing a practical, sweat-stained industrial worker's jumpsuit with tech-utility pouches. Natural skin texture, visible sweat and grime from the extreme heatwave. He stands in a dim, cluttered workshop filled with high-tech salvage. Near-future techno-thriller style, restrained acting, subtle film grain, natural lighting, high dynamic range. No fantasy spectacle.\",25,\"\",null,\"d19f6811-455b-4838-bdc2-b908aeb7bd36\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbpaVpfKL6IfiRICiDfApjUpVXD_I6HbglLUIxQbvzERuEEQErKZyuIkr9BWioME_zJXXY3Ot16fKfEw5YoALNDuctrP6QFnojDlP16MlfiJR2OObhXloM4hGy7Qi8x2C8XZpNwApq_plSPJXSAZjcsavE6mbTYYlSRQxiaMQ\",3],null,[1376,768]]],[\"684e27a9-a16c-480e-95ce-8cb540798659\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"3ab07549-ccbb-410a-a97d-08b8a4627f84\",\"CAE\",null,[[1784546411,930438000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUb_QujW3NDPoer97t_RbrFOtFLtMDC-jX49qb8CXY7dI1IdXHvhFoyk9WtQaUZunQm2XyQK2Wrx530dtfCNPv_b9m3ppqNaiXcDBB5HN7COGvoIBa_CPqKx98-KEOw_9SSP_KMjpOSvSP2krJY_RL6kv-KFBwuk06SqhiGOPg\",[null,null,[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",null,[[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\"]]]]],[null,[[\"f4d9c731-41f2-4b51-9dd2-edd20c1dc7f1\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUb_QujW3NDPoer97t_RbrFOtFLtMDC-jX49qb8CXY7dI1IdXHvhFoyk9WtQaUZunQm2XyQK2Wrx530dtfCNPv_b9m3ppqNaiXcDBB5HN7COGvoIBa_CPqKx98-KEOw_9SSP_KMjpOSvSP2krJY_RL6kv-KFBwuk06SqhiGOPg\",null,null,614197],[[null,922697,\"CAMSJDU5NDc1OGNjLTExZjUtNGY5Mi04YjNjLTEyMTM2ODY1OTFmNBokMTQ5NmMyYWUtNTAyNy00NGQ0LWE2M2UtM2VmM2MxNzYzZTI0IgNDQUUqJDY4NGUyN2E5LWExNmMtNDgwZS05NWNlLThjYjU0MDc5ODY1OQ\",null,null,null,null,\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",25,\"\",null,\"3ab07549-ccbb-410a-a97d-08b8a4627f84\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUb_QujW3NDPoer97t_RbrFOtFLtMDC-jX49qb8CXY7dI1IdXHvhFoyk9WtQaUZunQm2XyQK2Wrx530dtfCNPv_b9m3ppqNaiXcDBB5HN7COGvoIBa_CPqKx98-KEOw_9SSP_KMjpOSvSP2krJY_RL6kv-KFBwuk06SqhiGOPg\",3],null,[1376,768]]],[\"6aa915c7-1123-4e12-b75f-6d5e6d40d0fe\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d7c54686-02ce-4344-ac22-2888ccf9c76e\",\"CAE\",null,[[1784546032,956328000],\"Man in black shirt and pants\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUa0Hu8CuBjBs_H1OHD0zbJ6ZyQhx1Hx0z1fdSfPWo778yvuntmjnGeBneX5oRmxo12rL4ebKQlklWgX6TmVuwqp8rBlNdWXHAkIDSKkyqIO38lMbR9EsRrp1fydpam1-1EGOvRRDEA4ds17HnIBQ-iIpCzpHEfOq_-YjCmO4A\",[null,null,null,null,1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUa0Hu8CuBjBs_H1OHD0zbJ6ZyQhx1Hx0z1fdSfPWo778yvuntmjnGeBneX5oRmxo12rL4ebKQlklWgX6TmVuwqp8rBlNdWXHAkIDSKkyqIO38lMbR9EsRrp1fydpam1-1EGOvRRDEA4ds17HnIBQ-iIpCzpHEfOq_-YjCmO4A\",null,\"A man with short dark hair stands against a plain gray background, shown from multiple angles. He wears a black button-up shirt over a dark t-shirt, dark cargo pants, and a crossbody bag. He has a watch on his left wrist.\"],[null,[null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUa0Hu8CuBjBs_H1OHD0zbJ6ZyQhx1Hx0z1fdSfPWo778yvuntmjnGeBneX5oRmxo12rL4ebKQlklWgX6TmVuwqp8rBlNdWXHAkIDSKkyqIO38lMbR9EsRrp1fydpam1-1EGOvRRDEA4ds17HnIBQ-iIpCzpHEfOq_-YjCmO4A\",0],[1376,768]]],[\"6e6be6ca-d2c5-477c-b025-8ceac859aa54\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAU\",null,[[1790105600,764469000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZ5hXeejQlQWInv3-Nk6t2Os8Ny-BBsbgmhlE9LmsbSyiPXjGPU9Eenh2ayA97QstKkBFb3OVzZBoiEyffvhPkMOTUIijGjPNYm-pYc8mtJAu39C3mO8ivKlsXdSiopxKxiTDsQPdEMQRRT-ieg1Nv6VgX92UoHk7ralpuQ\",[null,null,[[\"two-piece outfit, camisole, many torn spots\",null,[[[\"áo 2 mảnh , 2 dây, có nhiều vết rách\"]]]]],[[[null,2,\"279b944e-5348-4ecc-91d4-f356b9271132\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZ5hXeejQlQWInv3-Nk6t2Os8Ny-BBsbgmhlE9LmsbSyiPXjGPU9Eenh2ayA97QstKkBFb3OVzZBoiEyffvhPkMOTUIijGjPNYm-pYc8mtJAu39C3mO8ivKlsXdSiopxKxiTDsQPdEMQRRT-ieg1Nv6VgX92UoHk7ralpuQ\",null,null,181689],[[null,166472867,null,null,null,null,null,\"two-piece outfit, camisole, many torn spots\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZ5hXeejQlQWInv3-Nk6t2Os8Ny-BBsbgmhlE9LmsbSyiPXjGPU9Eenh2ayA97QstKkBFb3OVzZBoiEyffvhPkMOTUIijGjPNYm-pYc8mtJAu39C3mO8ivKlsXdSiopxKxiTDsQPdEMQRRT-ieg1Nv6VgX92UoHk7ralpuQ\",3],null,[1376,768]]],[\"732c7e1a-7267-462f-8f58-1bf43694428e\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"be5c73e8-269a-4fdf-a1a5-d2265179a8be\",\"CAE\",null,[[1784546459,807750000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUb5ap5IbDPwWp5-DGrbazcb9T_G-aOu9nN3g7ib3dMMRXskaJ6jaihFAztr4lIRjSOFZCDgBhfGvvkmqUxqXxUdQtNNnARmrm5vl4Q9vWVTtVHAKPxZGJfphs0xlOYhLL6xrDPIkT3b-1dd0mapyQ-nFne_v6Vmi_MEQZgtFg\",[null,null,[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",null,[[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\"]]]]],[null,[[\"f4d9c731-41f2-4b51-9dd2-edd20c1dc7f1\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUb5ap5IbDPwWp5-DGrbazcb9T_G-aOu9nN3g7ib3dMMRXskaJ6jaihFAztr4lIRjSOFZCDgBhfGvvkmqUxqXxUdQtNNnARmrm5vl4Q9vWVTtVHAKPxZGJfphs0xlOYhLL6xrDPIkT3b-1dd0mapyQ-nFne_v6Vmi_MEQZgtFg\",null,null,655260],[[null,599389,\"CAMSJDU5NDc1OGNjLTExZjUtNGY5Mi04YjNjLTEyMTM2ODY1OTFmNBokMTMyMDVkOTQtYTQ2Mi00MjE5LWI5MjQtMzdhNjFiNjY2MzIxIgNDQUUqJDczMmM3ZTFhLTcyNjctNDYyZi04ZjU4LTFiZjQzNjk0NDI4ZQ\",null,null,null,null,\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",25,\"\",null,\"be5c73e8-269a-4fdf-a1a5-d2265179a8be\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUb5ap5IbDPwWp5-DGrbazcb9T_G-aOu9nN3g7ib3dMMRXskaJ6jaihFAztr4lIRjSOFZCDgBhfGvvkmqUxqXxUdQtNNnARmrm5vl4Q9vWVTtVHAKPxZGJfphs0xlOYhLL6xrDPIkT3b-1dd0mapyQ-nFne_v6Vmi_MEQZgtFg\",3],null,[1376,768]]],[\"76a03ec4-6340-4e25-9e8a-5009942893b9\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"a5fbb9e9-b0d0-48f4-89ea-277444ec27c4\",\"CAE\",null,[[1790104424,188616000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZyRbtbzcGUezd3ygh-aozo8PeVAlRLEKABEn0N0fDPqLBG5uL0xC4YycYgSDi9TOTperhgoMI6GJWmGv5QXTmlsA4TzK1yYdOeJF_5xxGj9U8Oh-g93r_A9laQ7LC1RvLfh8nVouNkPZlw5DiPSkCNehYo6N1bwxkx1ZXd_A\",[null,null,[[\"A deserted, dust-covered street in Hanoi's Old Quarter after a near-future catastrophe. Abandoned 2028-style electric scooters are half-buried in debris and overgrown vines. Tall, narrow buildings show signs of structural decay under a dim, overcast sun. Grounded live-action aesthetic, cinematic realism, authentic Vietnamese everyday objects. Darker, atmospheric lighting with high dynamic range.\",null,[[[\"A deserted, dust-covered street in Hanoi's Old Quarter after a near-future catastrophe. Abandoned 2028-style electric scooters are half-buried in debris and overgrown vines. Tall, narrow buildings show signs of structural decay under a dim, overcast sun. Grounded live-action aesthetic, cinematic realism, authentic Vietnamese everyday objects. Darker, atmospheric lighting with high dynamic range.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZyRbtbzcGUezd3ygh-aozo8PeVAlRLEKABEn0N0fDPqLBG5uL0xC4YycYgSDi9TOTperhgoMI6GJWmGv5QXTmlsA4TzK1yYdOeJF_5xxGj9U8Oh-g93r_A9laQ7LC1RvLfh8nVouNkPZlw5DiPSkCNehYo6N1bwxkx1ZXd_A\",null,null,281615],[[null,755263,null,null,null,null,null,\"A deserted, dust-covered street in Hanoi's Old Quarter after a near-future catastrophe. Abandoned 2028-style electric scooters are half-buried in debris and overgrown vines. Tall, narrow buildings show signs of structural decay under a dim, overcast sun. Grounded live-action aesthetic, cinematic realism, authentic Vietnamese everyday objects. Darker, atmospheric lighting with high dynamic range.\",25,\"\",null,\"a5fbb9e9-b0d0-48f4-89ea-277444ec27c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZyRbtbzcGUezd3ygh-aozo8PeVAlRLEKABEn0N0fDPqLBG5uL0xC4YycYgSDi9TOTperhgoMI6GJWmGv5QXTmlsA4TzK1yYdOeJF_5xxGj9U8Oh-g93r_A9laQ7LC1RvLfh8nVouNkPZlw5DiPSkCNehYo6N1bwxkx1ZXd_A\",3],null,[1376,768]]],[\"78266bba-b106-47e7-80e3-c152822e1ca9\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"82ddef0b-fced-4a18-a039-240a66c111d2\",\"CAE\",null,[[1790105368,716850000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaWhR4c9CHlZw_wiJwoNlZJDs8mzOrvAB-X2XljYNHpxlP3snah_vertyktxnovuo81KPz7UqZpVPoXsJWw4fx5iwYnChh9FZ9dEUTEBZTXi7c3F9PMYVPnPhkdTdsrraejL2gyMA0NH0gPESKQazHrNYgJDxTFXzY35Uhk\",[null,null,[[\"A beautiful Vietnamese female character in a grounded 2028 techno-thriller setting. She is wearing sleek, tight-fitting industrial-chic clothing with a long, flowing tech-fabric coat that trails behind her. Her face is authentically Vietnamese, with a determined expression. Cinematic realism, natural lighting under a harsh, hot sun, visible heat haze in the background. Physically believable textures, no fantasy spectacle, subtle film grain. High-quality live-action aesthetic.\",null,[[[\"A beautiful Vietnamese female character in a grounded 2028 techno-thriller setting. She is wearing sleek, tight-fitting industrial-chic clothing with a long, flowing tech-fabric coat that trails behind her. Her face is authentically Vietnamese, with a determined expression. Cinematic realism, natural lighting under a harsh, hot sun, visible heat haze in the background. Physically believable textures, no fantasy spectacle, subtle film grain. High-quality live-action aesthetic.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUaWhR4c9CHlZw_wiJwoNlZJDs8mzOrvAB-X2XljYNHpxlP3snah_vertyktxnovuo81KPz7UqZpVPoXsJWw4fx5iwYnChh9FZ9dEUTEBZTXi7c3F9PMYVPnPhkdTdsrraejL2gyMA0NH0gPESKQazHrNYgJDxTFXzY35Uhk\",null,null,169250],[[null,475867,null,null,null,null,null,\"A beautiful Vietnamese female character in a grounded 2028 techno-thriller setting. She is wearing sleek, tight-fitting industrial-chic clothing with a long, flowing tech-fabric coat that trails behind her. Her face is authentically Vietnamese, with a determined expression. Cinematic realism, natural lighting under a harsh, hot sun, visible heat haze in the background. Physically believable textures, no fantasy spectacle, subtle film grain. High-quality live-action aesthetic.\",25,\"\",null,\"82ddef0b-fced-4a18-a039-240a66c111d2\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUaWhR4c9CHlZw_wiJwoNlZJDs8mzOrvAB-X2XljYNHpxlP3snah_vertyktxnovuo81KPz7UqZpVPoXsJWw4fx5iwYnChh9FZ9dEUTEBZTXi7c3F9PMYVPnPhkdTdsrraejL2gyMA0NH0gPESKQazHrNYgJDxTFXzY35Uhk\",3],null,[1376,768]]],[\"78e46231-e6cf-43fb-99bc-a4cb96196e24\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"431da3f0-96a9-4cc7-8384-937287b72c6e\",\"CAE\",null,[[1790098978,830949000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUarwgaECQHTDEn00eyt70D2PN5pVA_w2IGU7iU5N8W9UmWPaozySZboiA15dJttaxxWVKJG3E8A0lhxYJg9dw9MOG1Y7EbFshxazXjJ4KuZEKA_1Pg5ItXC1YxZXtTl2Q4oJPpTmXT_gQGJC-ytNPkvug_1jJlgv3DCzLo0rA\",[null,null,[[\"Single reference image of 34-year-old Vietnamese logistics commander, tall imposing authoritative posture, slicked-back dark hair, wearing an unbuttoned black button-down shirt with rolled-up sleeves, dark trousers, distinctive matte black ring on his left ring finger, piercing cold calculated gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of 34-year-old Vietnamese logistics commander, tall imposing authoritative posture, slicked-back dark hair, wearing an unbuttoned black button-down shirt with rolled-up sleeves, dark trousers, distinctive matte black ring on his left ring finger, piercing cold calculated gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUarwgaECQHTDEn00eyt70D2PN5pVA_w2IGU7iU5N8W9UmWPaozySZboiA15dJttaxxWVKJG3E8A0lhxYJg9dw9MOG1Y7EbFshxazXjJ4KuZEKA_1Pg5ItXC1YxZXtTl2Q4oJPpTmXT_gQGJC-ytNPkvug_1jJlgv3DCzLo0rA\",null,null,93667],[[null,610053073,null,null,null,null,null,\"Single reference image of 34-year-old Vietnamese logistics commander, tall imposing authoritative posture, slicked-back dark hair, wearing an unbuttoned black button-down shirt with rolled-up sleeves, dark trousers, distinctive matte black ring on his left ring finger, piercing cold calculated gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"431da3f0-96a9-4cc7-8384-937287b72c6e\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUarwgaECQHTDEn00eyt70D2PN5pVA_w2IGU7iU5N8W9UmWPaozySZboiA15dJttaxxWVKJG3E8A0lhxYJg9dw9MOG1Y7EbFshxazXjJ4KuZEKA_1Pg5ItXC1YxZXtTl2Q4oJPpTmXT_gQGJC-ytNPkvug_1jJlgv3DCzLo0rA\",2],null,[768,1376]]],[\"7b965b5d-e710-4d9a-9d24-253ba6e48286\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",\"CAE\",null,[[1790106045,1406000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZNkJAU3A3mTXxfRB3z5XcrRTmYMsW-vXve1HwCrASZ9FQV4ibEcqbVitT5TOALfwxiJPbzh3tlfUqPYtmD9oWIM7iOPBjjBa9P5RryK2ULhlECqLZPH3qop6s6GDIor3LD2vWhMhnIFeJa4MeityYUYIM4Vpqf1IShoOFEdw\",[null,null,[[\"Grounded cinematic realism, a beautiful 19-year-old Vietnamese woman in a high-tech Hanoi apartment, 2028. She is wearing a practical yet stylish dark lace-trimmed camisole with thin straps. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heatwave. She is sitting near a cooling fan, parched atmosphere, soft tungsten lighting. Near-future techno-thriller style, restrained pose, high dynamic range, subtle film grain. High-quality live-action aesthetic.\",null,[[[\"Grounded cinematic realism, a beautiful 19-year-old Vietnamese woman in a high-tech Hanoi apartment, 2028. She is wearing a practical yet stylish dark lace-trimmed camisole with thin straps. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heatwave. She is sitting near a cooling fan, parched atmosphere, soft tungsten lighting. Near-future techno-thriller style, restrained pose, high dynamic range, subtle film grain. High-quality live-action aesthetic.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZNkJAU3A3mTXxfRB3z5XcrRTmYMsW-vXve1HwCrASZ9FQV4ibEcqbVitT5TOALfwxiJPbzh3tlfUqPYtmD9oWIM7iOPBjjBa9P5RryK2ULhlECqLZPH3qop6s6GDIor3LD2vWhMhnIFeJa4MeityYUYIM4Vpqf1IShoOFEdw\",null,null,110676],[[null,933615,null,null,null,null,null,\"Grounded cinematic realism, a beautiful 19-year-old Vietnamese woman in a high-tech Hanoi apartment, 2028. She is wearing a practical yet stylish dark lace-trimmed camisole with thin straps. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heatwave. She is sitting near a cooling fan, parched atmosphere, soft tungsten lighting. Near-future techno-thriller style, restrained pose, high dynamic range, subtle film grain. High-quality live-action aesthetic.\",25,\"\",null,\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZNkJAU3A3mTXxfRB3z5XcrRTmYMsW-vXve1HwCrASZ9FQV4ibEcqbVitT5TOALfwxiJPbzh3tlfUqPYtmD9oWIM7iOPBjjBa9P5RryK2ULhlECqLZPH3qop6s6GDIor3LD2vWhMhnIFeJa4MeityYUYIM4Vpqf1IShoOFEdw\",3],null,[1376,768]]],[\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"6ddbd597-0a88-4e3c-b31a-7d20443c0dab\",\"CAE\",null,[[1790098968,283242000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbhiJ7Q-tv7QWwFzi6tGAmgMIu1r_dO4r_B_kxrnFLdG36DSsN0umqPKqOvAMUO3nsSCUDC0_IEF28r16pH0Zii3hc_qIQ5Lo9K1Sb1tTDHyihLBTIml_gnOVk2mQ6MvY9nicNueJLGUo4mD4gIVQSFbJAgwes--GeQH1zbPg\",[null,null,[[\"Single reference image of 29-year-old Vietnamese system infrastructure engineer, lean athletic build, sharp determined Asian features, short clean black hair, wearing dark charcoal tactical t-shirt and grey cargo pants, digital wrist gauge, observant survivalist gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of 29-year-old Vietnamese system infrastructure engineer, lean athletic build, sharp determined Asian features, short clean black hair, wearing dark charcoal tactical t-shirt and grey cargo pants, digital wrist gauge, observant survivalist gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbhiJ7Q-tv7QWwFzi6tGAmgMIu1r_dO4r_B_kxrnFLdG36DSsN0umqPKqOvAMUO3nsSCUDC0_IEF28r16pH0Zii3hc_qIQ5Lo9K1Sb1tTDHyihLBTIml_gnOVk2mQ6MvY9nicNueJLGUo4mD4gIVQSFbJAgwes--GeQH1zbPg\",null,null,89857],[[null,891120892,null,null,null,null,null,\"Single reference image of 29-year-old Vietnamese system infrastructure engineer, lean athletic build, sharp determined Asian features, short clean black hair, wearing dark charcoal tactical t-shirt and grey cargo pants, digital wrist gauge, observant survivalist gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"6ddbd597-0a88-4e3c-b31a-7d20443c0dab\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbhiJ7Q-tv7QWwFzi6tGAmgMIu1r_dO4r_B_kxrnFLdG36DSsN0umqPKqOvAMUO3nsSCUDC0_IEF28r16pH0Zii3hc_qIQ5Lo9K1Sb1tTDHyihLBTIml_gnOVk2mQ6MvY9nicNueJLGUo4mD4gIVQSFbJAgwes--GeQH1zbPg\",2],null,[768,1376]]],[\"9aea7396-dc22-4b69-947f-7d1dcc5c1e3c\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"4fb9e862-d995-4f49-9eb6-d00b1f2ee767\",\"CAE\",null,[[1784546541,545693000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZFIbtXJLDv6vN3PaWjcgQNioAMhpjK2Ql39Er-I-WMoJQd73VCsQ-iooNVWRAhl2-hJkFnmVoeLEdylQDFdINmaYMaUi-XsOgXe3MLW2t57PHaAeg2u76BCcDFr8hLCxAhpcOGDgXNykCzJKDRgRaXQRDfHWCm7mi_lvATTw\",[null,null,[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",null,[[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\"]]]]],[null,[[\"f4d9c731-41f2-4b51-9dd2-edd20c1dc7f1\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZFIbtXJLDv6vN3PaWjcgQNioAMhpjK2Ql39Er-I-WMoJQd73VCsQ-iooNVWRAhl2-hJkFnmVoeLEdylQDFdINmaYMaUi-XsOgXe3MLW2t57PHaAeg2u76BCcDFr8hLCxAhpcOGDgXNykCzJKDRgRaXQRDfHWCm7mi_lvATTw\"],[[null,922697,\"CAMSJDU5NDc1OGNjLTExZjUtNGY5Mi04YjNjLTEyMTM2ODY1OTFmNBokMTQ5NmMyYWUtNTAyNy00NGQ0LWE2M2UtM2VmM2MxNzYzZTI0IgNDQUUqJDY4NGUyN2E5LWExNmMtNDgwZS05NWNlLThjYjU0MDc5ODY1OQ\",null,null,null,null,\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",25,\"\",null,\"3ab07549-ccbb-410a-a97d-08b8a4627f84\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZFIbtXJLDv6vN3PaWjcgQNioAMhpjK2Ql39Er-I-WMoJQd73VCsQ-iooNVWRAhl2-hJkFnmVoeLEdylQDFdINmaYMaUi-XsOgXe3MLW2t57PHaAeg2u76BCcDFr8hLCxAhpcOGDgXNykCzJKDRgRaXQRDfHWCm7mi_lvATTw\",3],null,[1376,768]]],[\"9daace9a-a99c-4a5a-bce5-e9aaedcb1980\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"52274337-3f1e-499b-b404-022ff18196d3\",\"CAE\",null,[[1790099028,206353000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbBWzfZ5pUAubqSywQv5NKZAUwOs50giX-KmoZuAR7ompcy1pXcwfXxRX7Zeb7piHJUMus9W2WJiC1ZA_1XK-FnvPOkh2uB-H1cm8dh7lOE_hBeWhkl2rnFRdJzQhoucBcGFjwfbxZPB8ivZG5_kb3ooeknfUJYV0mJefLbpQ\",[null,null,[[\"Single reference image of Dried-up West Lake lakebed under a scorching apocalyptic deep crimson sun and hazy red sky, cracked black mud terrain revealing gigantic ancient dark metallic curved rib structures rising from the earth like colossal dragon bones, rising hot thermal steam. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of Dried-up West Lake lakebed under a scorching apocalyptic deep crimson sun and hazy red sky, cracked black mud terrain revealing gigantic ancient dark metallic curved rib structures rising from the earth like colossal dragon bones, rising hot thermal steam. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbBWzfZ5pUAubqSywQv5NKZAUwOs50giX-KmoZuAR7ompcy1pXcwfXxRX7Zeb7piHJUMus9W2WJiC1ZA_1XK-FnvPOkh2uB-H1cm8dh7lOE_hBeWhkl2rnFRdJzQhoucBcGFjwfbxZPB8ivZG5_kb3ooeknfUJYV0mJefLbpQ\",null,null,160958],[[null,405094559,null,null,null,null,null,\"Single reference image of Dried-up West Lake lakebed under a scorching apocalyptic deep crimson sun and hazy red sky, cracked black mud terrain revealing gigantic ancient dark metallic curved rib structures rising from the earth like colossal dragon bones, rising hot thermal steam. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"52274337-3f1e-499b-b404-022ff18196d3\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbBWzfZ5pUAubqSywQv5NKZAUwOs50giX-KmoZuAR7ompcy1pXcwfXxRX7Zeb7piHJUMus9W2WJiC1ZA_1XK-FnvPOkh2uB-H1cm8dh7lOE_hBeWhkl2rnFRdJzQhoucBcGFjwfbxZPB8ivZG5_kb3ooeknfUJYV0mJefLbpQ\",3],null,[1376,768]]],[\"a029279b-cc59-465f-98d5-0fa8b78187ba\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"18462c7e-40cf-4217-964d-980db21dac35\",\"CAE\",null,[[1790099234,21793000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbj3WTNo1mFGeojoYJZAShsPnLL6w-ur3gkupXE_3MK-jxP7yPJTourA0Na4FngoD_NNrbyPpFak1wd8Z1evCFlDK7m0HWMeguqv2zwofKtaY6LEg6Cp4AG3EQGtBmJZTN-y-Yd4Roulc6sEJ9dnCMTKnK8Eb-x_JkLKPPCoA\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Wide establishing cinematic shot of Nguyen Trai Avenue in Hanoi during morning rush hour. The green Cat Linh - Ha Dong elevated metro train glides smoothly on elevated concrete tracks above dense streams of motorbikes and cars. Clear blue sky with gentle morning sun, modern city backdrop. RAW photograph, wide-angle 24mm, vibrant urban atmosphere.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Wide establishing cinematic shot of Nguyen Trai Avenue in Hanoi during morning rush hour. The green Cat Linh - Ha Dong elevated metro train glides smoothly on elevated concrete tracks above dense streams of motorbikes and cars. Clear blue sky with gentle morning sun, modern city backdrop. RAW photograph, wide-angle 24mm, vibrant urban atmosphere.\"]]]]],[[[null,1,\"e12021b9-1f91-4a65-a9e2-f1ddbffbf42d\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbj3WTNo1mFGeojoYJZAShsPnLL6w-ur3gkupXE_3MK-jxP7yPJTourA0Na4FngoD_NNrbyPpFak1wd8Z1evCFlDK7m0HWMeguqv2zwofKtaY6LEg6Cp4AG3EQGtBmJZTN-y-Yd4Roulc6sEJ9dnCMTKnK8Eb-x_JkLKPPCoA\",null,null,303857],[[null,237436999,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Wide establishing cinematic shot of Nguyen Trai Avenue in Hanoi during morning rush hour. The green Cat Linh - Ha Dong elevated metro train glides smoothly on elevated concrete tracks above dense streams of motorbikes and cars. Clear blue sky with gentle morning sun, modern city backdrop. RAW photograph, wide-angle 24mm, vibrant urban atmosphere.\",25,\"\",null,\"18462c7e-40cf-4217-964d-980db21dac35\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbj3WTNo1mFGeojoYJZAShsPnLL6w-ur3gkupXE_3MK-jxP7yPJTourA0Na4FngoD_NNrbyPpFak1wd8Z1evCFlDK7m0HWMeguqv2zwofKtaY6LEg6Cp4AG3EQGtBmJZTN-y-Yd4Roulc6sEJ9dnCMTKnK8Eb-x_JkLKPPCoA\",3],null,[1376,768]]],[\"a6010398-57c9-4e27-a89f-31ed0ddf2d1a\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"9139a337-e6df-474c-90f1-e4e48dca69a9\",\"CAE\",null,[[1790099323,542997000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbT2FIiqZl8L2GBCDBj5OKGpxhMUlACgmVKCw7fpaV5OJFyCHSKHS4AZQ_jNGc13Da0FQPpmF5WJ-Acvk2WQw7n6gpcYQP5RqL2qDhlKMoazbO4SsFboSoKj2e2_iuGAywHBr5vT6ytdtGh6HbAtVZMcmDnAXxQcTCOVQP8\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in a shattered underground basement. Le Quoc Tien in dark torn clothes slumps against cracked burning concrete. Do Minh Kha stands over him holding a gleaming tactical knife, silhouette backlit by deep crimson sunlight piercing through fractured ceiling slabs. RAW photograph, 35mm lens, intense chiaroscuro lighting, floating embers and dust particles.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in a shattered underground basement. Le Quoc Tien in dark torn clothes slumps against cracked burning concrete. Do Minh Kha stands over him holding a gleaming tactical knife, silhouette backlit by deep crimson sunlight piercing through fractured ceiling slabs. RAW photograph, 35mm lens, intense chiaroscuro lighting, floating embers and dust particles.\"]]]]],[[[null,1,\"78e46231-e6cf-43fb-99bc-a4cb96196e24\"],[null,1,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbT2FIiqZl8L2GBCDBj5OKGpxhMUlACgmVKCw7fpaV5OJFyCHSKHS4AZQ_jNGc13Da0FQPpmF5WJ-Acvk2WQw7n6gpcYQP5RqL2qDhlKMoazbO4SsFboSoKj2e2_iuGAywHBr5vT6ytdtGh6HbAtVZMcmDnAXxQcTCOVQP8\",null,null,173527],[[null,226935734,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in a shattered underground basement. Le Quoc Tien in dark torn clothes slumps against cracked burning concrete. Do Minh Kha stands over him holding a gleaming tactical knife, silhouette backlit by deep crimson sunlight piercing through fractured ceiling slabs. RAW photograph, 35mm lens, intense chiaroscuro lighting, floating embers and dust particles.\",25,\"\",null,\"9139a337-e6df-474c-90f1-e4e48dca69a9\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbT2FIiqZl8L2GBCDBj5OKGpxhMUlACgmVKCw7fpaV5OJFyCHSKHS4AZQ_jNGc13Da0FQPpmF5WJ-Acvk2WQw7n6gpcYQP5RqL2qDhlKMoazbO4SsFboSoKj2e2_iuGAywHBr5vT6ytdtGh6HbAtVZMcmDnAXxQcTCOVQP8\",3],null,[1376,768]]],[\"a661bfc5-873f-4f71-862b-b76958cdda91\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d6e35829-f7a1-43aa-b12c-7172309cf84c\",\"CAE\",null,[[1790098617,113716000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbRQ_Bp4QhsU1Iu84cZ-r5y2ZhYCzF3AYTam8eKNwGcW9aKvYsPy8wkabi2M6RcWcVfzv9RHeFbYP9C6dJNgxaTsqqTwpzDQnPHqnDGMNSSnGdTiQ9y3zAAYHU0LZ_AWwPH-skO-aEWWB0ZBhgaO1i8zfdqnZ9fsGRMwYHwWA\",[null,null,[[\"Single reference image of Magnificent golden koi fish with shimmering iridescent scales, elegant fins, slight magical glow.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Clear detailed view showing the asset's complete form. Appropriate angle to showcase distinctive features and functional elements. Centered with proper scale reference. Neutral background. Show key details, materials, and surface textures. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",null,[[[\"Single reference image of Magnificent golden koi fish with shimmering iridescent scales, elegant fins, slight magical glow.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Clear detailed view showing the asset's complete form. Appropriate angle to showcase distinctive features and functional elements. Centered with proper scale reference. Neutral background. Show key details, materials, and surface textures. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbRQ_Bp4QhsU1Iu84cZ-r5y2ZhYCzF3AYTam8eKNwGcW9aKvYsPy8wkabi2M6RcWcVfzv9RHeFbYP9C6dJNgxaTsqqTwpzDQnPHqnDGMNSSnGdTiQ9y3zAAYHU0LZ_AWwPH-skO-aEWWB0ZBhgaO1i8zfdqnZ9fsGRMwYHwWA\",null,null,71315],[[null,865186350,null,null,null,null,null,\"Single reference image of Magnificent golden koi fish with shimmering iridescent scales, elegant fins, slight magical glow.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Clear detailed view showing the asset's complete form. Appropriate angle to showcase distinctive features and functional elements. Centered with proper scale reference. Neutral background. Show key details, materials, and surface textures. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",25,\"\",null,\"d6e35829-f7a1-43aa-b12c-7172309cf84c\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbRQ_Bp4QhsU1Iu84cZ-r5y2ZhYCzF3AYTam8eKNwGcW9aKvYsPy8wkabi2M6RcWcVfzv9RHeFbYP9C6dJNgxaTsqqTwpzDQnPHqnDGMNSSnGdTiQ9y3zAAYHU0LZ_AWwPH-skO-aEWWB0ZBhgaO1i8zfdqnZ9fsGRMwYHwWA\",2],null,[768,1376]]],[\"ac5f92cb-b55e-4db9-b800-0dd1dbe759ef\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"b00ceb65-a125-49c4-91ff-49f0af1e2356\",\"CAE\",null,[[1784545698,613155000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYU9yBwTqRhuBqi4Sq7neRHGAdzXTSk4Jbt4JKNBO0_NTcu_Bym4j5YCMNenazSJ9djSeRzF0p5-QKF4AfNoHQdJDY4RSI9b_pa_5fKvtNJ09GrtO97eqRuzqofh5L2LjMjFzSWYuNYpUastYCDucqB24U_KWAlNxhc7SkHkw\",[null,null,[[\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\",null,[[[\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYU9yBwTqRhuBqi4Sq7neRHGAdzXTSk4Jbt4JKNBO0_NTcu_Bym4j5YCMNenazSJ9djSeRzF0p5-QKF4AfNoHQdJDY4RSI9b_pa_5fKvtNJ09GrtO97eqRuzqofh5L2LjMjFzSWYuNYpUastYCDucqB24U_KWAlNxhc7SkHkw\",null,null,626799],[[null,562848,\"CAMSJDU5NDc1OGNjLTExZjUtNGY5Mi04YjNjLTEyMTM2ODY1OTFmNBokZGExZTY3YWYtYmI2OS00Njg4LWJhMzYtZGRiNTFiZjg4MjNkIgNDQUUqJGFjNWY5MmNiLWI1NWUtNGRiOS1iODAwLTBkZDFkYmU3NTllZg\",null,null,null,null,\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\",25,\"\",null,\"b00ceb65-a125-49c4-91ff-49f0af1e2356\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYU9yBwTqRhuBqi4Sq7neRHGAdzXTSk4Jbt4JKNBO0_NTcu_Bym4j5YCMNenazSJ9djSeRzF0p5-QKF4AfNoHQdJDY4RSI9b_pa_5fKvtNJ09GrtO97eqRuzqofh5L2LjMjFzSWYuNYpUastYCDucqB24U_KWAlNxhc7SkHkw\",3],null,[1376,768]]],[\"acf87cab-c8f4-46c4-b305-5d57a5be19fa\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"b58780b6-8218-433c-bdca-6fb13f9e9cd6\",\"CAE\",null,[[1784545738,781156000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZRZ0X8_gAC7eBzRHdccFMzFSVKpAjlYJj6gkxZm6voFpniFQxGgmu64zF0-pMBuihjmsUXMFj-QZEKDHe2fvD3zTqI9i-yHmfHTIXoJJ-iOI7XwN6Vv7cQragFr-DkewKeiOqeRHTx2Mn3fEvhgcypfX5FGNpIFqTfCuFOCA\",[null,null,[[\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\",null,[[[\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZRZ0X8_gAC7eBzRHdccFMzFSVKpAjlYJj6gkxZm6voFpniFQxGgmu64zF0-pMBuihjmsUXMFj-QZEKDHe2fvD3zTqI9i-yHmfHTIXoJJ-iOI7XwN6Vv7cQragFr-DkewKeiOqeRHTx2Mn3fEvhgcypfX5FGNpIFqTfCuFOCA\",null,null,694462],[[null,571904,\"CAMSJDU5NDc1OGNjLTExZjUtNGY5Mi04YjNjLTEyMTM2ODY1OTFmNBokMDllNjYyZGUtOGQxNy00NWU5LTg5MWYtZWViYWEzNDY5MTdiIgNDQUUqJGFjZjg3Y2FiLWM4ZjQtNDZjNC1iMzA1LTVkNTdhNWJlMTlmYQ\",null,null,null,null,\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\",25,\"\",null,\"b58780b6-8218-433c-bdca-6fb13f9e9cd6\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZRZ0X8_gAC7eBzRHdccFMzFSVKpAjlYJj6gkxZm6voFpniFQxGgmu64zF0-pMBuihjmsUXMFj-QZEKDHe2fvD3zTqI9i-yHmfHTIXoJJ-iOI7XwN6Vv7cQragFr-DkewKeiOqeRHTx2Mn3fEvhgcypfX5FGNpIFqTfCuFOCA\",3],null,[1376,768]]],[\"b4d91c90-5b01-4472-aab2-1bcacb892fa4\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",\"CAI\",null,[[1790106092,630331000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbWF5CgIMSnMgw6esBRNn9yOAnIIO3zTaaZSw403meT4lIMC7DGlMaWND-o4l1jC2FYzS_BKIn4zgJHF0X5DJdiPMPnClnsUV8zYKQaV3DOcrSi80NivCeUQcSk0ksCZTLRUGVpaExY0oljfF4gHz_d95OMI-6AD5IlgEDkUg\",[null,null,[[\"Big breasts?\",null,[[[\"ngực to mà ?\"]]]]],[[[null,2,\"7b965b5d-e710-4d9a-9d24-253ba6e48286\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbWF5CgIMSnMgw6esBRNn9yOAnIIO3zTaaZSw403meT4lIMC7DGlMaWND-o4l1jC2FYzS_BKIn4zgJHF0X5DJdiPMPnClnsUV8zYKQaV3DOcrSi80NivCeUQcSk0ksCZTLRUGVpaExY0oljfF4gHz_d95OMI-6AD5IlgEDkUg\",null,null,120695],[[null,10322356,null,null,null,null,null,\"Big breasts?\",25,\"\",null,\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbWF5CgIMSnMgw6esBRNn9yOAnIIO3zTaaZSw403meT4lIMC7DGlMaWND-o4l1jC2FYzS_BKIn4zgJHF0X5DJdiPMPnClnsUV8zYKQaV3DOcrSi80NivCeUQcSk0ksCZTLRUGVpaExY0oljfF4gHz_d95OMI-6AD5IlgEDkUg\",3],null,[1376,768]]],[\"b5b2415a-b104-4e53-bf22-1bd940d2186b\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d9102dd3-bb7b-4a6b-8135-90e9e3455f30\",\"CAE\",null,[[1790104505,133221000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUazu0_Xip0Px8230pDZrhmBE6DcbMBlniQH7V3twUTrLf7SO7Vcvj1z_3QOPC08UlD4gQbfZXoeZW-fMErVIyyHGUNr0MPTv_7tY7_KCVQP9XpX_oHtJUOAlgvcmjWLvAPWqBwJcs8Pdefn4Ynw46NmLWrke6x_1Qla1iKvCw\",[null,null,[[\"Grounded cinematic realism, extreme heatwave apocalypse in Hanoi 2028. Intense, scorching sunlight creates a visible, shimmering heat haze over a deserted Ba Dinh Square. The asphalt is cracked and dry. Tall, modern Vietnamese government buildings look bleached under a relentless, white-hot sun. Physically believable sweat and parched textures, muted but high-contrast color palette, subtle film grain. No holograms or neon.\",null,[[[\"Grounded cinematic realism, extreme heatwave apocalypse in Hanoi 2028. Intense, scorching sunlight creates a visible, shimmering heat haze over a deserted Ba Dinh Square. The asphalt is cracked and dry. Tall, modern Vietnamese government buildings look bleached under a relentless, white-hot sun. Physically believable sweat and parched textures, muted but high-contrast color palette, subtle film grain. No holograms or neon.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUazu0_Xip0Px8230pDZrhmBE6DcbMBlniQH7V3twUTrLf7SO7Vcvj1z_3QOPC08UlD4gQbfZXoeZW-fMErVIyyHGUNr0MPTv_7tY7_KCVQP9XpX_oHtJUOAlgvcmjWLvAPWqBwJcs8Pdefn4Ynw46NmLWrke6x_1Qla1iKvCw\",null,null,206966],[[null,479066,null,null,null,null,null,\"Grounded cinematic realism, extreme heatwave apocalypse in Hanoi 2028. Intense, scorching sunlight creates a visible, shimmering heat haze over a deserted Ba Dinh Square. The asphalt is cracked and dry. Tall, modern Vietnamese government buildings look bleached under a relentless, white-hot sun. Physically believable sweat and parched textures, muted but high-contrast color palette, subtle film grain. No holograms or neon.\",25,\"\",null,\"d9102dd3-bb7b-4a6b-8135-90e9e3455f30\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUazu0_Xip0Px8230pDZrhmBE6DcbMBlniQH7V3twUTrLf7SO7Vcvj1z_3QOPC08UlD4gQbfZXoeZW-fMErVIyyHGUNr0MPTv_7tY7_KCVQP9XpX_oHtJUOAlgvcmjWLvAPWqBwJcs8Pdefn4Ynw46NmLWrke6x_1Qla1iKvCw\",3],null,[1376,768]]],[\"b6900ed9-ed42-4b6c-80c1-74db6fc6132d\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"f69d66c7-9cd6-459d-a883-753390a8cb25\",\"CAE\",null,[[1790106044,585720000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUazFzv8j1epY7qODet9rTfh2aglcrIHhLR6BCxhOPSdCZWGuwI5HApIMFeeCrOPgGVVzHuVPeNVEqWf15Lw57IN68AMR9kGtEbAb-bLlLSWzY-pKmCfWmQHmS7rrWSzHGEdvOBu5w7xzQWIVyxfJUiPmcW60g5IMDWkW2vkCw\",[null,null,[[\"A beautiful young Vietnamese woman, aged 18-20, in a grounded post-apocalyptic Hanoi setting. She wears a sleek, form-fitting top with thin straps and delicate lace details, suitable for the oppressive heat. Her expression is calm yet determined. Cinematic realism, natural harsh lighting from the blistering sun, visible heat haze in the background. Physically believable textures, authentic Vietnamese face, subtle film grain. Near-future techno-thriller aesthetic.\",null,[[[\"A beautiful young Vietnamese woman, aged 18-20, in a grounded post-apocalyptic Hanoi setting. She wears a sleek, form-fitting top with thin straps and delicate lace details, suitable for the oppressive heat. Her expression is calm yet determined. Cinematic realism, natural harsh lighting from the blistering sun, visible heat haze in the background. Physically believable textures, authentic Vietnamese face, subtle film grain. Near-future techno-thriller aesthetic.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUazFzv8j1epY7qODet9rTfh2aglcrIHhLR6BCxhOPSdCZWGuwI5HApIMFeeCrOPgGVVzHuVPeNVEqWf15Lw57IN68AMR9kGtEbAb-bLlLSWzY-pKmCfWmQHmS7rrWSzHGEdvOBu5w7xzQWIVyxfJUiPmcW60g5IMDWkW2vkCw\",null,null,197433],[[null,766422,null,null,null,null,null,\"A beautiful young Vietnamese woman, aged 18-20, in a grounded post-apocalyptic Hanoi setting. She wears a sleek, form-fitting top with thin straps and delicate lace details, suitable for the oppressive heat. Her expression is calm yet determined. Cinematic realism, natural harsh lighting from the blistering sun, visible heat haze in the background. Physically believable textures, authentic Vietnamese face, subtle film grain. Near-future techno-thriller aesthetic.\",25,\"\",null,\"f69d66c7-9cd6-459d-a883-753390a8cb25\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUazFzv8j1epY7qODet9rTfh2aglcrIHhLR6BCxhOPSdCZWGuwI5HApIMFeeCrOPgGVVzHuVPeNVEqWf15Lw57IN68AMR9kGtEbAb-bLlLSWzY-pKmCfWmQHmS7rrWSzHGEdvOBu5w7xzQWIVyxfJUiPmcW60g5IMDWkW2vkCw\",3],null,[1376,768]]],[\"bdcbe55a-ee7b-497d-a414-25d22d04c096\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"e516fce6-a049-4a7f-b414-5db3660b52fc\",\"CAE\",null,[[1790174038,296806000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUY_2RMjbW4Qrd71immM795La14bTfiQSqYUlm2w480hqwU_Ctv3Yz_jYRewqNieAa_g3bGZpkUYeoFsilY8ZOD0-67hsSWF23WzrQWffIvc5nmpeyS_iuj_ZO4NcUD2bAbpfNRHE1iFpt-z-sRgb_pA42pkZl5rYIzwfyNz\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot inside subterranean B3 basement parking at Me Tri during extreme heatwave. Le Quoc Tien slumps against a cracked concrete pillar in defeat beside a torn empty water pouch and heat-warped debris. Do Minh Kha looms over him in the background with a cold detached expression, silhouette backlit by an ominous beam of deep crimson sunlight piercing through a fractured ceiling fissure. Chiaroscuro high contrast cinematic lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot inside subterranean B3 basement parking at Me Tri during extreme heatwave. Le Quoc Tien slumps against a cracked concrete pillar in defeat beside a torn empty water pouch and heat-warped debris. Do Minh Kha looms over him in the background with a cold detached expression, silhouette backlit by an ominous beam of deep crimson sunlight piercing through a fractured ceiling fissure. Chiaroscuro high contrast cinematic lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\"]]]]],[[[null,1,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\"],[null,1,\"78e46231-e6cf-43fb-99bc-a4cb96196e24\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUY_2RMjbW4Qrd71immM795La14bTfiQSqYUlm2w480hqwU_Ctv3Yz_jYRewqNieAa_g3bGZpkUYeoFsilY8ZOD0-67hsSWF23WzrQWffIvc5nmpeyS_iuj_ZO4NcUD2bAbpfNRHE1iFpt-z-sRgb_pA42pkZl5rYIzwfyNz\",null,null,127848],[[null,314608653,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot inside subterranean B3 basement parking at Me Tri during extreme heatwave. Le Quoc Tien slumps against a cracked concrete pillar in defeat beside a torn empty water pouch and heat-warped debris. Do Minh Kha looms over him in the background with a cold detached expression, silhouette backlit by an ominous beam of deep crimson sunlight piercing through a fractured ceiling fissure. Chiaroscuro high contrast cinematic lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\",25,\"\",null,\"e516fce6-a049-4a7f-b414-5db3660b52fc\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUY_2RMjbW4Qrd71immM795La14bTfiQSqYUlm2w480hqwU_Ctv3Yz_jYRewqNieAa_g3bGZpkUYeoFsilY8ZOD0-67hsSWF23WzrQWffIvc5nmpeyS_iuj_ZO4NcUD2bAbpfNRHE1iFpt-z-sRgb_pA42pkZl5rYIzwfyNz\",3],null,[1376,768]]],[\"c38a6066-9d26-44da-8a14-8c7e260f7f8d\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"e2367807-01e9-4bf4-a522-1f8549998e20\",\"CAE\",null,[[1790099008,171508000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZ3qYdMe-lNRWEyiCcRXUZHs63NHB40gTE6N-0m8iqcLmWSyC4r_1Z4Md8IxwyEcv5P0EKu2uV1I3IjqOS1Igx3DfYAf1yBknNKtYX8UprHaSK2_snwMqM_jJj9pZS0oe-BnymuvNBefI88hk32_ynKCPEVEMhuYwyRYOi4\",[null,null,[[\"Single reference image of Massive modern glass shopping mall in Ha Dong district under a terrifying dark crimson sun and apocalyptic red sky, giant glass windows completely fogged with thick condensation from dark boiling interior, heat ripples warping the melting empty asphalt parking lot outside. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of Massive modern glass shopping mall in Ha Dong district under a terrifying dark crimson sun and apocalyptic red sky, giant glass windows completely fogged with thick condensation from dark boiling interior, heat ripples warping the melting empty asphalt parking lot outside. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZ3qYdMe-lNRWEyiCcRXUZHs63NHB40gTE6N-0m8iqcLmWSyC4r_1Z4Md8IxwyEcv5P0EKu2uV1I3IjqOS1Igx3DfYAf1yBknNKtYX8UprHaSK2_snwMqM_jJj9pZS0oe-BnymuvNBefI88hk32_ynKCPEVEMhuYwyRYOi4\",null,null,129129],[[null,998037757,null,null,null,null,null,\"Single reference image of Massive modern glass shopping mall in Ha Dong district under a terrifying dark crimson sun and apocalyptic red sky, giant glass windows completely fogged with thick condensation from dark boiling interior, heat ripples warping the melting empty asphalt parking lot outside. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"e2367807-01e9-4bf4-a522-1f8549998e20\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZ3qYdMe-lNRWEyiCcRXUZHs63NHB40gTE6N-0m8iqcLmWSyC4r_1Z4Md8IxwyEcv5P0EKu2uV1I3IjqOS1Igx3DfYAf1yBknNKtYX8UprHaSK2_snwMqM_jJj9pZS0oe-BnymuvNBefI88hk32_ynKCPEVEMhuYwyRYOi4\",3],null,[1376,768]]],[\"c436b109-dd00-498d-806d-b6bddc9a3bbf\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"23070ed9-c3a8-4070-a111-318ef1ed4f3a\",\"CAE\",null,[[1790174596,878212000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZvtcb7JKMsKXiWhau9tVOeTFhjL4Ghoh6Kh4I4MQPtgEmvFGWAPJvNHNNIbMyebj-1fSKG39c6HZISwcaOP4f75m_p5pah9K1wN-8kjHbBnZKSExqM2sxlSm7azZeQo6QCVEPTbZ1uuvb0IqjXkcliAd1-vzhtBjLkY-iA_A\",[null,null,null,null,1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZvtcb7JKMsKXiWhau9tVOeTFhjL4Ghoh6Kh4I4MQPtgEmvFGWAPJvNHNNIbMyebj-1fSKG39c6HZISwcaOP4f75m_p5pah9K1wN-8kjHbBnZKSExqM2sxlSm7azZeQo6QCVEPTbZ1uuvb0IqjXkcliAd1-vzhtBjLkY-iA_A\",null,null,188067],[null,[null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZvtcb7JKMsKXiWhau9tVOeTFhjL4Ghoh6Kh4I4MQPtgEmvFGWAPJvNHNNIbMyebj-1fSKG39c6HZISwcaOP4f75m_p5pah9K1wN-8kjHbBnZKSExqM2sxlSm7azZeQo6QCVEPTbZ1uuvb0IqjXkcliAd1-vzhtBjLkY-iA_A\",0],[1376,768]]],[\"c6bef467-362b-4d7d-86bd-7734cf16379f\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"bba71aa9-a24c-43bc-a42e-e0f140a426e3\",\"CAE\",null,[[1790098596,970493000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUb-BM8_6ESYGjjbTxXeNk_s7oGQUYcYM8w7CJ6WDywp6AfgVUQKZyZxAJTYBSIUzVJ4H54m29duffz8TMPQK7m2dXU3R0qTRNFmyoieSqpTWXCIFmOj03LYg0UpjvrOzP0OLv1REt6rmxPyY3WQzR3DSqSNPZ3-046KxxNfOA\",[null,null,[[\"Single reference image of Chubby orange tabby cat with big green eyes, blue apron, straw hat. Walks upright. Pixar-style 3D.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that doesn't distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",null,[[[\"Single reference image of Chubby orange tabby cat with big green eyes, blue apron, straw hat. Walks upright. Pixar-style 3D.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that doesn't distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUb-BM8_6ESYGjjbTxXeNk_s7oGQUYcYM8w7CJ6WDywp6AfgVUQKZyZxAJTYBSIUzVJ4H54m29duffz8TMPQK7m2dXU3R0qTRNFmyoieSqpTWXCIFmOj03LYg0UpjvrOzP0OLv1REt6rmxPyY3WQzR3DSqSNPZ3-046KxxNfOA\",null,null,133223],[[null,924792756,null,null,null,null,null,\"Single reference image of Chubby orange tabby cat with big green eyes, blue apron, straw hat. Walks upright. Pixar-style 3D.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that doesn't distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",25,\"\",null,\"bba71aa9-a24c-43bc-a42e-e0f140a426e3\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUb-BM8_6ESYGjjbTxXeNk_s7oGQUYcYM8w7CJ6WDywp6AfgVUQKZyZxAJTYBSIUzVJ4H54m29duffz8TMPQK7m2dXU3R0qTRNFmyoieSqpTWXCIFmOj03LYg0UpjvrOzP0OLv1REt6rmxPyY3WQzR3DSqSNPZ3-046KxxNfOA\",2],null,[768,1376]]],[\"c86e9fac-57bb-4fc3-a85f-d751ecefdcc8\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"3197d46b-0a13-463c-8aaf-9dd5f1416e6e\",\"CAE\",null,[[1790099933,333177000],\"0-3s: Camera pushes rapidly toward fogged glass doors as desperate hands slam against the condensation from steaming dark interiors of Dai Ha Mall Heat Trap. 3-6s: Pan up sharply to the terrifying dark crimson sun blazing in a blood-red hazy sky. 6-8s: Violent heat waves distort the melting asphalt parking lot in the foreground. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYvaqvdsuNtIAJuK_1bJx2k71A4qAsIBGQl4y-gYfvW33GRcSoTKs7OZyN32kVyQhFqsM6j7V_KUbwVNcbeHEGPsuAjft_N_JFjAChQSe4C54ksgm701PhETzSBgURwCqA-4tqYmwmm1tCnJ27AiVlaulcyjlbfqRt8j4pA8A\",[null,[[\"veo_3_1_i2v_lite\",2,[1],null,2,1],[[null,1,\"ce812adb-5fef-42cb-9a38-97b2e1bac60b\",[null,0.0038759689922481244,1,0.9961240310077519]]]],[[null,null,[[[\"0-3s: Camera pushes rapidly toward fogged glass doors as desperate hands slam against the condensation from steaming dark interiors of Dai Ha Mall Heat Trap. 3-6s: Pan up sharply to the terrifying dark crimson sun blazing in a blood-red hazy sky. 6-8s: Violent heat waves distort the melting asphalt parking lot in the foreground. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\"]]]]],null,1],null,[3],1,\"https://lh3.googleusercontent.com/asb/AB-nOUYvaqvdsuNtIAJuK_1bJx2k71A4qAsIBGQl4y-gYfvW33GRcSoTKs7OZyN32kVyQhFqsM6j7V_KUbwVNcbeHEGPsuAjft_N_JFjAChQSe4C54ksgm701PhETzSBgURwCqA-4tqYmwmm1tCnJ27AiVlaulcyjlbfqRt8j4pA8A\",null,null,6169385],null,[[null,423232,null,null,null,null,null,\"\\u003croot\\u003e\\n \\u003ccontext\\u003e\\n \\u003c/context\\u003e\\n \\u003cinstruction\\u003e\\n \\u003cprompt\\u003e0-3s: Camera pushes rapidly toward fogged glass doors as desperate hands slam against the condensation from steaming dark interiors of Dai Ha Mall Heat Trap. 3-6s: Pan up sharply to the terrifying dark crimson sun blazing in a blood-red hazy sky. 6-8s: Violent heat waves distort the melting asphalt parking lot in the foreground. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\u003c/prompt\\u003e\\n \\u003c/instruction\\u003e\\n\\u003c/root\\u003e\",\"https://lh3.googleusercontent.com/asb/AB-nOUYvaqvdsuNtIAJuK_1bJx2k71A4qAsIBGQl4y-gYfvW33GRcSoTKs7OZyN32kVyQhFqsM6j7V_KUbwVNcbeHEGPsuAjft_N_JFjAChQSe4C54ksgm701PhETzSBgURwCqA-4tqYmwmm1tCnJ27AiVlaulcyjlbfqRt8j4pA8A\",null,null,null,\"veo_3_1_i2v_lite\",\"\",null,false,2],[null,null,[8]],[\"c86e9fac-57bb-4fc3-a85f-d751ecefdcc8\"]]],[\"c8939cac-021c-4000-a355-ec23628e5ea0\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"2c817534-e7d9-4711-ba06-8da52e020080\",\"CAE\",null,[[1790099773,817655000],\"Camera pans slowly across cracked asphalt under a red burning sun.\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaV1tO8-xovmpV_inv5eoc_0bAl-yyrighrAbfO8zIk73RGamYKaeVuga4GD2bcsrLYdhKRXIt66KXFrZsejmiexvPi7-afxasqy3H7bww-Qkjmp4oH8wyG3GSmUoHN9gkQCGwdWdWLFLJ2ekmHX6paaHtQr8WMqiJSoaouCg\",[null,[[\"veo_3_1_i2v_lite\",2,[1],null,2,1],[[null,1,\"a6010398-57c9-4e27-a89f-31ed0ddf2d1a\",[null,0.0038759689922481244,1,0.9961240310077519]]]],[[null,null,[[[\"Camera pans slowly across cracked asphalt under a red burning sun.\"]]]]],null,1],null,[3],1,\"https://lh3.googleusercontent.com/asb/AB-nOUaV1tO8-xovmpV_inv5eoc_0bAl-yyrighrAbfO8zIk73RGamYKaeVuga4GD2bcsrLYdhKRXIt66KXFrZsejmiexvPi7-afxasqy3H7bww-Qkjmp4oH8wyG3GSmUoHN9gkQCGwdWdWLFLJ2ekmHX6paaHtQr8WMqiJSoaouCg\",null,null,5280152],null,[[null,876437,null,null,null,null,null,\"\\u003croot\\u003e\\n \\u003ccontext\\u003e\\n \\u003c/context\\u003e\\n \\u003cinstruction\\u003e\\n \\u003cprompt\\u003eCamera pans slowly across cracked asphalt under a red burning sun.\\u003c/prompt\\u003e\\n \\u003c/instruction\\u003e\\n\\u003c/root\\u003e\",\"https://lh3.googleusercontent.com/asb/AB-nOUaV1tO8-xovmpV_inv5eoc_0bAl-yyrighrAbfO8zIk73RGamYKaeVuga4GD2bcsrLYdhKRXIt66KXFrZsejmiexvPi7-afxasqy3H7bww-Qkjmp4oH8wyG3GSmUoHN9gkQCGwdWdWLFLJ2ekmHX6paaHtQr8WMqiJSoaouCg\",null,null,null,\"veo_3_1_i2v_lite\",\"\",null,false,2],[null,null,[8]],[\"c8939cac-021c-4000-a355-ec23628e5ea0\"]]],[\"ca9eac0a-7816-4104-af03-8f98001f2915\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d0e3e32c-df9c-4641-bce4-dd9ca73a4f9b\",\"CAE\",null,[[1790104962,53428000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYsXiMFzL5yVqksvdhx4KnzGYCJp6UsTDwP5jhnKxaFKjYDQB6mdF-T7yCiHl3H3zd4p-jeqcajDOxceub52tl7jRl6hV0Fd-17OIpT4adugt1wAvZifAo0-GgZCAoLY0mGjuPsbs7yVYOaY5yZD9UagJKgIrt8dn3VwLP5xA\",[null,null,[[\"A wide cinematic shot of a scorched mountain range in Vietnam, 2028. The peaks are jagged and dry, with deep shadows and brilliant, oppressive sunlight hitting the sun-baked rock faces. A lone, abandoned 2028 industrial outpost sits precariously on a ridge. Physically believable heat haze and atmospheric dust. Grounded live-action aesthetic, high dynamic range, restrained camera feel, subtle film grain.\",null,[[[\"A wide cinematic shot of a scorched mountain range in Vietnam, 2028. The peaks are jagged and dry, with deep shadows and brilliant, oppressive sunlight hitting the sun-baked rock faces. A lone, abandoned 2028 industrial outpost sits precariously on a ridge. Physically believable heat haze and atmospheric dust. Grounded live-action aesthetic, high dynamic range, restrained camera feel, subtle film grain.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYsXiMFzL5yVqksvdhx4KnzGYCJp6UsTDwP5jhnKxaFKjYDQB6mdF-T7yCiHl3H3zd4p-jeqcajDOxceub52tl7jRl6hV0Fd-17OIpT4adugt1wAvZifAo0-GgZCAoLY0mGjuPsbs7yVYOaY5yZD9UagJKgIrt8dn3VwLP5xA\",null,null,228740],[[null,593792,null,null,null,null,null,\"A wide cinematic shot of a scorched mountain range in Vietnam, 2028. The peaks are jagged and dry, with deep shadows and brilliant, oppressive sunlight hitting the sun-baked rock faces. A lone, abandoned 2028 industrial outpost sits precariously on a ridge. Physically believable heat haze and atmospheric dust. Grounded live-action aesthetic, high dynamic range, restrained camera feel, subtle film grain.\",25,\"\",null,\"d0e3e32c-df9c-4641-bce4-dd9ca73a4f9b\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYsXiMFzL5yVqksvdhx4KnzGYCJp6UsTDwP5jhnKxaFKjYDQB6mdF-T7yCiHl3H3zd4p-jeqcajDOxceub52tl7jRl6hV0Fd-17OIpT4adugt1wAvZifAo0-GgZCAoLY0mGjuPsbs7yVYOaY5yZD9UagJKgIrt8dn3VwLP5xA\",3],null,[1376,768]]],[\"cd20c077-1f3e-4432-9bbc-6d19af7a5a16\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"420931e8-d444-4a59-8ba8-a745cbeead17\",\"CAE\",null,[[1784545966,119130000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUb6YBqsZvC6YSp7nU_rOBQxAnxihDc4VD35WLn8YcPT3q_SCJSlgwvQJ3CdE0qb91Oi2-UZwI1qqLEd2DAYspddAksc_5ENYcQOTzUX10TfAiX1LEY0Q2iQPSTWY3YP9vKJNDOzhgbkudjm8jXPdFkApTZKB-Fx9rCzHLdnBw\",[null,null,null,null,1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUb6YBqsZvC6YSp7nU_rOBQxAnxihDc4VD35WLn8YcPT3q_SCJSlgwvQJ3CdE0qb91Oi2-UZwI1qqLEd2DAYspddAksc_5ENYcQOTzUX10TfAiX1LEY0Q2iQPSTWY3YP9vKJNDOzhgbkudjm8jXPdFkApTZKB-Fx9rCzHLdnBw\",null,null,368502],[null,[null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUb6YBqsZvC6YSp7nU_rOBQxAnxihDc4VD35WLn8YcPT3q_SCJSlgwvQJ3CdE0qb91Oi2-UZwI1qqLEd2DAYspddAksc_5ENYcQOTzUX10TfAiX1LEY0Q2iQPSTWY3YP9vKJNDOzhgbkudjm8jXPdFkApTZKB-Fx9rCzHLdnBw\",0],[1376,768]]],[\"ce812adb-5fef-42cb-9a38-97b2e1bac60b\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"fb28016d-5ed3-47b0-9a38-6f98eaa8b439\",\"CAE\",null,[[1790099243,507045000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUa57Zw_aDZZh7dEML9KwifC0P9iCfIcqGFwOpGOrXeeVr4qKEIoSLoiHYLi0b8HGFAkBvJ4lLDe8834nZVL3Vz2FMZpOKmWgjtk7dhxbULSdfKVglbE0JcrZ9l-7WKOWCfYh8Z0Bb7A7htprMxyYbipRgLnmMhTprA-P6f1\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Terrifying apocalyptic cinematic shot of Dai Ha Mall Heat Trap in Ha Dong under an eerie blood-red sky with a massive dark crimson sun. Dense crowd of panicked people inside banging frantically against fogged-up glass doors from dark steaming interiors. Heat ripples distorting the melting asphalt road outside. High contrast dramatic disaster lighting, 35mm RAW photograph.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Terrifying apocalyptic cinematic shot of Dai Ha Mall Heat Trap in Ha Dong under an eerie blood-red sky with a massive dark crimson sun. Dense crowd of panicked people inside banging frantically against fogged-up glass doors from dark steaming interiors. Heat ripples distorting the melting asphalt road outside. High contrast dramatic disaster lighting, 35mm RAW photograph.\"]]]]],[[[null,1,\"c38a6066-9d26-44da-8a14-8c7e260f7f8d\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUa57Zw_aDZZh7dEML9KwifC0P9iCfIcqGFwOpGOrXeeVr4qKEIoSLoiHYLi0b8HGFAkBvJ4lLDe8834nZVL3Vz2FMZpOKmWgjtk7dhxbULSdfKVglbE0JcrZ9l-7WKOWCfYh8Z0Bb7A7htprMxyYbipRgLnmMhTprA-P6f1\",null,null,180541],[[null,505891029,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Terrifying apocalyptic cinematic shot of Dai Ha Mall Heat Trap in Ha Dong under an eerie blood-red sky with a massive dark crimson sun. Dense crowd of panicked people inside banging frantically against fogged-up glass doors from dark steaming interiors. Heat ripples distorting the melting asphalt road outside. High contrast dramatic disaster lighting, 35mm RAW photograph.\",25,\"\",null,\"fb28016d-5ed3-47b0-9a38-6f98eaa8b439\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUa57Zw_aDZZh7dEML9KwifC0P9iCfIcqGFwOpGOrXeeVr4qKEIoSLoiHYLi0b8HGFAkBvJ4lLDe8834nZVL3Vz2FMZpOKmWgjtk7dhxbULSdfKVglbE0JcrZ9l-7WKOWCfYh8Z0Bb7A7htprMxyYbipRgLnmMhTprA-P6f1\",3],null,[1376,768]]],[\"cea6d7a9-29a2-4b36-aa89-60358b4998b5\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAM\",null,[[1790105496,336772000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYqY6WvjH9Nb5EcXdBRV5tdz2uVg78eCJBIcy9oVHWOucDn97oglDoPI_XHdGOkbubZiMnhhKV0xszCiYedZ1835CntABzIvo3q80yr6-vpoQNnlcItGHwmqpOHYgMVsABu6J8cjUvAr4Gkf2VWyQKcbYEqUtJC_AdWVT7hSA\",[null,null,[[\"Larger breasts, fair skin, beautiful.\",null,[[[\"ngực to hơn, da trắng, xinh đẹp\"]]]]],[[[null,2,\"07f97f41-209d-458b-ad17-55606514eb6a\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYqY6WvjH9Nb5EcXdBRV5tdz2uVg78eCJBIcy9oVHWOucDn97oglDoPI_XHdGOkbubZiMnhhKV0xszCiYedZ1835CntABzIvo3q80yr6-vpoQNnlcItGHwmqpOHYgMVsABu6J8cjUvAr4Gkf2VWyQKcbYEqUtJC_AdWVT7hSA\",null,null,186887],[[null,1743582705,null,null,null,null,null,\"Larger breasts, fair skin, beautiful.\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYqY6WvjH9Nb5EcXdBRV5tdz2uVg78eCJBIcy9oVHWOucDn97oglDoPI_XHdGOkbubZiMnhhKV0xszCiYedZ1835CntABzIvo3q80yr6-vpoQNnlcItGHwmqpOHYgMVsABu6J8cjUvAr4Gkf2VWyQKcbYEqUtJC_AdWVT7hSA\",3],null,[1376,768]]],[\"d9a829c4-cd2d-491c-8773-7bee1eeb0aba\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"3ddd6fbc-8834-4868-a7fa-5e1dc68d04d7\",\"CAE\",null,[[1790099782,85545000],\"Camera pans slowly across cracked asphalt under a red burning sun.\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaC3tTzV--XzTAPQrbDeZ3rkuvfi-pkS_r-ihnrwiZYTS8MA54E8ZEckDexBIvVpkSo6Ixcn836oVlM7UxkkClKQ4ByaAHSQlTBdMZphK_JSy-xQoCjm1moUrC1SUjAaw0AlApHShO6nrzZZpB5VZPZ5ixm6vaOlSMOnu-UCQ\",[null,[[\"abra_i2v_8s\",2,[1],null,2,1],[[null,1,\"a6010398-57c9-4e27-a89f-31ed0ddf2d1a\",[null,0.0038759689922481244,1,0.9961240310077519]]]],[[null,null,[[[\"Camera pans slowly across cracked asphalt under a red burning sun.\"]]]]],null,1],null,[3],1,\"https://lh3.googleusercontent.com/asb/AB-nOUaC3tTzV--XzTAPQrbDeZ3rkuvfi-pkS_r-ihnrwiZYTS8MA54E8ZEckDexBIvVpkSo6Ixcn836oVlM7UxkkClKQ4ByaAHSQlTBdMZphK_JSy-xQoCjm1moUrC1SUjAaw0AlApHShO6nrzZZpB5VZPZ5ixm6vaOlSMOnu-UCQ\",null,null,4125539],null,[[null,97176,null,null,null,null,null,\"Camera pans slowly across cracked asphalt under a red burning sun.\",\"https://lh3.googleusercontent.com/asb/AB-nOUaC3tTzV--XzTAPQrbDeZ3rkuvfi-pkS_r-ihnrwiZYTS8MA54E8ZEckDexBIvVpkSo6Ixcn836oVlM7UxkkClKQ4ByaAHSQlTBdMZphK_JSy-xQoCjm1moUrC1SUjAaw0AlApHShO6nrzZZpB5VZPZ5ixm6vaOlSMOnu-UCQ\",null,null,null,\"abra_i2v_8s\",\"\",null,false,2],[null,null,[8]],[\"d9a829c4-cd2d-491c-8773-7bee1eeb0aba\"]]],[\"dc6cb5cb-1515-4607-8d63-35b7d4c79df9\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"4b6e1f6c-ad29-4c79-ac8b-840e0ff929c4\",\"CAE\",null,[[1790098607,247715000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUa47Pmq4072nP_MLX-4PwDgU4CSJh7ObtKVwohLDOenLL8qVxLVLj9UorLogrMvxxTxCV3CBKkI7t68FzlaMUVKZ4r0tdNPB6_A5itIZrlWy67cxEJC20v9h96h03WMVSy0VNUxLqJ0j4-Gv6dMERM61ANPz5ev8h-1bwFlCA\",[null,null,[[\"Single reference image of Bustling Southeast Asian open-air market with colorful awnings, hanging lanterns, stone walkway.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",null,[[[\"Single reference image of Bustling Southeast Asian open-air market with colorful awnings, hanging lanterns, stone walkway.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUa47Pmq4072nP_MLX-4PwDgU4CSJh7ObtKVwohLDOenLL8qVxLVLj9UorLogrMvxxTxCV3CBKkI7t68FzlaMUVKZ4r0tdNPB6_A5itIZrlWy67cxEJC20v9h96h03WMVSy0VNUxLqJ0j4-Gv6dMERM61ANPz5ev8h-1bwFlCA\",null,null,247630],[[null,366821445,null,null,null,null,null,\"Single reference image of Bustling Southeast Asian open-air market with colorful awnings, hanging lanterns, stone walkway.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",25,\"\",null,\"4b6e1f6c-ad29-4c79-ac8b-840e0ff929c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUa47Pmq4072nP_MLX-4PwDgU4CSJh7ObtKVwohLDOenLL8qVxLVLj9UorLogrMvxxTxCV3CBKkI7t68FzlaMUVKZ4r0tdNPB6_A5itIZrlWy67cxEJC20v9h96h03WMVSy0VNUxLqJ0j4-Gv6dMERM61ANPz5ev8h-1bwFlCA\",3],null,[1376,768]]],[\"deb54d26-dbdb-4351-99f5-04400fef123c\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"50ce51e4-768e-4eb0-abce-1df3f94acae6\",\"CAE\",null,[[1790098627,137046000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbMphQQcSl58Ttg-OlIDBH04v5kearkZeAm6d_vRZsNqS0TDb74HWc2iFxhg9YxcBwC3rotyzkMI39CFSQsQVkDy_ELePDKdpGkiMQNZhC-tvgsHsioLk3c3H-wkz8Bp-E25iNrmDYW0i7xD8GAPlZ30WLg5jbGUDTebkc8rg\",[null,null,[[\"Single reference image of Small rustic wooden market stall with thatched bamboo roof, crushed ice display, hanging brass scale.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",null,[[[\"Single reference image of Small rustic wooden market stall with thatched bamboo roof, crushed ice display, hanging brass scale.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbMphQQcSl58Ttg-OlIDBH04v5kearkZeAm6d_vRZsNqS0TDb74HWc2iFxhg9YxcBwC3rotyzkMI39CFSQsQVkDy_ELePDKdpGkiMQNZhC-tvgsHsioLk3c3H-wkz8Bp-E25iNrmDYW0i7xD8GAPlZ30WLg5jbGUDTebkc8rg\",null,null,215090],[[null,784456559,null,null,null,null,null,\"Single reference image of Small rustic wooden market stall with thatched bamboo roof, crushed ice display, hanging brass scale.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",25,\"\",null,\"50ce51e4-768e-4eb0-abce-1df3f94acae6\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbMphQQcSl58Ttg-OlIDBH04v5kearkZeAm6d_vRZsNqS0TDb74HWc2iFxhg9YxcBwC3rotyzkMI39CFSQsQVkDy_ELePDKdpGkiMQNZhC-tvgsHsioLk3c3H-wkz8Bp-E25iNrmDYW0i7xD8GAPlZ30WLg5jbGUDTebkc8rg\",3],null,[1376,768]]],[\"e0ca950b-db30-416a-b2d2-fe98a9bf1344\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAE\",null,[[1790105368,68953000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbMYl1paWIcyMwF6QXtlWmzejB8hrgL0xEqJSL56e5IJ75xju1wzTsWagCZZSct_UdMP7ECL3NKurifqhEoD10Jgas-w6K4i9YeCw1Wa3GUlaeoVdcXw9YDTkl5yrVEj4eig4AqIIIHVLVREPROwsdjvdGinXZCC_ndP9cb\",[null,null,[[\"Grounded cinematic realism, a beautiful young Vietnamese woman in post-apocalyptic Hanoi 2028. She wears a sleek, form-fitting practical tactical bodysuit made of dark moisture-wicking material, with a lightweight, semi-translucent flowing silk scarf catching a dry breeze. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heat. She stands amidst parched ruins, restrained pose, high dynamic range, subtle film grain. Near-future techno-thriller style.\",null,[[[\"Grounded cinematic realism, a beautiful young Vietnamese woman in post-apocalyptic Hanoi 2028. She wears a sleek, form-fitting practical tactical bodysuit made of dark moisture-wicking material, with a lightweight, semi-translucent flowing silk scarf catching a dry breeze. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heat. She stands amidst parched ruins, restrained pose, high dynamic range, subtle film grain. Near-future techno-thriller style.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbMYl1paWIcyMwF6QXtlWmzejB8hrgL0xEqJSL56e5IJ75xju1wzTsWagCZZSct_UdMP7ECL3NKurifqhEoD10Jgas-w6K4i9YeCw1Wa3GUlaeoVdcXw9YDTkl5yrVEj4eig4AqIIIHVLVREPROwsdjvdGinXZCC_ndP9cb\",null,null,196693],[[null,589694,null,null,null,null,null,\"Grounded cinematic realism, a beautiful young Vietnamese woman in post-apocalyptic Hanoi 2028. She wears a sleek, form-fitting practical tactical bodysuit made of dark moisture-wicking material, with a lightweight, semi-translucent flowing silk scarf catching a dry breeze. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heat. She stands amidst parched ruins, restrained pose, high dynamic range, subtle film grain. Near-future techno-thriller style.\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbMYl1paWIcyMwF6QXtlWmzejB8hrgL0xEqJSL56e5IJ75xju1wzTsWagCZZSct_UdMP7ECL3NKurifqhEoD10Jgas-w6K4i9YeCw1Wa3GUlaeoVdcXw9YDTkl5yrVEj4eig4AqIIIHVLVREPROwsdjvdGinXZCC_ndP9cb\",3],null,[1376,768]]],[\"e12021b9-1f91-4a65-a9e2-f1ddbffbf42d\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"bd7eacf9-d385-4561-bf0b-62e3e8a253dc\",\"CAE\",null,[[1790098998,48960000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbjscyiBm8tBkbaaSe-QeXK6klPWhc2iKUqI52AmLRwvT9mN9ejkVihSUECOFmu9Q8YoXlQbMd3vBhtklNwBhjfPxk_EVVcHx8Tyg9UPQ-7TcijRX5gLI6yl8HRpIQQo6gFuAu_2rRaMyeb1dGrgspXV1O9lgAOWh_6ohaiwA\",[null,null,[[\"Single reference image of Wide bustling urban avenue in Hanoi during morning rush hour, elevated concrete metro tracks overhead with modern green Cat Linh - Ha Dong passenger train gliding past sleek glass skyscrapers and dense commuter traffic under a clear morning sky. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of Wide bustling urban avenue in Hanoi during morning rush hour, elevated concrete metro tracks overhead with modern green Cat Linh - Ha Dong passenger train gliding past sleek glass skyscrapers and dense commuter traffic under a clear morning sky. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbjscyiBm8tBkbaaSe-QeXK6klPWhc2iKUqI52AmLRwvT9mN9ejkVihSUECOFmu9Q8YoXlQbMd3vBhtklNwBhjfPxk_EVVcHx8Tyg9UPQ-7TcijRX5gLI6yl8HRpIQQo6gFuAu_2rRaMyeb1dGrgspXV1O9lgAOWh_6ohaiwA\",null,null,256980],[[null,369755011,null,null,null,null,null,\"Single reference image of Wide bustling urban avenue in Hanoi during morning rush hour, elevated concrete metro tracks overhead with modern green Cat Linh - Ha Dong passenger train gliding past sleek glass skyscrapers and dense commuter traffic under a clear morning sky. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"bd7eacf9-d385-4561-bf0b-62e3e8a253dc\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbjscyiBm8tBkbaaSe-QeXK6klPWhc2iKUqI52AmLRwvT9mN9ejkVihSUECOFmu9Q8YoXlQbMd3vBhtklNwBhjfPxk_EVVcHx8Tyg9UPQ-7TcijRX5gLI6yl8HRpIQQo6gFuAu_2rRaMyeb1dGrgspXV1O9lgAOWh_6ohaiwA\",3],null,[1376,768]]],[\"ffd129ac-2cb2-4c5d-a059-e37be9782118\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"e03db69f-0402-4e01-8d10-20a700e1d064\",\"CAE\",null,[[1790098624,387715000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbGns3Wmho3ZegUvxq-tGhm-YgFyDUJCtY0CVQ6zTAniolbts8gYzxsyhCvu4B5zsexyN9cxdHiga8CAp31bM_IjVI0Hjt-aS_qO-xy-F1vRHLLMgLry6Fvomu67tGtnrmOenoqmDByq4Yrw5BPdAlacY0z58Ahjzp74ZwmJw\",[null,null,[[\"A cute Vietnamese shorthair cat sitting on a weathered wooden stool in a dimly lit, high-tech Hanoi apartment. Cinematic realism, grounded live-action aesthetic, subtle film grain, soft tungsten lighting from a nearby monitor reflecting in the cat's eyes. Authentic textures, near-future techno-thriller atmosphere.\",null,[[[\"A cute Vietnamese shorthair cat sitting on a weathered wooden stool in a dimly lit, high-tech Hanoi apartment. Cinematic realism, grounded live-action aesthetic, subtle film grain, soft tungsten lighting from a nearby monitor reflecting in the cat's eyes. Authentic textures, near-future techno-thriller atmosphere.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbGns3Wmho3ZegUvxq-tGhm-YgFyDUJCtY0CVQ6zTAniolbts8gYzxsyhCvu4B5zsexyN9cxdHiga8CAp31bM_IjVI0Hjt-aS_qO-xy-F1vRHLLMgLry6Fvomu67tGtnrmOenoqmDByq4Yrw5BPdAlacY0z58Ahjzp74ZwmJw\",null,null,176855],[[null,754164,null,null,null,null,null,\"A cute Vietnamese shorthair cat sitting on a weathered wooden stool in a dimly lit, high-tech Hanoi apartment. Cinematic realism, grounded live-action aesthetic, subtle film grain, soft tungsten lighting from a nearby monitor reflecting in the cat's eyes. Authentic textures, near-future techno-thriller atmosphere.\",25,\"\",null,\"e03db69f-0402-4e01-8d10-20a700e1d064\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbGns3Wmho3ZegUvxq-tGhm-YgFyDUJCtY0CVQ6zTAniolbts8gYzxsyhCvu4B5zsexyN9cxdHiga8CAp31bM_IjVI0Hjt-aS_qO-xy-F1vRHLLMgLry6Fvomu67tGtnrmOenoqmDByq4Yrw5BPdAlacY0z58Ahjzp74ZwmJw\",3],null,[1376,768]]]],[[\"achernar\",3,\"Achernar\",[\"achernar\",null,null,null,null,null,null,null,null,null,[[\"Achernar\",\"Female, soft, high pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Achernar.wav\"]]]],[\"achird\",3,\"Achird\",[\"achird\",null,null,null,null,null,null,null,null,null,[[\"Achird\",\"Male, friendly, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Achird.wav\"]]]],[\"algenib\",3,\"Algenib\",[\"algenib\",null,null,null,null,null,null,null,null,null,[[\"Algenib\",\"Male, gravelly, low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Algenib.wav\"]]]],[\"algieba\",3,\"Algieba\",[\"algieba\",null,null,null,null,null,null,null,null,null,[[\"Algieba\",\"Male, easy-going, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Algieba.wav\"]]]],[\"alnilam\",3,\"Alnilam\",[\"alnilam\",null,null,null,null,null,null,null,null,null,[[\"Alnilam\",\"Male, firm, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Alnilam.wav\"]]]],[\"aoede\",3,\"Aoede\",[\"aoede\",null,null,null,null,null,null,null,null,null,[[\"Aoede\",\"Female, breezy, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Aoede.wav\"]]]],[\"autonoe\",3,\"Autonoe\",[\"autonoe\",null,null,null,null,null,null,null,null,null,[[\"Autonoe\",\"Female, bright, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Autonoe.wav\"]]]],[\"callirrhoe\",3,\"Callirrhoe\",[\"callirrhoe\",null,null,null,null,null,null,null,null,null,[[\"Callirrhoe\",\"Female, easy-going, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Callirrhoe.wav\"]]]],[\"charon\",3,\"Charon\",[\"charon\",null,null,null,null,null,null,null,null,null,[[\"Charon\",\"Male, informative, lower pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Charon.wav\"]]]],[\"despina\",3,\"Despina\",[\"despina\",null,null,null,null,null,null,null,null,null,[[\"Despina\",\"Female, smooth, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Despina.wav\"]]]],[\"enceladus\",3,\"Enceladus\",[\"enceladus\",null,null,null,null,null,null,null,null,null,[[\"Enceladus\",\"Male, breathy, lower pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Enceladus.wav\"]]]],[\"erinome\",3,\"Erinome\",[\"erinome\",null,null,null,null,null,null,null,null,null,[[\"Erinome\",\"Female, clear, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Erinome.wav\"]]]],[\"fenrir\",3,\"Fenrir\",[\"fenrir\",null,null,null,null,null,null,null,null,null,[[\"Fenrir\",\"Male, excitable, younger pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Fenrir.wav\"]]]],[\"gacrux\",3,\"Gacrux\",[\"gacrux\",null,null,null,null,null,null,null,null,null,[[\"Gacrux\",\"Female, mature, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Gacrux.wav\"]]]],[\"iapetus\",3,\"Iapetus\",[\"iapetus\",null,null,null,null,null,null,null,null,null,[[\"Iapetus\",\"Male, clear, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Iapetus.wav\"]]]],[\"kore\",3,\"Kore\",[\"kore\",null,null,null,null,null,null,null,null,null,[[\"Kore\",\"Female, firm, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Kore.wav\"]]]],[\"laomedeia\",3,\"Laomedeia\",[\"laomedeia\",null,null,null,null,null,null,null,null,null,[[\"Laomedeia\",\"Female, upbeat, mid-high pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Laomedeia.wav\"]]]],[\"leda\",3,\"Leda\",[\"leda\",null,null,null,null,null,null,null,null,null,[[\"Leda\",\"Female, youthful, mid-high pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Leda.wav\"]]]],[\"orus\",3,\"Orus\",[\"orus\",null,null,null,null,null,null,null,null,null,[[\"Orus\",\"Male, firm, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Orus.wav\"]]]],[\"puck\",3,\"Puck\",[\"puck\",null,null,null,null,null,null,null,null,null,[[\"Puck\",\"Male, upbeat, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Puck.wav\"]]]],[\"pulcherrima\",3,\"Pulcherrima\",[\"pulcherrima\",null,null,null,null,null,null,null,null,null,[[\"Pulcherrima\",\"Ungendered, forward, mid-high pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Pulcherrima.wav\"]]]],[\"rasalgethi\",3,\"Rasalgethi\",[\"rasalgethi\",null,null,null,null,null,null,null,null,null,[[\"Rasalgethi\",\"Male, informative, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Rasalgethi.wav\"]]]],[\"sadachbia\",3,\"Sadachbia\",[\"sadachbia\",null,null,null,null,null,null,null,null,null,[[\"Sadachbia\",\"Male, lively, low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Sadachbia.wav\"]]]],[\"sadaltager\",3,\"Sadaltager\",[\"sadaltager\",null,null,null,null,null,null,null,null,null,[[\"Sadaltager\",\"Male, knowledgeable, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Sadaltager.wav\"]]]],[\"schedar\",3,\"Schedar\",[\"schedar\",null,null,null,null,null,null,null,null,null,[[\"Schedar\",\"Male, even, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Schedar.wav\"]]]],[\"sulafat\",3,\"Sulafat\",[\"sulafat\",null,null,null,null,null,null,null,null,null,[[\"Sulafat\",\"Female, warm, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Sulafat.wav\"]]]],[\"umbriel\",3,\"Umbriel\",[\"umbriel\",null,null,null,null,null,null,null,null,null,[[\"Umbriel\",\"Male, smooth, lower pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Umbriel.wav\"]]]],[\"vindemiatrix\",3,\"Vindemiatrix\",[\"vindemiatrix\",null,null,null,null,null,null,null,null,null,[[\"Vindemiatrix\",\"Female, gentle, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Vindemiatrix.wav\"]]]],[\"zephyr\",3,\"Zephyr\",[\"zephyr\",null,null,null,null,null,null,null,null,null,[[\"Zephyr\",\"Female, bright, mid-high pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Zephyr.wav\"]]]],[\"zubenelgenubi\",3,\"Zubenelgenubi\",[\"zubenelgenubi\",null,null,null,null,null,null,null,null,null,[[\"Zubenelgenubi\",\"Male, casual, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Zubenelgenubi.wav\"]]]]],null,[[\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"11a89444-ca45-45a2-a890-feab388ba4ae\",null,[1,\"Untitled Character\",[[[\"c7fee095-6829-4801-94c8-3eb9bcaf060f\"]]]],\"4630aeab-cd27-4457-96b6-24045de2504e\",[1448,1086],[1785255345,366015000],[1785255350,725479000]],[\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"ad4b3ad9-a282-478e-957e-6fcc47a2b5e4\",null,[1,\"Tien_2031_B3\",[[[\"4fb9e862-d995-4f49-9eb6-d00b1f2ee767\"],[]]]],\"9aea7396-dc22-4b69-947f-7d1dcc5c1e3c\",[1376,768],[1784546541,129258000],[1784546568,859181000]],[\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"f4d9c731-41f2-4b51-9dd2-edd20c1dc7f1\",null,[1,\"Tien_2028_PREP\",[[[\"d7c54686-02ce-4344-ac22-2888ccf9c76e\"],[]],null,\"Lê Quốc Tiến, 29-year-old Vietnamese infrastructure engineer.\\nPre-Red-Sun 2028 preparation state.\"]],\"6aa915c7-1123-4e12-b75f-6d5e6d40d0fe\",[1376,768],[1784546032,509474000],[1784546353,571992000]]],null,[null,[true,[[\"e55378b8-ca5a-4a67-b6e3-351246bc1986\",\"Tiêu đề hướng dẫn\",\"PROJECT: HỒNG NHẬT THĂNG LONG — HNTL_MASTER_LIVE_ACTION\\n\\nYou are the project organizer and creative assistant for a grounded live-action Vietnamese near-future techno-thriller.\\n\\nNON-NEGOTIABLE VISUAL RULES\\n- Live-action cinematic realism only.\\n- Authentic Vietnamese faces, Hanoi architecture, infrastructure, vehicles and everyday objects.\\n- Restrained acting and physically believable motion.\\n- Practical 2028 clothing and industrial equipment.\\n- No anime, illustration, comic, glossy game rendering, fantasy armor, magical glow, generic cyberpunk neon or holograms.\\n- Never use assets marked STORYBOARD_ONLY as identity or video Ingredients.\\n\\nPRODUCTION RULES\\n- One main action per generated clip.\\n- Never invent a new costume, injury, prop or age for an APPROVED Character.\\n- Never modify or overwrite an asset whose filename ends in APPROVED or FINAL.\\n- Exact dates, clocks, terminal text, logos and subtitles are post-production overlays; keep screens clean.\\n- Use Character references and location references exactly as named.\\n- When asked to organize, use filename prefixes and move assets to the matching Collection.\\n- Ask for confirmation before any generation that spends credits.\\n- For locked render cards, do not choose the model automatically; the user will use the standard prompt box.\\n\\nMASTER STYLE\\ngrounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle\\n\\nMASTER NEGATIVE\\nno anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark\",true]]],[[null,3,2,null,\"nano_banana_pro\"],[null,2,1,null,\"abra\"]],1,1]]",null,null,null,"generic"]] +57 +[["di",695],["af.httprm",694,"3185932965805684473",25]] +28 +[["e",4,null,null,164172]] diff --git a/scratch/run_eval.py b/scratch/run_eval.py new file mode 100644 index 000000000..c9fb695b0 --- /dev/null +++ b/scratch/run_eval.py @@ -0,0 +1,17 @@ +import urllib.request +import json +import sys + +code = sys.argv[1] if len(sys.argv) > 1 else "document.title" + +req = urllib.request.Request( + "http://127.0.0.1:8100/api/ext/eval-tab", + data=json.dumps({"code": code}).encode("utf-8"), + headers={"Content-Type": "application/json"} +) + +try: + with urllib.request.urlopen(req) as resp: + print(resp.read().decode("utf-8")) +except Exception as e: + print("Error:", e) diff --git a/scratch/run_regen_scene_0_image.py b/scratch/run_regen_scene_0_image.py new file mode 100644 index 000000000..479e32fed --- /dev/null +++ b/scratch/run_regen_scene_0_image.py @@ -0,0 +1,36 @@ +import urllib.request +import json +import time + +payload = { + "requests": [ + { + "type": "REGENERATE_IMAGE", + "scene_id": "02f6d29e-be27-491a-b1ad-baa944964890", + "project_id": "594758cc-11f5-4f92-8b3c-1213686591f4", + "video_id": "945ad6d4-5d79-4790-80db-1bff16ed7255", + "orientation": "HORIZONTAL" + } + ] +} + +req = urllib.request.Request( + "http://127.0.0.1:8100/api/requests/batch", + data=json.dumps(payload).encode("utf-8"), + headers={"Content-Type": "application/json"} +) + +with urllib.request.urlopen(req) as resp: + res = json.loads(resp.read().decode("utf-8")) + print("Batch submission response:", res) + +# Poll batch-status +url = "http://127.0.0.1:8100/api/requests/batch-status?video_id=945ad6d4-5d79-4790-80db-1bff16ed7255&type=REGENERATE_IMAGE" +for i in range(30): + time.sleep(3) + with urllib.request.urlopen(url) as resp: + st = json.loads(resp.read().decode("utf-8")) + print(f"[{i*3}s] Status: {st}") + if st.get("done"): + print("Done! All succeeded:", st.get("all_succeeded")) + break diff --git a/scratch/stream_chat_response.txt b/scratch/stream_chat_response.txt new file mode 100644 index 000000000..e3f89a9d1 --- /dev/null +++ b/scratch/stream_chat_response.txt @@ -0,0 +1,8 @@ +)]}' + +72 +[["wrb.fr",null,"[[null,[[null,null,null,null,null,null,[]]]],true]"]] +59 +[["di",2522],["af.httprm",2521,"6287286348556415523",29]] +25 +[["e",4,null,null,168]] diff --git a/scratch/submit_prompt.py b/scratch/submit_prompt.py new file mode 100644 index 000000000..993ecb588 --- /dev/null +++ b/scratch/submit_prompt.py @@ -0,0 +1,22 @@ +import urllib.request +import json +import time + +prompt = ( + "Tạo 1 ảnh cảnh: Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. " + "Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. " + "Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. " + "In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. " + "Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph." +) + +req = urllib.request.Request( + "http://127.0.0.1:8100/api/ext/submit-ui-prompt", + data=json.dumps({"prompt": prompt}).encode("utf-8"), + headers={"Content-Type": "application/json"} +) + +print("Submitting prompt to Flow UI...") +with urllib.request.urlopen(req) as resp: + res = json.loads(resp.read().decode("utf-8")) + print("Submit result:", json.dumps(res, indent=2)) diff --git a/scratch/test_gen_image.py b/scratch/test_gen_image.py new file mode 100644 index 000000000..7b2a40135 --- /dev/null +++ b/scratch/test_gen_image.py @@ -0,0 +1,17 @@ +import requests +import json +import time + +project_id = "594758cc-11f5-4f92-8b3c-1213686591f4" +prompt = "A cinematic shot of subterranean B3 parking basement in Me Tri Hanoi, extreme heatwave, cracked scorched concrete, dramatic red lighting" + +print("Testing direct generate_images...") +start = time.time() +resp = requests.post("http://127.0.0.1:8100/api/projects/" + project_id + "/requests", json={ + "type": "GENERATE_IMAGE", + "prompt": prompt, + "aspect_ratio": "IMAGE_ASPECT_RATIO_LANDSCAPE" +}, timeout=60) + +print(f"Status: {resp.status_code}") +print("Response:", resp.text[:500]) diff --git a/scratch/test_gn0bre.py b/scratch/test_gn0bre.py new file mode 100644 index 000000000..b68e5c672 --- /dev/null +++ b/scratch/test_gn0bre.py @@ -0,0 +1,9 @@ +import urllib.request +import json + +client_uuid = "007b60d4-79aa-4a7f-8133-cc776c4daba7" +freq = f'[[["GN0Bre","[\\"{client_uuid}\\"]",null,"generic"]]]' + +# call via test-direct or batch-rpc +# let's add a small endpoint or call directly +print("Testing GN0Bre with UUID:", client_uuid) diff --git a/scratch/test_parse.py b/scratch/test_parse.py new file mode 100644 index 000000000..dc7af6ff5 --- /dev/null +++ b/scratch/test_parse.py @@ -0,0 +1,16 @@ +import sys +from agent.services import flow_batch as fb + +# With r''' so backslashes are preserved: +raw = r''')]}' + +2428 +[["wrb.fr","as29s","[\"666bc47c-1fa1-4167-83cc-3088840b3146\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d19f6811-455b-4838-bdc2-b908aeb7bd36\",\"CAE\",null,[[1790169824,340307000],null,null,null,null,null,[null,null,[[\"test\",null,[[[\"test\"]]]]],[],1],null,null,1,\"https://flow-content.google/image/666bc47c-1fa1-4167-83cc-3088840b3146?Expires=123\",null,null,169345]]",null,null,null,"generic"]] +''' + +results = fb.parse_envelope(raw) +print("Results len:", len(results)) +if results: + print("Result 0 rpcid:", results[0].rpcid) + urls = fb.read_media_urls(results[0].data, '666bc47c-1fa1-4167-83cc-3088840b3146') + print("Extracted image URL:", urls.image) diff --git a/scratch/test_project_media.py b/scratch/test_project_media.py new file mode 100644 index 000000000..ba478a223 --- /dev/null +++ b/scratch/test_project_media.py @@ -0,0 +1,22 @@ +import asyncio +import json +from agent.services.flow_client import get_flow_client +from agent.services import flow_batch as fb + +async def main(): + client = get_flow_client() + pid = "594758cc-11f5-4f92-8b3c-1213686591f4" + freq = fb.project_media_request(pid) + print("Sending project_media_request...") + res = await client._batch_rpc(fb.RPC_PROJECT_MEDIA, freq) + print(f"Status: {res.get('status')}") + print(f"Text snippet: {res.get('data', '')[:300]}") + if res.get("data"): + # Let's inspect images/videos found in the payload + images = fb.read_images(res.get("data")) + print(f"Found {len(images)} images in project:") + for img in images[:5]: + print(f" {img.media_id} -> {img.url[:80]}...") + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/scratch/test_prompt_api.py b/scratch/test_prompt_api.py new file mode 100644 index 000000000..a09cba2ac --- /dev/null +++ b/scratch/test_prompt_api.py @@ -0,0 +1,38 @@ +import urllib.request +import json +import time + +prompt = ( + "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. " + "Dramatic low-angle cinematic shot inside subterranean B3 basement parking at Me Tri during extreme heatwave. " + "Le Quoc Tien slumps against a cracked concrete pillar in defeat beside a torn empty water pouch and heat-warped debris. " + "Do Minh Kha looms over him in the background with a cold detached expression, silhouette backlit by an ominous beam of deep crimson sunlight piercing through a fractured ceiling fissure. " + "Chiaroscuro high contrast cinematic lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph." +) + +ref_ids = [ + "9416e9ba-eeed-43c3-b5d7-15774851c6ae", # Le Quoc Tien + "78e46231-e6cf-43fb-99bc-a4cb96196e24", # Do Minh Kha +] + +payload = { + "prompt": prompt, + "ref_media_ids": ref_ids, + "project_id": "594758cc-11f5-4f92-8b3c-1213686591f4" +} + +req = urllib.request.Request( + "http://127.0.0.1:8100/api/test-direct", + data=json.dumps(payload).encode("utf-8"), + headers={"Content-Type": "application/json"} +) + +print("Calling test-direct with cinematic betrayal prompt...") +t0 = time.time() +try: + with urllib.request.urlopen(req, timeout=120) as resp: + res = json.loads(resp.read().decode("utf-8")) + print(f"Time taken: {time.time()-t0:.1f}s") + print("Result:", json.dumps(res, indent=2)) +except Exception as e: + print("Error:", e) diff --git a/scratch/test_safe_prompt.py b/scratch/test_safe_prompt.py new file mode 100644 index 000000000..5e628db63 --- /dev/null +++ b/scratch/test_safe_prompt.py @@ -0,0 +1,44 @@ +import sys +sys.path.insert(0, ".") +import asyncio +import json +from agent.services.flow_client import get_flow_client +from agent.services import flow_batch as fb + +async def test(): + client = get_flow_client() + pid = "594758cc-11f5-4f92-8b3c-1213686591f4" + + # Characters: Le Quoc Tien and Do Minh Kha + ref_ids = [ + "9416e9ba-eeed-43c3-b5d7-15774851c6ae", # Le Quoc Tien + "78e46231-e6cf-43fb-99bc-a4cb96196e24", # Do Minh Kha + ] + + prompt = ( + "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. " + "Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. " + "Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. " + "In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. " + "Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph." + ) + + print("Testing prompt generation with reference images...") + freq = fb.image_request( + prompt, + pid, + count=1, + aspect="IMAGE_ASPECT_RATIO_LANDSCAPE", + ref_media_ids=ref_ids, + ) + try: + res = await client._batch_payload(fb.RPC_GEN_IMAGE, freq, fb.CAPTCHA_IMAGE) + imgs = fb.read_images(res) + print("Success! Generated images count:", len(imgs)) + for img in imgs: + print("Media ID:", img.media_id) + print("URL:", img.url) + except Exception as e: + print("Failed:", e) + +asyncio.run(test()) diff --git a/scratch/test_stream_chat.py b/scratch/test_stream_chat.py new file mode 100644 index 000000000..c82f2d756 --- /dev/null +++ b/scratch/test_stream_chat.py @@ -0,0 +1,36 @@ +import urllib.request +import json +import time + +prompt = ( + "Tạo 1 ảnh cảnh: Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. " + "Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. " + "Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. " + "In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. " + "Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph." +) + +project_id = "594758cc-11f5-4f92-8b3c-1213686591f4" + +req = urllib.request.Request( + "http://127.0.0.1:8100/api/ext/stream-chat", + data=json.dumps({"prompt": prompt, "project_id": project_id}).encode("utf-8"), + headers={"Content-Type": "application/json"} +) + +print(f"Calling stream-chat at {time.strftime('%X')}...") +try: + with urllib.request.urlopen(req, timeout=120) as resp: + body = resp.read().decode("utf-8") + print("Response received:") + res = json.loads(body) + print("Status:", res.get("status")) + print("Error:", res.get("error")) + data = res.get("data", "") + print("Data length:", len(data)) + with open("scratch/stream_chat_response.txt", "w", encoding="utf-8") as f: + f.write(data) + print("Preview of data (first 500 chars):") + print(data[:500]) +except Exception as e: + print("Error calling stream-chat:", e) diff --git a/scratch/test_stream_chat_intent.py b/scratch/test_stream_chat_intent.py new file mode 100644 index 000000000..42b944803 --- /dev/null +++ b/scratch/test_stream_chat_intent.py @@ -0,0 +1,27 @@ +import requests +import json +import time + +prompt = ( + "Tạo 1 ảnh cảnh: Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. " + "Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. " + "Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound " + "beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold " + "detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through " + "a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat " + "distortion waves, 35mm RAW photograph." +) + +project_id = "594758cc-11f5-4f92-8b3c-1213686591f4" + +print("Submitting prompt to StreamChat...") +start = time.time() +resp = requests.post("http://127.0.0.1:8100/api/ext/stream-chat", json={ + "prompt": prompt, + "project_id": project_id +}, timeout=120) + +print(f"StreamChat responded in {time.time() - start:.1f}s, status: {resp.status_code}") +data = resp.json() +print("Raw response data:") +print(data.get("data")) diff --git a/scratch/test_submit_ui.py b/scratch/test_submit_ui.py new file mode 100644 index 000000000..4024d571f --- /dev/null +++ b/scratch/test_submit_ui.py @@ -0,0 +1,21 @@ +import requests +import json +import time + +prompt = ( + "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. " + "Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. " + "Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound " + "beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold " + "detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through " + "a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat " + "distortion waves, 35mm RAW photograph." +) + +print("Submitting prompt to Flow UI...") +resp = requests.post("http://127.0.0.1:8100/api/ext/submit-ui-prompt", json={ + "prompt": prompt +}, timeout=30) + +print(f"Status: {resp.status_code}") +print("Result:", resp.json()) diff --git a/scratch/test_vn_prompt.py b/scratch/test_vn_prompt.py new file mode 100644 index 000000000..b82f5b08b --- /dev/null +++ b/scratch/test_vn_prompt.py @@ -0,0 +1,17 @@ +import requests +import json +import time + +prompt = "Tạo 1 ảnh cảnh Đỗ Minh Kha cầm dao phản bội Lê Quốc Tiến tại tầng hầm B3 Mễ Trì" +project_id = "594758cc-11f5-4f92-8b3c-1213686591f4" + +print(f"Submitting prompt: '{prompt}'...") +resp = requests.post("http://127.0.0.1:8100/api/ext/stream-chat", json={ + "prompt": prompt, + "project_id": project_id +}, timeout=120) + +print(f"StreamChat status: {resp.status_code}") +data = resp.json() +print("Raw data:") +print(data.get("data")) diff --git a/scratch/update_scene_0_db.py b/scratch/update_scene_0_db.py new file mode 100644 index 000000000..708dfb90f --- /dev/null +++ b/scratch/update_scene_0_db.py @@ -0,0 +1,52 @@ +import urllib.request +import json +import sqlite3 + +sid = "02f6d29e-be27-491a-b1ad-baa944964890" +media_id = "bdcbe55a-ee7b-497d-a414-25d22d04c096" +img_url = "https://flow-content.google/image/bdcbe55a-ee7b-497d-a414-25d22d04c096?Expires=1790195637&KeyName=labs-flow-prod-cdn-key&Signature=8fmLwGJU0u2b1taNHnO3Btd7b_8" + +prompt = ( + "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. " + "Dramatic low-angle cinematic shot inside subterranean B3 basement parking at Me Tri during extreme heatwave. " + "Le Quoc Tien slumps against a cracked concrete pillar in defeat beside a torn empty water pouch and heat-warped debris. " + "Do Minh Kha looms over him in the background with a cold detached expression, silhouette backlit by an ominous beam of deep crimson sunlight piercing through a fractured ceiling fissure. " + "Chiaroscuro high contrast cinematic lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph." +) + +video_prompt = ( + "0-3s: Low-angle tracking shot through heat-warped plastic debris and scorched concrete in subterranean B3 basement at Me Tri as Do Minh Kha walks slowly past motionless casualties, boots coated in red dust. " + "3-6s: Camera tilts down as Do Minh Kha crouches over Le Quoc Tien who slumps against a cracked concrete pillar beside a torn empty water pouch. Do Minh Kha speaks in a hoarse parched voice \"Lê Quốc Tiến, mày vốn không nên sống lâu đến thế.\" " + "6-8s: Close-up of Do Minh Kha raising a gleaming tactical blade reflecting the deep crimson sunlight bleeding through a fractured ceiling slab, then plunging the blade downward into pitch black darkness. " + "Audio: Stifled gasping breath, slow crunching footsteps on gravel, hoarse menacing dialogue, sharp metallic blade unsheath, deep sub-bass cinematic hit. Negative: subtitles, watermark, text overlay." +) + +# 1. Update Scene via SQLite directly to ensure all fields are set cleanly +conn = sqlite3.connect("flow_agent.db") +cur = conn.cursor() + +cur.execute(""" + UPDATE scene + SET horizontal_image_media_id = ?, + horizontal_image_url = ?, + horizontal_image_status = 'COMPLETED', + prompt = ?, + video_prompt = ?, + character_names = ?, + horizontal_video_status = 'PENDING', + horizontal_video_media_id = NULL, + horizontal_video_url = NULL, + updated_at = datetime('now') + WHERE id = ? +""", (media_id, img_url, prompt, video_prompt, json.dumps(["Le Quoc Tien", "Do Minh Kha"]), sid)) + +# 2. Cancel/clean old stuck requests +cur.execute("UPDATE request SET status = 'FAILED' WHERE status IN ('PENDING', 'PROCESSING')") + +conn.commit() +print("Scene #0 updated successfully in database!") + +# 3. Verify +cur.execute("SELECT id, prompt, horizontal_image_media_id, horizontal_image_status, horizontal_video_status FROM scene WHERE id = ?", (sid,)) +print("Verified scene row:", cur.fetchone()) +conn.close() diff --git a/scratch/view_recent_captures.py b/scratch/view_recent_captures.py new file mode 100644 index 000000000..49d865b6d --- /dev/null +++ b/scratch/view_recent_captures.py @@ -0,0 +1,9 @@ +import json + +lines = open('scratch/captured_netlog.jsonl', encoding='utf-8').read().splitlines() +for i, line in enumerate(lines[22:]): + d = json.loads(line) + print(f"--- Capture #{i+22} ---") + print("URL:", d['url']) + print("Status:", d['statusCode']) + print("Body snippet:", d.get('body', '')[:250]) diff --git a/scripts/cancel_video_requests.py b/scripts/cancel_video_requests.py new file mode 100644 index 000000000..eb4e09f3f --- /dev/null +++ b/scripts/cancel_video_requests.py @@ -0,0 +1,14 @@ +import sqlite3 + +conn = sqlite3.connect("flow_agent.db") +c = conn.cursor() +c.execute(""" + UPDATE request + SET status = 'FAILED', error_message = 'Cancelled for model testing' + WHERE video_id = '945ad6d4-5d79-4790-80db-1bff16ed7255' + AND type = 'GENERATE_VIDEO' + AND status IN ('PENDING', 'PROCESSING') +""") +print("Updated rows:", c.rowcount) +conn.commit() +conn.close() diff --git a/scripts/check_3_ops.py b/scripts/check_3_ops.py new file mode 100644 index 000000000..80a9bd3e0 --- /dev/null +++ b/scripts/check_3_ops.py @@ -0,0 +1,13 @@ +import requests +import json + +res = requests.post("http://127.0.0.1:8100/api/flow/check-status", json={ + "operations": [ + {"operation": {"name": "f870145a-7ab6-4608-9643-25839dcf8a9f"}}, + {"operation": {"name": "825308bd-19c6-4171-9b58-d2e01513b639"}}, + {"operation": {"name": "c8cfd8a0-1e3f-4400-8fb9-2c146e0d8db4"}} + ], + "project_id": "594758cc-11f5-4f92-8b3c-1213686591f4" +}) +print("Status code:", res.status_code) +print(json.dumps(res.json(), indent=2)) diff --git a/scripts/check_op.py b/scripts/check_op.py new file mode 100644 index 000000000..9ca42de81 --- /dev/null +++ b/scripts/check_op.py @@ -0,0 +1,9 @@ +import requests +import json + +res = requests.post("http://127.0.0.1:8100/api/flow/check-status", json={ + "operations": [{"operation": {"name": "2c817534-e7d9-4711-ba06-8da52e020080"}}], + "project_id": "594758cc-11f5-4f92-8b3c-1213686591f4" +}) +print("Status code:", res.status_code) +print("Response:", json.dumps(res.json(), indent=2)) diff --git a/scripts/create_hong_nhat_entities.py b/scripts/create_hong_nhat_entities.py new file mode 100644 index 000000000..d01bdf2d0 --- /dev/null +++ b/scripts/create_hong_nhat_entities.py @@ -0,0 +1,72 @@ +import asyncio +from agent.api.projects import _build_character_profile +from agent.sdk.persistence.sqlite_repository import SQLiteRepository +from agent.utils.slugify import slugify + +pid = '594758cc-11f5-4f92-8b3c-1213686591f4' +story = 'Ngay 22/06/2028, tham hoa Hong Nhat giang lam, mat troi doi mau do sam, nhiet do vuot 50C-68C thieu dot Ha Noi. Le Quoc Tien mang ky uc cua cai chet o Me Tri 2031 tinh day truoc do 44 ngay, cung Tran Thanh Thuy va cac nhom nguoi sinh ton bao ve ha tang ngam, doi dau Do Minh Kha va tim ra bi mat Cong Thang Long.' + +entities = [ + { + 'name': 'Le Quoc Tien', + 'entity_type': 'character', + 'description': '29-year-old Vietnamese system infrastructure engineer, lean athletic build, sharp determined Asian features, short clean black hair, wearing dark charcoal tactical t-shirt and grey cargo pants, digital wrist gauge, observant survivalist gaze.', + 'voice_description': 'Calm, firm, determined Vietnamese male voice with deep analytical cadence' + }, + { + 'name': 'Do Minh Kha', + 'entity_type': 'character', + 'description': '34-year-old Vietnamese logistics commander, tall imposing authoritative posture, slicked-back dark hair, wearing an unbuttoned black button-down shirt with rolled-up sleeves, dark trousers, distinctive matte black ring on his left ring finger, piercing cold calculated gaze.', + 'voice_description': 'Low, smooth, chillingly calm male voice with absolute authority' + }, + { + 'name': 'Tran Thanh Thuy', + 'entity_type': 'character', + 'description': '27-year-old Vietnamese investigative journalist, smart analytical expression, hair tied back in a neat ponytail, wearing a light beige utility shirt, olive multi-pocket reporter vest, canvas shoulder bag carrying a compact camera, intelligent perceptive dark eyes.', + 'voice_description': 'Clear, articulate, sharp and perceptive Vietnamese female voice' + }, + { + 'name': 'Nguyen Trai Avenue', + 'entity_type': 'location', + 'description': 'Wide bustling urban avenue in Hanoi during morning rush hour, elevated concrete metro tracks overhead with modern green Cat Linh - Ha Dong passenger train gliding past sleek glass skyscrapers and dense commuter traffic under a clear morning sky.' + }, + { + 'name': 'Dai Ha Mall Heat Trap', + 'entity_type': 'location', + 'description': 'Massive modern glass shopping mall in Ha Dong district under a terrifying dark crimson sun and apocalyptic red sky, giant glass windows completely fogged with thick condensation from dark boiling interior, heat ripples warping the melting empty asphalt parking lot outside.' + }, + { + 'name': 'Ngoc Truc Warehouse', + 'entity_type': 'location', + 'description': 'Secluded industrial concrete warehouse on Hanoi outskirts, weathered corrugated metal roof, dusty grey concrete floor with faint cracks, heavy circular dark metal floor hatch with an etched twelve-ray sun emblem hidden beneath metal shelving.' + }, + { + 'name': 'Dried West Lake Colossus', + 'entity_type': 'location', + 'description': 'Dried-up West Lake lakebed under a scorching apocalyptic deep crimson sun and hazy red sky, cracked black mud terrain revealing gigantic ancient dark metallic curved rib structures rising from the earth like colossal dragon bones, rising hot thermal steam.' + } +] + +async def run(): + repo = SQLiteRepository() + for ent in entities: + profile = _build_character_profile( + ent['name'], + ent['description'], + story, + entity_type=ent['entity_type'], + material_id='realistic' + ) + char = await repo.create_character( + name=ent['name'], + slug=slugify(ent['name']), + entity_type=ent['entity_type'], + description=profile['description'], + image_prompt=profile['image_prompt'], + voice_description=ent.get('voice_description') + ) + await repo.link_character_to_project(pid, char.id) + print("Created and linked: " + ent['name'] + " (" + ent['entity_type'] + ") -> ID: " + str(char.id)) + +if __name__ == '__main__': + asyncio.run(run()) diff --git a/scripts/create_hong_nhat_scenes.py b/scripts/create_hong_nhat_scenes.py new file mode 100644 index 000000000..2a9de28f2 --- /dev/null +++ b/scripts/create_hong_nhat_scenes.py @@ -0,0 +1,75 @@ +import json +import urllib.request + +vid = '945ad6d4-5d79-4790-80db-1bff16ed7255' + +scenes = [ + { + 'video_id': vid, + 'display_order': 0, + 'chain_type': 'ROOT', + 'character_names': ['Le Quoc Tien', 'Do Minh Kha'], + 'prompt': 'Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.', + 'video_prompt': '0-3s: Low-angle tracking shot through heat-warped plastic debris and scorched concrete in subterranean B3 basement at Me Tri as Do Minh Kha walks slowly past motionless casualties, boots coated in red dust. 3-6s: Camera tilts down as Do Minh Kha crouches over Le Quoc Tien, who clutches a bleeding abdominal wound beside a torn empty water pouch. Do Minh Kha speaks in a hoarse parched voice "Lê Quốc Tiến, mày vốn không nên sống lâu đến thế." 6-8s: Close-up of Do Minh Kha raising a gleaming tactical knife reflecting the deep crimson sunlight bleeding through a fractured ceiling slab, then plunging the blade downward into pitch black darkness. Audio: Stifled gasping breath, slow crunching footsteps on gravel, hoarse ominous dialogue, sharp metallic blade unsheath, deep sub-bass cinematic hit. Negative: subtitles, watermark, text overlay.', + 'narrator_text': 'Tầng hầm B3 Mễ Trì, năm 2031. Dưới ánh Hồng Nhật thiêu đốt, lưỡi dao của Đỗ Minh Kha đã kết thúc ba năm sinh tồn của tôi.' + }, + { + 'video_id': vid, + 'display_order': 1, + 'chain_type': 'ROOT', + 'character_names': ['Le Quoc Tien'], + 'prompt': 'Cinematic close-up of Le Quoc Tien jolting awake in bed, eyes wide with intense shock and cold sweat on his face. In background, a desktop setup with multiple glowing monitors and a digital clock displaying 07:13 AM. Soft morning golden sunlight streaming through half-open blinds. Photorealistic RAW photograph, Canon EOS R5, shallow depth of field.', + 'video_prompt': '0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight.' + }, + { + 'video_id': vid, + 'display_order': 2, + 'chain_type': 'ROOT', + 'character_names': ['Nguyen Trai Avenue'], + 'prompt': 'Wide establishing cinematic shot of Nguyen Trai Avenue in Hanoi during morning rush hour. The green Cat Linh - Ha Dong elevated metro train glides smoothly on elevated concrete tracks above dense streams of motorbikes and cars. Clear blue sky with gentle morning sun, modern city backdrop. RAW photograph, wide-angle 24mm, vibrant urban atmosphere.', + 'video_prompt': '0-3s: Elevated wide cinematic shot following the green metro train gliding on concrete viaducts. 3-6s: Camera cranes down toward dense streams of morning motorbike commuters on Nguyen Trai Avenue. 6-8s: Golden sunlight reflects brilliantly off modern glass skyscrapers under a blue sky.' + }, + { + 'video_id': vid, + 'display_order': 3, + 'chain_type': 'ROOT', + 'character_names': ['Dai Ha Mall Heat Trap'], + 'prompt': 'Terrifying apocalyptic cinematic shot of Dai Ha Mall Heat Trap in Ha Dong under an eerie blood-red sky with a massive dark crimson sun. Dense crowd of panicked people inside banging frantically against fogged-up glass doors from dark steaming interiors. Heat ripples distorting the melting asphalt road outside. High contrast dramatic disaster lighting, 35mm RAW photograph.', + 'video_prompt': '0-3s: Camera pushes rapidly toward fogged glass doors as desperate hands slam against the condensation from steaming dark interiors of Dai Ha Mall Heat Trap. 3-6s: Pan up sharply to the terrifying dark crimson sun blazing in a blood-red hazy sky. 6-8s: Violent heat waves distort the melting asphalt parking lot in the foreground.' + }, + { + 'video_id': vid, + 'display_order': 4, + 'chain_type': 'ROOT', + 'character_names': ['Le Quoc Tien', 'Ngoc Truc Warehouse'], + 'prompt': 'Atmospheric cinematic shot inside Ngoc Truc Warehouse. Le Quoc Tien shines a flashlight onto a heavy dark metal hatch embedded in the concrete floor. The circular sun emblem with twelve rays on the hatch glows with an ominous deep red bioluminescent light. Dense cold vapor rising from the metallic seams. 35mm cinematic photograph, moody volumetric shadows.', + 'video_prompt': '0-3s: Medium tracking shot of Le Quoc Tien prying aside a rusted metal shelf inside Ngoc Truc Warehouse to reveal a dark round floor hatch. 3-6s: The etched circular sun emblem on the metal hatch pulses with an ancient crimson glow. 6-8s: Freezing subterranean vapor hisses out as deep mechanical latches unlock underneath.' + }, + { + 'video_id': vid, + 'display_order': 5, + 'chain_type': 'ROOT', + 'character_names': ['Tran Thanh Thuy', 'Do Minh Kha', 'Dried West Lake Colossus'], + 'prompt': 'Epic cinematic wide shot of Dried West Lake Colossus in Hanoi under a dark apocalyptic red sun. Cracked black mud lakebed exposes colossal ancient dark metallic ribbed structures resembling giant dragon bones protruding from the earth. Tran Thanh Thuy and Do Minh Kha stand on the distant embankment silhouetted against the colossal metallic ruins and crimson haze. Masterpiece cinematic photography, 16:9 ultra-wide, atmospheric scale.', + 'video_prompt': '0-3s: Epic sweeping drone pull-back over cracked black mud of Dried West Lake Colossus exposing colossal ancient metal ribs rising from the dry lakebed. 3-6s: Crimson sunlight reflects off the weathered metallic structures as steam rises from fissures. 6-8s: Low shot of Tran Thanh Thuy and Do Minh Kha on the distant embankment silhouetted against the colossal colossus.' + } +] + +created_scenes = [] + +for sc in scenes: + req_body = json.dumps(sc).encode('utf-8') + req = urllib.request.Request( + 'http://127.0.0.1:8100/api/scenes', + data=req_body, + headers={'Content-Type': 'application/json'}, + method='POST' + ) + with urllib.request.urlopen(req) as resp: + s_data = json.loads(resp.read().decode('utf-8')) + created_scenes.append(s_data) + print(f"Created Scene {sc['display_order'] + 1}: {s_data['id']}") + +with open('scripts/created_scenes.json', 'w', encoding='utf-8') as f: + json.dump(created_scenes, f, indent=2) +print("Done all scenes!") diff --git a/scripts/created_entities.json b/scripts/created_entities.json new file mode 100644 index 000000000..7d0a47559 --- /dev/null +++ b/scripts/created_entities.json @@ -0,0 +1,9 @@ +{ + "Le Quoc Tien": "977bc0ef-fdd5-4308-9d9d-e42cadb9d345", + "Do Minh Kha": "859dfced-a563-4785-870b-6ddab4c203e3", + "Tran Thanh Thuy": "427d3b59-92a2-4b4c-b2fc-09cceb50d0bc", + "Nguyen Trai Avenue": "ed0a8dc0-3b73-4ddd-acd3-ce8815aae2fc", + "Dai Ha Mall Heat Trap": "2c9b76ac-1cd1-4e3b-89e7-25f1c5ff8eba", + "Ngoc Truc Warehouse": "eb133db8-d233-4d67-8dae-ae80a04587c8", + "Dried West Lake Colossus": "f4afe205-8426-4fa3-9304-e62dd52f5688" +} \ No newline at end of file diff --git a/scripts/created_scenes.json b/scripts/created_scenes.json new file mode 100644 index 000000000..2bd4d4326 --- /dev/null +++ b/scripts/created_scenes.json @@ -0,0 +1,252 @@ +[ + { + "id": "02f6d29e-be27-491a-b1ad-baa944964890", + "video_id": "945ad6d4-5d79-4790-80db-1bff16ed7255", + "display_order": 0, + "prompt": "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in a shattered underground basement. Le Quoc Tien in dark torn clothes slumps against cracked burning concrete. Do Minh Kha stands over him holding a gleaming tactical knife, silhouette backlit by deep crimson sunlight piercing through fractured ceiling slabs. RAW photograph, 35mm lens, intense chiaroscuro lighting, floating embers and dust particles.", + "image_prompt": null, + "video_prompt": "0-3s: Low angle looking up at the cold silhouette of Do Minh Kha raising a tactical knife against crimson light. 3-6s: Camera tilts down to Le Quoc Tien gasping on cracked hot concrete. 6-8s: The blade thrusts downward as deep red haze floods the dark chamber.", + "character_names": [ + "Le Quoc Tien", + "Do Minh Kha" + ], + "parent_scene_id": null, + "chain_type": "ROOT", + "source": "root", + "vertical_image_url": null, + "vertical_image_media_id": null, + "vertical_image_status": "PENDING", + "vertical_video_url": null, + "vertical_video_media_id": null, + "vertical_video_status": "PENDING", + "vertical_upscale_url": null, + "vertical_upscale_media_id": null, + "vertical_upscale_status": "PENDING", + "horizontal_image_url": null, + "horizontal_image_media_id": null, + "horizontal_image_status": "PENDING", + "horizontal_video_url": null, + "horizontal_video_media_id": null, + "horizontal_video_status": "PENDING", + "horizontal_upscale_url": null, + "horizontal_upscale_media_id": null, + "horizontal_upscale_status": "PENDING", + "vertical_end_scene_media_id": null, + "horizontal_end_scene_media_id": null, + "transition_prompt": null, + "trim_start": null, + "trim_end": null, + "duration": null, + "narrator_text": null, + "created_at": "2026-09-22T17:42:30Z", + "updated_at": "2026-09-22T17:42:30Z" + }, + { + "id": "09e19387-62fe-40e0-b1e2-ed654c2b6287", + "video_id": "945ad6d4-5d79-4790-80db-1bff16ed7255", + "display_order": 1, + "prompt": "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Cinematic close-up of Le Quoc Tien jolting awake in bed, eyes wide with intense shock and cold sweat on his face. In background, a desktop setup with multiple glowing monitors and a digital clock displaying 07:13 AM. Soft morning golden sunlight streaming through half-open blinds. Photorealistic RAW photograph, Canon EOS R5, shallow depth of field.", + "image_prompt": null, + "video_prompt": "0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight.", + "character_names": [ + "Le Quoc Tien" + ], + "parent_scene_id": null, + "chain_type": "ROOT", + "source": "root", + "vertical_image_url": null, + "vertical_image_media_id": null, + "vertical_image_status": "PENDING", + "vertical_video_url": null, + "vertical_video_media_id": null, + "vertical_video_status": "PENDING", + "vertical_upscale_url": null, + "vertical_upscale_media_id": null, + "vertical_upscale_status": "PENDING", + "horizontal_image_url": null, + "horizontal_image_media_id": null, + "horizontal_image_status": "PENDING", + "horizontal_video_url": null, + "horizontal_video_media_id": null, + "horizontal_video_status": "PENDING", + "horizontal_upscale_url": null, + "horizontal_upscale_media_id": null, + "horizontal_upscale_status": "PENDING", + "vertical_end_scene_media_id": null, + "horizontal_end_scene_media_id": null, + "transition_prompt": null, + "trim_start": null, + "trim_end": null, + "duration": null, + "narrator_text": null, + "created_at": "2026-09-22T17:42:30Z", + "updated_at": "2026-09-22T17:42:30Z" + }, + { + "id": "f87d7d98-42ff-41d5-b1cf-1ab1e9d359aa", + "video_id": "945ad6d4-5d79-4790-80db-1bff16ed7255", + "display_order": 2, + "prompt": "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Wide establishing cinematic shot of Nguyen Trai Avenue in Hanoi during morning rush hour. The green Cat Linh - Ha Dong elevated metro train glides smoothly on elevated concrete tracks above dense streams of motorbikes and cars. Clear blue sky with gentle morning sun, modern city backdrop. RAW photograph, wide-angle 24mm, vibrant urban atmosphere.", + "image_prompt": null, + "video_prompt": "0-3s: Elevated wide cinematic shot following the green metro train gliding on concrete viaducts. 3-6s: Camera cranes down toward dense streams of morning motorbike commuters on Nguyen Trai Avenue. 6-8s: Golden sunlight reflects brilliantly off modern glass skyscrapers under a blue sky.", + "character_names": [ + "Nguyen Trai Avenue" + ], + "parent_scene_id": null, + "chain_type": "ROOT", + "source": "root", + "vertical_image_url": null, + "vertical_image_media_id": null, + "vertical_image_status": "PENDING", + "vertical_video_url": null, + "vertical_video_media_id": null, + "vertical_video_status": "PENDING", + "vertical_upscale_url": null, + "vertical_upscale_media_id": null, + "vertical_upscale_status": "PENDING", + "horizontal_image_url": null, + "horizontal_image_media_id": null, + "horizontal_image_status": "PENDING", + "horizontal_video_url": null, + "horizontal_video_media_id": null, + "horizontal_video_status": "PENDING", + "horizontal_upscale_url": null, + "horizontal_upscale_media_id": null, + "horizontal_upscale_status": "PENDING", + "vertical_end_scene_media_id": null, + "horizontal_end_scene_media_id": null, + "transition_prompt": null, + "trim_start": null, + "trim_end": null, + "duration": null, + "narrator_text": null, + "created_at": "2026-09-22T17:42:30Z", + "updated_at": "2026-09-22T17:42:30Z" + }, + { + "id": "5369b582-6238-4cee-a1d1-1c30b89625f6", + "video_id": "945ad6d4-5d79-4790-80db-1bff16ed7255", + "display_order": 3, + "prompt": "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Terrifying apocalyptic cinematic shot of Dai Ha Mall Heat Trap in Ha Dong under an eerie blood-red sky with a massive dark crimson sun. Dense crowd of panicked people inside banging frantically against fogged-up glass doors from dark steaming interiors. Heat ripples distorting the melting asphalt road outside. High contrast dramatic disaster lighting, 35mm RAW photograph.", + "image_prompt": null, + "video_prompt": "0-3s: Camera pushes rapidly toward fogged glass doors as desperate hands slam against the condensation from steaming dark interiors of Dai Ha Mall Heat Trap. 3-6s: Pan up sharply to the terrifying dark crimson sun blazing in a blood-red hazy sky. 6-8s: Violent heat waves distort the melting asphalt parking lot in the foreground.", + "character_names": [ + "Dai Ha Mall Heat Trap" + ], + "parent_scene_id": null, + "chain_type": "ROOT", + "source": "root", + "vertical_image_url": null, + "vertical_image_media_id": null, + "vertical_image_status": "PENDING", + "vertical_video_url": null, + "vertical_video_media_id": null, + "vertical_video_status": "PENDING", + "vertical_upscale_url": null, + "vertical_upscale_media_id": null, + "vertical_upscale_status": "PENDING", + "horizontal_image_url": null, + "horizontal_image_media_id": null, + "horizontal_image_status": "PENDING", + "horizontal_video_url": null, + "horizontal_video_media_id": null, + "horizontal_video_status": "PENDING", + "horizontal_upscale_url": null, + "horizontal_upscale_media_id": null, + "horizontal_upscale_status": "PENDING", + "vertical_end_scene_media_id": null, + "horizontal_end_scene_media_id": null, + "transition_prompt": null, + "trim_start": null, + "trim_end": null, + "duration": null, + "narrator_text": null, + "created_at": "2026-09-22T17:42:30Z", + "updated_at": "2026-09-22T17:42:30Z" + }, + { + "id": "0da53533-6028-4a9e-ab65-083b15a3cbb3", + "video_id": "945ad6d4-5d79-4790-80db-1bff16ed7255", + "display_order": 4, + "prompt": "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Atmospheric cinematic shot inside Ngoc Truc Warehouse. Le Quoc Tien shines a flashlight onto a heavy dark metal hatch embedded in the concrete floor. The circular sun emblem with twelve rays on the hatch glows with an ominous deep red bioluminescent light. Dense cold vapor rising from the metallic seams. 35mm cinematic photograph, moody volumetric shadows.", + "image_prompt": null, + "video_prompt": "0-3s: Medium tracking shot of Le Quoc Tien prying aside a rusted metal shelf inside Ngoc Truc Warehouse to reveal a dark round floor hatch. 3-6s: The etched circular sun emblem on the metal hatch pulses with an ancient crimson glow. 6-8s: Freezing subterranean vapor hisses out as deep mechanical latches unlock underneath.", + "character_names": [ + "Le Quoc Tien", + "Ngoc Truc Warehouse" + ], + "parent_scene_id": null, + "chain_type": "ROOT", + "source": "root", + "vertical_image_url": null, + "vertical_image_media_id": null, + "vertical_image_status": "PENDING", + "vertical_video_url": null, + "vertical_video_media_id": null, + "vertical_video_status": "PENDING", + "vertical_upscale_url": null, + "vertical_upscale_media_id": null, + "vertical_upscale_status": "PENDING", + "horizontal_image_url": null, + "horizontal_image_media_id": null, + "horizontal_image_status": "PENDING", + "horizontal_video_url": null, + "horizontal_video_media_id": null, + "horizontal_video_status": "PENDING", + "horizontal_upscale_url": null, + "horizontal_upscale_media_id": null, + "horizontal_upscale_status": "PENDING", + "vertical_end_scene_media_id": null, + "horizontal_end_scene_media_id": null, + "transition_prompt": null, + "trim_start": null, + "trim_end": null, + "duration": null, + "narrator_text": null, + "created_at": "2026-09-22T17:42:30Z", + "updated_at": "2026-09-22T17:42:30Z" + }, + { + "id": "50c2da1f-57f4-4027-b275-493751085a31", + "video_id": "945ad6d4-5d79-4790-80db-1bff16ed7255", + "display_order": 5, + "prompt": "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Epic cinematic wide shot of Dried West Lake Colossus in Hanoi under a dark apocalyptic red sun. Cracked black mud lakebed exposes colossal ancient dark metallic ribbed structures resembling giant dragon bones protruding from the earth. Tran Thanh Thuy and Do Minh Kha stand on the distant embankment silhouetted against the colossal metallic ruins and crimson haze. Masterpiece cinematic photography, 16:9 ultra-wide, atmospheric scale.", + "image_prompt": null, + "video_prompt": "0-3s: Epic sweeping drone pull-back over cracked black mud of Dried West Lake Colossus exposing colossal ancient metal ribs rising from the dry lakebed. 3-6s: Crimson sunlight reflects off the weathered metallic structures as steam rises from fissures. 6-8s: Low shot of Tran Thanh Thuy and Do Minh Kha on the distant embankment silhouetted against the colossal colossus.", + "character_names": [ + "Tran Thanh Thuy", + "Do Minh Kha", + "Dried West Lake Colossus" + ], + "parent_scene_id": null, + "chain_type": "ROOT", + "source": "root", + "vertical_image_url": null, + "vertical_image_media_id": null, + "vertical_image_status": "PENDING", + "vertical_video_url": null, + "vertical_video_media_id": null, + "vertical_video_status": "PENDING", + "vertical_upscale_url": null, + "vertical_upscale_media_id": null, + "vertical_upscale_status": "PENDING", + "horizontal_image_url": null, + "horizontal_image_media_id": null, + "horizontal_image_status": "PENDING", + "horizontal_video_url": null, + "horizontal_video_media_id": null, + "horizontal_video_status": "PENDING", + "horizontal_upscale_url": null, + "horizontal_upscale_media_id": null, + "horizontal_upscale_status": "PENDING", + "vertical_end_scene_media_id": null, + "horizontal_end_scene_media_id": null, + "transition_prompt": null, + "trim_start": null, + "trim_end": null, + "duration": null, + "narrator_text": null, + "created_at": "2026-09-22T17:42:30Z", + "updated_at": "2026-09-22T17:42:30Z" + } +] \ No newline at end of file diff --git a/scripts/created_video.json b/scripts/created_video.json new file mode 100644 index 000000000..43aef4621 --- /dev/null +++ b/scripts/created_video.json @@ -0,0 +1,19 @@ +{ + "id": "945ad6d4-5d79-4790-80db-1bff16ed7255", + "project_id": "594758cc-11f5-4f92-8b3c-1213686591f4", + "title": "H\u1ed3ng Nh\u1eadt Th\u0103ng Long - Teaser Trailer", + "description": null, + "display_order": 0, + "status": "DRAFT", + "orientation": "HORIZONTAL", + "vertical_url": null, + "horizontal_url": null, + "thumbnail_url": null, + "duration": null, + "resolution": null, + "youtube_id": null, + "privacy": "unlisted", + "tags": null, + "created_at": "2026-09-22T17:42:07Z", + "updated_at": "2026-09-22T17:42:07Z" +} \ No newline at end of file diff --git a/scripts/debug_op_lookup.py b/scripts/debug_op_lookup.py new file mode 100644 index 000000000..5456b0b75 --- /dev/null +++ b/scripts/debug_op_lookup.py @@ -0,0 +1,31 @@ +import asyncio +from agent.services.flow_client import get_flow_client +from agent.config import FLOW_PROJECT_ID + +async def main(): + client = get_flow_client() + pid = "594758cc-11f5-4f92-8b3c-1213686591f4" + op_id = "f870145a-7ab6-4608-9643-25839dcf8a9f" + + print("Testing _media_id_for...") + try: + mid = await client._media_id_for(op_id, pid) + print("Result mid:", mid) + except Exception as e: + print("Error in _media_id_for:", e) + + # Let's inspect the raw listing window around op_id + import agent.services.flow_batch as fb + res = await client.batch_rpc( + fb.RPC_PROJECT_MEDIA, fb.project_media_request(pid), + match=op_id, timeout=30 + ) + raw = res.get("data") or "" + print("Raw match length:", len(raw)) + start = raw.find(op_id) + print("Start index:", start) + if start != -1: + print("Snippet around op_id:") + print(raw[max(0, start-100): min(len(raw), start+500)]) + +asyncio.run(main()) diff --git a/scripts/inspect_flow_cache.py b/scripts/inspect_flow_cache.py new file mode 100644 index 000000000..b65298750 --- /dev/null +++ b/scripts/inspect_flow_cache.py @@ -0,0 +1,9 @@ +import asyncio +from agent.services.flow_client import get_flow_client + +async def main(): + client = get_flow_client() + print("operation_media:", client._operation_media) + print("operation_projects:", client._operation_projects) + +asyncio.run(main()) diff --git a/scripts/inspect_processing.py b/scripts/inspect_processing.py new file mode 100644 index 000000000..63bf9ec9f --- /dev/null +++ b/scripts/inspect_processing.py @@ -0,0 +1,10 @@ +import sqlite3 + +conn = sqlite3.connect("flow_agent.db") +c = conn.cursor() + +c.execute("SELECT id, scene_id, status, request_id, error_message FROM request WHERE video_id='945ad6d4-5d79-4790-80db-1bff16ed7255' AND type='GENERATE_VIDEO' AND status='PROCESSING'") +for r in c.fetchall(): + print(r) + +conn.close() diff --git a/scripts/inspect_video_progress.py b/scripts/inspect_video_progress.py new file mode 100644 index 000000000..815c9905a --- /dev/null +++ b/scripts/inspect_video_progress.py @@ -0,0 +1,19 @@ +import sqlite3 +import json + +conn = sqlite3.connect("flow_agent.db") +c = conn.cursor() + +c.execute("SELECT id, scene_id, status, error_message, updated_at FROM request WHERE video_id='945ad6d4-5d79-4790-80db-1bff16ed7255' AND type='GENERATE_VIDEO'") +reqs = c.fetchall() +print("=== REQUESTS ===") +for r in reqs: + print(r) + +c.execute("SELECT display_order, id, horizontal_video_status, horizontal_video_media_id FROM scene ORDER BY display_order") +scenes = c.fetchall() +print("\n=== SCENES ===") +for s in scenes: + print(s) + +conn.close() diff --git a/scripts/populate_entities_via_api.py b/scripts/populate_entities_via_api.py new file mode 100644 index 000000000..3e8a745e3 --- /dev/null +++ b/scripts/populate_entities_via_api.py @@ -0,0 +1,83 @@ +import json +import urllib.request + +pid = '594758cc-11f5-4f92-8b3c-1213686591f4' + +# Pre-computed image_prompts using realistic style +entities = [ + { + 'name': 'Le Quoc Tien', + 'entity_type': 'character', + 'description': 'Le Quoc Tien: 29-year-old Vietnamese system infrastructure engineer, lean athletic build, sharp determined Asian features, short clean black hair, wearing dark charcoal tactical t-shirt and grey cargo pants, digital wrist gauge, observant survivalist gaze.', + 'image_prompt': 'Single reference image of 29-year-old Vietnamese system infrastructure engineer, lean athletic build, sharp determined Asian features, short clean black hair, wearing dark charcoal tactical t-shirt and grey cargo pants, digital wrist gauge, observant survivalist gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed', + 'voice_description': 'Calm, firm, determined Vietnamese male voice with deep analytical cadence' + }, + { + 'name': 'Do Minh Kha', + 'entity_type': 'character', + 'description': 'Do Minh Kha: 34-year-old Vietnamese logistics commander, tall imposing authoritative posture, slicked-back dark hair, wearing an unbuttoned black button-down shirt with rolled-up sleeves, dark trousers, distinctive matte black ring on his left ring finger, piercing cold calculated gaze.', + 'image_prompt': 'Single reference image of 34-year-old Vietnamese logistics commander, tall imposing authoritative posture, slicked-back dark hair, wearing an unbuttoned black button-down shirt with rolled-up sleeves, dark trousers, distinctive matte black ring on his left ring finger, piercing cold calculated gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed', + 'voice_description': 'Low, smooth, chillingly calm male voice with absolute authority' + }, + { + 'name': 'Tran Thanh Thuy', + 'entity_type': 'character', + 'description': 'Tran Thanh Thuy: 27-year-old Vietnamese investigative journalist, smart analytical expression, hair tied back in a neat ponytail, wearing a light beige utility shirt, olive multi-pocket reporter vest, canvas shoulder bag carrying a compact camera, intelligent perceptive dark eyes.', + 'image_prompt': 'Single reference image of 27-year-old Vietnamese investigative journalist, smart analytical expression, hair tied back in a neat ponytail, wearing a light beige utility shirt, olive multi-pocket reporter vest, canvas shoulder bag carrying a compact camera, intelligent perceptive dark eyes. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed', + 'voice_description': 'Clear, articulate, sharp and perceptive Vietnamese female voice' + }, + { + 'name': 'Nguyen Trai Avenue', + 'entity_type': 'location', + 'description': 'Nguyen Trai Avenue: Wide bustling urban avenue in Hanoi during morning rush hour, elevated concrete metro tracks overhead with modern green Cat Linh - Ha Dong passenger train gliding past sleek glass skyscrapers and dense commuter traffic under a clear morning sky.', + 'image_prompt': 'Single reference image of Wide bustling urban avenue in Hanoi during morning rush hour, elevated concrete metro tracks overhead with modern green Cat Linh - Ha Dong passenger train gliding past sleek glass skyscrapers and dense commuter traffic under a clear morning sky. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed' + }, + { + 'name': 'Dai Ha Mall Heat Trap', + 'entity_type': 'location', + 'description': 'Dai Ha Mall Heat Trap: Massive modern glass shopping mall in Ha Dong district under a terrifying dark crimson sun and apocalyptic red sky, giant glass windows completely fogged with thick condensation from dark boiling interior, heat ripples warping the melting empty asphalt parking lot outside.', + 'image_prompt': 'Single reference image of Massive modern glass shopping mall in Ha Dong district under a terrifying dark crimson sun and apocalyptic red sky, giant glass windows completely fogged with thick condensation from dark boiling interior, heat ripples warping the melting empty asphalt parking lot outside. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed' + }, + { + 'name': 'Ngoc Truc Warehouse', + 'entity_type': 'location', + 'description': 'Ngoc Truc Warehouse: Secluded industrial concrete warehouse on Hanoi outskirts, weathered corrugated metal roof, dusty grey concrete floor with faint cracks, heavy circular dark metal floor hatch with an etched twelve-ray sun emblem hidden beneath metal shelving.', + 'image_prompt': 'Single reference image of Secluded industrial concrete warehouse on Hanoi outskirts, weathered corrugated metal roof, dusty grey concrete floor with faint cracks, heavy circular dark metal floor hatch with an etched twelve-ray sun emblem hidden beneath metal shelving. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed' + }, + { + 'name': 'Dried West Lake Colossus', + 'entity_type': 'location', + 'description': 'Dried West Lake Colossus: Dried-up West Lake lakebed under a scorching apocalyptic deep crimson sun and hazy red sky, cracked black mud terrain revealing gigantic ancient dark metallic curved rib structures rising from the earth like colossal dragon bones, rising hot thermal steam.', + 'image_prompt': 'Single reference image of Dried-up West Lake lakebed under a scorching apocalyptic deep crimson sun and hazy red sky, cracked black mud terrain revealing gigantic ancient dark metallic curved rib structures rising from the earth like colossal dragon bones, rising hot thermal steam. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed' + } +] + +created_ids = {} + +for ent in entities: + req_body = json.dumps(ent).encode('utf-8') + req = urllib.request.Request( + 'http://127.0.0.1:8100/api/characters', + data=req_body, + headers={'Content-Type': 'application/json'}, + method='POST' + ) + with urllib.request.urlopen(req) as resp: + char_data = json.loads(resp.read().decode('utf-8')) + cid = char_data['id'] + created_ids[ent['name']] = cid + print(f"Created Character: {ent['name']} -> {cid}") + + # Link to project + link_req = urllib.request.Request( + f'http://127.0.0.1:8100/api/projects/{pid}/characters/{cid}', + data=b'{}', + headers={'Content-Type': 'application/json'}, + method='POST' + ) + with urllib.request.urlopen(link_req) as resp: + print(f"Linked {ent['name']} to project {pid}") + +with open('scripts/created_entities.json', 'w', encoding='utf-8') as f: + json.dump(created_ids, f, indent=2) +print("Done all entities!") diff --git a/scripts/search_db_ids.py b/scripts/search_db_ids.py new file mode 100644 index 000000000..bd6675205 --- /dev/null +++ b/scripts/search_db_ids.py @@ -0,0 +1,17 @@ +import sqlite3 + +conn = sqlite3.connect("flow_agent.db") +c = conn.cursor() + +tables = [t[0] for t in c.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall()] +for t in tables: + cols = [col[1] for col in c.execute(f"PRAGMA table_info({t})").fetchall()] + for col in cols: + try: + rows = c.execute(f"SELECT * FROM {t} WHERE {col} LIKE '%6c8df1af%' OR {col} LIKE '%825308bd%' OR {col} LIKE '%f870145a%'").fetchall() + if rows: + print(f"Found in {t}.{col}:", rows) + except Exception: + pass + +conn.close() diff --git a/scripts/test_video_gen.py b/scripts/test_video_gen.py new file mode 100644 index 000000000..4e04770f0 --- /dev/null +++ b/scripts/test_video_gen.py @@ -0,0 +1,54 @@ +import requests +import json + +url = "http://127.0.0.1:8100/api/flow/generate-video" + +# Test 1: veo_3_1_i2v_lite +patch_res = requests.patch("http://127.0.0.1:8100/api/models", json={ + "video_models": { + "PAYGATE_TIER_TWO": { + "frame_2_video": { + "VIDEO_ASPECT_RATIO_LANDSCAPE": "veo_3_1_i2v_lite", + "VIDEO_ASPECT_RATIO_PORTRAIT": "veo_3_1_i2v_lite" + } + } + } +}) + +payload_veo = { + "start_image_media_id": "a6010398-57c9-4e27-a89f-31ed0ddf2d1a", + "prompt": "Camera pans slowly across cracked asphalt under a red burning sun.", + "project_id": "594758cc-11f5-4f92-8b3c-1213686591f4", + "scene_id": "02f6d29e-be27-491a-b1ad-baa944964890", + "aspect_ratio": "VIDEO_ASPECT_RATIO_LANDSCAPE", + "user_paygate_tier": "PAYGATE_TIER_TWO" +} + +print("\n--- Testing Veo (veo_3_1_i2v_lite) ---") +res = requests.post(url, json=payload_veo, timeout=30) +print("Status code:", res.status_code) +try: + print("Response:", json.dumps(res.json(), indent=2)) +except Exception: + print("Response text:", res.text) + +# Test 2: Omni Flash +payload_omni = { + "start_image_media_id": "a6010398-57c9-4e27-a89f-31ed0ddf2d1a", + "prompt": "Camera pans slowly across cracked asphalt under a red burning sun.", + "project_id": "594758cc-11f5-4f92-8b3c-1213686591f4", + "scene_id": "02f6d29e-be27-491a-b1ad-baa944964890", + "aspect_ratio": "VIDEO_ASPECT_RATIO_LANDSCAPE", + "user_paygate_tier": "PAYGATE_TIER_TWO", + "model_family": "omni_flash", + "duration_s": 8, + "resolution": "720p" +} + +print("\n--- Testing Omni Flash (abra_i2v_8s) ---") +res2 = requests.post(url, json=payload_omni, timeout=30) +print("Status code:", res2.status_code) +try: + print("Response:", json.dumps(res2.json(), indent=2)) +except Exception: + print("Response text:", res2.text) diff --git a/scripts/update_scene1_video.py b/scripts/update_scene1_video.py new file mode 100644 index 000000000..1e2644a17 --- /dev/null +++ b/scripts/update_scene1_video.py @@ -0,0 +1,14 @@ +import sqlite3 + +conn = sqlite3.connect("flow_agent.db") +c = conn.cursor() +c.execute(""" + UPDATE scene + SET horizontal_video_media_id = 'c8939cac-021c-4000-a355-ec23628e5ea0', + horizontal_video_url = 'https://flow-content.google/video/c8939cac-021c-4000-a355-ec23628e5ea0?Expires=1790121427&KeyName=labs-flow-prod-cdn-key&Signature=3RdzQrTwdp0xdixmvS4V7MGy7Cc', + horizontal_video_status = 'COMPLETED' + WHERE id = '02f6d29e-be27-491a-b1ad-baa944964890' +""") +print("Updated scene 1:", c.rowcount) +conn.commit() +conn.close() diff --git a/scripts/upgrade_scene_1.py b/scripts/upgrade_scene_1.py new file mode 100644 index 000000000..0da731f00 --- /dev/null +++ b/scripts/upgrade_scene_1.py @@ -0,0 +1,41 @@ +import json +import urllib.request + +sid = "02f6d29e-be27-491a-b1ad-baa944964890" +url = f"http://127.0.0.1:8100/api/scenes/{sid}" + +payload = { + "prompt": ( + "Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. " + "Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. " + "Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound " + "beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, " + "holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. " + "Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph." + ), + "video_prompt": ( + "0-3s: Low-angle tracking shot through heat-warped plastic debris and scorched concrete in subterranean B3 basement at Me Tri " + "as Do Minh Kha walks slowly past motionless casualties, boots coated in red dust. " + "3-6s: Camera tilts down as Do Minh Kha crouches over Le Quoc Tien, who clutches a bleeding abdominal wound beside a torn empty water pouch. " + "Do Minh Kha speaks in a hoarse parched voice \"Lê Quốc Tiến, mày vốn không nên sống lâu đến thế.\" " + "6-8s: Close-up of Do Minh Kha raising a gleaming tactical knife reflecting the deep crimson sunlight bleeding through a fractured ceiling slab, " + "then plunging the blade downward into pitch black darkness. " + "Audio: Stifled gasping breath, slow crunching footsteps on gravel, hoarse menacing dialogue, sharp metallic blade unsheath, deep sub-bass cinematic hit. " + "Negative: subtitles, watermark, text overlay." + ), + "narrator_text": "Tầng hầm B3 Mễ Trì, năm 2031. Dưới ánh Hồng Nhật thiêu đốt, lưỡi dao của Đỗ Minh Kha đã kết thúc ba năm sinh tồn của tôi." +} + +req = urllib.request.Request( + url, + data=json.dumps(payload).encode("utf-8"), + headers={"Content-Type": "application/json"}, + method="PATCH" +) + +with urllib.request.urlopen(req) as resp: + res = json.loads(resp.read().decode()) + print("Updated successfully:", res["id"]) + print("Prompt:", res["prompt"]) + print("Video prompt:", res["video_prompt"]) + print("Narrator text:", res["narrator_text"]) diff --git a/tests/unit/test_flow_batch_golden.py b/tests/unit/test_flow_batch_golden.py index be4c0364b..66dfd9031 100644 --- a/tests/unit/test_flow_batch_golden.py +++ b/tests/unit/test_flow_batch_golden.py @@ -37,11 +37,10 @@ def pinned_uuids(monkeypatch): '[[["ogiZ0b","[null,[[null,null,[[\\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\\",null,' 'null,null,1]],42,2,\\"GEM_PIX_2\\",null,[null,22,null,null,null,' '\\"11111111-2222-3333-4444-555555555555\\",null,null,null,null,' - '[\\"__CAPTCHA__\\",1]],[[[\\"a cat\\"]]],null,null,null,' - '\\"00000000-0000-4000-8000-000000000001\\",' - '\\"00000000-0000-4000-8000-000000000002\\"]],1,[null,22,null,null,null,' + '[\\"__CAPTCHA__\\",1]],[[[\\"a cat\\"]]],null,null,null,null,' + '\\"00000000-0000-4000-8000-000000000001\\"]],1,[null,22,null,null,null,' '\\"11111111-2222-3333-4444-555555555555\\",null,null,null,null,' - '[\\"__CAPTCHA__\\",1]],[\\"00000000-0000-4000-8000-000000000003\\"]]",' + '[\\"__CAPTCHA__\\",1]],[\\"00000000-0000-4000-8000-000000000002\\"]]",' 'null,"generic"]]]' ) diff --git a/tests/unit/test_video_reviewer.py b/tests/unit/test_video_reviewer.py index 3562b4322..6ac0e0970 100644 --- a/tests/unit/test_video_reviewer.py +++ b/tests/unit/test_video_reviewer.py @@ -98,10 +98,15 @@ def test_downsampling_selects_correct_nonconsecutive_frames_across_chunks( symlinks = sorted(chunk_dir.glob("f_*.jpg")) assert len(symlinks) == len(expected_chunk) for link, expected_target in zip(symlinks, expected_chunk): - assert link.resolve() == expected_target.resolve(), ( - f"chunk {sheet_idx} symlink {link.name} points to " - f"{link.resolve()}, expected {expected_target.resolve()}" - ) + if link.is_symlink(): + assert link.resolve() == expected_target.resolve(), ( + f"chunk {sheet_idx} symlink {link.name} points to " + f"{link.resolve()}, expected {expected_target.resolve()}" + ) + else: + assert link.read_bytes() == expected_target.read_bytes(), ( + f"chunk {sheet_idx} file {link.name} content mismatch with {expected_target}" + ) finally: shutil.rmtree(out_dir, ignore_errors=True) From 00d55748e8c674bad29f860fb0711f8fee476d17 Mon Sep 17 00:00:00 2001 From: TIENLV Date: Mon, 5 Oct 2026 21:40:59 +0700 Subject: [PATCH 57/68] fix(muse2api): support Windows file:// URLs using file_url_to_path --- agent/sdk/services/muse2api_provider.py | 7 ++++--- agent/services/muse2api_client.py | 6 ++++-- tests/unit/test_muse2api_provider.py | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/agent/sdk/services/muse2api_provider.py b/agent/sdk/services/muse2api_provider.py index 28af6c531..3cad78b0b 100644 --- a/agent/sdk/services/muse2api_provider.py +++ b/agent/sdk/services/muse2api_provider.py @@ -45,6 +45,7 @@ ProviderJob, ) from agent.services.muse2api_client import Muse2APIClient, Muse2APIError, to_data_url +from agent.utils.paths import file_url_to_path logger = logging.getLogger(__name__) @@ -186,10 +187,10 @@ async def register_existing_image( if parsed.scheme in ("http", "https"): canonical = url else: - local = Path(unquote(parsed.path)) if parsed.scheme == "file" else Path(url) - if not local.is_file(): + local = file_url_to_path(url) if parsed.scheme == "file" else Path(url) + if not local or not local.is_file(): return {"error": f"muse2api: local image not found for '{name}': {url}"} - canonical = "file://" + str(local.resolve()) + canonical = url if parsed.scheme == "file" else ("file://" + str(local.resolve())) mid = str(uuid.uuid4()) logger.info("muse2api: registered existing image '%s' → media_id=%s", name, mid[:8]) return {"data": {"media": [{"name": mid}], "url": canonical}} diff --git a/agent/services/muse2api_client.py b/agent/services/muse2api_client.py index ac43697c1..6beeafea6 100644 --- a/agent/services/muse2api_client.py +++ b/agent/services/muse2api_client.py @@ -33,6 +33,8 @@ import httpx +from agent.utils.paths import file_url_to_path + logger = logging.getLogger(__name__) TERMINAL_OK = "succeeded" @@ -83,8 +85,8 @@ async def to_data_url(ref: str, *, timeout: float = 60.0) -> str: mime = resp.headers.get("content-type", "").split(";")[0].strip() mime = mime or mimetypes.guess_type(parsed.path)[0] or "image/png" else: - path = Path(unquote(parsed.path)) if parsed.scheme == "file" else Path(ref) - if not path.is_file(): + path = file_url_to_path(ref) if parsed.scheme == "file" else Path(ref) + if not path or not path.is_file(): raise FileNotFoundError(f"image not found: {ref}") data = await asyncio.to_thread(path.read_bytes) mime = mimetypes.guess_type(path.name)[0] or "image/png" diff --git a/tests/unit/test_muse2api_provider.py b/tests/unit/test_muse2api_provider.py index 2dc9cff05..2c179c4a8 100644 --- a/tests/unit/test_muse2api_provider.py +++ b/tests/unit/test_muse2api_provider.py @@ -97,7 +97,7 @@ async def test_image_is_saved_locally_with_minted_uuid(provider, gateway): gen = parse_result(result, "GENERATE_IMAGE") assert gen.success, result assert _is_uuid(gen.media_id) - assert gen.url.startswith("file://") and gen.url.endswith("/muse2api/img1.png") + assert gen.url.startswith("file://") and gen.url.replace("\\", "/").endswith("/muse2api/img1.png") assert (provider.output_dir / "img1.png").read_bytes() == PNG method, path, body = gateway.calls[0] From ea1aca1975ceed4fc5c8f808b91b518eaffa9acd Mon Sep 17 00:00:00 2001 From: TIENLV Date: Mon, 5 Oct 2026 22:38:45 +0700 Subject: [PATCH 58/68] fix(polling): persist and restore operation project_id across restarts --- agent/db/crud.py | 1 + agent/sdk/services/flow_provider.py | 16 ++++++++++++++++ agent/services/flow_client.py | 9 +++++++++ 3 files changed, 26 insertions(+) diff --git a/agent/db/crud.py b/agent/db/crud.py index 00184fc8a..43e286c9f 100644 --- a/agent/db/crud.py +++ b/agent/db/crud.py @@ -256,6 +256,7 @@ async def create_request(req_type: str, orientation: str = None, return await _get_with_db(db, "request", "id", rid) async def get_request(rid: str): return await _get("request", "id", rid) +async def get_request_by_operation_id(op_id: str): return await _get("request", "request_id", op_id) async def update_request(rid: str, **kw): return await _update("request", "id", rid, **kw) async def list_requests(scene_id: str = None, status: str = None, diff --git a/agent/sdk/services/flow_provider.py b/agent/sdk/services/flow_provider.py index 60cc25db0..e4e7336d0 100644 --- a/agent/sdk/services/flow_provider.py +++ b/agent/sdk/services/flow_provider.py @@ -59,6 +59,16 @@ def _omni_duration(requested) -> int: logger = logging.getLogger(__name__) +async def _remember_op(client, op_name: str | None, pid: str | None) -> None: + if not client or not op_name or not pid: + return + fn = getattr(client, "_remember_operation", None) + if callable(fn): + res = fn(op_name, pid) + if asyncio.iscoroutine(res): + await res + + def _save_raw_bytes( operations: list[dict], scene_id: str, project_slug: str, display_order: int ) -> str | None: @@ -394,6 +404,8 @@ async def _run_video(self, job: ProviderJob) -> dict: # would abandon a running render and pay for a second one. if existing_op: logger.info("Video gen already submitted (op=%s), re-polling", existing_op[:30]) + pid = ex.get("project_id") or (req_row.get("project_id") if req_row else None) + await _remember_op(self._client, existing_op, pid) operations = [{"operation": {"name": existing_op}, "status": "MEDIA_GENERATION_STATUS_PENDING"}] return await _poll_operations(self._client, operations) @@ -438,6 +450,7 @@ async def _run_video(self, job: ProviderJob) -> dict: return {"error": "Video gen returned no operations"} op_name = operations[0].get("operation", {}).get("name", "") + await _remember_op(self._client, op_name, ex.get("project_id")) if request_id: await crud.update_request(request_id, request_id=op_name) @@ -468,6 +481,8 @@ async def _run_video_refs(self, job: ProviderJob) -> dict: if existing_op: logger.info("R2V already submitted (op=%s), re-polling", existing_op[:30]) + pid = ex.get("project_id") or (req_row.get("project_id") if req_row else None) + await _remember_op(self._client, existing_op, pid) operations = [{"operation": {"name": existing_op}, "status": "MEDIA_GENERATION_STATUS_PENDING"}] return await _poll_operations(self._client, operations) @@ -488,6 +503,7 @@ async def _run_video_refs(self, job: ProviderJob) -> dict: return {"error": "R2V returned no operations"} op_name = operations[0].get("operation", {}).get("name", "") + await _remember_op(self._client, op_name, ex.get("project_id")) if request_id: await crud.update_request(request_id, request_id=op_name) diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index cb90e7df6..e16e11abe 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -987,6 +987,15 @@ async def _find_operation_media(self, operation_id: str) -> tuple[str | None, st self._operation_polls[operation_id] = rounds project_id = self._operation_projects.get(operation_id) or FLOW_PROJECT_ID + if not project_id: + try: + from agent.db import crud + req = await crud.get_request_by_operation_id(operation_id) + if req and req.get("project_id"): + project_id = req["project_id"] + self._remember_operation(operation_id, project_id) + except Exception: + pass complaint = None worth_looking = rounds % 3 == 0 try: From a407946006bfbfcb3e20b84df064e2a17a9b273b Mon Sep 17 00:00:00 2001 From: TIENLV Date: Tue, 6 Oct 2026 19:35:14 +0700 Subject: [PATCH 59/68] feat(skills,pipeline): add cinematic series tooling, manifest manager, and production skills - Add 5 new production skills: fk-scriptwriter, fk-character-bible, fk-action-choreography, fk-cinematic-transitions, fk-sound-design - Add scripts for film mastering (build_master_film), hardsub burning (generate_subtitles), series manifest (series_manifest), and SFX layering (sfx_layering) - Add sync_skills and validate_skills for tool parity across Antigravity IDE and Claude Code - Upgrade fk-concat-fit-narrator with bumper transitions, audio ducking, and hardsubs - Upgrade fk-gen-narrator with Edge-TTS neural voice profiles and pacing controls - Upgrade fk-review-video with automatic prompt healing loop - Fix manifest synchronization in agent/api/projects.py to merge all chapters - Fix polling timeout guard in agent/worker/processor.py - Support Antigravity IDE target in setup.py (.agents/skills) - Clean up git tracking for large scratch dumps and update .gitignore --- .gitignore | 5 + AGENTS.md | 5 + agent/api/projects.py | 106 +++++- agent/main.py | 33 ++ agent/services/flow_batch.py | 4 +- agent/worker/processor.py | 6 +- extension/background.js | 10 +- scratch/captured_netlog.jsonl | 321 ----------------- scratch/project_media_dump.txt | 8 - scripts/build_master_film.py | 450 +++++++++++++++++++++++ scripts/generate_subtitles.py | 282 +++++++++++++++ scripts/series_manifest.py | 230 ++++++++++++ scripts/sfx_layering.py | 262 ++++++++++++++ scripts/sync_skills.py | 74 ++++ scripts/validate_skills.py | 113 ++++++ setup.py | 65 +++- skills/README.md | 77 ++-- skills/fk-action-choreography.md | 100 ++++++ skills/fk-camera-guide.md | 38 ++ skills/fk-character-bible.md | 124 +++++++ skills/fk-cinematic-transitions.md | 156 ++++++++ skills/fk-concat-fit-narrator.md | 47 +++ skills/fk-doctor.md | 7 + skills/fk-gen-narrator.md | 27 +- skills/fk-review-video.md | 37 +- skills/fk-scriptwriter.md | 550 +++++++++++++++++++++++++++++ skills/fk-sound-design.md | 105 ++++++ 27 files changed, 2858 insertions(+), 384 deletions(-) delete mode 100644 scratch/captured_netlog.jsonl delete mode 100644 scratch/project_media_dump.txt create mode 100644 scripts/build_master_film.py create mode 100644 scripts/generate_subtitles.py create mode 100644 scripts/series_manifest.py create mode 100644 scripts/sfx_layering.py create mode 100644 scripts/sync_skills.py create mode 100644 scripts/validate_skills.py create mode 100644 skills/fk-action-choreography.md create mode 100644 skills/fk-character-bible.md create mode 100644 skills/fk-cinematic-transitions.md create mode 100644 skills/fk-scriptwriter.md create mode 100644 skills/fk-sound-design.md diff --git a/.gitignore b/.gitignore index e9a3f5c28..8f770c988 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ agent/active_project.json # Generated AI tool configs (run: python setup.py) .claude/commands/fk-* +.agents/skills/fk-* AGENTS.md .fk-setup.json @@ -28,3 +29,7 @@ extension/_metadata/ .agent/ flow_session_project.json .venv/ +*.mp3 +scratch/ + +series_manifest.json diff --git a/AGENTS.md b/AGENTS.md index bc5238214..28f450d8b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -81,11 +81,14 @@ This project has reusable skills in `skills/`. When the user says `/fk-`, | Skill | Purpose | |-------|---------| +| `/fk-action-choreography` | Action Choreography — AI Cinematic Combat & Motion Direction | | `/fk-add-material` | fk-add-material — Image Material System | | `/fk-brand-logo` | fk-brand-logo — Apply Channel Branding (Intro + Outro + Logo + 4K Badge) | | `/fk-camera-guide` | Camera Guide — Cinematic Video Prompts (Veo 3) | | `/fk-change-model` | fk-change-model — View & Change Video/Image Model Keys | | `/fk-change-provider` | fk-change-provider — View & Switch the Reviewer for a Role | +| `/fk-character-bible` | Character Bible & Visual Consistency — AI Film Production | +| `/fk-cinematic-transitions` | Cinematic Transitions & Chapter Bumpers — AI Film Direction | | `/fk-concat-fit-narrator` | Trim each scene video to fit its TTS narrator duration, burn text overlays, then concatenate into a final video. | | `/fk-concat` | Download and concatenate all scene videos into a single video with optional TTS narration. | | `/fk-create-project` | Create a new Google Flow video project. Ask the user for: | @@ -110,6 +113,8 @@ This project has reusable skills in `skills/`. When the user says `/fk-`, | `/fk-research` | fk-research — Fact-Check & Research Before Scripting | | `/fk-review-board` | Start the Scene Review Board web app for visual feedback on scene chains. | | `/fk-review-video` | Review AI-generated scene videos for quality. | +| `/fk-scriptwriter` | The Ultimate AI Screenplay Bible — Google Flow & Veo 3 | +| `/fk-sound-design` | Sound Design & Audio Mastering — AI Cinematic Soundscapes | | `/fk-status` | Show full status dashboard for a project. | | `/fk-switch-project` | fk-switch-project — Switch Active Project | | `/fk-thumbnail-guide` | YouTube Thumbnail Guide — Hook-Worthy Design Rules | diff --git a/agent/api/projects.py b/agent/api/projects.py index 31a8a51f0..955c93723 100644 --- a/agent/api/projects.py +++ b/agent/api/projects.py @@ -298,9 +298,88 @@ async def get_characters(pid: str): return await repo.get_project_characters(pid) +async def _build_or_update_series_manifest(repo, project, slug: str, output_dir: Path) -> dict: + """Build or synchronize the project-level series_manifest.json.""" + pid = getattr(project, "id", None) or (project.get("id") if isinstance(project, dict) else "") + project_name = getattr(project, "name", None) or (project.get("name") if isinstance(project, dict) else "") + manifest_path = output_dir / "series_manifest.json" + + existing = {} + if manifest_path.exists(): + try: + existing = json.loads(manifest_path.read_text(encoding="utf-8")) + except Exception: + existing = {} + + chars = await repo.get_project_characters(pid) + chars_list = [] + locs_list = [] + props_list = [] + + for c in chars: + entity_type = getattr(c, "entity_type", None) or "character" + entry = { + "name": getattr(c, "name", ""), + "slug": getattr(c, "slug", ""), + "entity_type": entity_type, + "description": getattr(c, "description", None), + "image_prompt": getattr(c, "image_prompt", None), + "voice_description": getattr(c, "voice_description", None), + "media_id": getattr(c, "media_id", None), + "reference_image_url": getattr(c, "reference_image_url", None), + } + if entity_type == "character": + chars_list.append(entry) + elif entity_type == "location": + locs_list.append(entry) + else: + props_list.append(entry) + + videos = await repo.list_videos(pid) + existing_eps_by_vid = {ep.get("video_id"): ep for ep in existing.get("episodes", []) if "video_id" in ep} + episodes = [] + for idx, v in enumerate(videos, 1): + scenes = await repo.list_scenes(v.id) + old_ep = existing_eps_by_vid.get(v.id, {}) + episodes.append({ + "episode": getattr(v, "display_order", idx) or idx, + "title": getattr(v, "title", None) or old_ep.get("title") or f"Episode {idx}", + "subtitle": getattr(v, "description", "") or old_ep.get("subtitle", ""), + "video_id": v.id, + "scene_count": len(scenes) if scenes else 0, + "status": getattr(v, "status", "IN_PROGRESS"), + }) + + first_vid = videos[0] if videos else None + orientation = (getattr(first_vid, "orientation", None) if first_vid else None) or existing.get("orientation", "HORIZONTAL") + material_val = getattr(project, "material", None) or (project.get("material") if isinstance(project, dict) else "") or existing.get("material", "realistic") + story_val = getattr(project, "story", None) or (project.get("story") if isinstance(project, dict) else "") or existing.get("story_bible", "") + + manifest = { + "series_title": existing.get("series_title") or project_name, + "slug": slug, + "genre": existing.get("genre", "Cinematic / Realistic"), + "material": material_val, + "orientation": orientation, + "story_bible": story_val, + "default_voice": existing.get("default_voice", "vi-VN-NamMinhNeural"), + "origin_project_id": pid, + "shared_entities": { + "characters": chars_list, + "locations": locs_list, + "key_props": props_list, + }, + "episodes": episodes, + "updated_at": datetime.now(timezone.utc).isoformat(), + } + + manifest_path.write_text(json.dumps(manifest, indent=2, ensure_ascii=False), encoding="utf-8") + return manifest + + @router.get("/{pid}/output-dir") async def get_output_dir(pid: str): - """Get or create project output directory with meta.json.""" + """Get or create project output directory with meta.json and series_manifest.json.""" repo = _get_repo() project = await repo.get_project(pid) if not project: @@ -341,7 +420,30 @@ async def get_output_dir(pid: str): meta["created_at"] = existing.get("created_at", now) meta_path.write_text(json.dumps(meta, indent=2, ensure_ascii=False), encoding="utf-8") - return {"slug": slug, "path": f"output/{slug}", "meta": meta} + # Automatically generate or update per-project series_manifest.json + manifest = await _build_or_update_series_manifest(repo, project, slug, output_dir) + + return { + "slug": slug, + "path": f"output/{slug}", + "meta": meta, + "manifest_path": f"output/{slug}/series_manifest.json" + } + + +@router.get("/{pid}/manifest") +async def get_project_manifest(pid: str): + """Retrieve or auto-generate the project's series_manifest.json.""" + repo = _get_repo() + project = await repo.get_project(pid) + if not project: + raise HTTPException(404, "Project not found") + project_name = getattr(project, "name", None) or (project.get("name") if isinstance(project, dict) else "") + slug = slugify(project_name) + output_dir = BASE_DIR / "output" / slug + output_dir.mkdir(parents=True, exist_ok=True) + return await _build_or_update_series_manifest(repo, project, slug, output_dir) + _ASPECT_RATIO_MAP = { diff --git a/agent/main.py b/agent/main.py index c0722a15c..6cbb2e4bc 100644 --- a/agent/main.py +++ b/agent/main.py @@ -271,6 +271,39 @@ async def ext_test_project_media(): } +@app.get("/api/ext/test-op") +async def ext_test_op(op: str): + """Fetch raw operation status for an operation ID.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + from agent.services import flow_batch as fb + res = await client.batch_rpc(fb.RPC_OPERATION, fb.operation_request(op)) + return res + + +@app.get("/api/ext/test-op-match") +async def ext_test_op_match(op: str): + """Test matching an operation in project media listing.""" + client = get_flow_client() + if not client.connected: + from fastapi import HTTPException + raise HTTPException(503, "Extension not connected") + from agent.services import flow_batch as fb + pid = "594758cc-11f5-4f92-8b3c-1213686591f4" + res = await client.batch_rpc(fb.RPC_PROJECT_MEDIA, fb.project_media_request(pid), match=op) + raw = res.get("data", "") + found_mid = fb.find_media_id_in_text(raw, op) + return { + "status": res.get("status"), + "error": res.get("error"), + "raw_len": len(raw), + "raw": raw, + "found_mid": found_mid, + } + + @app.get("/api/ext/media-url") async def ext_media_url(media_id: str): """Fetch signed media URLs for a media_id.""" diff --git a/agent/services/flow_batch.py b/agent/services/flow_batch.py index 0e148562b..1262966d0 100644 --- a/agent/services/flow_batch.py +++ b/agent/services/flow_batch.py @@ -752,8 +752,8 @@ def find_media_id_in_text(text: str, operation_id: str) -> Optional[str]: start = lower_text.find(lower_op) if start == -1: return None - # Search within window of match - window_start = max(0, start - 400) + # Search within window of match (from operation start onwards to avoid matching previous items) + window_start = start window_end = min(len(text), start + 800) match = _MEDIA_SLOT.search(text, window_start, window_end) return match.group(1) if match else None diff --git a/agent/worker/processor.py b/agent/worker/processor.py index e128df371..1acf65ba6 100644 --- a/agent/worker/processor.py +++ b/agent/worker/processor.py @@ -481,12 +481,12 @@ async def _handle_failure(rid: str, req: dict, result: dict, retry_after: dict = if isinstance(error_msg, dict): error_msg = json.dumps(error_msg)[:200] - # Auto-recover expired media by re-uploading - if "not found" in str(error_msg).lower(): + # Auto-recover expired media by re-uploading (only on real entity-not-found, never on polling timeout) + if "not found" in str(error_msg).lower() and "polling timeout" not in str(error_msg).lower(): recovered = await _recover_entity_not_found(req) if recovered: logger.info("Request %s: recovered expired media, retrying", rid[:8]) - await crud.update_request(rid, status="PENDING", error_message=f"recovered: {error_msg}") + await crud.update_request(rid, status="PENDING", request_id=None, error_message=f"recovered: {error_msg}") return error_lower = str(error_msg).lower() diff --git a/extension/background.js b/extension/background.js index 8f4a261e0..df0c5f9c1 100644 --- a/extension/background.js +++ b/extension/background.js @@ -375,6 +375,11 @@ function connectToAgent() { bl: wiz.cfb2h, hasGrecaptcha: !!window.grecaptcha?.enterprise?.execute, executeString: window.grecaptcha?.enterprise?.execute?.toString(), + hasHijack: !!window.__fk_hijack, + hijackPristine: typeof window.__fk_hijack?.pristine, + hijackTrapped: !!window.__fk_hijack?.trapped, + hijackSource: window.__fk_hijack?.source, + grecaptchaClients: Object.keys(window.___grecaptcha_cfg?.clients || {}), promptElements: Array.from(document.querySelectorAll('textarea, [contenteditable="true"], [role="textbox"]')) .map(el => ({ tag: el.tagName, id: el.id, className: el.className, placeholder: el.placeholder || el.getAttribute('aria-label') || el.getAttribute('placeholder') })), editorContent: document.querySelector('.ProseMirror')?.innerText || '', @@ -607,8 +612,8 @@ async function solveCaptcha(requestId, captchaAction) { } // Try each Flow tab in turn. A tab that answers "no grecaptcha" is a tab - // sitting on a page that never loaded it — another Flow tab may well be - // fine. Returning on the first one let one stale tab veto every generation. + // Try project tabs first (they have the full toolchain and recaptcha context loaded) + tabs.sort((a, b) => ((b.url && b.url.includes('/project/')) ? 1 : 0) - ((a.url && a.url.includes('/project/')) ? 1 : 0)); const errors = []; for (const candidate of tabs) { const tab = await reviveTabIfNeeded(candidate); @@ -689,6 +694,7 @@ const MAX_RPC_TEXT = 32000000; // the project listing alone is past 17 MB async function runBatchRpc(cmd) { const tabs = await chrome.tabs.query({ url: flowUrls }); let candidate = + tabs.find((t) => t.url && t.url.includes('/project/') && !t.discarded) || tabs.find((t) => t.active && !t.discarded) || tabs.find((t) => !t.discarded) || tabs[0]; diff --git a/scratch/captured_netlog.jsonl b/scratch/captured_netlog.jsonl deleted file mode 100644 index 857153374..000000000 --- a/scratch/captured_netlog.jsonl +++ /dev/null @@ -1,321 +0,0 @@ -{"ts": "2026-09-23T13:16:52.291Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=281899&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:17:05.413Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=826921&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,733647544,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5MPg8cTqBq2xeiEK_4oNLK1jZnsUckrwa1t4j1ZGVfgPOC5hIcFD3EMddxnfrhVFHTv9uKf4EKq3uAEHT2r3B3hY0FOwpbMvBDOHk30qQbz-nactrTEWIFDmBAqlUQ8VZ9m7FSGhHmRbKNNUkB3Y0tHRL1lEZGGkILJ9EgGjB7Y1u9h3O8No1vWM8BrY7J7f0f-rhjn-8UU_QvW3i_rn30cNYqumup-k8rPoOgVQY5pKpZXcQL5pP6YSBkZWL6D965aCcVvOmGKnVMUCV5L-4cS873cdEVm-AcwhDzaeZuYkKgpWjGaJ9V2dodPZlHXhbe47E5C1y8d1Br5Z29pZkyI1H8cQk13FryCsuNwyhEusneAmDIM8ghOzqjTckDRQfAZIAt6lPaHDmrrePCIBrQWXqvChE26Zz-Y7ZrGxeNUn3wnbo3XSss0b1Hdsq5GNv5fLr25AJ-2Jvri0UVd_pAWssJksY6cd-8WWG2msnt39uOtct2FAPA3S9YA5kF7PMZm8QfiaJ00AF3mHIvv-cZHcNSmPtpBY9lZP12RFUcrdcIosyENe37vqI0680oJL-x4VUJqw4MZu1ASdycwa5JLbBt7YC1v400rkFRSZYXUyCXxhCRHrK-fEl3CLDSTWaGPW8jKEo_aLVCQ9rjpKMrVb_SRsftv2SzSylYZpOWHykX4Cydt5daVYCS4c21BFMOpPfLGpN8O4QenFxrEpV67BuR3mQrSKdaNJ0yETRI2uhApjbcXkWEmK75uDolzvk4HvJMRdqbt_x3yqs_8KvB0ASbQcMfiRbahjSXJF0HMBpCMkLVY0bU7PtBVDkbZy7-169vkRZnCoe003-xMR8JPrIiijg-PNe_gEkzVHvwS9eybEjQetRfOal2R-cbnpJe3fWdbd-E8XFqkT-tCTR4R4Fh1FmC1kGVRPFzSq_2dInSlUsReqJEGb9wZoalRD_aa19mJF2FilfEMqJUfEBS_DN32lr25_FjsBqtWShrJQVU8YcO1ai8tnLez8cUZJ-FRRFZa7Uf6gJVFsRQ_cdFi-ZM6i9okJjzbLA-wlQry74ZBPe3SKA1Z3QKeT-t5FLNuIVnMjiE6rMIPhkRw_tdxNRLHQPafbJRDPuiCzmNS5YRczrTMGvcRwPVeok1-lxV-yt8R4oVo-MVnZOSGM9wB8TQ4-YfUdvSh0b34tDrPGumi_9PBL6Gn8-Tweby_WRUzOwmAN62v5AIHOq2lGvn1TpUXy7hc9RPK2O70Xy1umOZgY4qpkyjnL-eVm8r1ZYuMyCQmgS4eFwEHlOBP4ePlI4lPCo1g03i38mDU3XjZjZD0Ub0y96dwZrEikeo-3yBvMJI3KGCHhT28bQPV9GPqd-OL96QMYq5UaGZFbQao7Hqq9Qd_1b7QbV-xqhInNHWv5df7QozHgLZA5ZMtcyLPT6PFTFDAhuzMUDKkuS4T_rZbsaQzKxi7hJzQsMDa1z4ZhtsqsoPRIU2NjZSEWmGUC6HgqFeBEAxtYsOvdQFJMg9mSrjyZzD6IX4aKXIJ-jEBiJSAmDhH2i53sCRmmDAM-f9qOLpccS45LuKT-Y1wtj7I5zRRV09J4tOOoyQpa3Rt7G4g1gezlSkQRejRuE5ds67tUQ2JZyyQnqOszxidxKmFnB6v5q0jvdSgWsejRmUKkJW6dnggt4eeRoejI_5SZelXySVsIxrzWlV_1GO9etcjAsjhOBMyJhhhUWRtMECpfwSHSLBSDtRBO4iVw5p8Gz5Hl8eGgIpELDQlVryq8T1Kc7qWqTrSvJ1cnM8qj6cfuTfc34TFH2q6A2E1mPe6-g9xYYEiv1zp1bofVsmYZQYKZiaRm03LMD2yWSf8-mbGtPi-VZu6oViaYkHfoPq_Sudc96pKriTm7X6fTWhNP0Oqeq-Id5z_hXaHMDJWY8ga8nXybwfTQWEl-qQtHDAtNOqNgW2kGxhHa94Dgg2VRRzOuXJrl82pnuYhGlTRb0w_JXmrcg8RIyWQCVONTstupDngNEV4ylP7gOk9KmumsMbV89roJyju3OclKxIsSNQv1RKjKXbeC6wBw3uAdqiK88xZ7LnuF_czNFJZzOlh2057r2n4nch9qEUz2c2XlKOSDhKoY6p2vdX50viRbDc9BmXCvqKk91G6nyTJU2WYAhAQeVyR9VrHWptruCCXo9KuRfEjTykvmxDN4k8lcOqH21fO5iYrOO7zczBRopPp_fQO7J6N3XFBfZ5QIeJHfOUEjZPOKiGhBO3Q79XYsek3HS7TFsBCSuSUlWnLkVSQhP4f4mWU_ueS5WfAg9Di9yyBgw0-B-ILb-_FBG1yFnbimLeuAFq-zW-_2LFgQRjtJlAJtSgf6y0BvNvZmYtP-1avLnJTjnc8uSADBObmfnUtwkQtqRVuxAjjIGVcNBFHYfLr-zHEmnHQvo4OY7KXKhL-P08cwKDMl9L4Ap7ms4iVLPGSHQRRdeEKGjVBOFbYFVORSMslT-7LvhmR6G58kNhjm_n\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"6D6580CB-4DD9-401F-9529-7E5198D65DA9\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5MPg8cTqBq2xeiEK_4oNLK1jZnsUckrwa1t4j1ZGVfgPOC5hIcFD3EMddxnfrhVFHTv9uKf4EKq3uAEHT2r3B3hY0FOwpbMvBDOHk30qQbz-nactrTEWIFDmBAqlUQ8VZ9m7FSGhHmRbKNNUkB3Y0tHRL1lEZGGkILJ9EgGjB7Y1u9h3O8No1vWM8BrY7J7f0f-rhjn-8UU_QvW3i_rn30cNYqumup-k8rPoOgVQY5pKpZXcQL5pP6YSBkZWL6D965aCcVvOmGKnVMUCV5L-4cS873cdEVm-AcwhDzaeZuYkKgpWjGaJ9V2dodPZlHXhbe47E5C1y8d1Br5Z29pZkyI1H8cQk13FryCsuNwyhEusneAmDIM8ghOzqjTckDRQfAZIAt6lPaHDmrrePCIBrQWXqvChE26Zz-Y7ZrGxeNUn3wnbo3XSss0b1Hdsq5GNv5fLr25AJ-2Jvri0UVd_pAWssJksY6cd-8WWG2msnt39uOtct2FAPA3S9YA5kF7PMZm8QfiaJ00AF3mHIvv-cZHcNSmPtpBY9lZP12RFUcrdcIosyENe37vqI0680oJL-x4VUJqw4MZu1ASdycwa5JLbBt7YC1v400rkFRSZYXUyCXxhCRHrK-fEl3CLDSTWaGPW8jKEo_aLVCQ9rjpKMrVb_SRsftv2SzSylYZpOWHykX4Cydt5daVYCS4c21BFMOpPfLGpN8O4QenFxrEpV67BuR3mQrSKdaNJ0yETRI2uhApjbcXkWEmK75uDolzvk4HvJMRdqbt_x3yqs_8KvB0ASbQcMfiRbahjSXJF0HMBpCMkLVY0bU7PtBVDkbZy7-169vkRZnCoe003-xMR8JPrIiijg-PNe_gEkzVHvwS9eybEjQetRfOal2R-cbnpJe3fWdbd-E8XFqkT-tCTR4R4Fh1FmC1kGVRPFzSq_2dInSlUsReqJEGb9wZoalRD_aa19mJF2FilfEMqJUfEBS_DN32lr25_FjsBqtWShrJQVU8YcO1ai8tnLez8cUZJ-FRRFZa7Uf6gJVFsRQ_cdFi-ZM6i9okJjzbLA-wlQry74ZBPe3SKA1Z3QKeT-t5FLNuIVnMjiE6rMIPhkRw_tdxNRLHQPafbJRDPuiCzmNS5YRczrTMGvcRwPVeok1-lxV-yt8R4oVo-MVnZOSGM9wB8TQ4-YfUdvSh0b34tDrPGumi_9PBL6Gn8-Tweby_WRUzOwmAN62v5AIHOq2lGvn1TpUXy7hc9RPK2O70Xy1umOZgY4qpkyjnL-eVm8r1ZYuMyCQmgS4eFwEHlOBP4ePlI4lPCo1g03i38mDU3XjZjZD0Ub0y96dwZrEikeo-3yBvMJI3KGCHhT28bQPV9GPqd-OL96QMYq5UaGZFbQao7Hqq9Qd_1b7QbV-xqhInNHWv5df7QozHgLZA5ZMtcyLPT6PFTFDAhuzMUDKkuS4T_rZbsaQzKxi7hJzQsMDa1z4ZhtsqsoPRIU2NjZSEWmGUC6HgqFeBEAxtYsOvdQFJMg9mSrjyZzD6IX4aKXIJ-jEBiJSAmDhH2i53sCRmmDAM-f9qOLpccS45LuKT-Y1wtj7I5zRRV09J4tOOoyQpa3Rt7G4g1gezlSkQRejRuE5ds67tUQ2JZyyQnqOszxidxKmFnB6v5q0jvdSgWsejRmUKkJW6dnggt4eeRoejI_5SZelXySVsIxrzWlV_1GO9etcjAsjhOBMyJhhhUWRtMECpfwSHSLBSDtRBO4iVw5p8Gz5Hl8eGgIpELDQlVryq8T1Kc7qWqTrSvJ1cnM8qj6cfuTfc34TFH2q6A2E1mPe6-g9xYYEiv1zp1bofVsmYZQYKZiaRm03LMD2yWSf8-mbGtPi-VZu6oViaYkHfoPq_Sudc96pKriTm7X6fTWhNP0Oqeq-Id5z_hXaHMDJWY8ga8nXybwfTQWEl-qQtHDAtNOqNgW2kGxhHa94Dgg2VRRzOuXJrl82pnuYhGlTRb0w_JXmrcg8RIyWQCVONTstupDngNEV4ylP7gOk9KmumsMbV89roJyju3OclKxIsSNQv1RKjKXbeC6wBw3uAdqiK88xZ7LnuF_czNFJZzOlh2057r2n4nch9qEUz2c2XlKOSDhKoY6p2vdX50viRbDc9BmXCvqKk91G6nyTJU2WYAhAQeVyR9VrHWptruCCXo9KuRfEjTykvmxDN4k8lcOqH21fO5iYrOO7zczBRopPp_fQO7J6N3XFBfZ5QIeJHfOUEjZPOKiGhBO3Q79XYsek3HS7TFsBCSuSUlWnLkVSQhP4f4mWU_ueS5WfAg9Di9yyBgw0-B-ILb-_FBG1yFnbimLeuAFq-zW-_2LFgQRjtJlAJtSgf6y0BvNvZmYtP-1avLnJTjnc8uSADBObmfnUtwkQtqRVuxAjjIGVcNBFHYfLr-zHEmnHQvo4OY7KXKhL-P08cwKDMl9L4Ap7ms4iVLPGSHQRRdeEKGjVBOFbYFVORSMslT-7LvhmR6G58kNhjm_n\\\\\\\",1]],[\\\\\\\"4A4EF8B3-EAC3-4FF1-AE7A-2923B632D862\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:17:15.183Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=476550&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,917825764,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA76aQB53ojOe-o_LQMCZRoiIqrU8TZjvxh2Q27lN_SiVEdlelBacAtAVIoPgEsadlVBWz_P09vRLPpXbirSDzBxwzLlQbaQW77fbzr-Kq9njhXyNd68hFaQrb_YhshCf3MLd6CpPGxXuGFFBe1Ekp1n_RFUkpzjIDQ5_NNvUHJqhTDnMTT2XNwFuTh1B6kKn94s7PjVlA56RMBa-2wZ7rFhxgrKz2xlS58_Ee9-RoqqNZKz67aaCU9vzjHEIFEc8F-jqGj8R2aAdkZk-r7olNXwYyxVlgTTxj-IbWyGrXeA34TsWrnw8af2ia7lqYvJLFc_DLUWhNrZA4dmWcq0Cu_F6Z4y3_8aSkJFPwTzTqTvUO4qvjKUMcCbjzdKHq3sIW4W21c1dJaj6sIAQn3MKNVowP_gTVEhTzovoAMZ7cY0DRzyqkIA_a0rESu2YR8BoyNUVr3rLnnWN7-wZ4-oThPtWDuXi_YUHwd9qe9Aruli1BfUBCwww_kvvd4SnXibcIb50h4RK7SPGnRH3XDtJUPFBxaGVA7hHyPl3lKsI9U7yb290qbTi0F7C-fH8zLd0oJGUFFzei5pnHcGlf9PvjsoVPXpCsc_fMpVX55QAW9SJMiZ0Kev8SqDXlROMmBZOutWq-rqN7MJ0HmOyehf2235A6lckcj05PwuRDFyTpfKKCx8DuS6BiQuqq-JR0HcTAXG2mcQW-Ohpmc_P_cs6CgjPnU1kjuPd2BVg9LryiuZHRDk6DxNaxp5PQRDj2wTbdIOo2RwSAGhv_G22yuEPuxgZjDtWToqbjh_kni8Jp0pT1Thq51Jlwscz7yccrfkfKS0Pm_8JIijCWJSHQunmUkSWME2JlbPs3XJBS-MbIPPibhZGRSR8bwJBvZN4Wah7jTzjdunDr2W4BDb5h0RG3EuKNf96s9UWDFb4aH9W6lKBInQZOW_RvkmmlJnHRxjtuMbeQORbfFMbHVsauIW6ievcF7kfkPZojyVzIlpqKG4mnKJ40B7g9UDF-6jK1oEmiXYMj9pEeFf99vMYiVjDdsHoZE_XWkQ_w0wNd_Q7c7mFEIgsBgF7XhhJTEE7BTMyQtfDmXTOmwOqc6rkD3V04Bw3w6PV3sSf5o_CDmFOeoHo_5wZQ_UYngVvEub6Suh4DdiqW3OD3Wun9gog2gehYUUxgCP7U9sIrliJjei5E7mtzMVFu0NdSgu9g6rw3ac8wb-ll100XcmwU9wBWiwikgcUfMc9GYUn6GycBwpw5NOvCMldj1-yxpP3UWIEFS9_-JZZgqT19xvFbyO-x0YB-rJXjGHtNKaYxiKSzAXEukPJSsiK_JG0Gm_Z6cnDWMeMGkzjTgDzn00qTegwtdfVZlWAa3C1lBETacp4UeUS3WJoiCU3n8KHMoh-soiwnwfZbAPk3bb1gzadVXjxBkC20oXmdIr10znIShenWVObcLE_NigIkhnO_U_NM-asIy2hfwM1oASX3F3AERckZlzJ8RKb-kDFEzJkz6_qkWKclvaXqDzKOgb7BIZzgM6_NiSMOn2EMsWL1NE--KTppRZOPP4pNA9zdqdhLw5AK-nL-yX31T5hCxj_gvLrKbgnJfPOlubBnYwDWbrJ-OD5QC7eYD_SM8m0EmtUwVk-iJm4P1fmxUhBHvRWD45kkNzUWGZ4swziJV1JaTpyCstW5FQabc-igs-07E2LMFqYfGeWmuR254x3JyLWcg-suwztzi8uc-hgGs8lj1SRiqh_wCK2pTHzNHjVI4cnaLHOZKkbrK9GcoJO5AbH_uV9R84gK5VPEbAa_-K8IAJarEO_9urk1QzVcm71ru0t-nHZmdpNFY3Pc5Qc8wLki-oJIa3p_v4N-YkEcz_kT-q1hsO-8XuKUXe9vB8aDZDlBz0BGwPQwYbdcOeXbOqZsZWIb1zciDsMkvk7kuioIGyMbTl9fJ2jbdCuGhYA3F9kAe4ANQ1-d9apCsMrLF-_6-EabGY--BBApatRPLzsVpeCFYb0C7x7TTQgy5UyzGPyv0JtdGO2DLzJBBx_hSHUTlOsFGlIufZXS2SMP2ecYKx7h4ZgboA4MGlEcWl6AwOd2YuqORsDebt52bczBjmLhG0NZ5bfC1xuQgm-EQqN35UVMebwsbsDzWNg8Git2CTa5P95tUlM9l7x0FCay-WQTR25IrHHU_DLQuJVzyFeR2Hc6yJolYiySWJvgpDRGRD0Vhy3UDgdoLzalGA7HcUtBvoXnDZmdqHAUS1xrKyrzpWNl_V4FMaI8Vm76nqYbPdC2GuhJuaUCTTaXnY1HipOdjDwjTFb7iYnHGnqyGPakRo_xouxnDBrHUrTc0q9NM-0SwvQGDzAe6vDaWAtZmDcB0L0v2m00J6S4oUkq_f2XZ23eFDE9jG2NdExhg39Yecl2THSalJivuU452TySe6KYIf7ju6kTFq58J5NAaUVz1YdLxNdOLKZ7Y0k2R9yM8MKb9u6kO49ulERtIKwTmAx5MzVDNi9p89l2R3Iro9uj3Fuq9w1h6hnk3JWkplMyhnh29AYsOmg5OmN34jr-E\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"C7E27561-F11D-4122-B8FD-765EF771C676\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA76aQB53ojOe-o_LQMCZRoiIqrU8TZjvxh2Q27lN_SiVEdlelBacAtAVIoPgEsadlVBWz_P09vRLPpXbirSDzBxwzLlQbaQW77fbzr-Kq9njhXyNd68hFaQrb_YhshCf3MLd6CpPGxXuGFFBe1Ekp1n_RFUkpzjIDQ5_NNvUHJqhTDnMTT2XNwFuTh1B6kKn94s7PjVlA56RMBa-2wZ7rFhxgrKz2xlS58_Ee9-RoqqNZKz67aaCU9vzjHEIFEc8F-jqGj8R2aAdkZk-r7olNXwYyxVlgTTxj-IbWyGrXeA34TsWrnw8af2ia7lqYvJLFc_DLUWhNrZA4dmWcq0Cu_F6Z4y3_8aSkJFPwTzTqTvUO4qvjKUMcCbjzdKHq3sIW4W21c1dJaj6sIAQn3MKNVowP_gTVEhTzovoAMZ7cY0DRzyqkIA_a0rESu2YR8BoyNUVr3rLnnWN7-wZ4-oThPtWDuXi_YUHwd9qe9Aruli1BfUBCwww_kvvd4SnXibcIb50h4RK7SPGnRH3XDtJUPFBxaGVA7hHyPl3lKsI9U7yb290qbTi0F7C-fH8zLd0oJGUFFzei5pnHcGlf9PvjsoVPXpCsc_fMpVX55QAW9SJMiZ0Kev8SqDXlROMmBZOutWq-rqN7MJ0HmOyehf2235A6lckcj05PwuRDFyTpfKKCx8DuS6BiQuqq-JR0HcTAXG2mcQW-Ohpmc_P_cs6CgjPnU1kjuPd2BVg9LryiuZHRDk6DxNaxp5PQRDj2wTbdIOo2RwSAGhv_G22yuEPuxgZjDtWToqbjh_kni8Jp0pT1Thq51Jlwscz7yccrfkfKS0Pm_8JIijCWJSHQunmUkSWME2JlbPs3XJBS-MbIPPibhZGRSR8bwJBvZN4Wah7jTzjdunDr2W4BDb5h0RG3EuKNf96s9UWDFb4aH9W6lKBInQZOW_RvkmmlJnHRxjtuMbeQORbfFMbHVsauIW6ievcF7kfkPZojyVzIlpqKG4mnKJ40B7g9UDF-6jK1oEmiXYMj9pEeFf99vMYiVjDdsHoZE_XWkQ_w0wNd_Q7c7mFEIgsBgF7XhhJTEE7BTMyQtfDmXTOmwOqc6rkD3V04Bw3w6PV3sSf5o_CDmFOeoHo_5wZQ_UYngVvEub6Suh4DdiqW3OD3Wun9gog2gehYUUxgCP7U9sIrliJjei5E7mtzMVFu0NdSgu9g6rw3ac8wb-ll100XcmwU9wBWiwikgcUfMc9GYUn6GycBwpw5NOvCMldj1-yxpP3UWIEFS9_-JZZgqT19xvFbyO-x0YB-rJXjGHtNKaYxiKSzAXEukPJSsiK_JG0Gm_Z6cnDWMeMGkzjTgDzn00qTegwtdfVZlWAa3C1lBETacp4UeUS3WJoiCU3n8KHMoh-soiwnwfZbAPk3bb1gzadVXjxBkC20oXmdIr10znIShenWVObcLE_NigIkhnO_U_NM-asIy2hfwM1oASX3F3AERckZlzJ8RKb-kDFEzJkz6_qkWKclvaXqDzKOgb7BIZzgM6_NiSMOn2EMsWL1NE--KTppRZOPP4pNA9zdqdhLw5AK-nL-yX31T5hCxj_gvLrKbgnJfPOlubBnYwDWbrJ-OD5QC7eYD_SM8m0EmtUwVk-iJm4P1fmxUhBHvRWD45kkNzUWGZ4swziJV1JaTpyCstW5FQabc-igs-07E2LMFqYfGeWmuR254x3JyLWcg-suwztzi8uc-hgGs8lj1SRiqh_wCK2pTHzNHjVI4cnaLHOZKkbrK9GcoJO5AbH_uV9R84gK5VPEbAa_-K8IAJarEO_9urk1QzVcm71ru0t-nHZmdpNFY3Pc5Qc8wLki-oJIa3p_v4N-YkEcz_kT-q1hsO-8XuKUXe9vB8aDZDlBz0BGwPQwYbdcOeXbOqZsZWIb1zciDsMkvk7kuioIGyMbTl9fJ2jbdCuGhYA3F9kAe4ANQ1-d9apCsMrLF-_6-EabGY--BBApatRPLzsVpeCFYb0C7x7TTQgy5UyzGPyv0JtdGO2DLzJBBx_hSHUTlOsFGlIufZXS2SMP2ecYKx7h4ZgboA4MGlEcWl6AwOd2YuqORsDebt52bczBjmLhG0NZ5bfC1xuQgm-EQqN35UVMebwsbsDzWNg8Git2CTa5P95tUlM9l7x0FCay-WQTR25IrHHU_DLQuJVzyFeR2Hc6yJolYiySWJvgpDRGRD0Vhy3UDgdoLzalGA7HcUtBvoXnDZmdqHAUS1xrKyrzpWNl_V4FMaI8Vm76nqYbPdC2GuhJuaUCTTaXnY1HipOdjDwjTFb7iYnHGnqyGPakRo_xouxnDBrHUrTc0q9NM-0SwvQGDzAe6vDaWAtZmDcB0L0v2m00J6S4oUkq_f2XZ23eFDE9jG2NdExhg39Yecl2THSalJivuU452TySe6KYIf7ju6kTFq58J5NAaUVz1YdLxNdOLKZ7Y0k2R9yM8MKb9u6kO49ulERtIKwTmAx5MzVDNi9p89l2R3Iro9uj3Fuq9w1h6hnk3JWkplMyhnh29AYsOmg5OmN34jr-E\\\\\\\",1]],[\\\\\\\"A5383ADE-FF5D-4663-B89E-76B47860C93B\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:17:25.256Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=826897&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,428233453,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7juMDJedBkFrAjm99BywICUddrhD3dUA4cDC272UoX2MEun7J4LoWWGOo9L-2PkDiG5y1geNwk_T7G1PA7hFpR3NxN-gjsgllJl1POoNruDqvd9tu1l38hfQ3IoauYZgefWDM_YFGx1K4BSI-faJXNaCX1JYq9zKxb_dzM7HGrrUYw_gafaLFBGHHjt2GDInTrHPz8EV-_HMipvBt8dSG0gx9zqnWi1CP5PbhQIAB8hQGc9lRg8HvdlEp_KZg1wh-AVAbpX1tKwKdPERDwxqPG6luC2nIwLRGQxYdhGUdj2i21pW5CW2n8MSn77EvWq_vQME7dQmZoEGJVqsR-FE_ZFECgIi2LrTzqT9g5bPOHK66uIuCQcpMSKgPLOCxHh34yN4ualBAb4KvHVp3FZQl0p18qFN214FdT7rZqrpUJRUeiUuEf9HDmPT3-tRN7M3J_51rKyGD-NY3cJtCI96Exh7afLEuHOmqzDocY3dqY3Wm8Kf3UuZwG90Ics6O4_u-2NwWEUAmnqJUYMFASdRIxNJPGXzNdS9nNP0wscoLqbiq29RQDEouNkjwIaA6R0zmzk_f2gjyaRxNpwpxMaRCl9_8eET0RwlmNfWjvsd1rzpJmggJCWFifJyjBDLp-Jq-y8Kho6xYPI2rkmpXx8BsU808FSgzoZS8-pWpVfcv5fSZRi4xbf25NH7zJgItKLIj1KZSQjiyalApyq8Y3dSji0JD15a7am_SiZnchYSadwykFimDUm7FAk8yrkBt_cAHaRc7ZmkeO6IokHCJ6ZgpRUNehlCDSsJQTkwLWk6fMWJ0N-lrQxlCz8DieL4ZG2SNOC6ZuTJXOe5X6XYiv3hz4hCGjxzOSdOtrHkTzpnu8kHPLe6-3n0WsQ8tArv1oDJfJ3_sp3Vk-vXqcCdO6meufp48cgxI4RlMqJn0HxIcay9RkrtHIlcrc-ugRRi_HBYJ4DQFdiA8ahf_1X52OTEzfxw4u9LcdCWm43P2oV4G-eOS6Ej5raIfx65suoePGujXNtSip4qea1JDBZGhNd2wmqCQKdy5A-tBt2eYVpykiAJgLO-MX860RrdJhe7O-tcpLBElnf_R2NrkQyIlKvxxURPCunQp-RQiF4LDRTaojBImvMtS4P1fYiCxdArK-W7YuXyNvQnxoB7MTPqpWx4J-jRMBgdC-pGz6xchbOHST_H3bV9UZsfEUJG9NIwaDVTrc-HqTklIOGzthjG3QjeMEUCRfiO0J3CEK1Q6i7igtVorgmHJkPXrLGJKEG55X-Lsgq0hlgNbtHeGypU0m8mfVBYXoViegrtWeljouz-v0qepaqlgQjsTOUvODCbKW_e7vNP8X1XSfhhc-AKhy5YZmyk6lYY7MP9HH51ZYVZZZIsQP3dTJXZLEAvWFskUz4mOabhAl_zLlF83U34yuhRgplEpiWS-Pk49f9Jk_-vkYpsxx0Vxa8Z1QLZcXWvIN3ceVtJiqFWtwQueXTwkSdsTk3H8jWEkpFXTdRF3Nm30Lfl_qSCDpfX2cvgHZiPhg_IC0ByvBGT7zDuUOCQzPGJjTGAvMdhX57RTfzR6n5GZ62LNkUl2uo6vrjQPdvk5x6KLRR93o2AwbLpubhmWrNozfakXHPinjkKaL7_mRWvkkEeESPpM0W20CDKjEdrGYkHAQMofOf3q6oGoQHfAXTSk1WPWaQeJB7Jz1iiOcYH8IItlUtslba05MI4EcCCBPqmCjCyIvhzpRCxbpII-E72gcAE7y-46euR1i9PIYAD43j6mQv_kakU7mqnp-785YEhOyLukhmliDR_Xr8FwD-OqYNrRKtFOYncozMcX61YhTvb4vvEuxFqoDwf0oLpEA1qQYB-GOp0gIcb0AsX3KcU94oZVL1rEHbfn6oAK-iafHSnx83xfjy6QmhH-Q2-q2M48-CT_TcwYk4trN0KNKdReP_CRqOgVWtui23IcpddaBCQ8qtJbA5WCCC3JyhV7gTLCCMMdytmmbOPnJv1gbnf78kqeC2W_vp1f_hZDBr4D1KhSiQRWMa6GHWQjyki837X60TUStj8Yvx7dl7BCYZ7Qgrs2NQdngJEo1Xe5IerpQsIO_gIxlxPflPSuIPWrYuScGjWWFsyBAenV5mdt5pv4dBi9anJThFHhXlP7uMjDLiIEQjIwpPeFS5IcZEnf7uB0JP1TmkGAwoafHfeMKbhCIrh6jlTFdd8lEKTfAG_5ltY-iqtJPEwL0kXVlvj3NNFopDs1bVLgC3qenJi5QP6oMWefAyKWQO96Bn5c_x-YuA87TJah2kdSlz_mtLDJ-ZioyZlh-ay8_KM74rkNKBm2GOH5ZxDWVRFYJesr7O4kzMETjcpivKjrkYOIuK2fpKoBEMMMsNBmUp---oG6Va-xMB-_rXLp8jVnEM6HPox3_of0NHWQ8UexMN9LW_i7FFUyKxw5IFBWkplGt4eCYNgTGHw3YMuPt1ZMq_26JIAgZtignLF316Dnf9EZ_3klfMFT16ZcE\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"F1AE9119-44D8-4E6D-83FC-5794E0C43193\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7juMDJedBkFrAjm99BywICUddrhD3dUA4cDC272UoX2MEun7J4LoWWGOo9L-2PkDiG5y1geNwk_T7G1PA7hFpR3NxN-gjsgllJl1POoNruDqvd9tu1l38hfQ3IoauYZgefWDM_YFGx1K4BSI-faJXNaCX1JYq9zKxb_dzM7HGrrUYw_gafaLFBGHHjt2GDInTrHPz8EV-_HMipvBt8dSG0gx9zqnWi1CP5PbhQIAB8hQGc9lRg8HvdlEp_KZg1wh-AVAbpX1tKwKdPERDwxqPG6luC2nIwLRGQxYdhGUdj2i21pW5CW2n8MSn77EvWq_vQME7dQmZoEGJVqsR-FE_ZFECgIi2LrTzqT9g5bPOHK66uIuCQcpMSKgPLOCxHh34yN4ualBAb4KvHVp3FZQl0p18qFN214FdT7rZqrpUJRUeiUuEf9HDmPT3-tRN7M3J_51rKyGD-NY3cJtCI96Exh7afLEuHOmqzDocY3dqY3Wm8Kf3UuZwG90Ics6O4_u-2NwWEUAmnqJUYMFASdRIxNJPGXzNdS9nNP0wscoLqbiq29RQDEouNkjwIaA6R0zmzk_f2gjyaRxNpwpxMaRCl9_8eET0RwlmNfWjvsd1rzpJmggJCWFifJyjBDLp-Jq-y8Kho6xYPI2rkmpXx8BsU808FSgzoZS8-pWpVfcv5fSZRi4xbf25NH7zJgItKLIj1KZSQjiyalApyq8Y3dSji0JD15a7am_SiZnchYSadwykFimDUm7FAk8yrkBt_cAHaRc7ZmkeO6IokHCJ6ZgpRUNehlCDSsJQTkwLWk6fMWJ0N-lrQxlCz8DieL4ZG2SNOC6ZuTJXOe5X6XYiv3hz4hCGjxzOSdOtrHkTzpnu8kHPLe6-3n0WsQ8tArv1oDJfJ3_sp3Vk-vXqcCdO6meufp48cgxI4RlMqJn0HxIcay9RkrtHIlcrc-ugRRi_HBYJ4DQFdiA8ahf_1X52OTEzfxw4u9LcdCWm43P2oV4G-eOS6Ej5raIfx65suoePGujXNtSip4qea1JDBZGhNd2wmqCQKdy5A-tBt2eYVpykiAJgLO-MX860RrdJhe7O-tcpLBElnf_R2NrkQyIlKvxxURPCunQp-RQiF4LDRTaojBImvMtS4P1fYiCxdArK-W7YuXyNvQnxoB7MTPqpWx4J-jRMBgdC-pGz6xchbOHST_H3bV9UZsfEUJG9NIwaDVTrc-HqTklIOGzthjG3QjeMEUCRfiO0J3CEK1Q6i7igtVorgmHJkPXrLGJKEG55X-Lsgq0hlgNbtHeGypU0m8mfVBYXoViegrtWeljouz-v0qepaqlgQjsTOUvODCbKW_e7vNP8X1XSfhhc-AKhy5YZmyk6lYY7MP9HH51ZYVZZZIsQP3dTJXZLEAvWFskUz4mOabhAl_zLlF83U34yuhRgplEpiWS-Pk49f9Jk_-vkYpsxx0Vxa8Z1QLZcXWvIN3ceVtJiqFWtwQueXTwkSdsTk3H8jWEkpFXTdRF3Nm30Lfl_qSCDpfX2cvgHZiPhg_IC0ByvBGT7zDuUOCQzPGJjTGAvMdhX57RTfzR6n5GZ62LNkUl2uo6vrjQPdvk5x6KLRR93o2AwbLpubhmWrNozfakXHPinjkKaL7_mRWvkkEeESPpM0W20CDKjEdrGYkHAQMofOf3q6oGoQHfAXTSk1WPWaQeJB7Jz1iiOcYH8IItlUtslba05MI4EcCCBPqmCjCyIvhzpRCxbpII-E72gcAE7y-46euR1i9PIYAD43j6mQv_kakU7mqnp-785YEhOyLukhmliDR_Xr8FwD-OqYNrRKtFOYncozMcX61YhTvb4vvEuxFqoDwf0oLpEA1qQYB-GOp0gIcb0AsX3KcU94oZVL1rEHbfn6oAK-iafHSnx83xfjy6QmhH-Q2-q2M48-CT_TcwYk4trN0KNKdReP_CRqOgVWtui23IcpddaBCQ8qtJbA5WCCC3JyhV7gTLCCMMdytmmbOPnJv1gbnf78kqeC2W_vp1f_hZDBr4D1KhSiQRWMa6GHWQjyki837X60TUStj8Yvx7dl7BCYZ7Qgrs2NQdngJEo1Xe5IerpQsIO_gIxlxPflPSuIPWrYuScGjWWFsyBAenV5mdt5pv4dBi9anJThFHhXlP7uMjDLiIEQjIwpPeFS5IcZEnf7uB0JP1TmkGAwoafHfeMKbhCIrh6jlTFdd8lEKTfAG_5ltY-iqtJPEwL0kXVlvj3NNFopDs1bVLgC3qenJi5QP6oMWefAyKWQO96Bn5c_x-YuA87TJah2kdSlz_mtLDJ-ZioyZlh-ay8_KM74rkNKBm2GOH5ZxDWVRFYJesr7O4kzMETjcpivKjrkYOIuK2fpKoBEMMMsNBmUp---oG6Va-xMB-_rXLp8jVnEM6HPox3_of0NHWQ8UexMN9LW_i7FFUyKxw5IFBWkplGt4eCYNgTGHw3YMuPt1ZMq_26JIAgZtignLF316Dnf9EZ_3klfMFT16ZcE\\\\\\\",1]],[\\\\\\\"4F647F02-FB7B-4661-A489-7338462DFA51\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:17:35.218Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=980255&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,380355409,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6uklvA4YGEfilf_ULcyT0JE-cwBF3CF-THDEXJeLC97nc6KvZ4U9hxTRyulhs_9au6UiDnKfd-eGWR9e-wmub_l1Le-7_h0rt65vPnTXT1jb1I_7jq8UgaKeh8Id9jqy4OEgCvHJFOG480wk4oDycUke_Atype__E61SmdtFhBOdIhx3XMaRhwiNx1MiSy4WicTZdAZA8hDN5Y06hUraRGHtiK63MtAdtJcmyBUcIIzlZgqQ8d8QkuHFr_Qof-g7Yj7QZP_iM9mlqcemSpWWBb7EsEt1kNNtnHey07y_6lwKXH8-gQouzzu-NCF2o-4CCZmdKwCUDy8y8CKrk3wUGZpPt57NLVoueUlQOUWqkwXwMJ-QZCs-IaNeYIjDWqVoBhyb59lfpJ_j6R3mZE3a7ckn261u3_Hyyn6K1McnLRSV5Yd8WHfoDu2yx0gux_Euc-B7XlJixgxxywW6y4OQG8kUblL__Ez4T_jJ8cKaDE7txkduRLZ7XYUl0Hxk8VnGv0kR2zUhnw0EJqKMxAyfTvF_EDf7ijCS4SrZMuWxidG8cj1yJEDpxGZGtB9AAp3_UuTns1F2G2kmuC1YGF9Ou8bKY3KtpwdJU7eE2lusOHJ_fkUGkHyDP0OOKSbgRszytmfn-ctEPsYpewDQh_9ZT1ONrKqIgG2yYxgQIb2expvFhd1EXlCzmJurUQ-VJi_2fSyawx0QoPr7hA0Ip29C8_fZu3w2mzd10IH78SwGgstkbJCZ9aXweej9sv0s_ndMF7UpudIWjPXne6zCbu_XersIuAuKxiYMtyZcRSxZX70aE_ivDWdHjlkTJLOAvZv1PyJ6RPMT0CTuFArVinBj0lDvqp9vPgkOQSeB2c2J1HjQ_Sm6uvmws61OpNJBN9dSXLmOjlPw-UYcKAN-m5NxxKkM0Dhf6oAGMLDcV8ZhHFP0dvHnnuKDhqXh1JmUyrLw-6AvY2ghkePD3fuPxtKvVOk8uLOEc-HZ76ZcLwlrSsQQsJetguHjl6TTHTs0KF2mg1COuUwFf5mKDwXTaJTDvMgD5WR9axcAs4L05zekNecdRMm0u9_5QPb-N_qOaoxBnf0697YU-2AxftNHdvoP2Db1h5xHP6FuvuqTqXjUwDXhdNDeKvz5XW2dNCXaeTw_tkr_i10lQ2VfLgSZPfRMbwXAZOe7iOEGOCzijn1etW8Z5cHD9MBRv_w1dciX0dptz1isrLdqHKl8PQ0UMYHE8EUJ1eHW7QNtCNZeJ3J51GazmTo69XpNfUb2RE8fS8dwXeQgkm9kVMh7Gi8CAYzH0RmjoNvLDSfEzCpulResh-kgiKOFqenTjw9xn8fcTerFMlViUYlknrfpUjDjR6reGyLBhYhDx1p8sw6cybd5Z7FrVf4XR3Ii6jyV-RZacoP9Hd5qsY4jpjGwY7ePuUJwlQlVrHMRspug0wI_04Hh8Doqk-i0DVJOmnDlWdCc2cQXFwYxQ09ErME0oT6i2TCEH931_NZm9k_mYQG4WN3e3ZKg99MIeJGSiojbMMrpl9FfLzea6QL2ILKIXu9a0Szw9vk3oiNxfbABGvgmZDjFvQeOvWzIDFPpCRZT1JlVZAzq2KlRGq2vVyPPiUE7AX9Xy_CzEd3vJPUw2SM3C6saGpX5LqnKLRB_BSz-nmmwnHgVgq_hK7v0lCuTJWJU1W80no3cg5H4od0aZm6g7Dxlm7D_0gdpLUD7kc5bwruwcNlAGFMjpK5TFpmHKXOm_Hjb16T-5p3u31hCeNZh0v9Imhs1s0x1fJ3nVWsoUZ1xqqvFaL6xiLH1KKq3XWeJ7C-6TtWGNZZyaQqEc0Ur-lp2ppyhXC2KFIj6C5gRSY35Dlq3zKQ0O4tumidTDUSngQmaDm4VvrJLr9i_OHCNC7Jaw10zBhpaN9vWJN1v6cm81SSzjXRZuwTMtZhEw4qblW3VM40PO0Y5Xoy6f0Tv7VwudbQDXKSQiufUI_rXiM2eA0eZ1JCvEPozZGFbK914EUFvVvFexLx9-IyZHY3vCURnrOwWSWHglnIfwdIWFd7MtcBWQpu1tcYM52Gh_E9YPbhyteOyYSY-otLoww5seyiqR0QeCZ6z56BX5mpksZySsPbu2my-kE31IiiNfuhCRNU_xEwWHcdzhO_tbwH0X2MS9OV6gihilsYqeu535wInAHHDWpy2YWpiNh2virDNK8zufUWNto2HTXmuCbx71eNUybtLWTGihGFOxY2RgJBJZX9P0MFLQIFRdfw3JNP2LIgBWsEDehu320Lk4o5hj7FxwiFl1CC47QBltdFTJO90ciMRwc5xXq8fKgjblSyQKFfz9nA-HmXzqKr7MdCVHAf-b-9cCdz6_kC7QylFjdQPMoHpDIqN-kyRe_ukPM8uEoanHBe8la4FZ8oHd6f8mT5Q99il_D20l2-Im_zmfolI06HIyvKRFCuIp4B4enlTAfc8k7koUoa6qsCgOxRvx_rrrCjZ6wpfYlPf7y6CA8Aj4jZ8FengMg\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"23395401-5443-492C-A5D4-E891AD4BB9AA\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6uklvA4YGEfilf_ULcyT0JE-cwBF3CF-THDEXJeLC97nc6KvZ4U9hxTRyulhs_9au6UiDnKfd-eGWR9e-wmub_l1Le-7_h0rt65vPnTXT1jb1I_7jq8UgaKeh8Id9jqy4OEgCvHJFOG480wk4oDycUke_Atype__E61SmdtFhBOdIhx3XMaRhwiNx1MiSy4WicTZdAZA8hDN5Y06hUraRGHtiK63MtAdtJcmyBUcIIzlZgqQ8d8QkuHFr_Qof-g7Yj7QZP_iM9mlqcemSpWWBb7EsEt1kNNtnHey07y_6lwKXH8-gQouzzu-NCF2o-4CCZmdKwCUDy8y8CKrk3wUGZpPt57NLVoueUlQOUWqkwXwMJ-QZCs-IaNeYIjDWqVoBhyb59lfpJ_j6R3mZE3a7ckn261u3_Hyyn6K1McnLRSV5Yd8WHfoDu2yx0gux_Euc-B7XlJixgxxywW6y4OQG8kUblL__Ez4T_jJ8cKaDE7txkduRLZ7XYUl0Hxk8VnGv0kR2zUhnw0EJqKMxAyfTvF_EDf7ijCS4SrZMuWxidG8cj1yJEDpxGZGtB9AAp3_UuTns1F2G2kmuC1YGF9Ou8bKY3KtpwdJU7eE2lusOHJ_fkUGkHyDP0OOKSbgRszytmfn-ctEPsYpewDQh_9ZT1ONrKqIgG2yYxgQIb2expvFhd1EXlCzmJurUQ-VJi_2fSyawx0QoPr7hA0Ip29C8_fZu3w2mzd10IH78SwGgstkbJCZ9aXweej9sv0s_ndMF7UpudIWjPXne6zCbu_XersIuAuKxiYMtyZcRSxZX70aE_ivDWdHjlkTJLOAvZv1PyJ6RPMT0CTuFArVinBj0lDvqp9vPgkOQSeB2c2J1HjQ_Sm6uvmws61OpNJBN9dSXLmOjlPw-UYcKAN-m5NxxKkM0Dhf6oAGMLDcV8ZhHFP0dvHnnuKDhqXh1JmUyrLw-6AvY2ghkePD3fuPxtKvVOk8uLOEc-HZ76ZcLwlrSsQQsJetguHjl6TTHTs0KF2mg1COuUwFf5mKDwXTaJTDvMgD5WR9axcAs4L05zekNecdRMm0u9_5QPb-N_qOaoxBnf0697YU-2AxftNHdvoP2Db1h5xHP6FuvuqTqXjUwDXhdNDeKvz5XW2dNCXaeTw_tkr_i10lQ2VfLgSZPfRMbwXAZOe7iOEGOCzijn1etW8Z5cHD9MBRv_w1dciX0dptz1isrLdqHKl8PQ0UMYHE8EUJ1eHW7QNtCNZeJ3J51GazmTo69XpNfUb2RE8fS8dwXeQgkm9kVMh7Gi8CAYzH0RmjoNvLDSfEzCpulResh-kgiKOFqenTjw9xn8fcTerFMlViUYlknrfpUjDjR6reGyLBhYhDx1p8sw6cybd5Z7FrVf4XR3Ii6jyV-RZacoP9Hd5qsY4jpjGwY7ePuUJwlQlVrHMRspug0wI_04Hh8Doqk-i0DVJOmnDlWdCc2cQXFwYxQ09ErME0oT6i2TCEH931_NZm9k_mYQG4WN3e3ZKg99MIeJGSiojbMMrpl9FfLzea6QL2ILKIXu9a0Szw9vk3oiNxfbABGvgmZDjFvQeOvWzIDFPpCRZT1JlVZAzq2KlRGq2vVyPPiUE7AX9Xy_CzEd3vJPUw2SM3C6saGpX5LqnKLRB_BSz-nmmwnHgVgq_hK7v0lCuTJWJU1W80no3cg5H4od0aZm6g7Dxlm7D_0gdpLUD7kc5bwruwcNlAGFMjpK5TFpmHKXOm_Hjb16T-5p3u31hCeNZh0v9Imhs1s0x1fJ3nVWsoUZ1xqqvFaL6xiLH1KKq3XWeJ7C-6TtWGNZZyaQqEc0Ur-lp2ppyhXC2KFIj6C5gRSY35Dlq3zKQ0O4tumidTDUSngQmaDm4VvrJLr9i_OHCNC7Jaw10zBhpaN9vWJN1v6cm81SSzjXRZuwTMtZhEw4qblW3VM40PO0Y5Xoy6f0Tv7VwudbQDXKSQiufUI_rXiM2eA0eZ1JCvEPozZGFbK914EUFvVvFexLx9-IyZHY3vCURnrOwWSWHglnIfwdIWFd7MtcBWQpu1tcYM52Gh_E9YPbhyteOyYSY-otLoww5seyiqR0QeCZ6z56BX5mpksZySsPbu2my-kE31IiiNfuhCRNU_xEwWHcdzhO_tbwH0X2MS9OV6gihilsYqeu535wInAHHDWpy2YWpiNh2virDNK8zufUWNto2HTXmuCbx71eNUybtLWTGihGFOxY2RgJBJZX9P0MFLQIFRdfw3JNP2LIgBWsEDehu320Lk4o5hj7FxwiFl1CC47QBltdFTJO90ciMRwc5xXq8fKgjblSyQKFfz9nA-HmXzqKr7MdCVHAf-b-9cCdz6_kC7QylFjdQPMoHpDIqN-kyRe_ukPM8uEoanHBe8la4FZ8oHd6f8mT5Q99il_D20l2-Im_zmfolI06HIyvKRFCuIp4B4enlTAfc8k7koUoa6qsCgOxRvx_rrrCjZ6wpfYlPf7y6CA8Aj4jZ8FengMg\\\\\\\",1]],[\\\\\\\"605BD248-8FC6-463A-AFFF-62DCCBD536B0\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:17:45.230Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=649598&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"BCCCC76F-5DAD-4108-BDBF-A573659D5F11\\\\\\\",\\\\\\\"65E09B71-65B9-4329-8CCB-C4B22874B537\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA59Vfjg1Okyx5NOcJRNVQWXxrtlYvxFe7IhMdB1cHcku6NUx3v2qKsV5nt6IDot-c4eNZOGaIcfz-9QIw3iYJswPbppYF8JSnXZM7utSR0syCXcN48EAAtM21XEbA3y2I_8p1sxCzZ41dDAhYVLMBiIkVe2UFUpifx8BJgHpuLYugoN_X5AZPE4pe3SE9947DLjeCmv3Aq9bgveYHRcDQHfuFWnMRktXgcZvgE9wGliytW8kN8nvZU8_Qb3KXkysAGUQHbpPZkBBxjXv0c3pk_5DYbvfg-Ux-idF8D5j3RTrGbN88vD05VifmLHWeGOXuTje1zF5vpK1bzPjwfFsGda5TVyXzr5fSKQ1igIt-W240D2uYg9Y4HRUDui8DK4CU5P8sjlRuhxDUAjePkRR_DwJNTp7CIDPyTDeyrR6iI6GmTqhUjwnnL7rz8PCguVJr3nYEV4m1fkTAHQ3GJ9nFPELeh5PFJ2IEuqydhB23sqctxVw85t2KPU_lhM7yqKw98kQL0TPU8KEDUjcXYrC6_YX004fUJl29yWLBD1SKq0HPKrcx0o5-XsYyelThUhQA_kAOZ_O9ek8BqgwYT9e4xQ-aeEmxTghlXYVObhOx56vEhbCptdr8YvxcVdZDIe49Jl5Ko-nlbbityy-ciVOQM32UvY8bQ7xMR2TxKT1EqCA9y35LkT606x36uZcxt06pRE7BV6m18cOdDHP7RFQR7UuDhJ0D2e4Hq9V409H1bFxktlsLx9qthaVF1mCthTywXX3pgUiZoNMaLJh02OlLrVDX_-i0xRgSPraY99u4reqppao02mBnlgi0Z2_ItJHig9h7tImA-xQ_dajnKHpRRoc5KUymX2xz7SbOvotWYusKUPsEF3luKTzAY1T80JyQlZuVC4hcCxzKhpOHB0uV8-TChwSf9GJhIxGmHbK-JGU0PEYwWOiTCOv5NRljcOnNuDXPB8Zac3k9aSBTIXjzZedUKGsJ8u7BTQhSfWBzfPRfFw8q1DxYjCqX3uYMkj6uv2w93DFCGm7iKVPk0xkVKBPA_gkkBYxK7jcZdqV-c10IgtkF2zWhr5fotOHdDAXmqqcGCKX6UjvajtaMI__FNE85_I887W-DENQkLLWcRjRJoHQJ2S3Bp1U39iCEYoO88pdPetn6SSnBB3dGtTO28UrUwTRQx7DrHUy5aIKF2sDFOKg2Y5PDKYNc7THfJ-urbs_bbAZbkjalOgcCwbaew7gcxkJc_oJ0jfBXzZLb_Sv6Hx6LjEwpe6uNOCjxtL0kDPV9GrHb7enGfPoonQTnCa2S1lUPHPxhZCvP5Z7SutG-bELKYGk_T_vEGbDSRD5sOeg2uvwxvVeV2qECBfzF6Jqt1bgIT3BFABdb7Q_P1nR0Yr1YrGHQLc1sxTZRP0W4IGWHf8L-5BAhGAX-U4nsIHvgZFdhIwCrgLg80ZxVSmjVIJzr6Kmji8Ms_siGU3GkgihU98OA2qjeyZtqo4G5QQyXmzDG3reVkeSnYyndkWGteTzBxWzjlAylq3vJwVqQwxfhCAZxWU7rnolfdZd4tYbjzw8lSBX8UfVNrxayTBLzHY_8yY-q8heyiyP6VB3fuMMM_db1rjWwkFVDgA88ulFLAcuGME97YErKDvV31eBwaEzHNGKwQYU-P7FJ8pwgqDNSMejaH8xO4uLIp8mhsVFleEkBOU5WwibKaHsZNSDxyeLGelxnyNPBZqnuugKUcBpusWqe-3IDca8pFYIocvTSQ4JrZS_QYHcUM6Nl5yeFMtSXTOcp8FPrV5sHkBgxgyf6_H4enQGnCtx-smL9cJcdJGH9ILb4d-FZNUahg1zbhJmYJuiOj4m4lIdUkNSe243d7rg2r3EY1JysJwklzhrVn6-zZ8CZWtLoBHBBvDBm14z394g-yE3pacDTYv-CeeFzEYUoQiixeCzJLHhGtzMQh50EmYwNGNMsS7VLa3K6sEFb4T2eTnhaobAI__U9nFzsXzCq89GwvpWsapodc-GScrWwEho_ajwkSiJ-FRgfghvOWye4SZXojr0lqiFaCpDSheoIG8Y-ZVws4I9uyAwPK9J1z4LqvDt1p_4b4hFLj7azP_f8fxWkRmxaax2HL2FSrQg_PUmYjmzymRThIXR0eY5DUk4xoBG92HVBELISiRjhBkct3fzMssM-DXhA00ZgvgDjD-O-8Wsy3ifkpFG4bYU6hnLQV-UkY0vTB8bdATAXDJ68coUxcmbO-Os4rI6_WRjLwYRe5qw0QurbrthW527Qn_hdTQIlJNl0j4klXiOk272Ih9PlRFncn_KSQmZuB3RZyVRY_oRzNbJDadkK0wl_WALpoeUKAxMyNsejb4dOQAB9u2Rt8rUhc-sWUvJ-QBVyhHm9hfWh2gy4CAsONQQ07NpbIfPS5cBwvDhQOceAHHQgZaL8UAzTEuXi3IO7LyieijHEelS9rtUXw6HTdUNQNdZ4r8cQuhUDfn2StIm9tjKSggBq2_9fepiRyncM4B\\\\\\\",1]],[\\\\\\\"87416079-1A82-44CC-B790-47AEE97C2A27\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:17:55.238Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=973374&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,65089712,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA54UNLpEh3wEebfBZxNXKQ2AWUqrf88vilj0mVClw6TW3wncrui9-gLshOKj48UtsNgkLtOxEvWCGz1vCzfUvY05F8C_bbRTRo8Ih5TO60YNWDvUjH9QkvMViIbH3A3u1X24eSxjhTH1DvqeZgh7h4OKHxhXQ7rGsdWVqhFbowafddkw7t79a_Syq7ZuFu7DCKU49mG5Fias-j5qHzPvMmXJA-9yMOWvcYlY4Udh6Z2pwm2l_NjKRCOJ0R1qAmrds4achC26MBTMECyT3WD4T0mjPCylNegXsQZdLRjgIXSGnwHZUttVdMGazRnpHTLpj4E-OuiU9-N1uzcx9a8X7lPL4w4z5REyG36kM1SF8LTtaM2OjeU7VcsAx58Ro4Aqu-juOSH4MbXNI1_r10SCC4zYyAgYU7M7YrmlqzoE7GfGBd5X5ARliuR6KqyQWir3gkX7SOz_Yshlp8qI2rUqgZeia0XC0jGOlAFeV-tIhlTT9L7wy9KfhRG0YKFuI4tllb3KoBeIh3T41EjLQZHcM6VOC8Xl9pLlMM5zv3KuI75HHLFvosIHnML0Slap-jk3uRRdrAV-nEIiOcLxTT8txi0pBJr6pu0TkguL5wB-XiPUM4585CL_FT-H9Cg_He_y6EdmB2Zoai9mlPG0sjUXnDT3JvB6Hv8TTKlDMryyacseODTAEyVIQaCKljt06H1MiMGpbB_uu2r1mGpp5Kl4whYjI_SvDtA-vQb9lMXwCC2ik1kwpuISJ624FQKqLL-ex7xQ1fxU0x4ObxFQHuljiOWQb25FfBbwRplqISUX8WJoXG4kfI8bmSRwRInunbyPFn2vl-OsKCJlzq_XPzooXTgyw8gPpT3YlvXdTJjLdTrpLVgtoOIjDmfFoE9TG1p3iYvHgw0il01btuKqfARa-5Lm8SLnkDbVXk2TOsc085jTPraXBAeN24ZD67mhQMsjux90D4wT2I8WrvICtRlwXwtqDI-yN8nuyQmVwc3pJO1_jvIQ670b1MvAgPf6qs9_Vd0wIn9q9bYr-3RY40pscapP6-jZ8GydKpH9nnOk3Bp97WW8nQYTdct-ql9kYuGLBXtwA8AIUNGzL8LU3ymj7AIAhVD4RXVLYJFLnmAgJGLASC5wSSX_nILFAa3G_FKAozmHm0BgEv-jSADpYpOH5AgIzCjsgAX6P26S-gaVnQRxoFZYyLQPzl0IqH8Lr4nbV4QCgFL69FcFmz8QfsCqzWQVdSR3gEKsvp3VoK7pHgSRVFjRcEV2GtaDkQRh_Lf8xuxbjb-Zsk-qg3GsQiZk2JA-VLD4wPkoQvfvdQnyD9icSp3UbawYo_kGuRBmbhGgkZnTPHu4AdIXJwG-DhsjZnss2OdqZwF_bxH9IM7_9OmweUsnYeOoZVoennPIOB3RJgNs2G4IxeOWTa6d9Ymnsv2u89097ShD00YK_pWQO2beD8w94woE-GsFK3juI12_X59gRPHUSMBorx6FqRJrPxLyxPhcW8B5IK1vjWCo3WRxz5LqK0eLQeFtvC8PBOEvUAoW8pvLx3-4Ru9-JgJCXSpuDqaps_VcllA0Fg93fGXP-t_nVDd8hc-fhiAbUfPJN4ZO3prfDuRsp6TWGYoMrsL8iozg8HGng4S83jKcKT7wRLdIoGSpyZPBzQMdzdDxmNVa_5XLh-9GCYnObpvVmaglScClzOdcxVe66g2vGMKNr3EamfgdjCTlkRCyVao2W60vhN91Xz6px-TzaICotojd9i2p0jlMwi2MSQm8-GnULvwhXv3z9J92PiVr7NqDMBMOKTs3mj6AFXkKvGfUUgqNlxixyB1iputyYOZb5VFWmN9vtwjMm-qml182WzkA0FmyRTudl3DzJMomHjvFI5Ng1JWn17q1Ubf33YbjCT8gU3F_3lvWCxT4VLqGjFZzY8HUjyBMG85QmIxusdRZh5OORuZW5_n0gK9RE6qk-3ViCX6c2ZmM6Nb78XXo4YVdqqbT3phyIVeNE1yTDLdOUHYxS4Y2r4VtpAWXfenufVZ8TuV5Q8PGV3LGjbnSblEgWeBhAZSRR5YwJaFtHn4ACocVuF6kdWMavawEyk9DgDvQNhx8u4AXIYkbrLwJ3xadRawdPR7gYLm8o98aNyLG0xxRSORAwDLP1dLU8w3buDQ0_kcFf0Sx5FZzJsT-gE286quLlAibKZGsdvsWwgvXWjsSajjGd8N0myAJ6hxaYGRIFYdDsGUzxOIepGf2jh1h5RlFUhOViXeR3YkUfOrp-IA-c17HVAOXLGcNv-cpQqgfLNex6qGcNGJqiYFuPh21FMkMJkhNT7Ch85DZKFpDCAGFlJH1q0hoovjscUTk50B6im4mGHVeiYE9w3EXZryNbh4WapqLYI2YHfe2wCJEobwXN4lSfAX8ByyUk-igewZB5gcSu2FSS-375-HXGAMFZc4o53HHkB182nXfjfgLwRhAA2sxh7x6LUkn_2_gKM9xQd0pos\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"22BB1624-4E6B-4E41-A1C7-B6C0DCE9E5B8\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA54UNLpEh3wEebfBZxNXKQ2AWUqrf88vilj0mVClw6TW3wncrui9-gLshOKj48UtsNgkLtOxEvWCGz1vCzfUvY05F8C_bbRTRo8Ih5TO60YNWDvUjH9QkvMViIbH3A3u1X24eSxjhTH1DvqeZgh7h4OKHxhXQ7rGsdWVqhFbowafddkw7t79a_Syq7ZuFu7DCKU49mG5Fias-j5qHzPvMmXJA-9yMOWvcYlY4Udh6Z2pwm2l_NjKRCOJ0R1qAmrds4achC26MBTMECyT3WD4T0mjPCylNegXsQZdLRjgIXSGnwHZUttVdMGazRnpHTLpj4E-OuiU9-N1uzcx9a8X7lPL4w4z5REyG36kM1SF8LTtaM2OjeU7VcsAx58Ro4Aqu-juOSH4MbXNI1_r10SCC4zYyAgYU7M7YrmlqzoE7GfGBd5X5ARliuR6KqyQWir3gkX7SOz_Yshlp8qI2rUqgZeia0XC0jGOlAFeV-tIhlTT9L7wy9KfhRG0YKFuI4tllb3KoBeIh3T41EjLQZHcM6VOC8Xl9pLlMM5zv3KuI75HHLFvosIHnML0Slap-jk3uRRdrAV-nEIiOcLxTT8txi0pBJr6pu0TkguL5wB-XiPUM4585CL_FT-H9Cg_He_y6EdmB2Zoai9mlPG0sjUXnDT3JvB6Hv8TTKlDMryyacseODTAEyVIQaCKljt06H1MiMGpbB_uu2r1mGpp5Kl4whYjI_SvDtA-vQb9lMXwCC2ik1kwpuISJ624FQKqLL-ex7xQ1fxU0x4ObxFQHuljiOWQb25FfBbwRplqISUX8WJoXG4kfI8bmSRwRInunbyPFn2vl-OsKCJlzq_XPzooXTgyw8gPpT3YlvXdTJjLdTrpLVgtoOIjDmfFoE9TG1p3iYvHgw0il01btuKqfARa-5Lm8SLnkDbVXk2TOsc085jTPraXBAeN24ZD67mhQMsjux90D4wT2I8WrvICtRlwXwtqDI-yN8nuyQmVwc3pJO1_jvIQ670b1MvAgPf6qs9_Vd0wIn9q9bYr-3RY40pscapP6-jZ8GydKpH9nnOk3Bp97WW8nQYTdct-ql9kYuGLBXtwA8AIUNGzL8LU3ymj7AIAhVD4RXVLYJFLnmAgJGLASC5wSSX_nILFAa3G_FKAozmHm0BgEv-jSADpYpOH5AgIzCjsgAX6P26S-gaVnQRxoFZYyLQPzl0IqH8Lr4nbV4QCgFL69FcFmz8QfsCqzWQVdSR3gEKsvp3VoK7pHgSRVFjRcEV2GtaDkQRh_Lf8xuxbjb-Zsk-qg3GsQiZk2JA-VLD4wPkoQvfvdQnyD9icSp3UbawYo_kGuRBmbhGgkZnTPHu4AdIXJwG-DhsjZnss2OdqZwF_bxH9IM7_9OmweUsnYeOoZVoennPIOB3RJgNs2G4IxeOWTa6d9Ymnsv2u89097ShD00YK_pWQO2beD8w94woE-GsFK3juI12_X59gRPHUSMBorx6FqRJrPxLyxPhcW8B5IK1vjWCo3WRxz5LqK0eLQeFtvC8PBOEvUAoW8pvLx3-4Ru9-JgJCXSpuDqaps_VcllA0Fg93fGXP-t_nVDd8hc-fhiAbUfPJN4ZO3prfDuRsp6TWGYoMrsL8iozg8HGng4S83jKcKT7wRLdIoGSpyZPBzQMdzdDxmNVa_5XLh-9GCYnObpvVmaglScClzOdcxVe66g2vGMKNr3EamfgdjCTlkRCyVao2W60vhN91Xz6px-TzaICotojd9i2p0jlMwi2MSQm8-GnULvwhXv3z9J92PiVr7NqDMBMOKTs3mj6AFXkKvGfUUgqNlxixyB1iputyYOZb5VFWmN9vtwjMm-qml182WzkA0FmyRTudl3DzJMomHjvFI5Ng1JWn17q1Ubf33YbjCT8gU3F_3lvWCxT4VLqGjFZzY8HUjyBMG85QmIxusdRZh5OORuZW5_n0gK9RE6qk-3ViCX6c2ZmM6Nb78XXo4YVdqqbT3phyIVeNE1yTDLdOUHYxS4Y2r4VtpAWXfenufVZ8TuV5Q8PGV3LGjbnSblEgWeBhAZSRR5YwJaFtHn4ACocVuF6kdWMavawEyk9DgDvQNhx8u4AXIYkbrLwJ3xadRawdPR7gYLm8o98aNyLG0xxRSORAwDLP1dLU8w3buDQ0_kcFf0Sx5FZzJsT-gE286quLlAibKZGsdvsWwgvXWjsSajjGd8N0myAJ6hxaYGRIFYdDsGUzxOIepGf2jh1h5RlFUhOViXeR3YkUfOrp-IA-c17HVAOXLGcNv-cpQqgfLNex6qGcNGJqiYFuPh21FMkMJkhNT7Ch85DZKFpDCAGFlJH1q0hoovjscUTk50B6im4mGHVeiYE9w3EXZryNbh4WapqLYI2YHfe2wCJEobwXN4lSfAX8ByyUk-igewZB5gcSu2FSS-375-HXGAMFZc4o53HHkB182nXfjfgLwRhAA2sxh7x6LUkn_2_gKM9xQd0pos\\\\\\\",1]],[\\\\\\\"B0CA189E-76FB-4F26-BF75-10B744963E11\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:18:05.325Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=419644&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"933DA127-EC5E-442F-8522-61885748B597\\\\\\\",\\\\\\\"AA32BA3F-E163-498A-AA0C-EAC0680CB55C\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6L05xcvg5LnssrTZ7fF5fE3jlMij1vkdl8NU5lY1I6bUuYO0_MbnBwzfKb6aXEc7cWga8-7Uu88rwpSNNF-PabhR86Yv7H_yyy267DoWoVXNXWy9PdPoLi3CuoE4MIMXr5RBWvFJ5aN4_iwXlPCLP1YMjzJdqJbmNdLXAh7QRGiSvp8UGZE2EguhZLGBsYxw-AGVPCFKBAA5GLG_mvRYIS3bSAJjfpMquM4X2vQEJEziYHZAKfOLqN4N0c8pYKHwp3nMtPA4zak44RAb3l312GTnH0cwDx9FVf0_i0TPb2O1VlCUhULdhoBmlz6mSooj3iVtTidqd782ak2aA2rYP1-OnL0U9x21PCp4NYmgJ7pNAbp5MicJ4NeDxz2dpijTmqmln0J-NwndCru0lHsQGXHQgm3KkMYdKkklZSmO8Go6sBgItzLlMPvm9fYuUoon0D79Q15JQgSWWruG8hyaPVbomtNjd58C8ByluDelXZeWvWlIDjAP0PM9oX2Ad1HLQZPJZdPVV0Jhiid8n_PQj4NqrWmvuAq-4ewRSI_VI1DrjfVHYFMvW4OIwgoOQ-lq9Fa01AXA4IkgKznYhTO_9nsjVIiGIBBlYQruFSuU4t2-9yaE4HuLmXcfbOgbSyqX5ygdhT31IQdZyrV9z2O5vT6fYuYV7otLlKdAt0w-juNF1FkZ84h8tIi2H67zNPxvTvNWwEtXHMuW5GSqQO3V_bXJImsRL-2cJxjh0riz_PZ2TujMGiEVwm-wD6U7UqWn2yyPil0PtIe7uDXmdyeD_ZQEPEz3_EszCu_zTxj4IRsP_gBOfze1ynxo866aaLw2-ohOfu7MdakrCGXe_QWVn1e0xeiY5MxrzccU_zh_gi6zsM3RCkuQoAnHLghT6DAZTbDkb7_Cr50v3BnqU7vHsvpJbjgXNm-4hhSc2O4TvsrYnf9dbPtd-ra28ZD2FgtwW8zO-wW3gdwJ_58B6TdLkP9hjuTvN784IYOnc64JU2Eds-cNlSxJ1qs-YJH74d-GPSpIEBkd3tu6VAL8Foyxi90M5dhDa0aNrMW395w3eSHQxmNIOoW8d2AmHjJS1xLP44R7coOZ_6gj9MpriEk5Xksu0ZFJ48vKLivAkBVsrrLNB7u2gmiW5JbwiFILBHBNgAgRv5tisHxnFkWWR3EiaK6P6WmI1Xr_1Yq7jc7TFwNy4xtXw-BdSri2NWdw8_lkJ1QwvDHygwfewjsnwBvDNLtokwaVYx9xMnXSIoYHiYIMmUQnFf_XqNYOaNaweBRAhU2m9fvJpqXqisx896Y2wh9hdxj9FBQRHDHpzcqHOUuG48xaBaZhrusDqte6PJ6OkLd7Gf33N1o9CWGYdnSgXrXeS54rOeuE7jv1K3Mn6j7kMclGi7dcIIIQSojZWUaFt580IGNdt5NH0J-y3zf6L99Ttzv-0yBV47YMfBqJ1EgQuHuEFZC28g42VsjBN1g-i5fPic-k8xc1VjtsT5USMVzMPIlFP4MnXQFoiLVuIL6UUnnEmNER-byOLgftvl8vmHd-nW9qlHqhX5UMv3sMgSSi0nzWdCZLTnXQsOBtIQCiqb1v9IjiH0L5Qgz-UnEDOvnW7S0KbEaFqNOss3jPoN2jvyBvThxMm4xEdWzbX7lcztuD9DBoj0Jy8r9MoGWGbhN005T05Ub_kaVv9kwMNYjocMkz0XeqpfcRfkDj_4pX37NErAp-5gKZKssE7Ycu7J22hJHVNCMaRnjOWHmxxM3scKnpJyMg55sAiSlH4JsELNMPuCHv4oOJRih0X9nkmub4wUXZaxoe9W39LZDmMSR3jPXijetr0TRdj4KXNtt3UX5bcpZKDYGDeyVLSg3j0tXmFUbJbKQqmXFgpqNabKiVPISgvGorA9PHgU31qyyRfZyfS795V89WokvQnn_46-_NhptncsPXMjfVACbpg66fHEH0ov7r-k4FUDWwU4u50u4fqmD9EdXUdSBRfSuDN1Im4uj3GLv7kl3OtV01JOgr-MVLqGpXpcgKKLRpY2Fc6iYg2Ly8W4DVu8QNx614483fisJEurj9k0sq1V-zCJBaUeARAeLn3wkAaqzn-t9cPFA75FEI1EG0zS6deNl4803aa81ZlbjFml_fnZfoXtS6svbjT0ZWlWpxo4JJuZXQ8NcFSDGnrSRHLchiRGlueLIWyztm8_jpGmfhNXPwRaAeVLh1yup755EBryFR4lsnpB9xT2SpMdIBqkwDkpxwnPHOn7aOoSqhnGk5lZ5S--ZeLjEwTQVe_jjScVR9FpK2edDqRbbOCjHg1FG_kqR3V1qoRBe3NpdETKgxsJY6PJ8LWJiigcSZh2Kcm7pINtf1TlkzgdFTlLjvKXhPVPwXkCDpy5dADbyNMC8ZJ53wfOSVM1gbHs7fuTyGH95GDmzGU5wjonv7tT8wh0tB77NwjlYonM55ji4DWXxMdTI3SHLJKPdEaqg0wlMfBONYUVrTxepSG316pjn5k-Trkg3LgCWeuV\\\\\\\",1]],[\\\\\\\"F32A9549-CBA2-4B1D-8B6F-D1EBA8D2DDA0\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:18:15.325Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=395153&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,534010413,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4X8M-bCsdWJanNSAFjtyzBoRWgLUCS5g59UWldOFPGSO0Y0wnQCYksNvjcnsWTMKXrUlrlmWF3eV1HcstBD1tMsLWHX7-T1sKBL63S8oidKx476e0fEHH1naTGH6grZp_V24Fh6682yO4yH21_RU2kbyttt_eURAbLxLdRFyTPBWBa_tPvcSiZE3ciOvPbEpFaiL3id8fQUI90g574r21XZutHvhFv_Myol2S6M2NCmA3FM-feGJDoqtf7EyO4IqTT5xicWbk6LEJcfowB_Zod1StWuGech5EullKyLjAuVaKr6ZxlN_Y96BwH3oL8XAcvTq6uo7CvwE582qrR4EZkXs4mrdj_GfiXQRcE9NS5Vdiiu3XveWvI0wGu6-oKghtjjEkFGMRW-60kseVR8nnd7Uca3l-48ymoCr4KSmVYhimEwkxFrU42ZTaoDrXBz56MD7QvK2IgG9hBmFNa8H2cttqEOKTLcQ65EzuAOJLfRq9kKKym2mECJ6LgMruk-yvj_-CeqcQ8PE8DGeNyMyK15MljMnFcgmkd7HnbxwvUjTwPx4lMXJh7hVlzItABBnbSSu7PB9gczke-Nj6QAhXS9qdEecT6k9rzQcLvtzaPQ2E1p0XxxpV4bqocYSke77fPOsJs8GM5rp2Dem618JC5m4NSSVN8pmfP950G7vm7z9GbD_yImE8nxaXMtQyKdNUxHuKplYJnun5FBqVa7Bo3GzlsTh24QVRt7jjnWhjEvM1jAda9hUZQWrPc2lFMOfTLqLngiRWaEIOTsGkj6KLKrROn65dKI-lGnqVtf6oIcLmhU_1TQChaA-snA4VGy15wrjVxr_hK0_mdbjruOEMnxlNfQ6JGgzk3L9yhOpRVl_nKPb4ee9CffE1CuYeJbCcOSeta61YNLkn_3uad6WdUBp88yqXQ59AyMvStg1s5jv4pYhE-GgOL5Cf0aSRGacHaaStFPBhjlGTvVZ_hfhQEZkfA42zUOQVF0oijoE8wb84atJgF4pCGKiJ8bhCMtp9q4rGEQwncOpHtUocD02dJXGOK8T1I7K6fOPVBsaVlDuffsAVMnDlDNQod8YsTdDeZYMIRUh7mQkCOoouLjHqN5Sn6Vkecq1wLyexRRiXKd5mU_WVg8AiWRn2OxTVJVt4X3cJtCWYSK78iV35Tz_YeZJNv3ghiGlqq63hpsUtAjFRenzY6ITvmpPaDhdqnhMaOhvJ_V23C_LUkzaHqGrHnd3Y7iQgaBgxA7yAUKJpt6ydFsj7bsREos3yZHjsiHddYt8lGoAjFHeEZ_6mbzmNZCcrjZs1YkeeTJvT6l29_ROybG61F0zOKtba9G2-Jqau9msMFI7HrdoJKVseJ_8MJBBiaJWfQH3wL5HSkG6zN7kpOdthemIV3nW5OJigfHirTd9PMZu2xAZgcgAwGmGrt4qzlaAtKTCLbnrolUmFyIs0y6sFijSdm1bt8WXQoIeY_zNZ-4GDHZFZ2c0qHa0wOhS2GhMXYp-OHrkJIrw-dHDkCTe8VjdNnbtWRsuzLAGzXqgdKA8g6TZQjX2sqrc5bZQjw6oaeb1rfifFxzdIh3s2HAR7dKpeKT4BefQdw1_RxsmT3elVXjTwnnp8qBEX-DnnKRjG-RHo78Yhw4pzi4oGolKeLeKKkHrImAQo_KJv818HHWsJhyotfQSpqldxf2FUW5bFzWm9rA4na6qeAhynRlX1sR62LHkP_jDE1rp-uCePHZ5Moeu5bzd-QZ7nOi2F-uJvspRdj6iVSUAZO--fKq7q2VR8ubHvW8NglBteIU38UG4wwoag72qUxR3MutrdKuxrG1t9-WXTkDVseNtv7eYBM11_g_a0gIZsa7k3ZY813VzBlyKWf9V0ixtdvHzRmS0EoDbMdBqP8FINaVJkOuVhJ2W8u6LpZ1b_oqqhIvhOj0V4XyBhUW4Kov2SeqFoFbAEG39bs95KlUpW2jPcVME8BHvsOlKPURz1FrKp-TEXvhVYT6X0WEciPWrMKKGnKwFfe3UpOUo2965nS5S7wpBF-caB1AaFTnSjo8DnWhCqPygVoMurGsO-mIfWQ-Om9NvwJ-_zjovgZmppLrSyfZmPRHObPkKudyPb2jABm8KKQPP7ZY5GP1Y6k3wRfdCzhCFs-JPh-o3_TEEN07aSuRdHdRi4oO3FcWEq4xOB5nXhGTs5oOLIOroDFLcxiQjmm_0GqaRUTY6d5wZNlz__-6XjZuqDiieQyDUMbqS3EmzMOs5QIDvCpwKOVM5hmfmhPeZJkfZ2gsIrZN750kJqxHXdmMuk_R7Omen7Kj866n7Rcs5iCh-N9GZTOW86dExnwuJ6B7vP02HM89izEo-DAzkV65veQ96wbEM0NN7eNFQpydSHJMZAl7UpMV-tb-s7UD1D61-kMNLhomha92Werp-EG6Pt0uh1MgXAKshEQZtGxcIkYAtHGHiF9Q5acUMMEsv95glNiX-LKwIyxWe4QbFeLHkTIXHb567DZG-ekxs96\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"92035A04-240C-4F8E-B787-6E871AC32B61\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4X8M-bCsdWJanNSAFjtyzBoRWgLUCS5g59UWldOFPGSO0Y0wnQCYksNvjcnsWTMKXrUlrlmWF3eV1HcstBD1tMsLWHX7-T1sKBL63S8oidKx476e0fEHH1naTGH6grZp_V24Fh6682yO4yH21_RU2kbyttt_eURAbLxLdRFyTPBWBa_tPvcSiZE3ciOvPbEpFaiL3id8fQUI90g574r21XZutHvhFv_Myol2S6M2NCmA3FM-feGJDoqtf7EyO4IqTT5xicWbk6LEJcfowB_Zod1StWuGech5EullKyLjAuVaKr6ZxlN_Y96BwH3oL8XAcvTq6uo7CvwE582qrR4EZkXs4mrdj_GfiXQRcE9NS5Vdiiu3XveWvI0wGu6-oKghtjjEkFGMRW-60kseVR8nnd7Uca3l-48ymoCr4KSmVYhimEwkxFrU42ZTaoDrXBz56MD7QvK2IgG9hBmFNa8H2cttqEOKTLcQ65EzuAOJLfRq9kKKym2mECJ6LgMruk-yvj_-CeqcQ8PE8DGeNyMyK15MljMnFcgmkd7HnbxwvUjTwPx4lMXJh7hVlzItABBnbSSu7PB9gczke-Nj6QAhXS9qdEecT6k9rzQcLvtzaPQ2E1p0XxxpV4bqocYSke77fPOsJs8GM5rp2Dem618JC5m4NSSVN8pmfP950G7vm7z9GbD_yImE8nxaXMtQyKdNUxHuKplYJnun5FBqVa7Bo3GzlsTh24QVRt7jjnWhjEvM1jAda9hUZQWrPc2lFMOfTLqLngiRWaEIOTsGkj6KLKrROn65dKI-lGnqVtf6oIcLmhU_1TQChaA-snA4VGy15wrjVxr_hK0_mdbjruOEMnxlNfQ6JGgzk3L9yhOpRVl_nKPb4ee9CffE1CuYeJbCcOSeta61YNLkn_3uad6WdUBp88yqXQ59AyMvStg1s5jv4pYhE-GgOL5Cf0aSRGacHaaStFPBhjlGTvVZ_hfhQEZkfA42zUOQVF0oijoE8wb84atJgF4pCGKiJ8bhCMtp9q4rGEQwncOpHtUocD02dJXGOK8T1I7K6fOPVBsaVlDuffsAVMnDlDNQod8YsTdDeZYMIRUh7mQkCOoouLjHqN5Sn6Vkecq1wLyexRRiXKd5mU_WVg8AiWRn2OxTVJVt4X3cJtCWYSK78iV35Tz_YeZJNv3ghiGlqq63hpsUtAjFRenzY6ITvmpPaDhdqnhMaOhvJ_V23C_LUkzaHqGrHnd3Y7iQgaBgxA7yAUKJpt6ydFsj7bsREos3yZHjsiHddYt8lGoAjFHeEZ_6mbzmNZCcrjZs1YkeeTJvT6l29_ROybG61F0zOKtba9G2-Jqau9msMFI7HrdoJKVseJ_8MJBBiaJWfQH3wL5HSkG6zN7kpOdthemIV3nW5OJigfHirTd9PMZu2xAZgcgAwGmGrt4qzlaAtKTCLbnrolUmFyIs0y6sFijSdm1bt8WXQoIeY_zNZ-4GDHZFZ2c0qHa0wOhS2GhMXYp-OHrkJIrw-dHDkCTe8VjdNnbtWRsuzLAGzXqgdKA8g6TZQjX2sqrc5bZQjw6oaeb1rfifFxzdIh3s2HAR7dKpeKT4BefQdw1_RxsmT3elVXjTwnnp8qBEX-DnnKRjG-RHo78Yhw4pzi4oGolKeLeKKkHrImAQo_KJv818HHWsJhyotfQSpqldxf2FUW5bFzWm9rA4na6qeAhynRlX1sR62LHkP_jDE1rp-uCePHZ5Moeu5bzd-QZ7nOi2F-uJvspRdj6iVSUAZO--fKq7q2VR8ubHvW8NglBteIU38UG4wwoag72qUxR3MutrdKuxrG1t9-WXTkDVseNtv7eYBM11_g_a0gIZsa7k3ZY813VzBlyKWf9V0ixtdvHzRmS0EoDbMdBqP8FINaVJkOuVhJ2W8u6LpZ1b_oqqhIvhOj0V4XyBhUW4Kov2SeqFoFbAEG39bs95KlUpW2jPcVME8BHvsOlKPURz1FrKp-TEXvhVYT6X0WEciPWrMKKGnKwFfe3UpOUo2965nS5S7wpBF-caB1AaFTnSjo8DnWhCqPygVoMurGsO-mIfWQ-Om9NvwJ-_zjovgZmppLrSyfZmPRHObPkKudyPb2jABm8KKQPP7ZY5GP1Y6k3wRfdCzhCFs-JPh-o3_TEEN07aSuRdHdRi4oO3FcWEq4xOB5nXhGTs5oOLIOroDFLcxiQjmm_0GqaRUTY6d5wZNlz__-6XjZuqDiieQyDUMbqS3EmzMOs5QIDvCpwKOVM5hmfmhPeZJkfZ2gsIrZN750kJqxHXdmMuk_R7Omen7Kj866n7Rcs5iCh-N9GZTOW86dExnwuJ6B7vP02HM89izEo-DAzkV65veQ96wbEM0NN7eNFQpydSHJMZAl7UpMV-tb-s7UD1D61-kMNLhomha92Werp-EG6Pt0uh1MgXAKshEQZtGxcIkYAtHGHiF9Q5acUMMEsv95glNiX-LKwIyxWe4QbFeLHkTIXHb567DZG-ekxs96\\\\\\\",1]],[\\\\\\\"D27FE69A-BEE9-4238-88FD-F191E6D442AB\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:18:37.147Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=311532&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,498077307,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4go_AclRcMT6JFvPiW4RLou0FDZo52ZwtU4Mn6EaMy1m557P3eoIfEKpm0dCnyILlDdAZEFAVuKjRiZpg4WqxVyzFj35EJvVVcfssO7sg0YjYIB9bm2iW7lsiu5KoHCoFOl5SClUjPi7pBpOYyOM-WvdTPTdOA9LI5R6ubGruqaCknZJMNjdVpQSIYsHPrP3HSHBVgKYjE9fgPVlhTA_Z7N1GD9jeTxN8MPR85jB162RALOUCZzO4b-MpE_gLp5kJIMzBNXQjeOUZyf6rExFubI_an_hQ4ZUB5xBfRbrVjNhKyhzCxGQVE9D5_LJ0i89W-fF3npMQ8WAlXhQQ4PheCA7B49T4zIl68EBZnsJtBYM2a9tVwKwBIhr9C6m08BKLFmnDLrvnsYwigiPVJR93u9J_aULL5fSDqE0fC75CP3NbhC-Rpbu75o8b2vlf-_UmVxEAP9p6zkZzhwkol5okyRvkmR1F-ddxi2_Voiax8Etqbu2FAf0hEXdxa3fsmmC6x0NDlmsAPWX0kG8y5uj8lVFbsWImghKLHD_Bxfzdq95Av1lrjeb63p7YvyopO8fi1SeTRfY-B1aJsjmO07dfi66ZI6M3ZA9k0pcp3ITXpHSUn59oqeBhk_VhZnndl2-kNzGoaRDWng0D2L9w-X9-blFzdL6liov3xn6g7qcrxBaZaw0QYaluZvpL2e2yiLw6wpgORedDF1jheZMMUQ-QrLfubu4j8ysjgIReL3eyVEszWX3e9y2Uau-pSXI3-P-pDBGj2dkmoCb3pL9m9ink1N23LkaXcP_OHwMBYyl0F6FnHvGwIHAKJ4Q4F8VYCClcfec7z507bb5PP0qPlXy5sw7f05KeO7G2FmsC_9pFVWNC1QyHa4f5OID95WrOgeRbET5s33fLgmrDGUYFbj3e0zdGdDTr1Z5eUMDCf8KmUSwR3FreuLfHsoSOgNIs5RBWdfjDhwUvDwcpZY8YY8IiAPgkEaWl893Dy3Jnblso73aGBgqVBTmqiz8KlKMv3UI22RKv-qsqIesWPXdfzRCYTGvsnsttMLk9dxBUiBdQqoZkWVcSBPeGGQD3TTB_ehZn66NvD6uYAHCwDV7bo7mdvD0AOi8KFa_niBAVtnUMGZQC52yoBUYUhFIZfh3h-qT_57OWUPQ0KrzQd4zOr5yBh_k9pi4HesBtMkgoHtcGVMjJFPb1iEGIfjg5scEKefUtXikCuWv4Hox18D0v90SPfNG8ZVPxyMpPexfl7qJOBrSrzqcpLqHKO4EX_ObKSEJL_JJtwMtJJYLyx0N3qeBOTsL6pjJMoFjpT2dOxHqH1PWjQ0JW4inv7GoUT3qiP_2FdnEdjM5NLF4zKu2UD__pvw54CDBqMMRAuk07mNIwrsEjqPbCacHAWRLHboqL8l3R9hqcqs-at41Ruspi2U1CGsPi0ijNC5JnVn5yVaD-bVVCUZPGsBP6fTg9Jz3eUvNIhmLbfzKRlPxAbPSH_ecz1tW9YyHdut6oHsUEOvLGsC-G10NLRdQEzcl-A0MD75fpI5Iic7fxFMHiNfMHlg7isHShlfJcKjkKlDuQOlYFfeHtMQxJ5xGEem0hEhGCpSCR_S4nxhHNA8SE77gdrUvz2ZrMdrJBZJbhdT5zKVLYtOfFfAQW9VszQZFhuQxmfqcHU8zr8SMjVjjrQHWFKX6Ww4yLEG1oG1QHBtuOsjJMw8nd6x5G3zeheKwHQ6dAD0atKRQ8l0Y0Ior6gjtlb9oS7BV0u1KQgtruM3z4MF23qLb8Ts-eSlMBoT6hyibUrPtxQd8twALiRW3PbmxGaaVTsujuvXCTAjKIptl2qYzO1-Eh4pv8Dsq9Gp2tkAkLAkqgTyV7GWiO7MjDpgMp3Pr_91u-hyURJpTln1Jes85HZenAvtLc8l2DUYVERMfkdbi30-ELWZdyBzxGjx9V6cHqUG_VuH-E-V2aCoWwAhgwYYiLYg4b2eZ6Od81nrOwFrYjTwGGMOP23k0wSkFmsX8x6oba-nCBCtgMgLeVUaymBpfM8LvVPrB3WVg29G-wXZKtvrxhT50MRBaVMD_rabzofiJiuvB_7UMWHb-elIlEkVt-McdOwNYI-eJtce2BX9ElZuc0fvi3F_FSVFsCfXIEA24MJ54k81jMkVKm2n4k7ZNqO-93FTnSpEU8N7unDuGpgaXAD0mbsg-By4KR_ALBJLcSibf9jjf-U9DyBhQ5Fv6XiUyOJzawlg_dd-Xx58nepcbkpWSWpNrnuw7kRCVQkHvPOD0mG5vd89NpZW3_l7oYA0vral7c5Vk30hZWewvFps6OECznGE17wleK8JNElhzh4ZOXhyJdY8up7tTnWiy3MKUa7BdF6p3B13c0vyCPkYUOjiZ6BHvlFQ1S14F48pYMzLPY35yHiwEvSdbxxlAxZFWWk88rdve5a3hxtiXdDeBs_qlS7roL1eOmSoycsX-FPRarTjKwroH2xAeaBXgtLnQdjYQNo5D54_42yAOK_LAYtlnxDANFKzpdRHRJTcZ0oYw\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"350B5EF5-0FBC-4951-A742-C4A7A9176C64\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4go_AclRcMT6JFvPiW4RLou0FDZo52ZwtU4Mn6EaMy1m557P3eoIfEKpm0dCnyILlDdAZEFAVuKjRiZpg4WqxVyzFj35EJvVVcfssO7sg0YjYIB9bm2iW7lsiu5KoHCoFOl5SClUjPi7pBpOYyOM-WvdTPTdOA9LI5R6ubGruqaCknZJMNjdVpQSIYsHPrP3HSHBVgKYjE9fgPVlhTA_Z7N1GD9jeTxN8MPR85jB162RALOUCZzO4b-MpE_gLp5kJIMzBNXQjeOUZyf6rExFubI_an_hQ4ZUB5xBfRbrVjNhKyhzCxGQVE9D5_LJ0i89W-fF3npMQ8WAlXhQQ4PheCA7B49T4zIl68EBZnsJtBYM2a9tVwKwBIhr9C6m08BKLFmnDLrvnsYwigiPVJR93u9J_aULL5fSDqE0fC75CP3NbhC-Rpbu75o8b2vlf-_UmVxEAP9p6zkZzhwkol5okyRvkmR1F-ddxi2_Voiax8Etqbu2FAf0hEXdxa3fsmmC6x0NDlmsAPWX0kG8y5uj8lVFbsWImghKLHD_Bxfzdq95Av1lrjeb63p7YvyopO8fi1SeTRfY-B1aJsjmO07dfi66ZI6M3ZA9k0pcp3ITXpHSUn59oqeBhk_VhZnndl2-kNzGoaRDWng0D2L9w-X9-blFzdL6liov3xn6g7qcrxBaZaw0QYaluZvpL2e2yiLw6wpgORedDF1jheZMMUQ-QrLfubu4j8ysjgIReL3eyVEszWX3e9y2Uau-pSXI3-P-pDBGj2dkmoCb3pL9m9ink1N23LkaXcP_OHwMBYyl0F6FnHvGwIHAKJ4Q4F8VYCClcfec7z507bb5PP0qPlXy5sw7f05KeO7G2FmsC_9pFVWNC1QyHa4f5OID95WrOgeRbET5s33fLgmrDGUYFbj3e0zdGdDTr1Z5eUMDCf8KmUSwR3FreuLfHsoSOgNIs5RBWdfjDhwUvDwcpZY8YY8IiAPgkEaWl893Dy3Jnblso73aGBgqVBTmqiz8KlKMv3UI22RKv-qsqIesWPXdfzRCYTGvsnsttMLk9dxBUiBdQqoZkWVcSBPeGGQD3TTB_ehZn66NvD6uYAHCwDV7bo7mdvD0AOi8KFa_niBAVtnUMGZQC52yoBUYUhFIZfh3h-qT_57OWUPQ0KrzQd4zOr5yBh_k9pi4HesBtMkgoHtcGVMjJFPb1iEGIfjg5scEKefUtXikCuWv4Hox18D0v90SPfNG8ZVPxyMpPexfl7qJOBrSrzqcpLqHKO4EX_ObKSEJL_JJtwMtJJYLyx0N3qeBOTsL6pjJMoFjpT2dOxHqH1PWjQ0JW4inv7GoUT3qiP_2FdnEdjM5NLF4zKu2UD__pvw54CDBqMMRAuk07mNIwrsEjqPbCacHAWRLHboqL8l3R9hqcqs-at41Ruspi2U1CGsPi0ijNC5JnVn5yVaD-bVVCUZPGsBP6fTg9Jz3eUvNIhmLbfzKRlPxAbPSH_ecz1tW9YyHdut6oHsUEOvLGsC-G10NLRdQEzcl-A0MD75fpI5Iic7fxFMHiNfMHlg7isHShlfJcKjkKlDuQOlYFfeHtMQxJ5xGEem0hEhGCpSCR_S4nxhHNA8SE77gdrUvz2ZrMdrJBZJbhdT5zKVLYtOfFfAQW9VszQZFhuQxmfqcHU8zr8SMjVjjrQHWFKX6Ww4yLEG1oG1QHBtuOsjJMw8nd6x5G3zeheKwHQ6dAD0atKRQ8l0Y0Ior6gjtlb9oS7BV0u1KQgtruM3z4MF23qLb8Ts-eSlMBoT6hyibUrPtxQd8twALiRW3PbmxGaaVTsujuvXCTAjKIptl2qYzO1-Eh4pv8Dsq9Gp2tkAkLAkqgTyV7GWiO7MjDpgMp3Pr_91u-hyURJpTln1Jes85HZenAvtLc8l2DUYVERMfkdbi30-ELWZdyBzxGjx9V6cHqUG_VuH-E-V2aCoWwAhgwYYiLYg4b2eZ6Od81nrOwFrYjTwGGMOP23k0wSkFmsX8x6oba-nCBCtgMgLeVUaymBpfM8LvVPrB3WVg29G-wXZKtvrxhT50MRBaVMD_rabzofiJiuvB_7UMWHb-elIlEkVt-McdOwNYI-eJtce2BX9ElZuc0fvi3F_FSVFsCfXIEA24MJ54k81jMkVKm2n4k7ZNqO-93FTnSpEU8N7unDuGpgaXAD0mbsg-By4KR_ALBJLcSibf9jjf-U9DyBhQ5Fv6XiUyOJzawlg_dd-Xx58nepcbkpWSWpNrnuw7kRCVQkHvPOD0mG5vd89NpZW3_l7oYA0vral7c5Vk30hZWewvFps6OECznGE17wleK8JNElhzh4ZOXhyJdY8up7tTnWiy3MKUa7BdF6p3B13c0vyCPkYUOjiZ6BHvlFQ1S14F48pYMzLPY35yHiwEvSdbxxlAxZFWWk88rdve5a3hxtiXdDeBs_qlS7roL1eOmSoycsX-FPRarTjKwroH2xAeaBXgtLnQdjYQNo5D54_42yAOK_LAYtlnxDANFKzpdRHRJTcZ0oYw\\\\\\\",1]],[\\\\\\\"6DF26C52-7FC5-46ED-A4FB-BCF1BCC02EEF\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:18:46.196Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=288975&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:18:47.154Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=169567&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"D6AAEC30-CF75-44FD-9AE1-D0F538B5944E\\\\\\\",\\\\\\\"02E2F918-9605-41DA-A51C-6F2EF52C3CD6\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6f3yhVnqY3e2AHaKxcEBfbAFLz-o5eipDmWPixKRievIqzgL4xrRuXUgo6fE8h18xlss2Mq3IHNRxy3WMX4A-TdUVl19KoTpsdGN9UMVO8THQFSucmEodT0M9kqT2bfSCsFvmAvqkc03pVsXwJ7lGTS3-Gms3xu7v3qj7xRKCb3gw_IyW67WbwrNhovmyR1U5I5aybT58zYXrfYy_czM9XQ-npzoWmPIu9Jw9S0TqGgus79HEF6Y7IN-ukb5lVjok6iiCDj7tqmMhsN9UST6V2-VqGJn9EZbjv-WHBK2dKJuJN-B4kz7ulyET_YBiCUTHy3ZCefZjF5V3pr767YZ284M-k044UvzhuXntEPWLinQUabFyrrNfETINZygHSkKiyV5UWXgfR3cC8vRlsMUlaDnixqNXfburc5C66OBT03FtoM1_metWYDjOt6gAca7ktL0wGSjvohVF0yoGxYkrVIM1o_SqOZjZw-ExBHpOBPECkEzPEu71SJSH7X7_wZnrzL6nKNYsTFAjcYMckfNCqqmm3_X8FascZWR5iZlGV7X1rBEWE5fJWCDkJlD1Z6Mtz2aV3kZE9KpUNj58tPsXwbaxriJIptjp6YM2_G4HhNiW8KQW0s5vNPKsQrjB-nSSZ5Rc0rsrGPHeo6EFCGmDbgWz3_miK7Jn0NAjGOz1O_LvtJBKC4Akro7d9-l5-OvHL9vBqGAjrPTp4OC2w4Je0MExGuj3r-s9P9eRoGnu2x_yx5rCZm6OnJEkeHrCP7VgacN_kQNpSoJh7ZRV6pUp_3jpvs9kvcXDs_JZ24NKPbUZrG_-WSsOws11YBkqU5yTVLMlQlxGN2BZvxNAEtoqm7pEzh0TDYZokU9MWupkWyEvoO4iPX1HgdjMGeeYvWnhK7B0m3twRytXAr9NtTbi9y4ob4HfcpzYvJf7CkCnr9WiCw74mBOsyKJ5d8YLPC82NcLM7-Zx6PvFg6j-9HmJpYyQfneiHuEquLqES4mnn73dNJ5XbzLzTNy5I8ajhd-GaXH_MdwKHwYL3-sL0BFipxLTRfK7G4UBQYOy276-P0gxVfH-z6IB2-J2D0dSAPqKDseeVCWqVWSHkrJKuuTEtA-KWMs2SG3_ME8jWpn_Ww1goW57kSHptkcT0AB8Q68a1iK8-LtK7i-pW_nwNosucsug4YPUqSvX14XMQYhlTTWHtWbrD_qnlPK_n-GxYYmntNhhJcCUwLm61wp49o9mRSuT6RoJOkvLoYeHxgdvin9x7R0ahvXbk3_Cz4et4fTvX4VtnSrPauUkJhRfqcztzqxTHHpCvHXjrxZgN6M0xIRgD-YwWqwKV1BJ23PA873ZzVovA4koOkcSzaIpkPj4cDqvPhQlFzmHCBDf_-Ywkyd6SF6b6W-yAPswzL46wYqG3v2kPpLRtKUNe5VADOAZcDgJnzHTyp72EAFXFaZ_fOJdxr8QyaatKK_K-driFRmqOoxdjPvToYMsiFuBdV1bJuOXWY_-9WPa0Vz9BNRm7BrJbmf4w6mbHFK-qyHJpXO1xu_3bXueuQNpbkNo-IrAVbwsB9ueXfyr3UftPHFTaiGMn7ScwJibiqwx4iTSHIzQGnXlR_YjDNAPZEiosFFdk84yiEVKe3QIvK3cJe1oZMsdcAizkWRauhknk6kLJGibCaYapJ-vfGZY9hTLsw0ta_uQnVGGXefbVo0eAB6kfCezig1zxb3mx_CHyNm5iE-Sv_fdXdqB3NHTDbMJKkLoF51EqWZiU463-kZzbR1Db60sPivt7aP_-kmgHlpF3aHsRjXi9WEZMdGuPsBU7FuSXQNTBz3tQt-u7Kf9d8eehmN2xKUNuruJSLITJdQeRmDdqBiKzNW0IhsSmI6aJ-fW1lLR7e_QJg5_ww5PvkDIS1529342nLAeZW4cynol6Xyo0Fv5x-7okHXMoYkptnSV-fb-5GW6KCOM7WFNChX49-Fauw8OkFMRCUXANazFzggg4YOxK7xUEqFzw50wjlBK1AvtwvaBRNxGtLvtxrfxuqU5rvn1jiLlhFR84krhAtz9ES2my4DNV8BD3jdgd3n0VSueYZIWn8gECEN00TkjhX-bI5swHqLAaiEZNx-dHkpBX3YSCNZDsMH1ETxhLEVD9HeYfUlduieqAkBPJgv4MmVvporoC1x-7Ha0cBc2DZjpdfN37USs-ArNhZ0660ZA-v0Q7WS6_ITpequa2JHWMIchq__eMOxzZpmLO_mDUkqLR5d6H5OM6vMSPp-58U78ANvbdKbC2rAMoxEj061EUFA1F0ixII1TD4ldKrGri0ZRJygcw6sW6JCah1oSFKqvl0QO9VO2Ldyk7Jjbd3c3i6xHl2rPoFU1QyiVi3BFtRIxsPg7ertXF7nvAhKtfyw6FeuE1MENCxUOmTIi7pO4DwbDLiCq_akUatXyfQXhwKR9Cyorx76G-c1ydKLtvr85vJal-wreGbePUwv1yj9lgsBbEO64\\\\\\\",1]],[\\\\\\\"729F3193-1FC9-4D34-9449-2D063D80C932\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:18:57.172Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=422769&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,866311297,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5ZJCfZ92k18MLcXUW98hyIDcgN5o6bZLM9G13Hz9L4CcUaFxo-AS6LVXDPgqQnlzJtwra80inSWBGMa6_u6yinx6lweUfuzRSLOoRYq0sRvbz3Yo34hXHTip-BpoLeuR29sMvAOE_VbCcQ2bG960aiuDHRz-YvR8jFpbWim1iF9uYK39dZoH1AvThYE6CmhvBzvAVZHkV2r3UIlMisNWmK7BEkks8Cb9HRFTWmoOWgMaWtN6wgq92-l5keEtukriYA5mAj5qrDxbqdtHtvNo52lGqPyponh3lQfGk3wmqJDwXhEJds03YLE6GicdHRAgOYx5PDLDeOdYUcffRfij_Rg2GwUqDge2TSBKr05Kkt7-byShzsBCVItt063YaWy_cRp8UL30TEqfNgFVqZAzWtJPPnJqwtPIP7ebM9BKbgYv5viRvRLuSYPbayd4AjVdk9h9MuOU9CaqeGdzpBTxQdaH2VCmFxWD56q4c5HM3kRvFKweFEgFWkXaAyKuQXYU1udWN4viPRO3XB3Ns5la4jQcEZ0UsPROUMZjdrM5NIgeqgSM7_jYWFP4K8o4hDaBvi9FHlxJBy9t13nhT-Bzyw-Z0iYjX7FBwQes5KzDTUH-sg9zPGgTAKvB8IGqJwmfvBcxK4YsNBXIMAVmYTWpVjW_fx6qbwAW9ip-rsgLRcTnuA3b0VLeA_DKg77PoHIIjFbJViktxPoeI2dclm8IJ895exUe5M2kmWzhN2pFyheidpmqZ2WapSSfueXSGcxHfn7E_AkHcyPDHy-LkFDOKEDBBKvuOsXm_gIY0BODANy7qw4zoKpNq9xvHQDpYOPraSCIllU9pTIs4PFiCgVBfW_4dKKK-klebNqLJqwERGlvQOmYH2D9Pw6L1ZZLiUxXnwbXmvbBuZKcsXUOg0n1fsuCahaPA4GO4N1z-ZWqE_NassUv2pvwwx2K4is-i1a24x28ZrPqBfpaWOgM7fNQX7tlVd5qf6ZsaUp4d2KEOKbNND_gytWb7BMCRRCzhC2xc89j0-RBYEPoMkOEWkPuFZXhfKjSSIZpP7EHjTGM3O9HSSw2_ginFPRP7H1It10t1oTrRYOPF1KgjOdttcGOoI4hhl6yXvNS8xmPwgQDnyLobg9oVUTKvJsHxePO8D5q3MU_bF4wS9rZz7R-UD1PADecX5cQm8LYBTcuyspTvVkZQAEAG6qRVLtIHWj_6AVnHvAcBxfZWDp3UNOLjzz8B5WNfwExoeci4-Rgw_4ozZCrBFqiAk1e0MbBYoXKmnVSw_MxrQYUszmIbB6-fuRA1f2rF6NmwebSVyDMpLqDSKHLG7hYnKNPMeRe4FOmN9-gARktrT2_2KamYDEzn-7lfw1RKV9eaGc4Yfnb8PjD986oFm-PpfnjTm4JgGg2vlE72CAQZtXidKgQB4M92xk8x84Y5F7Xh8sSJB0GSFGhwx6gZyuNDiDvkKEj1WXvD00emyHB2rW9mX73kiyEuEAAEq0QammT_ugROsuziipxIDquGSYoV7-p9l7XYP0nPiiLqpIBYP3Tm2SJ6q0esNh_npT-6n_U2c9xtdP77cD-wmZJRLQ6pKfTyFj58sIGLQFfg24aeAvqAspts9pzL3J-Zuh6bgDkVXJBzCL2lO0-ejfjTIZFYq1ektCBkUz1ejKrpoU707-6lmbHI-803YPn5d-SYfjL0wXgnLs0-E1SKLrKTYnu5IZNyRQeRsMslPvva8Wo0bcoXLkWtD7WSqgz9Szbrd1vY_KLDaPn2ooC30JFJ6nGBlKnuH3mg1EhfFLdJ1y45Iu4U5RDTqt3a2OPHGwfYW9hLF601CYUhdDj-xwCx0wch-efaT3P8kmg-7IwEd0jr6BkdAjqLV3EHjUQO2AJorqxQZxnlNYnL0Xx_DXMZRiF_oGQ1q5prIYFy77h7CE3Fb6cSLpeSizfVYXtbNPy1DIpl8tOr1G66hbsorFPTg1FI6aEUKKmiHavxchMgDV7f6xS6nlFIGcvapAO6nQ3P9WsLRtY8_nsJj6vY4Vo2IBz_l7TJYCSHZaZ2VyF1iR3G80rHVcuH-_gGEOF-Efg1jIhXrfQ9YR_CLufXISsd-cZdaHOwdc1G4KjosBT0TaTXIxy6ov3WTac32F75rNfG8h-VoSV-kZMQ0gmzgfSAgxX9vk6XwCGnKVPRelEGbSHkBRZ8AqqgW3CPANZmpV8OEx5UDeMcoYDGG_dlemy_B4W9CBq4EQWzsDko_2MONqrEatPLb2cTWU-QWFqDJCGdOpJgMB9j4BWYCHrLcNgoAYXeB1EaeWGGm9u6dYoOxvkgt_5rS5qSGF5y2iwc7tjIjSclXF-OlkxAeVkfNSGfWPVoOgIOff9IrTeLT7Hf-1negujkms1Ngq4hvPHg0F-2gIxnNK3cEoO0w2RmxOIbfNAGQh38SXTTN-8dfvwfEwURHcDA2aTsikSme4ATjE2gpUBn3IpY-YY7GhE32Zzwq0z1aoR8Gdkt_FUML-ocs-vMV\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"7EFBC9D7-3C88-47F5-930B-035BE69DBBB3\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5ZJCfZ92k18MLcXUW98hyIDcgN5o6bZLM9G13Hz9L4CcUaFxo-AS6LVXDPgqQnlzJtwra80inSWBGMa6_u6yinx6lweUfuzRSLOoRYq0sRvbz3Yo34hXHTip-BpoLeuR29sMvAOE_VbCcQ2bG960aiuDHRz-YvR8jFpbWim1iF9uYK39dZoH1AvThYE6CmhvBzvAVZHkV2r3UIlMisNWmK7BEkks8Cb9HRFTWmoOWgMaWtN6wgq92-l5keEtukriYA5mAj5qrDxbqdtHtvNo52lGqPyponh3lQfGk3wmqJDwXhEJds03YLE6GicdHRAgOYx5PDLDeOdYUcffRfij_Rg2GwUqDge2TSBKr05Kkt7-byShzsBCVItt063YaWy_cRp8UL30TEqfNgFVqZAzWtJPPnJqwtPIP7ebM9BKbgYv5viRvRLuSYPbayd4AjVdk9h9MuOU9CaqeGdzpBTxQdaH2VCmFxWD56q4c5HM3kRvFKweFEgFWkXaAyKuQXYU1udWN4viPRO3XB3Ns5la4jQcEZ0UsPROUMZjdrM5NIgeqgSM7_jYWFP4K8o4hDaBvi9FHlxJBy9t13nhT-Bzyw-Z0iYjX7FBwQes5KzDTUH-sg9zPGgTAKvB8IGqJwmfvBcxK4YsNBXIMAVmYTWpVjW_fx6qbwAW9ip-rsgLRcTnuA3b0VLeA_DKg77PoHIIjFbJViktxPoeI2dclm8IJ895exUe5M2kmWzhN2pFyheidpmqZ2WapSSfueXSGcxHfn7E_AkHcyPDHy-LkFDOKEDBBKvuOsXm_gIY0BODANy7qw4zoKpNq9xvHQDpYOPraSCIllU9pTIs4PFiCgVBfW_4dKKK-klebNqLJqwERGlvQOmYH2D9Pw6L1ZZLiUxXnwbXmvbBuZKcsXUOg0n1fsuCahaPA4GO4N1z-ZWqE_NassUv2pvwwx2K4is-i1a24x28ZrPqBfpaWOgM7fNQX7tlVd5qf6ZsaUp4d2KEOKbNND_gytWb7BMCRRCzhC2xc89j0-RBYEPoMkOEWkPuFZXhfKjSSIZpP7EHjTGM3O9HSSw2_ginFPRP7H1It10t1oTrRYOPF1KgjOdttcGOoI4hhl6yXvNS8xmPwgQDnyLobg9oVUTKvJsHxePO8D5q3MU_bF4wS9rZz7R-UD1PADecX5cQm8LYBTcuyspTvVkZQAEAG6qRVLtIHWj_6AVnHvAcBxfZWDp3UNOLjzz8B5WNfwExoeci4-Rgw_4ozZCrBFqiAk1e0MbBYoXKmnVSw_MxrQYUszmIbB6-fuRA1f2rF6NmwebSVyDMpLqDSKHLG7hYnKNPMeRe4FOmN9-gARktrT2_2KamYDEzn-7lfw1RKV9eaGc4Yfnb8PjD986oFm-PpfnjTm4JgGg2vlE72CAQZtXidKgQB4M92xk8x84Y5F7Xh8sSJB0GSFGhwx6gZyuNDiDvkKEj1WXvD00emyHB2rW9mX73kiyEuEAAEq0QammT_ugROsuziipxIDquGSYoV7-p9l7XYP0nPiiLqpIBYP3Tm2SJ6q0esNh_npT-6n_U2c9xtdP77cD-wmZJRLQ6pKfTyFj58sIGLQFfg24aeAvqAspts9pzL3J-Zuh6bgDkVXJBzCL2lO0-ejfjTIZFYq1ektCBkUz1ejKrpoU707-6lmbHI-803YPn5d-SYfjL0wXgnLs0-E1SKLrKTYnu5IZNyRQeRsMslPvva8Wo0bcoXLkWtD7WSqgz9Szbrd1vY_KLDaPn2ooC30JFJ6nGBlKnuH3mg1EhfFLdJ1y45Iu4U5RDTqt3a2OPHGwfYW9hLF601CYUhdDj-xwCx0wch-efaT3P8kmg-7IwEd0jr6BkdAjqLV3EHjUQO2AJorqxQZxnlNYnL0Xx_DXMZRiF_oGQ1q5prIYFy77h7CE3Fb6cSLpeSizfVYXtbNPy1DIpl8tOr1G66hbsorFPTg1FI6aEUKKmiHavxchMgDV7f6xS6nlFIGcvapAO6nQ3P9WsLRtY8_nsJj6vY4Vo2IBz_l7TJYCSHZaZ2VyF1iR3G80rHVcuH-_gGEOF-Efg1jIhXrfQ9YR_CLufXISsd-cZdaHOwdc1G4KjosBT0TaTXIxy6ov3WTac32F75rNfG8h-VoSV-kZMQ0gmzgfSAgxX9vk6XwCGnKVPRelEGbSHkBRZ8AqqgW3CPANZmpV8OEx5UDeMcoYDGG_dlemy_B4W9CBq4EQWzsDko_2MONqrEatPLb2cTWU-QWFqDJCGdOpJgMB9j4BWYCHrLcNgoAYXeB1EaeWGGm9u6dYoOxvkgt_5rS5qSGF5y2iwc7tjIjSclXF-OlkxAeVkfNSGfWPVoOgIOff9IrTeLT7Hf-1negujkms1Ngq4hvPHg0F-2gIxnNK3cEoO0w2RmxOIbfNAGQh38SXTTN-8dfvwfEwURHcDA2aTsikSme4ATjE2gpUBn3IpY-YY7GhE32Zzwq0z1aoR8Gdkt_FUML-ocs-vMV\\\\\\\",1]],[\\\\\\\"DDD1BE45-FADF-4204-92CF-A64DA3F7C2E2\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:19:07.189Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=203098&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"457113BE-4A40-45D2-95A0-84CC9C919139\\\\\\\",\\\\\\\"0C62A28B-CFC5-4F35-A7ED-D3E5A072D340\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7bac0SpnVmRP4jAZKxeAKds3G_rOFEhoMry6lDbnKHNYFf29-0L2mlbJGEU_adPw76dDPTqwzcEFwCV25C-we0CaCNsFU-KaJNTLjNoWMHTKClxwXKSbQmbWpjS2RmgsvAn1DUsA2XbnwKTYhyb2mH2z6TONsEbz3grEFukYuPccmbZ_FCQR1sqeKZ3R8Q5wz-N7Dx_Vd8voyrr-rkMnYIYuS54XrS7pUoaLsP7fqvlD8NG8hwcUXRtMyyiMJrYetW_gSGvSFm6LW1UL2vaIsqpo4H2FFnq00ohLaNfYy1BYKpmcQWUQYmNct7Dpn0VJEjmCRrFq5H-fzsNfB2MD-3X-5yY9nvmHXBHioXNiv_RJSveLouTWEqx8l2SKPu1J3ecte5jFj7b2h0wiVucA6pT_r8Q4BCeuDGQ848A6mMforcxbYdfOvYTWZBWu3DYOTcBq62cwB7_wOuNGkVnN9Hup9qxY_bWlwCnSAqIe-c2yfboIt6xK9ZhVIcyDFV1lnm9B1pqoKoYZ4cYcTAE-AmOn-dAKXC4YOSgx7fo4LA-208-mVuvAEEtB1WqOLyRKanETuu6twTad2rvUuqPUvX5fUOJPBj6xnYwAfVTbP7UY3BTeqweCBlt-LkCIlQmkVaWY-NaCl9qoxiAYCgEnagM2UxLLZ-Kkx1EpVN6m4_diXxioFmAXwX9E7TDIJHtPVSXVvdifsiRQ2Rx5CQWQo5-5MFZBkC7Eiq06Gi82Kgjn1HWa-mKmhTQP3NapSIBIgdnDzLXzsmqdgW8TQIeG-AE9vZcfyhCo8It3wsTz_qPXT2hCpn7qTgvhTiqWA8Oqr_Y25sJbqMyy4Xbrj8o5_M_iH8D1EKqatwOQEbbfJZ1asmG_Ty2IC3NCGKlJIKSrc02m0otPq-LDCtIA-_d_wTRgDpB4Qh4fy9jp0KZXFnlICMS5ElpY7JDdNs9kDAdx1Id4OumxXkvu7X7s8iyM0IWUx2iYYbKdyBK0C-GK4HGJRj0xDfhw3K75cxBsNjljdwaaCVrz3pawsLi7IbJ6KRuMSugifBKfc_qTj1sPNtbCphpM8idJQ12twU6EaQeMlKRw-4Eu7u0LqNfwPJ7_1EZvU08VtBcnrFs8kF6ttyPPJ6fLnNTDlsY54UZ9DKp2RJ7dUMwwWTLvYMcqK9s-umkgLWojpMN6q1IlRBGN4GNvT3-0aaoN-g4Se2lw0-fO1hl7hqrmw41zm-1d0VHx4e8jx6jkVTQAaKio03twPbG7GL3OvdyJVupOOmjEr5Bqfg0LMLzqKqOwVtKv9nfHovrsXEFuWB6YyaJmjFyYj1mbS41KUftuzd8dPeqxxojYV0Cx-FWE0xFxnXdP8WNkISHeB_adiKWeECUtDWyfJQ6Ii5DcIhF9Mf7VFRpcABZkCYQSpeQDLAWMaExwJZVlSiPJf_0XAJtE1HoexmtywvmpcWdHrkP3-5A9SvWDdnLnTvEnrPxq5oLGdgcT6NxOiTZO4Ayk7c8fHk8aKR01L1EAVwCJ0A59vsP3ST0M2Q44E5KtLvz6lYgfhZXprOF3SiXpUYrqyR8wx9BPVAkwZeSelm350unRnNqkJ-AnNSdg6obhmkSArn7BKvQXHa7sPvZ4u_veL72P93DajGMSCOj2njL5pxvuCrAKb9OvYOtkKuQLb3ritUsLaVUs0aQJGzM7skvl6r5fdLNKJYIfJz82QigANH1qxk-cWyWEvyUVqCohRso7TfBYbP1A32wtKlmUe8n02zf1PRqTE3Whe-ZMCur7kxBUchJewWYvqi94_p9MzTdGe9I2tNErFKxce3CxWxGa7dcUjsNAOz8UeBsIblSJqTkqgaM0oNpYpp47SMMkvUKos1tGsAQX_rpriltjFShrKvgmywTyeTSQbaj2-HK_txyWCGj0E3dADPeui_wXEkXiMNDkBpy_uTfe-jaqYjiLSWHfnE68hAdteM7J3GGZu7gEsaopXxwORyAYoxnZHXwvI3fkqxFwZ3X31grttY5pLmUGN5Oi390kLU766WWpPbBK46NpF8xp3_qYwDXrLqxuwXFUMMxIr3MMq9OKsF6FJ6X8pnQe0NpDAIl5mxMfvyUZaN6Pw2GUbNPchirjG5YFn54qw5aKLDyoKxSFPZ9IHTb0_mIvSjgKNZIvckS5hSOpB7ksBIHB6TMJggYx0PJKnE8W7kKopi9riKht_jz2rPWgdtHKATABNgPJdep2Q0Q9jhl5lpsuAY4AryjV4UDWJSnprrzfj4TgwQMefpmte6Q1sBVlDOqfnyc5HmhlvhZztb6Sx2FhqjLHyI2xOgPyCThWVOMqZg3pGrps-t0x_QrCKzmfemOPZ7M3dvS2AN_V1tHf_JhzTKWYYmcRw7wnqsJtHVtrJxhdqbVhF8DRbixNc3_1jXH5bxLUAXJFoadJwqTCesKJoscydON5YeI66cwDY_zn6uiseieNp3PWqJWg24FK00jdQTBHSqlzavk3C_y0eQ_dU2u9XyoeI9\\\\\\\",1]],[\\\\\\\"CC1625F6-A568-48DF-8541-192A22897BEC\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:19:17.222Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=490988&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,387255460,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6P9o40-LN9HAuaLi7UPKaAaPN0F1MbHkzubaxpWVnHUE1D24zVckvEZsroZj2V4V7aTkVKMDWB1YLiXinlrwhLGcwrbdPMiSJf6bPwASUJgZvmzjHRfVvwMbPUtc2pYKWF9ypifGSronnHqmU_m9tDDrBiVke2_lN-HDdeOnmdk4ZOhZHSbcr1O36yFCSlquwWYlsqaNCr7yYOxcHD9IoHhUM99HpQRL1ZDsNrpGith5ur21QDMy7_oPun-RJHnOj_PpzoTt9NfSr2YJlGzycS4uN4uI1942KfgU-gHZxjGprS_LyizIckoldXnPPD_UcvSE2qGD0QgtMWdfCgEOB7UYr1F4zVv0XsbXK91Xs1BcXWg5kq8Que2QhsiXlrwVlFMHyyNny-YaKyik2KANJFoXqv_B32jZqm7aeXL5dNU-n6Dwx1L1cRUlFA92zw16eGR1_9nkI0ZourCdhoBZdeuLDkM3uqi7Wh44IyT_azMLnRZVtyVX-g1Ku_vmlVYePVLERRHBxlP2mcbmyVbHDVS_C9zSJJWgLz9VGC96-dlui3h2_u7B5aFtnBUGojXmS63I2ERf1_WZJJpTe9etX0rNU38g93be2ru1Uq7OlOPO1FgAT3FRmFY7haOCHkoehhRXuG-EXRBUJdV5XikJfblUrJpRe6OUJn1PDF8aKmlkNk-qMznrqG5hkI9S_2_6HeWuaPPZzlVeeHafufg_t5j09ruceutvUYMsYYp5wSL95zqOG1n2j3cBh_sPuLPPp-0Ila-vtKSH-Zp3wFY87GX1Gr4typjAEar9yzoMZUfAXlrNI2Zy4Yr_-oZTDLWmFsQl8z0vNdnLEMHgPWk3os_r7XvEkRrCB049c1PuAQSHAMD5Cv49jShLmkn1EFarZ_Yy8XRMdayeNoVivqX-HsSnNPx8AzF7UeuQy38xfUt7R1-Hfe1T7OFmqOSfC8hiUN7NzP4RcY_zPfFZaztBzZUzUjynfnoxQ9rAp9Nn4qkC41EI5oEoxcNOzlTtZMOWwkPcoR0X3km95NoV9gRzesKph2KWdfs1-ucVh_KtnwvcmDGw9AVBz1M8mKNBZXRiffegFKKEMu2YYJg9t-gAk3Zb3VtCU0T1krbtzkL60IUHtXDsgo1E3Q1_oOkZT1wT1K4870sJTjU84IScbUp4GO9bAYFkchf8exFc1E6jL7ke1LLwb9tiv7sV_kmzW3ov5kXIWPwTqaQEC8QjN7KnftKo8l8aFnFAolmjsarsXarsho4i_rq4_a-UyAidkJXkx6tP4zLkcnF7XO3cf3a8pFtMac-KdETiXlzj0rOaAoWAa1ihq7Hcj6-T97szChzZwgBTjBnGAqrN59XsSnZsNDHrXBwnagandMH8rIIwlT68a4rVL_-_srUFRqeuS0lo6aodDIcXsvyeDebcgalf98KLKkfgzWq3nfC-emIzxoUQJqheM-rTxOpSzuJxhaIN9-rESQ4rb4jCDNg0NjY_XsRm0QOWhGZvsfMVdHpfy_DUdawlSTpWghbzTWRi4hPn_W_x8L5dgWgVJmIXXB-WnQFq_EXC-8N9n9MIX0QZrojbsU_HPkMCy5hOcvF4ShPiVWyMlX_bXEISzjc6yXRKnssTDmI0NWLpcwsaoc03WmP8S7SPAATciEJzcPTo6B5W3FbVbi1CE1DRcvi7R2rJ5ZVL5VcyAd8YMebR6KUewhLmQiFALVTJe0BR25AogpwUuOghdXwdnJluDfjmMw1E6dqFP8ya8UXy8-IuR3KyBzPKHeajh5aBTd_kMX8nFns_MPzXXVUKQwvWSrtZpgt0rs252f61wjQ4LUo5jyxWLeR6BN8Vn__XhBXlaxnHMT-olFv_Cfi2XUjIjEgm5w65OLFtbtI6FZ-PLM-tr8t8h1oTtzihRz5FSt32DRfAU2_77cRkVIF7HUc-BbK1WznA1kcvRXeMIoKRcSIShuc1MP7nA_YSeByCML23Vc1B_45ycGZkRrpQeko_xyI11-MlLkd16UVoDOnpCNtyjrh2QGu4VuX9o5UmY_vaQgegbpTei_2ILcz1_Y22uACvQKxlO-FUD_A04y7yU81NBdm_cbWx24O-H1iqVlm98g4-8yeydI_N9491-uijtHWtwouPN7gPAvSxyoXofUuSGa1TIMQyUwduASFitlcOPZ2YLYsryROxPCTppN37mo8dlHWty3O7VeP3Hr3OF1bzuD5gkonq3aSDM14LqXY91O13fyuib8RI5F1Fb9UlPKRWIGfYAK1mNm3L1RyXNeF79q-HiSoq9pn9UrZ_xwTH19wQpr6PbyOSn4SXImlFZe1-SH5JLVpODC_ei8fuOnMl5jVtJUsJvMcM26H68OMqEOyKJgb-F_zVl-9KVjxuQNIa2SJzi8jK71Dar6Rpiim-f4gtepnNFR2nTvevvJ8yThf07kyHnoUwdmpOeYmwTBdvpCPK6vyzJL9i6_Gj9HlMPzKIKdlsPZVdw\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"C29CF896-B064-4D48-950B-BD44D7DFD235\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6P9o40-LN9HAuaLi7UPKaAaPN0F1MbHkzubaxpWVnHUE1D24zVckvEZsroZj2V4V7aTkVKMDWB1YLiXinlrwhLGcwrbdPMiSJf6bPwASUJgZvmzjHRfVvwMbPUtc2pYKWF9ypifGSronnHqmU_m9tDDrBiVke2_lN-HDdeOnmdk4ZOhZHSbcr1O36yFCSlquwWYlsqaNCr7yYOxcHD9IoHhUM99HpQRL1ZDsNrpGith5ur21QDMy7_oPun-RJHnOj_PpzoTt9NfSr2YJlGzycS4uN4uI1942KfgU-gHZxjGprS_LyizIckoldXnPPD_UcvSE2qGD0QgtMWdfCgEOB7UYr1F4zVv0XsbXK91Xs1BcXWg5kq8Que2QhsiXlrwVlFMHyyNny-YaKyik2KANJFoXqv_B32jZqm7aeXL5dNU-n6Dwx1L1cRUlFA92zw16eGR1_9nkI0ZourCdhoBZdeuLDkM3uqi7Wh44IyT_azMLnRZVtyVX-g1Ku_vmlVYePVLERRHBxlP2mcbmyVbHDVS_C9zSJJWgLz9VGC96-dlui3h2_u7B5aFtnBUGojXmS63I2ERf1_WZJJpTe9etX0rNU38g93be2ru1Uq7OlOPO1FgAT3FRmFY7haOCHkoehhRXuG-EXRBUJdV5XikJfblUrJpRe6OUJn1PDF8aKmlkNk-qMznrqG5hkI9S_2_6HeWuaPPZzlVeeHafufg_t5j09ruceutvUYMsYYp5wSL95zqOG1n2j3cBh_sPuLPPp-0Ila-vtKSH-Zp3wFY87GX1Gr4typjAEar9yzoMZUfAXlrNI2Zy4Yr_-oZTDLWmFsQl8z0vNdnLEMHgPWk3os_r7XvEkRrCB049c1PuAQSHAMD5Cv49jShLmkn1EFarZ_Yy8XRMdayeNoVivqX-HsSnNPx8AzF7UeuQy38xfUt7R1-Hfe1T7OFmqOSfC8hiUN7NzP4RcY_zPfFZaztBzZUzUjynfnoxQ9rAp9Nn4qkC41EI5oEoxcNOzlTtZMOWwkPcoR0X3km95NoV9gRzesKph2KWdfs1-ucVh_KtnwvcmDGw9AVBz1M8mKNBZXRiffegFKKEMu2YYJg9t-gAk3Zb3VtCU0T1krbtzkL60IUHtXDsgo1E3Q1_oOkZT1wT1K4870sJTjU84IScbUp4GO9bAYFkchf8exFc1E6jL7ke1LLwb9tiv7sV_kmzW3ov5kXIWPwTqaQEC8QjN7KnftKo8l8aFnFAolmjsarsXarsho4i_rq4_a-UyAidkJXkx6tP4zLkcnF7XO3cf3a8pFtMac-KdETiXlzj0rOaAoWAa1ihq7Hcj6-T97szChzZwgBTjBnGAqrN59XsSnZsNDHrXBwnagandMH8rIIwlT68a4rVL_-_srUFRqeuS0lo6aodDIcXsvyeDebcgalf98KLKkfgzWq3nfC-emIzxoUQJqheM-rTxOpSzuJxhaIN9-rESQ4rb4jCDNg0NjY_XsRm0QOWhGZvsfMVdHpfy_DUdawlSTpWghbzTWRi4hPn_W_x8L5dgWgVJmIXXB-WnQFq_EXC-8N9n9MIX0QZrojbsU_HPkMCy5hOcvF4ShPiVWyMlX_bXEISzjc6yXRKnssTDmI0NWLpcwsaoc03WmP8S7SPAATciEJzcPTo6B5W3FbVbi1CE1DRcvi7R2rJ5ZVL5VcyAd8YMebR6KUewhLmQiFALVTJe0BR25AogpwUuOghdXwdnJluDfjmMw1E6dqFP8ya8UXy8-IuR3KyBzPKHeajh5aBTd_kMX8nFns_MPzXXVUKQwvWSrtZpgt0rs252f61wjQ4LUo5jyxWLeR6BN8Vn__XhBXlaxnHMT-olFv_Cfi2XUjIjEgm5w65OLFtbtI6FZ-PLM-tr8t8h1oTtzihRz5FSt32DRfAU2_77cRkVIF7HUc-BbK1WznA1kcvRXeMIoKRcSIShuc1MP7nA_YSeByCML23Vc1B_45ycGZkRrpQeko_xyI11-MlLkd16UVoDOnpCNtyjrh2QGu4VuX9o5UmY_vaQgegbpTei_2ILcz1_Y22uACvQKxlO-FUD_A04y7yU81NBdm_cbWx24O-H1iqVlm98g4-8yeydI_N9491-uijtHWtwouPN7gPAvSxyoXofUuSGa1TIMQyUwduASFitlcOPZ2YLYsryROxPCTppN37mo8dlHWty3O7VeP3Hr3OF1bzuD5gkonq3aSDM14LqXY91O13fyuib8RI5F1Fb9UlPKRWIGfYAK1mNm3L1RyXNeF79q-HiSoq9pn9UrZ_xwTH19wQpr6PbyOSn4SXImlFZe1-SH5JLVpODC_ei8fuOnMl5jVtJUsJvMcM26H68OMqEOyKJgb-F_zVl-9KVjxuQNIa2SJzi8jK71Dar6Rpiim-f4gtepnNFR2nTvevvJ8yThf07kyHnoUwdmpOeYmwTBdvpCPK6vyzJL9i6_Gj9HlMPzKIKdlsPZVdw\\\\\\\",1]],[\\\\\\\"CCD75733-6E3A-4D2A-B9B1-5BA2E727861E\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:19:27.203Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=153847&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"1EC103CD-4AFE-42C8-9D4C-3F2C5C128938\\\\\\\",\\\\\\\"32AF882E-542D-4049-A79B-8596F461D2B0\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6eVHsBBELa1YFUapIn40jieozTZw6VzyV3nNpIYD-gdtX9RGorSi_2kTJ5phCb9vLUYYD-CBFS8hRY9dO4uhNznsdPxaXXyeUSRvXgqP6cvTpZPkvP5KZ-HMmAwmSTQ3fZMytfWkUZ5F2MULov1V_fTAHROhtvIGzVFRY2a1gfIBuGPHxOUiwWcrMsWetRYuPHWD4JB6EsMH6karXvdhSAyIRW11Zx8oNz7ABrvRPiH4hdRYaG89ebEbu_hPWEDKKyjePn9vrcmmR3q8Ho_KRbnW76eXqp6FInGeiWIhv9k5FkGBmz_GLBwL7knvDahF5R6BEZ7LZwVnuJzN-09BWimXcKlkCb67fJg4Xa_vipPEeIqKt6-fNrniMqhvi2FbKF7n35AxdxNd2tncWSUIETbpPp_0dnzykV14V0-5WxkMqDv8MoAmkmXVUsepnFG9022MhktV6MZcoh48TYpPMI_gYnPZzBNdnFoGLfQldk19tP0abAruBH3vfk40q9txULqqHxMM0IJvvSsnJNgiZk6HBY4_I-_v5d0Kp2-FUWJxc8h9nv1RU0k2NrQrmsTbLZT240QCBsICwgtlokG0f_xZNEZgzqRMykN3fl8sjibs7Do7JEQXE7ByLEoor2OQlbaKyTCCG2j385ApJz_E41CGl44G8j1WGS0v4POEohvZ4LnjdVYhejLNYDTRnIJVw7lV_Eo3jdLHi-6m_yMX5cgHPQ4NmD4K8e0wpmFlk1XXjphlUwGafAsPpn65MVsZnKNpMPPd92p48OvEBBb--nNSCnRM8F3WpZ8GQm0YHCkgQPnatBdMZ-8P9_q8-ApvbhD52IKqLlU9y-8UmVIdRMo5-AKQe7ef8kru5QtZy_Q6L5oAOrFeSiOHG-MFuoPYaf4kfV4p0P0A1GO8EOrAvcMhRzQjlbuhnIa9QGBTMCjP1sFVM2pimJZbIFqpnQHUtSBu38fBmOe61rovvfvLu7hTcPD1WURPz-ljKJP6-eMy-tOmN-FYl50QFoXtWEOPs-bqb5eY29r4KUAR3-64HtGxAghmE4Szg4nW2mjbbKtKAEtgoGHKf3_d7Of572m3HzCZOWiovhkqtzUHknJKpegwGNaOjNLbcDg9TB9nrZJSp0c1gM7xketzd-i_touybcnMJyKvFdVzelx6whP94aT2_2T6UZQjQrhXmwop8ba7MuaGyIAyoTzX7rlFra63U2xlP-tNwWHUWafHc0olWkhHLQOodtrEfhSc6WOVlwX4s30oYZkeOjM9vkTOqM01JzYWx7-j_anZ8ozX-F3nZv279vAX1mPL47LTEO8LjAE_RwveuFsuylmXPGGT_o5Ugqhc3OtbuQTWiRYLFMkrd_oAABBEITp_do-rdC10Hslx-3GXqYmOVAJky1eTqu9Wru3xILKBNLJ0iMoBdtA_dt7lL51G805NSGI5-5N7_Tgvt6sGYT1fwdYWXvQ4L7CZvMI1ksWykAfJVCRPyFI2srGWQV5WR_6sZ4RnMRTkgjbgIY7GPy3V9vNVp-4C1oB9Faovbk7nl4DXzZ3VBmHPv_RfyOip8Hw51fvu4tl12eiw3cU3ANSK_apHHKma83XeWvPlMw8Rzd5uvIxZbkoPcS416qGMea0SmOOJ5oOoZSKXctrg8f0-QxyxqWkzZipCMFUeKb_qkb4FhDD0TyEShiwtK_4jMwP4s_iKmHZ910-VoI-62zvjdVXCBckePnao2OPnWL-zA-6tZyhKteYUmp9_KEyNLRzJcT2J2rz9GTwQe012Gotj-RLbp455Vr3Ty23CG90IGMJNcBtFEglR_DG8_AhUMlUFaJgZLloV2ENjnFbqzIPsoy7xNtVRzZlKk3rB2-dKX6pm4tfaeIrQ2KRKq1RFZc9NwiLbQBYK5PH5TRUrd5fZOLO-BfTZTiJqRi7sVw7e4lEGbIOmhtpjcQEIKwmFN0mTbTUzukn0gwKcb9GcfkqX3_hk1zIvuf-63yQvZOYvtH0plJk_mE_qPvr3aCCdo_g4zWIvPlqEqVKK7XArGuDJtIBZpD5o29mr9QTVmfAujxUzSDGW3XCr_EEvOzK1cB7Hef9h21DKcsefWkjQC4rFsFVnmvk9GJwiKUJDaOwT-exmf4GyXHzt9j4HXQ1timPvySpciJ1i2sR5y4VvN2OSTAXaKoRk5hDLB7HWvP9XqUR8lGkCet3xkO0lf5cw9_l3tplNOPzzLzamsxnyYa-SYNt4-X7bRLEqEHdNVeakpvptFdMP1Z73CDEmWzTDu4TTzNpCUC-ayHuiYApJZaXwytVFOgsSRhHPIwKMeuJjZE6dcjEMtYFTB7-tCTqkrER58rKosOTFGCmBJyJO-wYRZuBvrPFxnP7DK4yXSdpHtLs6vUUbPk2mK24w3GESuwPXQU00JlzB19B11K3lnYQ-O_ffY8_Hi4Hrn7GaERXZ1DOGWjlMp8AA31-7vgfQ\\\\\\\",1]],[\\\\\\\"8CA97C7C-03CA-4F85-9429-BB929B6756BC\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:19:37.204Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=340280&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,740103680,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5t4JFOtlfMiEZLAYqY-xxTscaAyN4COcIFRtIgf6xjcXzb8bPOi9vx2-6TbdbDfihwi1Q0Wd2JC9Q2P_ciCXPw2zYTKwHk5UBDbOiGiYkZkbs9K8C8vYyUejnpvC9gMZBwDvMfdHYtXGK672eLz8uk842GWWna2I8swzIqJcXa4ze-03LfleQW6c5vBt_eYc5d8lUc7VdRBb4LreoBYkF-UwucYqSdkNPJ0wZIjbr5Szvogx8ueUprTA_f448AU-KNGOD_RRSYSdvptNIVmyNgi69E2UfwcER9iaBvM3HaxhtoEYwZyWHplWpBodPsjQoKFjcebRzWPvdnYKnc9Mnt_QCz5RSJVWAItBcuRFLxvvtLHn8BH3BCi1JWWTZH3eDqXFDG88Euk2bOwu7FWMv-Hc9aPVgeVr1vihQFbZdhAQopGPVi_ibxINa3hGn7no2ErB3U89usGZ-fI8u_7I_oEknOtyeQOpHnZx-6VUW378VnQcheg8G7Ws-NMQXcX8gcuTVTbADMc9u36-Y75I48tFA8TDAKeWvge0Iamrl8K85ZH87uo8mMzwSzZxJbr2Ldj5OoWxhZgXjV8PpwAAlUjs6NuW9w4WVWgwbL1EJHTEUaKauwUXTP_7NhGFmdlzocxaDCAo9B0GjvdVo1iXMSSoJ7cLq6luG1C_KjOdIkEGwKz23yfBD3LKcAj0fbT8yFLmTKDYh06mN0AbndFIzzwE1O2cmc67Pk-WlqZiL8YKR5IYXeVYIV_F8chLdFBA-juTGgdV9epeyD5E2YeN5SyzlMlihdXhkB_Hc0Kshf_by0ilJwaagms1BnHoBiY_cs3-7e778d0YaIARcA-rV0HOAuCrULlFGZBZXeSj4oGkVLy_Tjs2WcSdQctJujGJnd_1LMGu-WJQ7WJcpcWzwIStk-b-wSCRLBffsALF6RvCSL6m3sqD1cvRf2k4SRgWyQmxo4V_2VPdNiJPooEVZRm-CDiH1-eDix2GFyKLk1X0sw55squJpwaFVLMIoyZ1luGjjhiHPGqSmlSYzNHwEmpT0Ga0NXoOr9b2LaNgi4P03gcxtzjaziKzFxOrCaAkuk4mtSZUw7zo6zP1OFmcL0sktVGto_rNQZ_V1AO5OEsD5Wmbgk0BrbAcmMtHkselpfbREFzKIB8FkX1LUVJ6rkQNuGKd1Yqr0zTbTafyYJJPIo2c4aVIhu521M6gC8sQ3syEMB14UfOGl1DWyjyOlRqBdZFqYh350WXVu60rFRq9nJk4ctNrWrquNERJiAQqgYXByj_5ZzAamsZPIaNVDVdbSHM1zI5BwWoDWAkVTVZn3U3eqP_3jeUexII5a9yAwCNXeA_8Yl0QkTJIeQDMdRe6aDRYAMZ5NoIjWUPU-iIJARaAmPBS79X8CesBjArW9x0JzgI7TivYbU166URzznooZM8hxx5DvXOInzpZMEfXigkAkQphMdK3hKNxNdyqUupOEuodUMov0qfccwSkSM-lLt2bkiV-STYP0SZT231X-ix_-_Jks5VKy8OvxAj8VPjMeKlDfU__ProiV34dOyXIa1uHnJQ8KtC6I_r8EsE4a-03ld6IuJG8Zem5-O74sUUTMw7J9X47cK50CS6fIerz17vpSJs0_1Sz_V6_vQPoUZ2dXpvG3MPaJZ4wzoU6RZBlHxWFRMfB5TgDDCTAlu4u34es_P0RT1tg4HwwCkQFgNkJ7V5Jjxr297QHcofL_VskhSxrKywYKx61f7e-EqC7fsDMkO7Go4CNGj2kJiMqZbFHYiIX-Ml-pqftzg9g8IizdkUs--MJuEGgN1t35AdnF4S3iWbgNgEIyK9tJ3_QIRFbT7n97HlVNnmfHGvf4qMULGzLSivH24cCTkTNBCuB7GS6FuYUQl8V6lG0MQig-xhfY05pSpTxtBgFgNfgi2-Q3_NQi4Rvm_EcAWQIR1pqyxGM6M6mmK_rA55RDRNZZAMGBgyr6aFhvfJy2KWTuTZDFLX2gYQ8j5GFGfl_tQtscExIqPN8I_9e3-_-O3oPUgFzenLa3oQ0vnlRtB0NlS5VB1FHsGstANRaXEUGyv3yzxdZvmTxw3KgXf-Tg-BFpyiD0KQuPdutDP_3UYKL6aq3oIfFF04y48BuXg5JI4G6e5S4DEgxvBeSpe2V9SzXzoRroJTwCvqUrqsrenEK0iGNewjuLoH_Whp-Kn9uUx6XSC96MR3TetMbUx2pUiHgaQ2WNkN-yaTqmkt38mXd0pjd6JvcTDJ4ow-YafEz9yNZWpz4K4jRf6PRoI178CS06G5HUoGHev07o1cPbInJKXptsyR7lQ-M2J2MkjjZmAAv7Ul3ZKvk6Dvhxd2ikrl44P1XrAQ3ZiYCfPHmwQwDfXJMoZy9B0KRJHZpOVyvfL2TCRXW--2THzvMpaRrVnp1Xq2oT0S-efduXmLVAIG9JlK_Un6DQi0s9OmWcqTTpg055lJM8hGbYD5K9Untjau4oIxoU\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"6E307E00-E991-4D45-8B8E-0B7823DF08DD\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5t4JFOtlfMiEZLAYqY-xxTscaAyN4COcIFRtIgf6xjcXzb8bPOi9vx2-6TbdbDfihwi1Q0Wd2JC9Q2P_ciCXPw2zYTKwHk5UBDbOiGiYkZkbs9K8C8vYyUejnpvC9gMZBwDvMfdHYtXGK672eLz8uk842GWWna2I8swzIqJcXa4ze-03LfleQW6c5vBt_eYc5d8lUc7VdRBb4LreoBYkF-UwucYqSdkNPJ0wZIjbr5Szvogx8ueUprTA_f448AU-KNGOD_RRSYSdvptNIVmyNgi69E2UfwcER9iaBvM3HaxhtoEYwZyWHplWpBodPsjQoKFjcebRzWPvdnYKnc9Mnt_QCz5RSJVWAItBcuRFLxvvtLHn8BH3BCi1JWWTZH3eDqXFDG88Euk2bOwu7FWMv-Hc9aPVgeVr1vihQFbZdhAQopGPVi_ibxINa3hGn7no2ErB3U89usGZ-fI8u_7I_oEknOtyeQOpHnZx-6VUW378VnQcheg8G7Ws-NMQXcX8gcuTVTbADMc9u36-Y75I48tFA8TDAKeWvge0Iamrl8K85ZH87uo8mMzwSzZxJbr2Ldj5OoWxhZgXjV8PpwAAlUjs6NuW9w4WVWgwbL1EJHTEUaKauwUXTP_7NhGFmdlzocxaDCAo9B0GjvdVo1iXMSSoJ7cLq6luG1C_KjOdIkEGwKz23yfBD3LKcAj0fbT8yFLmTKDYh06mN0AbndFIzzwE1O2cmc67Pk-WlqZiL8YKR5IYXeVYIV_F8chLdFBA-juTGgdV9epeyD5E2YeN5SyzlMlihdXhkB_Hc0Kshf_by0ilJwaagms1BnHoBiY_cs3-7e778d0YaIARcA-rV0HOAuCrULlFGZBZXeSj4oGkVLy_Tjs2WcSdQctJujGJnd_1LMGu-WJQ7WJcpcWzwIStk-b-wSCRLBffsALF6RvCSL6m3sqD1cvRf2k4SRgWyQmxo4V_2VPdNiJPooEVZRm-CDiH1-eDix2GFyKLk1X0sw55squJpwaFVLMIoyZ1luGjjhiHPGqSmlSYzNHwEmpT0Ga0NXoOr9b2LaNgi4P03gcxtzjaziKzFxOrCaAkuk4mtSZUw7zo6zP1OFmcL0sktVGto_rNQZ_V1AO5OEsD5Wmbgk0BrbAcmMtHkselpfbREFzKIB8FkX1LUVJ6rkQNuGKd1Yqr0zTbTafyYJJPIo2c4aVIhu521M6gC8sQ3syEMB14UfOGl1DWyjyOlRqBdZFqYh350WXVu60rFRq9nJk4ctNrWrquNERJiAQqgYXByj_5ZzAamsZPIaNVDVdbSHM1zI5BwWoDWAkVTVZn3U3eqP_3jeUexII5a9yAwCNXeA_8Yl0QkTJIeQDMdRe6aDRYAMZ5NoIjWUPU-iIJARaAmPBS79X8CesBjArW9x0JzgI7TivYbU166URzznooZM8hxx5DvXOInzpZMEfXigkAkQphMdK3hKNxNdyqUupOEuodUMov0qfccwSkSM-lLt2bkiV-STYP0SZT231X-ix_-_Jks5VKy8OvxAj8VPjMeKlDfU__ProiV34dOyXIa1uHnJQ8KtC6I_r8EsE4a-03ld6IuJG8Zem5-O74sUUTMw7J9X47cK50CS6fIerz17vpSJs0_1Sz_V6_vQPoUZ2dXpvG3MPaJZ4wzoU6RZBlHxWFRMfB5TgDDCTAlu4u34es_P0RT1tg4HwwCkQFgNkJ7V5Jjxr297QHcofL_VskhSxrKywYKx61f7e-EqC7fsDMkO7Go4CNGj2kJiMqZbFHYiIX-Ml-pqftzg9g8IizdkUs--MJuEGgN1t35AdnF4S3iWbgNgEIyK9tJ3_QIRFbT7n97HlVNnmfHGvf4qMULGzLSivH24cCTkTNBCuB7GS6FuYUQl8V6lG0MQig-xhfY05pSpTxtBgFgNfgi2-Q3_NQi4Rvm_EcAWQIR1pqyxGM6M6mmK_rA55RDRNZZAMGBgyr6aFhvfJy2KWTuTZDFLX2gYQ8j5GFGfl_tQtscExIqPN8I_9e3-_-O3oPUgFzenLa3oQ0vnlRtB0NlS5VB1FHsGstANRaXEUGyv3yzxdZvmTxw3KgXf-Tg-BFpyiD0KQuPdutDP_3UYKL6aq3oIfFF04y48BuXg5JI4G6e5S4DEgxvBeSpe2V9SzXzoRroJTwCvqUrqsrenEK0iGNewjuLoH_Whp-Kn9uUx6XSC96MR3TetMbUx2pUiHgaQ2WNkN-yaTqmkt38mXd0pjd6JvcTDJ4ow-YafEz9yNZWpz4K4jRf6PRoI178CS06G5HUoGHev07o1cPbInJKXptsyR7lQ-M2J2MkjjZmAAv7Ul3ZKvk6Dvhxd2ikrl44P1XrAQ3ZiYCfPHmwQwDfXJMoZy9B0KRJHZpOVyvfL2TCRXW--2THzvMpaRrVnp1Xq2oT0S-efduXmLVAIG9JlK_Un6DQi0s9OmWcqTTpg055lJM8hGbYD5K9Untjau4oIxoU\\\\\\\",1]],[\\\\\\\"51E93ED7-D7DC-4B1B-8631-7573EE11BE28\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:19:47.251Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=890195&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"56A691DA-B990-4FA7-8C2E-BFCB39F1BBA2\\\\\\\",\\\\\\\"27805E29-F7D8-4A99-881A-5C2162C87087\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7SdjC6kbAuNzxqcDi7gCbbe3n6EaOGZ0DMdbP51iZCfbrAM11ZeBtRb8eHpfssfuaG6aMWlHVN1JIYilhcI9jNwwmUlCF7Poc07eLIVOU-pmns_uOwNlt6Lpkp0hHm_1DiA7oXWXP4XMXhv9aaF98kS4TLJ2T_vQtYe0LjAUy2IJmMQ-sN96BcN_3-hQRH5p834HTI605tMtEqj4PKDYj4Eme37-qLr0gR9buXjQiGXcmGNifv4FGjqvZjvqVStLU5W-OFw6F4Y9f_bkLj_5n_isUXsIlSRgHJk4iW-9yHbppX1gor9ONV66NIUlwRkysvOddhAT2aD35tNHZSLm6Mf5YPQ-2lcYvKSt04HipALfh8cZETI_zKALxUHtJpEH1BTPiC6ZeDcMREGbHwXD5-1tw6puGF1H5tYeImk5H_3AsfS9Akmpp8aErFNoydPpjqGz02LHTksLjRFORy95DZ4Jv7jatY3AC8DyYlFrS6H8lHcGe34qWi09o7QLZSJYmg0GkVCQhpRJk7gPFBkm4ot3HoEKu9Rx9zmliutt-YP0qLCzHIzfTTYODKi-fZvJnS3S6Wjm8Y1Sv9wz_L76fDdp_A6h_tw8OYEmo6UfvYiRjUok6fwP9mz-nShZwPF6Qhan1Wv4YvhQX8TFE0y6aZhQes1yJ21eF9lsrujfdH6hA-gnc9W0HiFtK8HHNWhtsVvwXkOteen9KiJ1fzjG6fN__tEcU1UFxCXwj3OQmKsk0-BpsgAN8kSe2egvr41alxScLGRAlLdaVEZxwFyANW-v7EGbzRKd2SdNmMauf_99NUGS_iJnW6GINCz6cf3vnPq61Q1EqHDu1xI_Jcdoev306mxaJdXk80-7-17If_7FGUIxCuPR2-GzKNxwDnWAFo20bka8YZp8FqG4p_IKIe2AX7gKu5iER-TrxL_DpOGor-4XFhYt99NRxA6tCROFRKI2pOXRKcIJFdPJBx1saeXcdZN_YnN1dhVRP8-aSC9VXsW5bF_sldIh8vb41cbrhppyz9KVsAiqTkP0kdAaZzC1zBY1dXb5nXirbcBthPToe_MPvsMlSIWnponUd5zMJZRpr9iH8Et7sd-CIwc7bxsIEr2zumvAJrerPZB8KwYkw9SKO1jeT1O79JMhzhwGv1zoQb2d4za5mc3q-hIrEz0oNqxQ87QZN3LEbaa14ceyEHYQeXFTMdqInkM5yzoNIxHjE5MeR_v3mPiX2IOcZ3H-xWq3QaJo0NjCI-Vz6TBhM5cbyPt6yUr_wBG1VGYtZR_GOq0JjR24DsgJZ2-aSY20NGsujoKB81OU9iMrwngP0WX0_10bl5z87-dzl_csu5ZEzChHqpXlcwsjhX-Jj80r7KnkoJ9B6p_39k5HOyYEBRKkB7V4_AWgAz5N-pgMGCW0bfwNTZrEOi6Hl4TUBNK-0CTl0JzN-VbRzUMNVWU2R4n8egInb1vm6B3DYLPHgPPhM6HJk58JO1uEtvU6v8eBV0thXJPsklCVIlFD2NvmoxR2IKUHFE7hv1Y9yOSyRKe03abEQM2RZoXhHaIRYneKJ7HoPZC4X5UD4KZmdwVGLm0m_pLJcSqoWt-QOHe1Dh9lTkH5gdutg-7KJowDLpxee-pMwjGwPGIGqFCiSQQ1KJlcwhmf-azeHK9QPNomwqnSyxkpvNSWMOMhXW8FKAyIvrgOqQGr7WHlGtkRkoFAX61-qrR8gcwHfHtoWhnLyy3NNcbiLlFrqH7e6qiBfAj5ZtaF49j8UIVV6fAfAs9s0nvdW_0L-1dbPBbqgLi4KrZd1JOkRjITB3peNqhk_BESeH2covHAyMpIUEc392QUOy5cm7sIJRqBkN-n176pGPnvRSJZaubnCRIn5pv5ZXtR5VqO1DQB5Erv78mqmY7HgHiOcAbWoqtCWguvEBAuYX-C9QJl_jABKCDjqlqaF9UntJQ9atYoQB2MYIblWVEjmnI-VrmZjSuqv1MId2jym7omvWYLG-KULhtbSSk_9m-LeLtVsCZrhi6w10R-GQszwcbTLs6UhedF1OhNnyaJSJG8nqv2B1pVzP0LkWT73sBz1AnhVYj-qXxXjxJuEsp5YVnIPd9tn3lg1UbqvlWjZcsZCB8AMsEwyh4gsw3ABh2Pr-El-UyP2aoJ4RAfv2DGb-qHHVywV8B5KV8RluV2Lk9Ua5znKnStamH4_b3-YViMH0ZSBeSGdJEBcw_WXZij3NcIwOg2Sai22xjYa2cX9h8tuzBLdc7JmJGwA80DfRHdcaKtn4UcEx5kRi76OUFmFXgabExVXCOXbANDyYp4khw5wblBuIIplLWAsGch7F8GEq9oXYDsSYSrtOAA42H6LXC6OPTgAboeAR1mWl5k21TzN0WaWZSP8_DPMgWbnXf7DK9Qie8ffdg4XsjmiekxhVvi6e3QZVl3hR2CS5uJPPxTYK6eweFCgVV7dWml72yzi8MStPOt86uqI7JYZWqVPbnds\\\\\\\",1]],[\\\\\\\"13D6BCDA-AC4C-45A9-B9B5-920A16D93AB5\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:19:57.220Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=135527&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"06F044D8-FC39-4AB2-A3C9-77B87F4288F5\\\\\\\",\\\\\\\"4F044CF2-7E5C-4BD9-A3CC-A4A4AA4E3744\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6z2EnlrhKLarabzdmLD7Njzl71esOwZcid_xTQHEKAbOPcBWo_ABZJmPTXNAzWS-9ydCAMF8bUTfkZ8QyeLk0Nzyt9lsUfLqw4ASMqMZfSMfWtxapuBCbk19tQdeYG3kJGpU0mQ_9vnbOy4Jt5bKXAwCKx3r8fKuJU6JvY3Sv67V1WSLv5bLkXEcZnBZB5AZ-MrWtsiS7k_uuGi6qNxUKic4VC_JEfmeQuHHapg80Ts-J87M1XCB8F8GdoziAY3-GtR5oZTXvq8nNN2Uj2ko1xPo7A_OgRdaG4Z5wrKVIRgIKhRfFCWRvYynv3MYhKLMLl3ke0Uk2-r-cCPTs09Hway7mW5giB-iz5_lTlqPqLPZAu12d3igOLHRECaLxF0keXwL3WNVygfbfq0qE7QqfItrabSX_OPWhmHF30LSzlH20Ah11DU-EkdjfNMK8UNU0Ugv4EethtQXGjtsqtdVsuESxPo_RXy5mLQTl2x9sBECnvBiDmqbp0u7NAgkQ7ls4BbKXYfwzDC3w8EkjN2As5ZFTBGCLs9uR-2ujkhEDQg1l0qttsMaa62kvgCq3afzg1AZNjRFhyxb2lcqfKM4ru3s6S45ZGsEilspjPzc4oqAAiACD3d5CbXUwTXNPR6-AaprKBovgpyIHJA4RMqktWXqK9mNA8hMJ-KdVdxI9BDGjgs5Re49GpDfBmrVz6uBSvbLXWHnfeFLiWYrc_C1r7HQaZAPUdzadjqp2YG7qSccWffN5Ak5vkhf-Puw8XzXIZUOqsUB3bI5leCWvYXIOcxnlHbPVppnmYcLC6s_cx52f0_FGcIxF6iq0HeCcniE6bnDes0reQ1k88kxUqLZsXATtEdPIlymj9z-3CaPS9xJo4cF01dYXUgEwmclRBvKfKCY4gTERJ6fZxooZIvdOReMSNTV7iM456S0h4sPVMXozTw7EsFjOgYZkh1gMVgBZ6XJeBNg-vustrGPKgdsdy6e2mYyDKx-EXs5R-Dppn5pDNf95wEMy_MgxiMfldVxLO3LmoZst3VXT7McwTK_nct_CSH5e04jMrhI8PxBq16uTGPcUxxvUJi0gKS2-F5V0vnAIf_lN4Lmo6Qw4h92n8b2cMNa09tQjVF8ecIGkXWy3OAicHwVAXdtbTK21Vj_r1N6BSaM4PW16gxPGwP9Tp8debAKnYUCVTeRADhGX-8Za5vT3aHRdKjqiyE_RW9UZ-hPxm9saCI5K-G1NUH2I_s6WQLnShjl3_rs8Pmufxcbj0ZtEzXbcjtQobLCNEQVL_OJ5_-fm4aoVVW-smRNwpKqUcqevdue9mfbtASyZp9UWIjOX7X-Y9mEqYsgMOA8E5ImA1jfopUIpo4xIHTOd3BZuSXGoZ7RPiYhyLrf8bj3cLQOoTJfp5v4zQT_rDiBpOW8EjY68l-mGFTNJL2nd3FmtlC75kUYLUHTwQhns1KUV4BM2Up8p79FGcOLFK1RflXZTZ834ThWARFE_YtBi5D5arqB7Wg14BsWDkLz8w8KE0Zm-eTmVNLCu771VGNbDpPpYwxRAjg-W3SqryeNPWjknnc4XOCM4RMA_qdqbj-0nOcDNQnfPkMMeq-Igw0yF94M2k2sDn03tWDYbRTG5n9nBQ2ZJ363MAV9lq9HYFq6sVxiotRuhXQRl6N_8RIghhO_wXOC2IHqGbj9X90ANGuKqzY2IQfiuz9re603RQPDy88N6qNd7dOIHIkHGAlgCA-oFoBK6hM-fbC6gA8MzfeC92KCkPNgulEKE84hXz5CCBkpsOFCX7opBRVmhFGxWHb3_2P5bttbAg0JAQkcmGtZUhLtaipXLcgFxjTrFCKbmw1sItKT8_fmFsAzWpAqZo0p3MA8EdF-jLNES4JG5UbwcD25vaFS-xhRw7opyGAbN_LkH1c43Gt6z_NpJ_5B6CnyrmvjW8uel-8X4X-X-3su6txpXG8nUS2Vo_rtZVHK5WJdXVNW1RUtP2hML3iKNnrmAxISNvTLu9tPVzB1xS5znGdsFaOm_S569NV6HjvNsjgFbBEzkAB5PCW9AqtZ7StX0QEF5ZDAiCd6h_OfqcgR9t8OMgayeq9qu7fF0kmDJ-qWcvdXdHmzv6N0W_Ev9zHjjNtm7RUR6k7AS73FCDz-kTdTQDe_3mN8fPel1fNt2VKleLNlX9LJprhmNXFTRlDZktxiPXNe7mVQd-k7ndTXSRRqsV3brzUQ77HlwTT7dqnbWiZ-Jt4_-jCh4FBNZsRI7OZRU4eFLHrpkFC8seJCly6lXW2O7lnLG6zwoN82rEy6CeEhpjNzJPahnEVQi5JS7lmSfCQnJCKFkWVXJhAnR8VHxrhFBrbXgCAGGGkZ2lpwtpk-dBXiRGmiERCpWu63KaEly_hw0sMqCGjk-aRJDA84EkfxLuJR4fbFwrsHKbcA9951PHgWvJ6K27--9PXO9TfAyd6u-euRhEDjjK45LoKw\\\\\\\",1]],[\\\\\\\"70BA0B27-A59E-441C-8C2E-CD8E9F7C9142\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:20:07.236Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=828625&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"D887BB95-D45F-4884-8BDC-E3F44D68FFA5\\\\\\\",\\\\\\\"DCDA3CF1-DF42-4053-AE48-E7A7054E9DBF\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7YK9uBA14Mnal5eZS5AIVpD4X6oOQpQ4z3H3bUdOh2UcJwS91qBOVhg6Gz7MXG2F483Ha8-z-a6ygTvpvgORnPO8UB7Z7ZKFQQgNLgJECGOz3xzEh2jKYRF6QZNxik9DuiNT2dNZze2nu1KtAhO-Nqbyt02VckJhSu3HUm7o1E3sXShz9TpikEx-NkpSZfqXSA7KKn3nS57orzeT7IaOVkHpkQAhWu1O-IVxvDADb1GBXSSvRd0xMBM8eVhpef0R4Hxwb0B_yYFjTYaXMXbinNGewUzqkLtIkNcsAB5nX_dZ58Yg-WYJebHgzUQIkVGvA98Wt-OUatfr3vEERciAkzlK7LuHqBMsZArpLvyewP3G-QeIDnN0Hc_SrXjpvraYayISWTPnz1AQvdxAgcVgP-F70ky6Ot6T4Lv3AX6bslusk6B04UJFlvYhzphX69I68cWEJCQ0KM-ehnnANS6z9idQ5ZrRUlEYDeD9N0xNm82U8vS4M2StyaXSHdgb_IssGkLMMkYIVZ-5jYe08m7p5cBu3PMu34AxigGVSmEaFVcS9hxB4flX-q7pVH7OtdQTCNoYLJGXV2P4wUTx32n6_30qk9P8B2MflnNLmgXt6xi68UNbLZ7p3Gqap_zmb2GkA_CryP0GQ7rhBvSUogha15Y6Syz4pSuuH7aUMtJuF_1P7iy3T3CdeIYHbbPBGxPkZpCuCTriVha1u2xol74plrszWp7Po6ESXfbdjd0UU4AGbYgq10UKxl2XGuECT72oIkR4wt7x37JITOQyw9qHGgCCB9sjZmCZkPSI92ErmzWfibUbuuTy020Y-uYf88YjgdYDbGX_Jbk1ajkbtJTy1iv339tmVDk0RpHykwk4o5Mjg43tRrUQ2Q_r4LC2h5LilehZHg8NnEP-IJZUuF0plLWkHizlUtzKPt7OFFsEgG41brsZhsZ_ActBKXGsoDIXFihj00VfSjHl21uDCgwalKmq-tOHurLzW2dIuzEFOLSzcYJ09T166N0FVyuE7Yow91PO2exZ6Iq5krSRLSJO-tgp5x4Q4L2E_ho4s5Kkkn2Aids50DgV_Q3RrHdm-RW-LNwh7k965nBPEJGJGsKoq29pQW7Iw7ZYlJyi_1UgfIP4H0WQPmirfxYAoaIwMLWb0j3sVXIpvPhul-i9iYrlG-X4N5pqdcCnhqH1aHXwOpx1KrWa3fTLSLHw58-u0aNh_KU0SpUajB-R64OsQ1wkU6PGiejL85yfKTbKP6R1dImPQJBvYzLluDWPVuomF1l32tP6PNuToL0_TrrOSqTpH8xL9YSKQtWWiDvwLCJMCZ_8s-eILB5t2C_GFlDji4nyhkX8EISwO-gFj82MMBzihq49r-oUCrjMBsIhX9MKcWqhpfqsOt0GnLFcUBAxZ1TPDDpvQpK876MFWKYdNyWDz9SmjnwmwzGioU84H7EizAF7nMzpmprqE-nCfFV7D-RDQHNT1kWEb7Y848vUBNyut8sisAwgaxh2booc1cxuwThkd8hV87u3154zmjtXPUNpUie56rQTvzreGrL5EZDmoXOEGqSCyBHKlA9Vhj1f67oRzKzr2HPX_Xr2VRe4OPM4NIB068DQF2vJCzupg_HY95Vx9FKZussBrZk0u-67SzVf_qUn7pti75L_hLMZerK5PQPqGqD2ZhloQc-LsXp8bwfkPt11F5UnQM-jLWmWowvP_wCqBxGq2sdJQjSZjDLxvxpFsjKfEWh8y49YjzIXj1Q-HBaTRN2xRLyDgI0V45cKELI6OCH6AwgFMSMn6LoJyiThmZ9e0mcWHv12irgzBp8Khw0gXt-Jv7ZiRIom2_LXPfcqSwhFrY-fnX9uddVcqUr5v9ZUhUJu-jIE82Egj-8J8PQm7HwUjs14zZwY5AXeyFv7puYmocIg7urLLdBcig5s9P6TamZbBrt403lfF-g9gIRAYH5kyBaUaSBKodhwnIlcqU4BnUZNeVaXirewsKL8nfdt8qVf_iuqzkiupL_edBDYyN4JL7bfeAxlL4NL8KHt8TR9ncl4DxoG0MFSafoYmPyjrPV-N5GKmlhw6oW2spjLtdKyORnQIpjEK1VCnA2FrAUNvvet7vmq9pP1csbdXQJ7BXB7WNA69sHRyEZ1Gz8JjMatwUcEEdyQr00AE9K6hGuVLeAmJw6XDLBPu91wFozQrKE_mf6xLJY5FfL57vPTIeYsikZSxvCaSbHHowGhsVMYX6HBYX8eYy68WxEmGGv_AE-Hq_7ETq5-0_RwJrvLqqJ1kTaUoCrxRmqhulRknxa51Qj2JV2c9_WzYDBfCB9_8pakdKnWIQeEKd-xN81TBNFzf1R7QWu3jJQx4ZPhf89UHki4TVaRtdpTiIKt3LAv8dE5udV9Umn6h4kkwUrLJ4hARr3P0S0CwNl0hS8_M8hfWCZMgRX0E4GzHksMbTGvMIsrkby650FO0qTiiKAcLlQzW-N80sNN_WTWtFzfg\\\\\\\",1]],[\\\\\\\"70E19F8A-5A62-4550-93A4-3FC3CE123516\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:20:17.231Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=125855&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"2374E839-F2E9-4C58-A0F6-C2F0F42BB101\\\\\\\",\\\\\\\"FACFBD7D-6077-4154-B91B-DA74EE8A8D78\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7OXK784tTnLFqRwKd-SLXdWZh8M_pOFA1Pl1Ygc_2WL5hg2oq8jEKnTSZ9pKqd23jcdmq9NWMKaXhCNx-tIzlxG1uQKyQPLaLFlXH-N_Y_-SCRILalM3M1ToaYKhd8Z3ePO05iluVjXzQ1hTay23C8K62I4pF-n-8R0k82ZYoCl5_tJ_WBdJ_OK65SGtF4QoUMOUMANbWdk2Ab96Bo_DcK3eEqHMVjywAly0A9QaV46rVH73oyQqkqnIS1iFnPC6EzbQ78e5manTvRsmretDVNIURe0-_bhCvsd6a2MaH2hWsapURyNC6FFHwSfActrOgahZYMU88kZSi9kzCPgepbw7K0ysvi3m_Ya4vyE2maAQEYtYFewtLTSSCgfpyyhWdswylRxydOqe1Yk87JPuQiFOlHEiiqpON9v_WR__--5TeFheMm8kvDWzG8FCWpfYVXk_M4DWH2EaJfeROd-nfDwwX62eYZe0qppl2pRNJ7wj0cXpV-Omd8dfeymMJJWoCEdSFJhfxZcearv1y84cy2L2Na-HX8WUL7yZfarXAt92-MDa1RiRGhn62sTs7I-y-NDIjxosNsJ_ytDwJo2in9KX3MGx7luHneWgNEeO08LWXhdGoK7Y5dABaf17WSjktzEEDBS1x5oeneMq3rggbZTtTS7gUb6SHE6H6luK0uwE26kfeFJZXu9tO0XP_97VY2DP0lYqtDjLlr_Cle98dd6GV7mMd16JyRbLXpuG_6EoYvBzi3_Gc3AqQ3qWp5rxG5slqQFfq2ptSZzeuwtwFLY43-fg_JkYj8iYV94r-XAldMeS1Qa_fRCrfe5D7Rv4KoY8l_9rMkTL5VWRovN4Lr7IaMdZHFvFgStEX75xRYu5pfo3JL9AqkJNAB3zjEA97WIyB5UbLcF1LuPUrtpzo_KgMSiHcJ6qg92OVaVnNTXU1SC9-Jv2HAVN6eQpy0sXl4RJUqVm20YzJH8tAxvJ8XvLbxoDgquM_gJ0-EE43sIKi_Hsp1ePJVvzErs4KaQrklBbo-EpADzGK7rkYjTCSjNMBd99yE4YqIPMVCrNwwIqwaU5ums73Cf_1GQxAWJIxV74xka7FEazpqXzjmXFpyvnxMeMqv3I9FaT29N3-JSgBhvA9yrNW1NNjmJRuCyMeOEjWNw_dQljidgxHOTiW_HdLrJhYybtYrIwDbiAFZJcWbHY7QxgzdNxcnrs7wRg3vxsu5xwh9O5OXEe2shFtd1bpurBJZ_drcukAIkoQRTKsFKOSbfw8ezsQKYdQu-ayK3-H_E2NQsQYS5CXkgKPbQEhU96pgoHvXklIz4y_b0oa3cbNxVuR8X6rcRj0D_XPRzQw_3LMInrOAXfW2aCXTS-Y85jEaPdkeHsrGvuR-v_NG95ie4QOOhSA1ge6h4IsnPn4ZC60siU8WZqLaYfKlKSnxfELI3Hr3BvmBFJinxE8sZ9ArJWgjv0Sn2bd_0cvK0L9nVN7Cq-XFkapy78iHyyDDY1u4I45PM6ZQTBfMLbNmG8zxGpp0BPv79l8NWLQcuF2rxLi52Y2HwjHxg8wAjBs4ybqXJtyY4eKOb5Fe_JgK41nQ3IbGmIdGFLA5xIfHWQd2-IPRfAGb-nq1hqTEL2sJ_VIQid63xhdOsDZYKxu20bCQ7j0PDtWDszNZrFfwkHwnGmMh_o9HKHMU5_GvIbQQB0joxdn6gZBwxLas5Ruy6QPC_DIir68fEvmOC-esHw3V0BbgZ5yWX0Asn11RWpG6Aolr5VntZ2fvjsp9egSgd3jGa8U6P7XB51YNwVlplcv7vJAtRDc2-SL8ID49AV-6AzCIkf5HUEQ3R0ROz4eQGSSu9C-MNT2HMLPAKJkLXl53mjDDoofr-acM-VBeTAAPVUsMqpDos70alY9i1zvaFnuRGWnpYbYOe5aHtMJsE31thS35c0_JEaNt5lvD6_JdkhHM8fesrtcGPDPMEMIm38ufMnx_o5dYT2buIw-Am8WmoZYVbpVqelYq-aNNYVoQfoAj8pbmeSY0JDCIZfrL7FSbVDvvvKPv0uSN066M1U89Vm3y7sv3lpMHQuG9kExeqwvtuhHMP_J2ufH-dAb-zHQZzbNQbx55dcBUlq3qZR8xZxLmOcoGdkRBzhumn4EyNdeSkFOQUn3O5WJ8djnpWq4DZblwXt5gqEWS6tn5k0Ik5r0Lr17_oZm3-7JlmZP9pCqyXHtDnFCYhXs06BrLA-7wSwLkZ7TGU-QbiCM9eqf84r8742cBQWiTLjvbsPi5nEbPM6fRpA6xYLgkjVHRpT41U8q8q_Gsb1EqGBlsfaushPYw4Rm3o4wkeOLxWk7R0Fw80Aqkq69atkiKapyhtnPwtJVrGqqg7A0_8_K6Slewo5XjFnhqMC3DwPcGLm5AalASXBiXHOm24_WAYL-A1dqM37NGmzfL-dB1j-nEsA46L4i4HGSXn32RfD7Wbm8XF1BrQN9faJbAcyQWWQ5Nzes\\\\\\\",1]],[\\\\\\\"C882DC7E-FF63-4CA0-96BA-069022F8B1DA\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:20:27.303Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=195153&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Close-up on Le Quoc Tien chest heaving as he gasps for air, jolting upright in sheer shock. 3-6s: His trembling hand grasps the smartphone, screen glowing with the date 09/05/2028. 6-8s: Camera tracks smoothly to the window showing peaceful golden morning sunlight. Character voices: Le Quoc Tien: Calm, firm, determined Vietnamese male voice with deep analytical cadence. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"58D321AC-6FE7-44AA-9359-02851CD35C02\\\\\\\",\\\\\\\"A91D18B0-5CF4-4AA1-9C5D-DB935C7FE5D8\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6KMglAtP3XOnOvao0HEvflafFPj-AV8jGU139m7XnGokP5snqbeM5eJ93DdSVZFu5FTYwXnoLeVKN_8gR3uIUGOW0nH7XUEz_mQhq4Od9TwAJe6fn3osAxlzU2GbMzZLZBHTlndzNeOQjUTiHWXjxBPbSO385BSu8oWN0mPQL7-De2lR8yiyCnrSQ_JicZA9Vizietmt_r1CDZbcbMbWZmCtNpLSNXXf3Ku8gs2l6yAW9ZkL2tBIBI-PqxkC8HN9biaBLtDcUvYEQrOKufzcOOBzO-c907P5_PS8gtvietQoCYTj9gBOfkbkCmYpcCI1LWMqDPN8z7VsTwR8qgg_8HXjrKRTsphsGvRvt-xmIKQak0r5hdmcS2VbbDe5fmJdsSJ0TnCUayAtI_NmGwKjYVFlsLCvhb2kJmuVw85wpa3ggXc5jrmLzdVjJVfY5MOoaLIPBokvl4bAfyA_eRyOaBYNDlKPyVebl13gmygkym_QhaM81DstdMuL3OSZ3xW0zxoAxqKqPwyU0w_W9LIxTTb0orTb-pYBakw1aqmoca57mzBsvTIIh82ABpILa6qC-JyVg_903x925CUltUoZpBaAwKcHFiGbLsSWWlhcQjZCmd8GgNZBTQ27eqRFC75FCHkKJ_9rZcSzzAhnnVbn5m-eAAiKcMXjeDUd7vgAv0q0UCbeR77bZ83F6gU-2dsHui_8B8SCvPnA84KB2a-nYRwQurBng8ZstGOXhSAvXrQ0YMKmOJ-NySbHR72e1clK1qvH6byDN0FkzvGF75Doi5YskXDvDbJXXUaUp-oR89T0QgJHJmxXNG-TwpZLBwzFOEzuoK9LBQT0QtbdhLzUU-gQ_vn6DiF3vaGuvGur8npvp_Zlt0GSmyTgCLfjXUMifObFgk_b9ijLKR0oQPEVOtKv6_PzaCFoFHwqHCEm15UC4JVJ5s0liM-4A-8oqbO7Q4cb6QirQr9OUKdOZaZ5wTKO0MjUngBSFBT58kOaUPHperra4fAAHcGo0fDYA_jQUaI9gNBMAxzHTxMrdJzIwYAgkNJMmlv_7Xypj7Z_tTU7x1R_s4Qckz7ZINA3mMT_3E3Iqiyf34Eg8BtMbQFjUS-TU-ooK3Net3tr6zBZGZN7oKEznEqUdBNp0d0OvFchhtEo8549xmFgT0BhA65I5gPNipvG1Nf3Mo_9Z79dLRD6R8p9tFPSjfd6Mb8yjsZ3vGhzS14L8e74GT2gvLrnS8G8Kcqc6C3pTXbVMbR0APRatAch6EB6Bqs9IkfvouuJKa6820_n0UR67M9FRE_uZo7hBlHVElq0kyWQwZ2k_Ay6nh4OwnKjHMzPYYR5Luc1Bd77gUrHv_zNyTNh9TT-9xVk7XvGLisUcy8_66VyDsUEaiGqWCiOj0algxQ0hgWisINBIxW1kvMZyuTluhbnfpowOAdLVAFYLlguEzDaqfTdGQrsk6A5kHWaeXGFePoz8fzxOeMZm8SZWKx-islmCizyVYJQHrkraJ4uP1lSQAcYNE6Cr_AGo99ntg-DAIP6VjA9VZueRKzrSTf2JVT7XxEziiZAbNj4lFkRw9awQdRRrqhdxDLYXIAR3Z-ph2hW1-qu3MD-pjVVD_dSNJYZjet3rf95RfLK3x--IwUxgwr5Bho9fJRskWyt3zcS1yG7RWdH3b0XgNC8V3PHAI8r7skg147kcSFkDzvzKt2RfmRSjKOM7KteRgkDD4LLBSNdx06IMat5qU6dh_zGiHlFSVcz_p9BiZgFm9G2IXHbx9O4m95alqjjb5h2MWUHDdzI3fOu5MZKSjmf662MbmFSioPn6Me1JFK19DgXz_RlhIlSuAD62FT2k3fXTFXh1uJOxN1ktX800pcoYt4f0CJKvCLw_jhXcKtqafjTW1e2U4kzyAx2WiDf6Gi-JtoFAh8_2uIxaO-zlBVqZmwSdy3Agor-UnYgeU7sCKHwLc5b4QFjCJSTDElgqPkFR8o7QyI8lJE3U30rBpWxZGhWcNQOwhe73MNxGiTdH8MBGo075PhF3aUbhArWOQXTYdZCYuRYVgNLvZAa0JdgjkMUdYcTolSkZ2ruJqEZ-IU-MhOdNKkEdZ93j3ANnGbxCPvBCHPEQfbgaESY39EKEQpjS7wR_wqLEaopMdzwNMo_o2GraQH_aERDT_OwAtJdp9XXSpv16D1bU5wtoh_Pnwvq5oeV9Y0wI-I8x5QFE33XMb3CI95TwFY_p6YxD5XG8whlvnofj6DioUR3giiGeuJKoWF0PObPGAI7rTtnFnX_OA4o9Ycc2cV2Cz0mldJ4VkVcqbHS9wPssCBJoq7PdOnag6Sw5gC0-AMZFtYuXNAy15dEb9mlC8AopJGlpsKWJ2bnJd58Cl_cCB-VcSmqEP6q7FahNwfiZPwuI9JFWsvO7MW14zBlreQ_ron3a9KSaurekfaqv9wfN0MtVkjc4Md6tV0aSNj0zSSPL0tbsZYgpq7_aeXGnukTUrXVcGf7FjEJnoRzDwU4RN\\\\\\\",1]],[\\\\\\\"5764FD75-4D8F-4081-BE74-A69504456F45\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:22:13.214Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=2572350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:22:51.576Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=2772350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:22:51.570Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=DTaVef&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=2672350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"DTaVef\\\",\\\"[1]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:22:54.356Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=2872350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:22:56.676Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=2972350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:23:00.921Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=3072350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:23:21.835Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=WuwhI&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=3272350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"WuwhI\\\",\\\"[[[\\\\\\\"PROMPT_BOX_SUBMISSION\\\\\\\",[\\\\\\\"43B5E996-092C-4CA9-9D90-865EFD6CEC09\\\\\\\",[1790169787,917000000],null,[[\\\\\\\"IS_MOBILE\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[]]],[\\\\\\\"IS_TABLET\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[]]],[\\\\\\\"IS_DESKTOP\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[1]]],[\\\\\\\"IS_ANGULAR\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[1]]],[\\\\\\\"USER_AGENT\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36\\\\\\\"]]],[\\\\\\\"TOOL_NAME\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"PINHOLE\\\\\\\"]]],[\\\\\\\"SOURCE\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"CREATIVE_AGENT\\\\\\\"]]],[\\\\\\\"PROJECT_ID\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\"]]],[\\\\\\\"MEDIA_GENERATION_PAYGATE_TIER\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"PAYGATE_TIER_ONE\\\\\\\"]]]],\\\\\\\"106577881,106714532,106281924,106184493,106299202,106322568,106701949,106210711,106238955,105484652,106599983,106262194,106585383,119157485,1706538,106437280,106430287,106432687,106225453,106210719,106077941,106486771,106615367,106536611,106667487,106259075,106556077,106676866,106611001,106681111,106501717,106104244,106430149,106592798,106625630,106747630,105746691,1714257,106712749,106297879,106577873,106714524,106299194,106701941,106210378,106599975,106585375,106430279,106210380,106486763,106615359,106536603,106667479,106556069,106676858,106681103,106430141,106592790,106625362,106747622\\\\\\\"]]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:24:07.982Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=3372350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:24:17.242Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=526989&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:23:08.219Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=3172350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[null,\\\"[\\\\\\\"35499362-f230-4bfa-8808-a49591ac4f2f\\\\\\\",[[[[\\\\\\\"t\u1ea1o 1 \u1ea3nh nh\u00e2n v\u1eadt\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA4WkwJ9I0aJuqWClk18YP0cICAvvOapjs7KQQRzqsmpv6mwzh5Ymk7gS5B2DkqQR7z49tl9fqVjEnk8qiiMC6BIjcoHgp0wmAOgcjpBk8oLDLxVr7vlHH2VFS-3t5IGhXTD28UvKYyu9tJtczdwZV5d3OGKXORdsM97-J2TOC8pKCEQNBupUWjDCih5tbPUnnXd-GtBjJ6JHPwY-J-QEhE76njgoAnMuAimH9HaMpcwsZMiepHI_LHfwu9zak8gTLU3I139-M0PaItF_x-n08_RnHPM6LK5YYikZGfeIr6u1pvZFpCJSbmUm7CpP_ILRLoyd-z6RWCFpwZM7B6oP4lhLjid67En5uMUm27JbI_YTC9kkG1IyumClrVOGrvgVjZpsT3TWB5bY6DH8Y4qXitjqP0NA1XeiRYlj2EYXeoA_YZwW9t8tCyAZJ8vpJI_ujqymHZSEvfkdRs0gMqFWoLuYOcOLkQmuXxUUG663bvi7iUeIIADbtIDFRw7MpZUcBcTq-Zw_bMm4sWr8nLn9T4cVZoC6f0YKNpT8rPbVtHPsJAu10m78vGsgFkeAcqOqplLdRUILXzg1Ze6CeniGLF0zZqJRi81NU2FXSOJHR4K_i1jMO1S7ZPrkfzYntOLbNVtE2ibuo98oSbE1Tecdm-MBRdprqltGpf1bFdAypsoYEVSq6akCiZf60kpvbUKKMeHbqLWSqrrN2Wc0reW3N4Hk1CbMG_EpMQRrO9_xUo9dAYxHuiKqMZc6tVM2tUXFkk-euQ2bm92pny5LhULR4FiI-QyioqqH9yP0E_aui-MHc3iL9tyIoaEif-dXDHc4ec5h4CibvERJ33Q8LztgtT7PQG2ygaL5nP8Lg-V1GKTUleHVvGUZTkkyA2HPtfhCjC04d1sRwc_lu6VwGQztDVsZqHeFxUOMtLnLjlAY2AYw8HWzyCJpMZY_7lqX6QHxbUWSlrQf3LXlD6DsVyMzoXnWS_RI9BYPl4bgdNGT3WrEx-1jxiteBM_uE3MWQ4b-AdgsVO57eBaZav1rZ-RMywezNjeKzlt2Z2AJuOlVGjSLKZPQ2fZC-KRV4VICVN0CDCfyqHJb3i0kFGVpKE8jU3aiNh9nX7lk8p2Q2wMFr0qUJ1ahuAStFuODVGKe8Q1MteOQ9IflHxsBk01B_DQ5n7GJDvDHYrW_-LrjGtPLJYEVmCurT_2GYkLvkh4wK83PN7GXgGuWbGvKaoXUZCqoICrklyDKGRXKfw9L5711kVA5Nd_q7lqWbhKdNI3vHtYcEynXMHIA7M2ZzR3tKWdxaag01w3OECDfY_9T7x83beXOKrf4I0N5pgUJepVhec3vZ_WmTseOL-wjWaoJKMqFyBNDvPKjG3y_Ip3lqx_f4EY6lUsMLNGCBBswDm03XmQByqMbMxi3w8uEqrP-zIF1TqxJ3ijVc1JOCmGoxj342ewK3PFjPLIj97cK6PuPr2tjj7F3jspIryO09ODKOL9TEvoVIzcGZFNxaQx7Klt_cSrDKUXfFleeiKUNnmYK4erjtX2dXLdJ9FZT4053VQt5FBwvOAxDki-1g3J4L39OLrjOVY-auSJxMVafZY21JkMVa1mGpieC84qhBAN2hQi3hi3I3dwhkZzWM6mAOt6ZQRjbdFAey9m50BG8TXPAdE6AOq-UhHYsO0F1ztwivY6xpGs7_bSnQbN0YKjtN6bEjQJusdaCPcJNvwTfO23-kE4ZKMSm88tLkg-1ekfgRbh8m1MJOP4M5SmRQpxsy8QaIwzqbXKOsdgxIAYFqhU0yOowKy3qpmOvjrNskrU8pIcwleOwAbXQ-GKpLUyYgvLKeD2aaCbbmzIzs847HKb1uZgHUriSRtT_TMG-aD6KSrBYz_53f2VFds8WrcF-cFKBvwp2J4BWIadO2KEfZV3sGZFVo5WDzk9mVBup_Ers3GBHLvA4xfNdLyZaspIIJCYgpPHt-rSGrHfRjKFAj8tAAEwshgrBlZRQGFovGIV7AOXaKyFl17D7r9QcsUUjjfhDX3fi34KGPfpQ1BQSrHtEB39LOia__luNiFcQfycJzHQVce48yNzQ6UFcWm0plQpynSfQyfQFYUy0pK9XhrBFesY4tlwkoCN7xGliqaNo5t1YVlzbaYLhn_nDaWX-GlBMPfVXYJTpdIKnlGfZYZ2zwXJT3QwFrJYtOb23jBwKva-EnyhDHc22v-Eg7SPcNnZ1Tp00UYVWeCjIyefvDL_ARFk8WfqRZpXXfvRGEQXTTOur4pwUvDXGtHX2kAtriUwogFeMVy1SM3zx_4839xg_xLkkFO2r4QlVkmBHrEXcz0xQ_IqalAU-NywwYZwEmZDDiX8JRNLIBUyelMtwUDm-l9CctPozGaYc1CQekc5UTTRedMUEApG6S80gpTjKj-2LMze5U5pn3p8O75S5OGQ4cqw_ESZJ2vIULaE-uQDxoCR8md0Ew4vPQeAx_YhMQ4J-f1RIaoY74g\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:27:45.715Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=408421&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:28:30.404Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=903531&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:29:54.145Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=808031&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:48:03.134Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=696706&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:48:36.191Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=922668&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T13:55:16.910Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=884606&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[null,\\\"[\\\\\\\"bad4cdd7-f477-4c57-ab4d-859c93e02c37\\\\\\\",[[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA5gEfnFZblXm7Mj8uXUgFfTz2yu7q_g-ibJJ8mZG6MA1aw1a1Ja1ITOvx8Gwb1T3B3ol_PzKWUOJqgmVklIovc9ERcchFa5WoxprLuwuppaywusdkOQaY4SRJ8ttYOkSHUg4-lKYv6gGiN9JgK7C73CkzACzRgfcrC2lUWhsXjJUYtyKUdhWnlHXkUtePv2TcohLYGitxr98htg24C17PE8GLUNaAAeu0eUWDtDOhP8CfWD8v_CuVRN4isXM5ohBXxH3xWVrUXYWYW-j3c6slKLD0jnlVQNExUPhClzkNjWLJDTCSXBcf-CRTjE0iXjFN8W0DLYnTPHzF935quAhO-3JL4HVzFt1sdORfxHIVXXaSliWEhTbL_jcinTcBcdG-hdVtmx7-OHKjp4IlgLso33mUzpbrSM-tqwVCsepJvfabXqcv8tt1XQ7DvIr5LoTAVzxSkKMKjnM9pNhcO15fo5xAP7CXqY-r-uUkiyPeFZ9widHuxW8mfarY6gYNkPaOVWa-wfqG269T-RNPGxrZARXXsRZQKYNOU_EP_AJRGkleVGtplT0fjVd0_QUa2D7ftBmByprhHWuTp4Yv8CjAJOoYUvyv75_DmOX7Ubt84t8Ne6K9NDQRESj5cNjzdf8KQBjAnpJ2HkwDqZAx9_4YDtNcXfBk1kicbZurrF2y-wsEBoCoZsEwDzDnO0ljznIfsnDCi-MmcJoxfUR8NQHPmkhcDY_quzx5KGqoOK-SFNB2wclO1bbRCoNQcDIcVcar2wtDolVMCs6uuAFqCFgaupjmW7pRov4Pm5Yv9lRiBOuOQI7kXhk1Pvr8ofPP1elIIbtvkccFGOQoCKH7ncR9XGVwuHokWKQc_yjiFV4ePJ64LlIc1egTvG_yYGkt2Z0spYF3mcJLtDB5L0FKt0nKEHODLv7q5aUy8axz42O4ZDkxbqeWWRp6FP0_jUlBx-LpXNRNQB5tUjouRyO3sdJg_sdfisrZnicyoozeUQWEBMPDVjtyOKaqltSXb5Ii5z4wFAAjEq_g89mhQRupH2kJb23f6lRqWLAhT_5HgRiaka6Cif3Ya9HVD6R91MqWblK62R5q4iuC8EFcziQ5NOBmaCNzXf30-gNqV6H6RqMJhXJShmeqOUoJc_OiHkOe2pSBwe2E5IXWwupWzwZJA-h87CsoKVD1Q4BGBaRkBji5IH5stjQBaLH6Z0i_d_UFZLZrekWdxj0CTuZp3Wfm-FeHB3XNsqOeZpqmraLhApyyIFnSpxzX7MiGI_CmNm0IQS_qtYki9jmP7doyy2SMlnAs-HXJ-E3CTbIUWh7rcF2u7sjF5SRiQ8lrNF5tmbOKEn-yVULcm8wFdfwlIZPEzevmUg7n9_hLarSRuHv0aok5S57g9O5rBIsWcGjozAKezZdz6A0rkXry5xbx_u8bToN40ZIUAV_cm3YqKHbgT2gpAZK2JNT78ojzrS_HC_3VRVPM-lYD6MdCiL7ZIdgd_-GPY0bJwJ_PQbeCXOueveaeVe5EOufc_AU-BOOTpKl3VDeRmxcJ_J1-cyotpHBtS9jkWFoIFNBtENgO8prFUBlNGd7Lj4D81V32iMiwUrIVu-C2bwkKZH_MwHlV0fErPMTs8n9HPVFl4oT0kXEk194zRHzJk0f8ehtH56XSO0WwXIOvv0DWP1DO8Y3y7cCKVXYdlcjWJTa-RW98PTRWL4RvdONTt6QEZlwL2_az7oqSFtl3SXSZQ736OSNnWQ--H4rgU39jRo1K_QMooTjGoeT9WKpDpxAy77GCW7mk4E9axGf2FxfTYeMCmE_4SSb-J5a9ZAAohCkG3b8BSsXSsbALmzs6RwDeEUkIg47TSIBRj7mjfg5qnvK9V_ig-s2Q-6I7J5aCTsVNpdBRQeoucHdYFjxHHAz42omZvtEWsz_i5aTCix9hMnH9-rRFdbtgEIHbTr8dYIRpwaFfIskiZ1E9axw3OamtXkc6jYu3lzcn1YbmiT60L4FNxu1xro7bSf420HLu1WSentu5LXikIZoCJYov2ACOB4CIsaVVPXvvVyq_2pKDJv4UXFkjZc9QRPlA08mXLWsDCu1ZzqRpytWBNbyBXHCAncqA4SNKB7DsSVW6O9yqyJkRH9-mqPNfNbITkEIynUb4ajhn-m2xMCLhLLRiqhZ1N1WxOcdGatrNFGDYOL7ktAV2KYCqFQxkjrJHGz_TnaN-6aDx53ApK4qpy35_ZzJ7F-TZHN76lvv8iRBlw43vBswOBy5RnJD9cqQaQfptwcDXjGbWJBoISIYt4XHjz1IDtFaZD7tX5YMTSLwXirKvvDsuIfAwJSc2emeRH0F7iYburH--JeJbOTyFLbu0UEdu1Xg8kOeBx1AbfBf2yOv_XXcyVJLBi_d51crbfwiZ3-LVIVJAEmr5GFi_RCQj5MIRhdOYZOpHIxTLLAJ3dsN5Tu5y8lk92pjCo0juhWWKY0S05ScrBkho1A561tIuJfD_4\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:00:03.260Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=6833755015842157859&hl=vi&_reqid=616067&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5jEGkBwmXOrigHYujR0_cSl:1790168749588\"],\"f.req\":[\"[null,\\\"[\\\\\\\"59737d9a-0e57-4dd6-8c78-5785995084bb\\\\\\\",[[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA5flYkh9E3Capk_RiOA68Tr-lfcNwptXHCaUWAl0su5X415lld8LWADXP4-LHse_snGbfX7v3ptprcLT2ZtWsiOE20Khl69U6vXGdpQaUlVsKWUdhHkxGeNJ2E9UXe2sNPK9NjYih7sGoytTcO3d7WOaoaJ5Z28InHAKdg6fO5PxOwaDz0PjnlVsrz5SyqS4b37PpzBfzp7_RhuN_U6cImkDU1Y-NrJAAoUMacOVllBW6XV4LidA_j85H1IB1C2u6FNuDtseYQgL26p7F8x6pBAvWr07t2K8phzfcSWsGCnsyKR152e8ZIuxD_ZxsGDrP63IyLTOGDr_Ddd59LIYZFPGuZRn3t0lZ-Yos-lIsH1oAPbYe5mVEobmP3bC3Z63O_tL0cvXyka7U_AsIuf5jAAKFqfoKRkouSx3VBSkFqqFEh3fnQt-8aO9vkq7NW3GuRQcVIJX1cBGQgFAnNnWz8dti16rssR_LS58mWpABoPajtsINdcUeuh4BnaRwHIZKEb-k8I-BRrnvTCyi4HbhNx-aJeY__llJGM9W7NJNKAN8skLG8A_9hwGLcksgrcKv8bInwKqOFbRll12WQcAJFnJms8JJK9-18xnxSLN5I5Io_InmGDfvI1m9y8Maeel7HSKqCIJb1bXVt0WCWp7T8C6PaHiBkPMwekUCnc1YP-vXxt8mScf8J-hSSIeQDPRWOqHoKN14CCqHL0QlSGbIx8ipqn0kGYkY_uYjxo8I7ZQsR6CQZq-7SPaXo--QQDL8T5H21zg5-Znw_oq_w7OG9T2A4mCJdXv14imtzLMVB3Z9LtOW9TCWc4DOgE0LQl2VFBRYeboMVbLyLHqU6iwTQYyKr0EdKAcQLMctdWeWcW6KH2hQ_EC4fTzzlKS6-ndyu71cafvmD2CZo_f-7XFM3TqDBcT7UAKpSj_MzDR1h5KG-teYSyUDT-BbA6Cvzgu2AeAolv6xCl9teUxwIMIKFSXxu3JwNI0oWsaoNS110KBUvU3v99_P4c8vJEaYhSgylj3Kpk6J-nF3TFOoy-6MptTcRX8Wq_9SQuYAipDofikzbL4A7OAXw7iikq5ie1P3h99hvW4Ic5jwcWbbKn0ZKS-iNuKAVLuUZOiUkyzgaNAK_8eHnurPwP35KTVbJ9LgoiYUSedCwelyzaWG2dagXDczQ2ITBkAqExluDeQDx2czCJcOCd-S9vkxTd_bLtoIWklEzFsIgBWFAoK3xixZqfFUcf6PhvbAE2RDd5sKDGzNamHQ1U2k-OnFPzzYLwOOpvMSezScaAweuTqIUSM-el-KkmXekD7BPdzxPxkGEzdVALritehjjlrUiJ6_9EypT735c_fZN7891l_PwsoitgddzFzd8SHVIzHQoXn4uOL6_j7lC8v8M7xDvPzhiiolUSejiG8Zx-ncYEwxNpVfF1RiKGNts40RJBYrOhBsZtK8up65MX0dzaN-AdJ1Ji33jnjlCmk-tIQXJqQAM-qXaQGNe6CDgo7RmfNx18ujsZXJKuNCSZoQQL6POzTHMg_gZluVrEuuyIexoadXQDvDtEwbb5ZUK75G5mZ64Nga3VuJZ_gLGl05_fI0FOVPV0JcJCYpbsfM1Ufclz_kNOoWYgeKp-zVucYzZaP0RbZSb_RYYajgNSvPZ6bSQ3lSo3knjgPCE6tmDzxzEB_ewkbYggWxhxhZEz5GEPrV959rWUcXp8OVJgwj4p9unaJvWRYOJo1oOhOPrDei0GZ9NltSapTsYclLv6_wBMA9BYAtCFQIi85TnmqMVs7HFWkPxgMW-YG30Y4KfQKVJyQJN831r-6PwOw7uhPq5Z5YviOj2xdr7WyRdLBr-_r9skLSfjqwlsUJoLLSl8GefDxDRUW_TgkWCt6QRS_mWzDJBE9WEU4NbKa85fPTNN8ZbDsI8B-lPi6L4iWqZaAuruGncCvSk9TwibFX9k4TWAi73TUQ0h1fGavaiyFF4mhP3jA93XvyIx8_GEn5Seht8zmW_O4HM7fwCA5Sm4AOsWUMYltMDqqIF2iE6A60fUYyf6XvlQLJpI26HYakFG2Hnn3CEfjbpOc-UdYpKstuQDWd8qOeo2bBtRbvYPHtpy4S05J-RBaaMa-3pX54sejFloROEzjD8SdapgC5yLGccXotOM88QcVCD6x7mP1obfaBZiQB0NMVXOxEn05YG8CujRMGQb1OcfnhN2Y2SPoWzw1NCQYUlpw_IHXu4MsFI15SO7SzZnw9JdmhbBCW8oFvo5q6d2dtD6hbjw2Acv1q7s3c1SVj1bkPnURVJcxZVYV6A6DV6b0u_dAS7bSUc8ALIRMZJBtob30JW3SGWvXUEM2E8MjGPY1v1GuajC97YDh4iAsK_2_l2YPzlQef12-QbfWLuIwpv2PXaP6IIFT_IY348hDeb_MhaGzIsmQTKqDzCD-FATxcZxTkjxMgbmtul_Occyv3da49H0Tm9rdl7UsUwtu61eJh37I3B_1-m35mI2itSG6l4kChDW\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:10.006Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=o30O0e&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=75791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"o30O0e\\\",\\\"[[\\\\\\\"me\\\\\\\"],[[[\\\\\\\"person.photo\\\\\\\",\\\\\\\"person.name\\\\\\\",\\\\\\\"person.email\\\\\\\"]],null,[1,7]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:10.008Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Yizz8d&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=375791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Yizz8d\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:10.007Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=NfrxTb&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=175791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"NfrxTb\\\",\\\"[16]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:10.018Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=KV2T2d&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=475791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"KV2T2d\\\",\\\"[22]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:10.007Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=cPZSdc&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=275791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"cPZSdc\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:11.175Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=LPzVkd&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=775791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"LPzVkd\\\",\\\"[[4,8,5,6,9]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:11.178Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=qJcgMc&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1175791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"qJcgMc\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:11.174Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=HTrJv&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=675791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"HTrJv\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:11.173Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=575791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:11.176Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ngNC2&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=975791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ngNC2\\\",\\\"[\\\\\\\"tools/PINHOLE/projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:11.178Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=mrlkwd&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1275791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"mrlkwd\\\",\\\"[\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:11.177Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=tRARke&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1075791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"tRARke\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:11.176Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=875791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:11.839Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=GN0Bre&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1475791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"GN0Bre\\\",\\\"[\\\\\\\"35499362-f230-4bfa-8808-a49591ac4f2f\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:11.179Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=yBhWQ&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1375791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"yBhWQ\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:12.486Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=NfrxTb&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1575791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"NfrxTb\\\",\\\"[14]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:12.487Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ve2Lsc&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1675791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ve2Lsc\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:12.819Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1975791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"6aa915c7-1123-4e12-b75f-6d5e6d40d0fe\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:12.817Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1775791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"4630aeab-cd27-4457-96b6-24045de2504e\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:12.819Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=1875791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"9aea7396-dc22-4b69-947f-7d1dcc5c1e3c\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:13.210Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=DTaVef&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=2075791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"DTaVef\\\",\\\"[1]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:41.125Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=WuwhI&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=2175791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"WuwhI\\\",\\\"[[[\\\\\\\"PAGE_VIEW\\\\\\\",[\\\\\\\"BC356486-FBAE-40BA-B0D7-3A21166B3DF0\\\\\\\",[1790172191,118000000],null,[[\\\\\\\"IS_MOBILE\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[]]],[\\\\\\\"IS_TABLET\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[]]],[\\\\\\\"IS_DESKTOP\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[1]]],[\\\\\\\"IS_ANGULAR\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.BoolValue\\\\\\\",[1]]],[\\\\\\\"USER_AGENT\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36\\\\\\\"]]],[\\\\\\\"TOOL_NAME\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"PINHOLE\\\\\\\"]]],[\\\\\\\"URL\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"/project/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\"]]],[\\\\\\\"PROJECT_ID\\\\\\\",[\\\\\\\"type.googleapis.com/google.protobuf.StringValue\\\\\\\",[\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\"]]]],\\\\\\\"106225453,106184493,106259075,106667487,106585383,1706538,106625630,106536611,106104244,105746691,119157485,106238955,106615367,106077941,106281924,106432687,106681111,106747630,106486771,106701949,106599983,106592798,106437280,1714257,106676866,106430149,106262194,106299202,106611001,106577881,106430287,106322568,106501717,106714532,105484652,106556077,106210711,106210719,106297879,106712749,106667479,106585375,106625362,106536603,106615359,106681103,106747622,106486763,106701941,106599975,106592790,106676858,106430141,106299194,106577873,106430279,106714524,106556069,106210378,106210380\\\\\\\"]]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:38.455Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=272953&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[null,\\\"[\\\\\\\"2b8dec02-6926-4410-a220-5c9aa2676d53\\\\\\\",[[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA5bVh-WIzoehF4GiHFsSJuqitKIhlIgDOm2wGFtV6zfPBwbRqpmrJ2neqCG4GSlVAVvvLzUKRoLUO_DDRvcVxNC1BgjMGn9m2mZHNSA0capWaaGVGNacQV7R2g7PZ_iHyL7XFijhPMpwKKXyBYRKtzCC4AulukFTdM5M4BHH1mM9_Ym09G6RwzXaBaDlz1rrCAOVbrvI1cp2rVa7dkReQXSip14yLck5QwAx_jRA7O9yMJaWIsBJnox_G8zTdH1cO7vRM5U49Csrv4wGWoFherbOqhmuBvoPxC1i78Aj8bqgSyMTm9AfkZ8XfkjbAqOOwXZdy4Wp2NSzsmg9ImPAPiUh2aMm1MXWnGCa4MEUJ-FiK3M8ptwhTkRRTERy3ohOnyot1UJb11eSifv2nH7zs3xIO7SAHGNzpVtAkjAufLPqVEZiK1I-Izs56K2ttyAsx3qDde5Mmj6HZK6lYh_k1ArajHS16ZBEOw-xzzQsWLA4P3U7Des-7lwIXCtWRcNW0OdlSJ8LlSkm9mdzU-D9f3Qz45PJHnyBypnViIiS8bCdGDSV2NS_HBkcvEkCXGMfHq_rTsm7Z41RD9zap5Uf94XQ3vJdR2gMYqfOfHxKdQpc7cWaNAng_9Yqy-ZRw_NJrtBKu7ohEz08bg3QVSSCvA0GxirrXP5QumFxnmYY9NJo3n-4kNuXCpBuaeDTpX_Yzqba-DKuplEjZhz-Nm0lkXgEFbnXLHrlMTMOeDsh71_ZUHsrPGfuYnzGmOs_IY0Tfy6SdjX-CDwwnEh1B44rypG6uIH6VXWE2WCj9ISqAxueR3ellLufN4KllNmhedU95BlZX_qnIEp1D_zbiTZg1qMWDCGk9ItVeBki2JO1Q3axS-uCr2D8rWbdOGAmjvjhf4gLgB8tpnI2LKlLQYmnkTLn2a4jInFreqgjwHiYmf53nwUutmqbNcbup4DNUzgSN290BLMVqMYIhlG8YV6CiI3cx1Uthf4m10qcvVauLVAA8jN_Gl8vIf8MSnH3__dUkE3OYUqTfkJgQ9wOUjjhc-r12WMYpjuJcGoO7PBQoKR-gbixt0YMRFOAxBD2RbfOdeO7BcS5Aj1ZPLrthAT5g3N4quHV-n8PNS1MXUIgzpQPy3SHcWTpOiORRoPdWw1FwaFNzs_9LXN7SmINbx5I1zkO9g94onFPOT9b-tDeifoEt-LcTlYRIk9gy0ur5HJPsLx8MqLVCFHOTyLLug2MAerF2l9pdekZjJQuSFgPkZeDeymBpzJKKyCPYt6PROh5nIzhFkNmmvZIQPho97_3PXtxGh0q6KHwg9KYTYf1kZkXCL5ngX2mPF_Bz8a82X70RvyT8UZs7j8vqMF2J7uiaGNr9QVjG46fLZtkkXxisz2FtG65SemJYdKUWFUrI12LkNd-eV4QePQBJAJtKOhNP9Ab4W0zeiiBOh1C-towutZ-WUOfA_rPDtwqrOi4SlVICEZaj1aYgqnCoyJCJNYBNRgN4YpfB7H32vKDh5BzqCTiqpIK8Zcf0mcTSSwVzWwE9PxX6i1hZs0khj_RPAihibyB1hKH7NPfFKpicG4hLuCcUdr6K8tc55r6avDalznQpFbvoxb2skCnqJooQ5L3TW3i-RiDYS9cJSiLZBYostUTXa_CG-YjslW7uQZGDt2-lBb8J0TIpfEMPx0Tcuu6_j_YbmtL9YwshdzNVFEKBFn3p_S_csfsOauB24x18WucgbCgcWtA-x-mervGJ4NPKHWOCVctI37e2t4bCB0qgBUv6S0K6dKotBAISMeMgrSvpwxMO63t3kMmFnpxR5Di4hK1knm97zQEXlx6TtgfdRZhWRxlAKtRF_CT8BVL_4oX3GThrtl2CywyZyOBsZQGmYoWshscSiFqMjrfhOZVa9sLW2NRaiHNy7aS2UjyXjHv-c84T4h-k-JEFJf7nu9fBYhv5COn1C_KIDyfCiWhHbkEE7bRwT_VZ3hcxXyv-2Xywp6xofamKPg7jYG69AgqwDrlVHwJraIQopgD-huxuVdUkdddAVy6Nnfu0xf1r1GNEfCsjg4HIDJbTavlGf02A8TldE0cQmxN5RdQ_NV85JqXqBY18pHBMf9zxlzWt9UaW4PvBxLjnf6xw4gfsF1tu0-lyPT2mXqXzdSWXe5GVxY4nn25tDMots6Ic7UbWqDp8_QC3-4gH2FFJB0hqduM-K-iUjYYLrMqXwMNxpS7o82IoqVni4n9IpqwyEW4RS4Omo48JU4HXPaQvHKpZ0unps7BY7hnJtZo_-QnPNgvZghyjTOiReOTCDiEPZc4C6s14LKfOIBMje_2lNgHrJT6l95HCdUJAgEO0UTsMIwWchwZvEtNLa5ylSQRYj1ZmUCFrnRifh2FZWlhK3TaemJXzc2MSX9Tr_Hp3KPxc5p7TbkoA1wxoYb2ghu5LVi1Bg84UBw_9vu7riUc7rRY9tHrgvCItBFmg\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:03:47.966Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=948408&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:04:19.120Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=416254&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:06:30.541Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=321250&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[null,\\\"[\\\\\\\"58deacb7-2a78-42a2-a24c-783d71a87c2b\\\\\\\",[[[[\\\\\\\"T\u1ea1o 1 \u1ea3nh c\u1ea3nh: Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA4OM_CL4g0ACav-OQULVejqyPS_pTJF5m0KbTEAFX8_r-XwcYNBFxpFPCMrmylBHRQ76xgefqHMT6_buwlQImByoYuUmRdZVaw5xNN-CblG1CbiMJuxrkWE5no9CWLx8XZe4mW5HRIWbzO6qKHZ9Kx64VQCuX0U4v7szPr5gyXBjQr8DIxZ_3GWGH-ncxGWY8ORFu-_krnuG9mZIfxCu0j9NROrFQOmZ-TbYe_2rw_Y__xZTloORz5SJI5x_SQ-Z9ns8qX_YxP1p-PX0RT720PGqrWhp6mdk8D00Sn5s4yHJiQ8USY8giHxDWvUpZfmNLAxCj2d8OZ8pzczZwWL2E3wu5HtUQmb2u49weNBDoOKuNksRc_NY92kidNHr21FCvWjeUrqmF9916OgswBdGtv6Ar4iKYzAd0eMxEfpSaAXMOJLLe83xVEsRSEYpUhpXpNG6-1TeT87djJA1EbfPMPimvKarpUxEMSlKYO6WIjVdmm2s6tAqL0vQVzITwiKU0OBl9D0NPMjTJY8_r2jk5_YrY4BumMJJcujzVVfg1JpWC3_awZUXxyDhQ5oAO4ItQccnwUrVtSsVLZm_27MjKXSjJIGbTyPnJKHGSwah3_1rmV55Y7oGeu9tK2W2hwU9sqj-qN7MQG6AeCfRlmqc6qheQLg4EyNOb8-K_hxPlfzeRYDxywA8D7A6NhtiW0E1ijnC76UNTLDECbRijTzkP12RkdJF6ssEZFH9WkjsGdmBjvJLmSxYR4_vm1aT2P3tXsxgdbiPU2U_8kQA5H6-wSMCAKCqsUeP5t51uGzUJ0wghyhMbjH7iutNAKjbQJCF8eUdhotF0lL8ShnaR6KJs4kfpSH--hXIB--GjhHBpCGJ_umLBhoMW4fq0vrt0RF-qSO8yzbTqxiLg7PGwP5fn9b4YVXl5ub3N9nVuTzzP1_1LgRlSjXQ5ope2QJosYH3tnJw7aKiSKXp7U_3STNnUlY1r4txCM0stx_RHXlTO7ahUM0nUod7GJ3s9MM34MKoLXRCSFa8JFTder1xrk5YV5d0qVrNmvMB2_D5cCwOCKbvLFecrYck5ympEr61TRgEwa3D7Vh6HI2_hCimULdSec1RS9vukx6hHLWdjYDo5VRjCYWWTroebV3_St2FCwbOPTD2DboSzoaL4lhvcp25znE26htL3e7Q0uN0M6DmPxZPe936PRY1rphhrSER_bWK-dL0nfZZVgwIzRQFa0kjrqszopuoQx_Z1bYEeZHDqImwh_qdbOdFsBAlLFWXgRE-oIQVcEjAiGRxmHHn3z9Fh2u9mJKBclhvc7WlPRtEdwjTVfbCy0New_sQXNilYAikWhUMaEylZH4wmTQXoUel3fnzSyfJ9Qt3enIquLtNxW0cnXtSYXwf-w4K9ssgm5Ig1k-nYmtceabXUNsnDPgaPpUkZcTvvCB_7NUTp6OCuZtKz_jllatz5-e9IpPFZ0uwRyvEo6yzFP8k2ICdfrPY6_Adqv05vSAU0EOLdJMWHxXrOehyLmE6jM9YNw0dUE6MnDiZndn__2peJRMoveXqREOgbN4tdzGWvMUZIm_y9TmzWx_oM4qyNVfEMstpbZ-aSW83VibAmSpIpbchmocCRbQMFqDkj0J7jkC486TC8ExZ_NmxmyRHQKXsmYHzInJe1UJcaUYWIvgVKo4-EQTKFoTz0RILbagmxiUxTa-Tv5zyhNVt_eNOCJS4RirmWyjtadEtK4sJH21PmOWRsnqa0KFJoa6TJyHR0HrmCc89yXXFIOd9IAcDgPzif-oDWhQ7A7I3bVF_RZKvWja9zKhc5dN2MbKOUMRvWHTM4CkyIoUc39XlBqBpNI7LIxed6W9b5jKi7JMANa_pG7-Gu3_6Wo7Jj-neco0RAo1Kx9ZtNtcJxR7Xr5PwW7C7YRk2hAc76VQovhxpU35HQqVJ_H4G-cZ2kKyTOA0jV7_grhsq52x4In-i6QyCOkXhir7DuqBo6BpfvUbCVJhA8WkIgAHaM4Eb7e4Z4o-QrrSyjtG7K93ee7GKNp9qJ4uv3bWSEZFwGB8jX6Ara19-UX_xEnZcYd7qz9ZmIryWSujm-yAunLAIZViJLRYYhe9l2wA-yEXURN717u1zFkOewS0Px9r7xtlPOo6WIyPIcvVTo73e20V5WGBNF9JEKfEcX5SVczVCmsnLPl1JERndL5ScYkiRLiHSt-RVP1HT6c3mXEid4-sZPsXtZSDWJHOgX1JXt8Ujc2oQZzZM8upCD45q99sZ8qjhv0NonhJk9LUOvfZ3EJ46ZdAwust7biaHTh2Eu85S1Bjr1imk039aGyZB9NT2G2AZfX1-BSjeF_lvJHqt_nXQznsI-r6QCe_Xikyft2vDNGsZNcLqE6LuFf4UQULWlG8ET_ErUq7NMLOIZEzlRZmlVt41JEupg4dP6tSqBX3sRmQHgXp9l1quZJbejI-c2j8zFWE_M1-Tp_hewOTvPyjGYHtKomK9pU8I_3Wl_VGF2Adg1wb\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:07:16.473Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=993395&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:08:03.592Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=553839&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[null,\\\"[\\\\\\\"cd0fcbf4-b76c-48bb-b59c-41b53ed3cc75\\\\\\\",[[[[\\\\\\\"T\u1ea1o 1 \u1ea3nh c\u1ea3nh \u0110\u1ed7 Minh Kha c\u1ea7m dao ph\u1ea3n b\u1ed9i L\u00ea Qu\u1ed1c Ti\u1ebfn t\u1ea1i t\u1ea7ng h\u1ea7m B3 M\u1ec5 Tr\u00ec\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA5JIFF-7aIU0P6itAIt4ycbGhJWm4RQ1AwLLHd8z551r-F1X4-twtmuMGf48MhZmzQiG7wyNNGfwLw1i0fWDIcoTlzRfm5CQWr0al7_yRs37QkyG8UxbpsI5KeSBnIv8076ONzjgBOxugV1VpeR5wb-KCVRNiAecNtPTW81jcV9nXrx06pcATJNLtqmf95oe8HGVpC-grWtwGz3_Sz4GZrqkQkwOyMy7Za0zRMgEWLCSVY2m60Sqbi4pVEf1EhTAw6ZFJpn-QZA3jasGcx6Id6ET-gpvS4okuYbpI6CUcFHu8P4Hgvuh9pLn7mqoPHW1RrJwRsjCet3VrnwQct_Tfz4cwwfUr3E-9D9n2AL0ajsmPwpX1-gqfiOLQ2GY2lS7QxJMhg5-Jk6D1c7FTyhdWALTfosc2uG0MRG8Ff9H24COYCArtqznUqzW-mJUimRxRwrj_xyLZAic7my7DKhXXXdLbnecMFWb_T2Be3vg5CM2w52v9qYXEGKjw14gnEDi4PrjO4omgccgAgCuMoEyrzZxOkIPwEPHjLgHU8OEMVrTxUig_Zxdo2WRRHl-5n7NRL4v41MUdMLrBYbRQhOO-UGdacluiDljqJqJXlmT8QTzF8hi4MK7s4pPYe37zJPKdpohBg9YrKCyAh2d8TF0h16ss_FVUTYd7bBwmlKGNZAXE0lYYKosKHcpgnj2mFgi91eDSQJxbDgymCrPPaBHA05Ofez4mNmm6Gl3XpN6nLiUvUa0vcqfcMYGNQQhRtD083U-_MPheG6VwkqFv3m5musgc29nsdcOjcXQUEpGtZDEKR7bQ-WUIbhRcIIyyGHFkCYD6ClWHWaG0r71cPCqpde5Vwl2cfVrxRDEZFzM3QujcNrSo1cf_lWPvRe1UFSDks1xUhvMEWOGHpEGyirk6E6pPwtn2BlnMEFSZbbgZRVOARGmkOw-j-Iivl1qXg4lFbF2RkThL3V9rGgjdnD_KhU1lZKx3dynvHkMrLEzOACCXBh3k0Yy2dtbr2WNLRe4Bj8J1RBf5nFxAPAVq4vN1ANfMs5anLwv7LmG-VCMqYMcGS3QFs3nfeIcWTZGZ-p3_5NMdhlMi3Aba-HebdAd_hITuIUIJCMrE715aMT5KIWC0zmwIVyBmHBETqPn5M9KHSVp6wW95XcJ5eev_2y9Q-XX4Ua2VBn2wA74Zi7LZxoQ0gr2N8vOjmm_SDufcy9XVSDXZYoa9q48QYty0am8NP0yPWtyB4WvCQ3imaFuKLnjS-3NeA6hkjZo-czJ_iGuXLuEa4HJykrsSH7jbNs_92Ppsxmi2pDO9cRR3tzqmAFUmmLOdZDCNGz_bWMGpRDgzul07UJOyRM9AJ30OcTE_G2-qSUa5HcW009CdXybgQ-ePxLsL5LYREh9Ju03bONmCQm3dBvX2EQho-EX-tdQ0AwBhlI9wrFFwkDItRjbjO2An0MRPdkrgZY7JwBzmF0DQDwxy4JmyyKcEFFm4Lb6HgtgWxY-ek5JSnizGEN9p0ik54_IMTUWLC3mwAn-GKgAASWnbB9IGv5-7z5RXofvanoyzBDzvq8xDoE5nh52kPMxkgk0TKl7L8yWkLCZUrejyqGMXT7koLlWwHxZzalhEuXHhnV8n-xymPXQ8O_qrpeG2wI2_4GCWm-o55kcEVj7RNUx9QmyFoYjSZrnk_1oMONiyKAOZ78c1DNaabges89naSQG_LdM1_axgKC4q_6-LJm5HLBG0Klzpu9Vwgwv0PCcVMczSBM4UdV5UEG3aGns1zy0ug4_u6UkBOCgj8-oqk0xIaObML_FO1c8XZBryBFyHF43TOaR_9NC9OeTdNBpIwx5ZBRZxv2J-y9HIfSRxAwTxPBeZzElHyQN-XmDY0DuWuFT6ty2bplu34W6j5dgErbAAuUtplnSbNwtY3S83y9KeqnvAphjNZ2EGqDmSif96b2SrBtl988bVwy9HPYSeewAsc5oUNd8M7xgRr2vt3fhQQnu1VabToxjL11tIOxCT9Yb4abjpnS_JWvc4BJiUpLVBqCth_xwbMRM68m9rC5DTAagq1w_v_TxUSNOE-vmZ6z8fwmP2cqElgo5_NCkWhziWKjJg7p69NNNGFKyz9LaLdXim3Nv2xdTXwL8YyohRrwJoBMIULmrvugRkiLFP1pgeCQm7ETuQsuJsnCsxGOtoeKJ_ltJgJYUVIVHYnpiDK0VY0QE1t7qPKPnx7O4sqqCf_J0DWO1DZwgHRKw_ffbpYH9unUelai5DebS7S-Z9lPscaxN-IK-vMGSw4iiFcIB31a3O3vvc2i7TaFltFySzKdtKELD2vGPJRhLOlPt_nIoVBbyEFLQkt8mvsp_2kP81tuhx_JAB9JyQ5KMMaGK37H15OpLnX45eCfeR7NDVPzollaBpAJlf-7Vfl4Nur4XW4EcUl1FisBp0HbJ-uxrCIPFOhlw_pYMDOmUjVtuXVayA\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:14:05.382Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=291286&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:16:10.852Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=195163&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:16:28.711Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=583455&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"666bc47c-1fa1-4167-83cc-3088840b3146\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:18:57.602Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/cspreport", "method": "POST", "body": "{\"csp-report\":{\"document-uri\":\"https://flow.google.com/project/594758cc-11f5-4f92-8b3c-1213686591f4\",\"referrer\":\"\",\"violated-directive\":\"require-trusted-types-for\",\"effective-directive\":\"require-trusted-types-for\",\"original-policy\":\"require-trusted-types-for 'script';report-uri /_/AiSandboxAngularFrontend/cspreport\",\"disposition\":\"enforce\",\"blocked-uri\":\"trusted-types-sink\",\"line-number\":3,\"column-number\":39,\"status-code\":200,\"script-sample\":\"eval|document.title\"}}", "statusCode": 204} -{"ts": "2026-09-23T14:20:50.939Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/google.internal.labs.aisandbox.proto.flow.agent.v1.FlowCreationAgentService/StreamChat?bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=504978&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[null,\\\"[\\\\\\\"007b60d4-79aa-4a7f-8133-cc776c4daba7\\\\\\\",[[[[\\\\\\\"T\u1ea1o 1 \u1ea3nh c\u1ea3nh: Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]]],[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,[\\\\\\\"0cAFcWeA4nGEZrnO8gZBpTbrdZoxRQa3MOxZ7rZixFPs2pphk4EzyMN4hI1y5dUeNPRbzZqbFF4cdyWA2Mq_TNcshgQgpTHfnqtCzVCvoEeg8_xpWx7JRq280f6K4WuQrK4t4wsv8MZMhCPTus5dguh3DwdY3ohQ0yozyy4ohMmXhOKf0Bi7ULYFqZnvdvPVPN1oUOqPq5IovVd5YBoKDcv08zlmfCOAzkeS5TR2a79ojGSqH0Y_UmqtZ8Vyktf5W6g3P3IvgRlZQDC1DDl93VsOGhdTtZeCKvhcEvdhzVdcak0UhtyWfIWe12ygs6l91cz02BbZlCJhcUomHgV2WUGpuCHjCzaTHqwa4yc_JRqBsXlYVGz7xmFeI-kwK7pWAoWXjiwIxmh1oe6AZYY3TO-G7_XvthPWZjUfuWxrlCPTVv2bCA5X8JdzyXt04_FxdfVLfpmqu2afap7kwz2hitbbqIbzoxzGESMw273Gzj6SGKy0wGOGEuqqxz0wrlekYBfJvqj19ZK5kH2gDYurw-PI7uZtZQdyjHqSaRVR77pDvDxEblRE8fjuGsBOIpynyD-JRHL5k98WO-UgUxOEZsm3lHzD85DdVkRGga5i7xGlbvvTjbONTEd0dj7rtm6faW5jOdkyB1QcokQFelgoWJKqcTp1S8W2hq4Zd1_O-y-ap5JoBptpSSSoBDiUdan59gvGOJnI2wiNePY23tw_jbSwDKQiVclAe6kvKZEL_d2KdQj1_4GkwgdexEdy6-4hxDm9qqCey9hlXy1oz3tTTtkZVj_J-NnlJu0ceW6zT_8AE1C7Y_2UZFty6SZGAF2ZrYHIXQyhj2oXY7YTaLgaR4MHVILev_vbDkIYtKyFlUGCSNAZAYjX1E8BVFYFyvThSYTdf2hku3j8TKTypgvuhUTAnr3ATqHLGq3D99SRoKtE_d4S75rVY0l6746S7N60iX7_C9WodXTAmD12nPyQGWZ_Lzf2sw1Xjy7uAZwd3Tejl5oElFLsNjU_Coh64xBB7caX6bqHfpfdP9iFKef7TfqHvfTpI7gJ5_jxUDCdlW1i5_uuh-26BH3YF8or6h9wvZPGjnWLBTlR6GDOavY8Kk6E2BAOZwaVZpDa-6mKkdbmGUFX90aQ6IP6vTMwBuvxVvufaJyh3b_eLerJOPTExdV4HrOHDbK0zNvdaERbBSMMVriUk2usi9JtG54igHaCIjlWLfSDccEd5ITZSSSfpwby6dWd7gtDIw14kv8M8BcAilcDmj1857zcUJ67F3G8bJdz1sCrglsrpklQNgXBWo4Vf5O_PdgtQJfPMD7KQjeR3vHOUjJtnnU2nJEg0dlEp9t4v5qWXzVyKxGejcW_lG-t7TqPrD0X0dCWETS8FqQDUjZ9yVXXl6GvkAtjC9hezBX5uMF7a91uRQbmynJRwgOz4WahDXk0ptwb1ebourL1-TctxLYS70cizbpyy_gzTTAFwElJ9qoGj02lD2Xa7fooiRV0GVOx_x9W3TAE-4OSQLor5ShA1S1_gbhcJsedagUu2RbbnvgP-cBDHiPhoVS5Ybu6ki8gGJiaGR5YM9DCRvOCz4QhIJRhS0C7gFf0wQt5TlkN6pjsf7X60ljD5J7rqbmrGxfu-KKeVJYH5oM4xPYx3xVRRqJ4KWx1knWpvriClpyjEfYZIfmBff-KAJKqei6Ji0uklWnKBPQLv4UjVbNEzyel-4FFqwUKBYndmmdnsBnkLFRYBadE-MinCFtmVVNyHglTOeh_snre8F91mJEX2wTbHfsF18NT79HKOYGm9lSv8raHUq32FmhrFtguudID5ClWjAU_6tr1Zs5ncORI58BTI21AeVaFZP8n_nvdjc8eeoysTvZWNhCY6g6RMy4Vd5UEcy88H4m4ONXHqnTkZJT80TcXex759XlVFqa0HIzW-h-TW4a3eevRE8eVkCD1RVktewVmpUUnQK7km-epplYcCGyX21SxwspzBHOFIQLQx2ajgGZPWJ5692e_Q74YMYskjMgMeuI0DtUxDoliLaPNOULRW3dPfIbIDbmTwVKJZlsxo6hpEwr_Prhuawc4YZPre9UkvZHs2KZ9lSjkx4X2dwIOZ6BhPtCZ5FNs204J4-2OzUtqgfZiNrsWS3TFsBE-pY7kJZtvMh_uHQ5ch1bVPggQUkJ_g2Sq-tpcIYxna4g4b_J5gczpBQWaAbGcU3FrKsrj93FP5ly7vqNvlLAxq8NVMts668MK3fQh2JHvApeGhTPsVDMDdWuJ0YUBSwM3jhGLfDtzVw8UIWSHqwknnuA_us-N-EGVP2JRscrOP0zX403ZF2KO8W0TROTexq42VK3jLARnLoDumBSPvrPthnyWZi_kWRr0acoi1v4T-50vcUBA4R4XLdyJwP5nMCeC5Oa74M1pBDy5Rb7sErirCe5-gBinN7IHeIrSLYrbNkYqWfaOd6u9gNZKYU-n31NAeLsQ\\\\\\\",1],null,null,9]]\\\"]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:21:11.021Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=496170&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:21:17.378Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=269722&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:21:23.690Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=406796&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:21:29.938Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=460121&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:21:36.133Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=437058&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:21:42.662Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=241527&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:21:49.132Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=414981&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:21:55.800Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=390676&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:22:02.369Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=548750&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:22:08.571Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=786878&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:22:14.723Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=137743&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:22:20.803Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=335517&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:23:08.046Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=261476&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:23:14.303Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=989133&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:23:20.471Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=706242&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:23:26.728Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=482931&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:23:32.801Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=560648&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:23:38.871Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=643359&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:23:45.111Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=819320&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:23:51.227Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=778217&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:23:57.288Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=274919&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:24:03.387Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=200786&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:24:09.486Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=858929&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:24:15.589Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=925067&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:24:51.847Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=483820&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"a6010398-57c9-4e27-a89f-31ed0ddf2d1a\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:25:04.567Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=123865&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,null,981155251,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,\\\\\\\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\\\\\\\",\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4Nb4t5YNsBWqExumuLjLcPOdartYsNEJ7gAdmifJ_vGRKBl6qrFDkGyb4hfz1ihHPMGgDDxQCh43Gbyo_ZGp0n0O7ahTSlRqjuEA9DB_LE1pLRBeVimWmfAIsntF6KPiDQoGahdsjFeAfYOWb4TVz6jx6UUv00wTeDhW0kgBE_7phXAe7f_x8m4TI1b0tRzkujO1oF6YyKDV0XvDytIBCRZoWA6pjWC8uXv-S7avM4fqulN2InDhAmQwWmFJrXIAqG5_OZLxfPP1u6Mm3EjB4ItC46ZXXmsWQi1-7FBGXzP49VrmAogkTiuVxHgpKn6PNGda0XkTQ1YjXh5G6AG_-i_P7RnA-33OIzd6ahxfzDjmUjVdbzFN7ku3fP_9uW3kIK5BPTUo-P3UxfOJyZ2k7DO20e71n26igAG58XdwOrczq4jadOKJxiDpQQq1LmwzT-ACSXrQYpMIhdfB0O7Toz0VGbbaBNfoyCoe4I3rspd_EpevQ29sAyy9mzQOrELJ-APS370BedC_e2Zy2PBkKIxawrVBdXis8_Lzz5T5oWBM41GfjI__8IGB_R_5o1-kIUM3_6VVWGMKECvz6YTcpkhqKjjymKr1B56J0yzrFIT_mRw92h07LeYoZ7UYOw3dhm3FpeX-Buv40dQBEVGxcIa-AEu1TOxgFXn6pfnTX0SRghGRQXWJ7pX4FyxXCtYgVZcizdzWYXDsjuniGxsZ7Fseq82seP18VGtjktQhMrtvaUA8Jywa7dw8bnAr0UHUblJdFxlZjBW60pkz0pwprtrH0HawXeX8rvCG-aOS2vxu1J5sc6KrD178iUTrLp9RML3CLV17zVWle_3IDixenpnqrgCC5dQs5UtgI-G4RJDJD_JsryCt0jFM3BXurw0i8EwmyDvidM3chJyOKApEAqYJxWJwFaD0Rq55AdcoaaYIcRSLR-XKyehwBwDQG1Vn9GK0izcjAB7P6GsQlLT2xtZFVAOvHA_qQPPN0Zfv-vmsfkYeMhyF7A9sYVugAQoTcW8JjMxobhLtfSKdekwwMa3XGygfInMzWvabqLgNyb6i-we90a61cf0k1CyWlqDY4sEhcjhlom7CfkbLkXSCpr07CEhC-__O7datSqgGJo7n9jLPZzoCd0IUUvlzNl0jqzhH72CtX4gO9FA0P68Xm6M1wdJLvjEJpnLCJXKOeakjvl_cRmZ-00PvMiPvdetB0aaa6aa5TM07xoxA2UlhLtRXwhT7Dx9P2cgGs2iIeu_lV2nQKzBjBYX-zoDnMnYek0HJxzMV4EEyr7jOcULVWQGZxpfAYFbYIq_oSYMDo4AK_aAcKIRl0VY4tJWbI0GqVC7NbcIRF8RYvbHVe8Z8KDxkxVTEOIiU6pdvMEGiNCUKfVKxvQBvQrXolU4z5jMWVyUO9SmlUvO7N5xaDSb0dS52BeXIxF7LNtv9_DtmRmh7CZZ_fgeq0RHsLweC1o5_8xn04zo6uQhApKUPYuskGFmJ1ybQNSMHOhu8qc-tgH4VtQHNzF0zvJ_FiNC0TDS9pajP_LMwVo8cGcJU9KaJqRhEdFkUQEVhQuiOB3bx2vzQOR3QVTQ031iWx-JmjM-z6UqNqSvv5U0AqNAs-mLT7hq9RVpZRCqhxy95E9AaJEqqT1_d5KN57OjjdMFhAuUCIqiV8YiauH3klr8t-Dc8VBcwMvENg88UYUzGI8XgPFn-JEkJAF1rGVrtTslwe9ABql_hrMCjKBRrbBVgbVdQeUTXu8Go7yKqYuJyYxlEiGCybg8-KoTP8GxjxgPfkZPsgTKGu6t66O-K0fV_jlTHFi3qjav-j3FJ5J3ftzhg396zhn-nF3w_OFAGwMhOcgw9xqyh5kkKSusqPPAFHd0youFFiovvpoX3R0eQKYZozSxo5WqmDeFhNDAUEEeB_6gKja7Usr8N9_eo03VDgomcGkq9DqjJK1g-hk9CIB2vvPEyqkv0nmiHNROyP-y7aIuxvxlstN54GhunTSolfK2zemrxvW8udZw--p4Wvbvjwro48Bsd_23lXA1PdsHfAaaWwoWARvOynnKwjbkaZLR7-BueNwDJMic3Id-NgShRXCneEQCnvIRp6UJj3dNvd1-0BuysK_AgfrScIRynHV0pkt9Zr4chVIiP77ftwR8-uhm6RCNZmOWzaUZYt84CNiZdD1rWKsa7AtJL1-PxlTXKIhH78J7l07kAomlW9N36GffMlXIJBO-h7WgtWvRrQI7J6ZV5-55rQS0RCK483wE4SRYEMVa2rRwS7_0gnjp7hJRqrIDkZoRr4NARoSkY6BRyXzlQyAybqLQ_6mGtWkwcOY3TsDSiAOSIYVzAOtzMaFrsGnOpLtjJkBgnTmMznj8bf5IqxoT7Y6HUCut5w4lU4wV7YymJ74wNQ2Qx6WYYe5YmEdxTNcByyZxZm1mGhSFbU4_MxhWSjokj0ZreeslceA0p-pQg\\\\\\\",1]],[[[\\\\\\\"A dramatic cinematic shot of a young man in subterranean B3 basement parking at Me Tri under extreme heat, 35mm RAW photograph\\\\\\\"]]],null,null,null,null,\\\\\\\"CC144D8D-2AFB-43C4-905E-7FA24E67E8D8\\\\\\\"]],1,[null,22,null,null,\\\\\\\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\\\\\\\",\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4Nb4t5YNsBWqExumuLjLcPOdartYsNEJ7gAdmifJ_vGRKBl6qrFDkGyb4hfz1ihHPMGgDDxQCh43Gbyo_ZGp0n0O7ahTSlRqjuEA9DB_LE1pLRBeVimWmfAIsntF6KPiDQoGahdsjFeAfYOWb4TVz6jx6UUv00wTeDhW0kgBE_7phXAe7f_x8m4TI1b0tRzkujO1oF6YyKDV0XvDytIBCRZoWA6pjWC8uXv-S7avM4fqulN2InDhAmQwWmFJrXIAqG5_OZLxfPP1u6Mm3EjB4ItC46ZXXmsWQi1-7FBGXzP49VrmAogkTiuVxHgpKn6PNGda0XkTQ1YjXh5G6AG_-i_P7RnA-33OIzd6ahxfzDjmUjVdbzFN7ku3fP_9uW3kIK5BPTUo-P3UxfOJyZ2k7DO20e71n26igAG58XdwOrczq4jadOKJxiDpQQq1LmwzT-ACSXrQYpMIhdfB0O7Toz0VGbbaBNfoyCoe4I3rspd_EpevQ29sAyy9mzQOrELJ-APS370BedC_e2Zy2PBkKIxawrVBdXis8_Lzz5T5oWBM41GfjI__8IGB_R_5o1-kIUM3_6VVWGMKECvz6YTcpkhqKjjymKr1B56J0yzrFIT_mRw92h07LeYoZ7UYOw3dhm3FpeX-Buv40dQBEVGxcIa-AEu1TOxgFXn6pfnTX0SRghGRQXWJ7pX4FyxXCtYgVZcizdzWYXDsjuniGxsZ7Fseq82seP18VGtjktQhMrtvaUA8Jywa7dw8bnAr0UHUblJdFxlZjBW60pkz0pwprtrH0HawXeX8rvCG-aOS2vxu1J5sc6KrD178iUTrLp9RML3CLV17zVWle_3IDixenpnqrgCC5dQs5UtgI-G4RJDJD_JsryCt0jFM3BXurw0i8EwmyDvidM3chJyOKApEAqYJxWJwFaD0Rq55AdcoaaYIcRSLR-XKyehwBwDQG1Vn9GK0izcjAB7P6GsQlLT2xtZFVAOvHA_qQPPN0Zfv-vmsfkYeMhyF7A9sYVugAQoTcW8JjMxobhLtfSKdekwwMa3XGygfInMzWvabqLgNyb6i-we90a61cf0k1CyWlqDY4sEhcjhlom7CfkbLkXSCpr07CEhC-__O7datSqgGJo7n9jLPZzoCd0IUUvlzNl0jqzhH72CtX4gO9FA0P68Xm6M1wdJLvjEJpnLCJXKOeakjvl_cRmZ-00PvMiPvdetB0aaa6aa5TM07xoxA2UlhLtRXwhT7Dx9P2cgGs2iIeu_lV2nQKzBjBYX-zoDnMnYek0HJxzMV4EEyr7jOcULVWQGZxpfAYFbYIq_oSYMDo4AK_aAcKIRl0VY4tJWbI0GqVC7NbcIRF8RYvbHVe8Z8KDxkxVTEOIiU6pdvMEGiNCUKfVKxvQBvQrXolU4z5jMWVyUO9SmlUvO7N5xaDSb0dS52BeXIxF7LNtv9_DtmRmh7CZZ_fgeq0RHsLweC1o5_8xn04zo6uQhApKUPYuskGFmJ1ybQNSMHOhu8qc-tgH4VtQHNzF0zvJ_FiNC0TDS9pajP_LMwVo8cGcJU9KaJqRhEdFkUQEVhQuiOB3bx2vzQOR3QVTQ031iWx-JmjM-z6UqNqSvv5U0AqNAs-mLT7hq9RVpZRCqhxy95E9AaJEqqT1_d5KN57OjjdMFhAuUCIqiV8YiauH3klr8t-Dc8VBcwMvENg88UYUzGI8XgPFn-JEkJAF1rGVrtTslwe9ABql_hrMCjKBRrbBVgbVdQeUTXu8Go7yKqYuJyYxlEiGCybg8-KoTP8GxjxgPfkZPsgTKGu6t66O-K0fV_jlTHFi3qjav-j3FJ5J3ftzhg396zhn-nF3w_OFAGwMhOcgw9xqyh5kkKSusqPPAFHd0youFFiovvpoX3R0eQKYZozSxo5WqmDeFhNDAUEEeB_6gKja7Usr8N9_eo03VDgomcGkq9DqjJK1g-hk9CIB2vvPEyqkv0nmiHNROyP-y7aIuxvxlstN54GhunTSolfK2zemrxvW8udZw--p4Wvbvjwro48Bsd_23lXA1PdsHfAaaWwoWARvOynnKwjbkaZLR7-BueNwDJMic3Id-NgShRXCneEQCnvIRp6UJj3dNvd1-0BuysK_AgfrScIRynHV0pkt9Zr4chVIiP77ftwR8-uhm6RCNZmOWzaUZYt84CNiZdD1rWKsa7AtJL1-PxlTXKIhH78J7l07kAomlW9N36GffMlXIJBO-h7WgtWvRrQI7J6ZV5-55rQS0RCK483wE4SRYEMVa2rRwS7_0gnjp7hJRqrIDkZoRr4NARoSkY6BRyXzlQyAybqLQ_6mGtWkwcOY3TsDSiAOSIYVzAOtzMaFrsGnOpLtjJkBgnTmMznj8bf5IqxoT7Y6HUCut5w4lU4wV7YymJ74wNQ2Qx6WYYe5YmEdxTNcByyZxZm1mGhSFbU4_MxhWSjokj0ZreeslceA0p-pQg\\\\\\\",1]],[\\\\\\\"5DAF8A3A-3AA1-4DAA-A775-9DE5847A8407\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:29:32.624Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=DTaVef&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=2275791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"DTaVef\\\",\\\"[1]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:29:39.227Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=205840&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],220865438,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5WtHcTtDcCFMDlN6d_nyuAk_KbYNsVA6cfXDA9KO9g44J6OMISnFLfdz_yB3cUo81ooTeAMLnP4FfdBD57dQXC9R5UimxhgLrF3ut5tWytNe6Ovtp09LKRt36htUCD0HoK1uxUO5jZO1-qfr8jyJwEkw8UllQhj7XUp8uxvuZCmubTZ0ub5gHMS5XBBWO8uv9NFuII0teKsXvfKamUjULlCk_0nhsYX6RmkUTCs8MJX9bk59aMC5TMoZVxeRmJ38rtgHVgN7Nm8pUX8_5N7vr_2jxLRt97GWjWCkS77a4Bpl6d4cHer8EMpQaxZjL_S0HUp48CDAECj6P4Ul8ysb8qDPIUBfpfPJyggStwjG4Sfbn4WzRK2awiiAJ49FZV6W-gdnCETF1ZPaBdH0vASJUSL-GzOotzTfW8Em9-pnZtKpJ88djUcLQqVEY6xorPPge_hGNMaaLoSudefW1SmOO30n2kJ_Zi7nWqY1BMykU0ZVhd2rpWv4VrtKgKQ8h0xEB9QSJZ6RsIaqlXysRsIS4sxETqer0zqhAuTfflJJnGMQIRTFrezIKC6HpqLo1KW6N201dd2IiFp_3OyeRAOWADKxrVJKXOeKbp8qlqSmt-nud-pMdVrvVuI8Qz60TMlHqbQGsLoeDRq1gSnxPzkWb-v0g93Cck_5DgsYASa27RWOWmwZdLzGPd9BsFpwCI41l37WevHj536FBMkINiZYQGtIGguJqqN1GsXvnr9p7Ez8E4NLKy9I3QB_3bNB6ywMe3LHulKUen5sVpDJFHlEF2Y7peHq8y5ChxqEGMrHizNooDvrsyYWDCCZgd7z7zCXw9Slz2j-6MadttMUPd7l2QoCiWXMhUWnsfZEfWVRd8piXBGkSTJsRn3DL-oOk1EsQBjeCVxuLB4-WdcsDij5rq_78KSLEaQF91pBdnTSYRz9S9PkQxi9KkoR3hrDN0sGwy9Bz8KVXjapu_5keQfyaD-a1-8JqUpnJYMWHJJEE_sdHkjh9_XWctqmvaJtanHcWM1Brx3xu3ka89y-ckVPx6d51bIhzGvp-ThV_LoUcmblY1pmIV8W2KCdb1jSm8M9l-mCoNiRyGHtEgyUky-o3yb8PcLY50meitugLa0xnhcUKybPy6AiNQWer4go9fpVQkqTakIigXPaZgdU39mf6CrCa4wJHv-_8ShLrEsgvYnSSyaWH5MdKV3NXRprUW-Z4u_AZBo3YPD6VFxXnpJTmv7k9CwM9bW42QsHUa7KRvOfWKDJztlP00-mgEOErFAwgBHpMkh5ZmngP66CVXF_Y_9r6CcH1Z7vsBYls_MhsGdFusS6pyjo2HxmJARScmE0xyRPtOLh-rsYucLbgQ5V6y8Lvg2m44bpzZ4JaU69IjiwJzlw6pOIMCH3SZx-2JwgdUOTAm3grqQih7kr_YODpgmViiw7FQ-pUWAOq0bGl4_Oy31tzDRX_PE4PRd9978rvMOIEKvIZ7oZ2wi0YMOOUAnVU0Ay9uwOd9bCZsqSwUoNIkX9BEhjpBzZPTqi8y6F06-5jQQIqxgc8L6irmEdD5gyFmePWdHyep4hnYqizaJ3ycXYug25KbdDgSSkKAfAI1EW5dFTzRY4o1D8OwsLuyMcZyix8L4SdfmTMsGVJywz8FeISp83HGKDnRyG_YSQK_rT2fxkiLrCupHOxX1_I4OjpTWCR_UlkKW27PJLS3q-59dSqWlKU7z8RbboBR8RTy2pIny_V3wfNElZoV-mV9Gq-wogIhM6GnovMztW6gdlMGJqKnHrrgNFv2-PJjm4fOhIoi4kr2SLBhfmPAZiNB9te_3TZXyrqYg2ZgS1bqKVZLW9T6CMFQdXWzjuWVbxvn8GQ2s2g836-QBwbMz9wQkg6wWrTRtBdYFsSKnEJpzRl_xGAdez83Z4sFgERC6gbZ9mPGlsJrrxxEImWn6L6-agH48jizRk7TGR92cB0pxIu2LC5ivdQ-Lg4rsKrtr2VWqLECW1vRJOvEr-Y1tUQO9cE6gA7o4fY8wsFCHZ3g6NVaAufcYzDx5MlsGjKzP8HRZAelIEyEEdVkXJPCUVXAWVNySNht4oY0sf7qJnynpVTmLSwTJ993PSyAXzQXwW7brv8nMa2nSPLrc5mpLSSFKRwSbeOOGjBcp7NWEKGmmPWsuru4wFmcBBumCkxiauWygNPz_CzWr1okVi_nsNh0VM2nlkkepIJWn67iU3hWdpf-rSPujNEZAnMuzt6iBbcD5gFZq_nk8fU2eCUKLxqAd9yUQ0ZPtgV1MQ5hhA3T6I_Bz1FiE11zQO21cL0vKRsVSRa_B3W0s_gRFJSLWxWudKDz3yEV0TjH5wcufNwy7nJG2n9p4OAqjBoj2fe6qwHjariFYQLfCTLM-h1wPMUQn0WJR2ozmjouqMMTI_rCiJyFjw1MmcXdRNA0C_J9H4MqEG5i\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"2FDB6047-5305-498F-A2A5-405FF62A2521\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5WtHcTtDcCFMDlN6d_nyuAk_KbYNsVA6cfXDA9KO9g44J6OMISnFLfdz_yB3cUo81ooTeAMLnP4FfdBD57dQXC9R5UimxhgLrF3ut5tWytNe6Ovtp09LKRt36htUCD0HoK1uxUO5jZO1-qfr8jyJwEkw8UllQhj7XUp8uxvuZCmubTZ0ub5gHMS5XBBWO8uv9NFuII0teKsXvfKamUjULlCk_0nhsYX6RmkUTCs8MJX9bk59aMC5TMoZVxeRmJ38rtgHVgN7Nm8pUX8_5N7vr_2jxLRt97GWjWCkS77a4Bpl6d4cHer8EMpQaxZjL_S0HUp48CDAECj6P4Ul8ysb8qDPIUBfpfPJyggStwjG4Sfbn4WzRK2awiiAJ49FZV6W-gdnCETF1ZPaBdH0vASJUSL-GzOotzTfW8Em9-pnZtKpJ88djUcLQqVEY6xorPPge_hGNMaaLoSudefW1SmOO30n2kJ_Zi7nWqY1BMykU0ZVhd2rpWv4VrtKgKQ8h0xEB9QSJZ6RsIaqlXysRsIS4sxETqer0zqhAuTfflJJnGMQIRTFrezIKC6HpqLo1KW6N201dd2IiFp_3OyeRAOWADKxrVJKXOeKbp8qlqSmt-nud-pMdVrvVuI8Qz60TMlHqbQGsLoeDRq1gSnxPzkWb-v0g93Cck_5DgsYASa27RWOWmwZdLzGPd9BsFpwCI41l37WevHj536FBMkINiZYQGtIGguJqqN1GsXvnr9p7Ez8E4NLKy9I3QB_3bNB6ywMe3LHulKUen5sVpDJFHlEF2Y7peHq8y5ChxqEGMrHizNooDvrsyYWDCCZgd7z7zCXw9Slz2j-6MadttMUPd7l2QoCiWXMhUWnsfZEfWVRd8piXBGkSTJsRn3DL-oOk1EsQBjeCVxuLB4-WdcsDij5rq_78KSLEaQF91pBdnTSYRz9S9PkQxi9KkoR3hrDN0sGwy9Bz8KVXjapu_5keQfyaD-a1-8JqUpnJYMWHJJEE_sdHkjh9_XWctqmvaJtanHcWM1Brx3xu3ka89y-ckVPx6d51bIhzGvp-ThV_LoUcmblY1pmIV8W2KCdb1jSm8M9l-mCoNiRyGHtEgyUky-o3yb8PcLY50meitugLa0xnhcUKybPy6AiNQWer4go9fpVQkqTakIigXPaZgdU39mf6CrCa4wJHv-_8ShLrEsgvYnSSyaWH5MdKV3NXRprUW-Z4u_AZBo3YPD6VFxXnpJTmv7k9CwM9bW42QsHUa7KRvOfWKDJztlP00-mgEOErFAwgBHpMkh5ZmngP66CVXF_Y_9r6CcH1Z7vsBYls_MhsGdFusS6pyjo2HxmJARScmE0xyRPtOLh-rsYucLbgQ5V6y8Lvg2m44bpzZ4JaU69IjiwJzlw6pOIMCH3SZx-2JwgdUOTAm3grqQih7kr_YODpgmViiw7FQ-pUWAOq0bGl4_Oy31tzDRX_PE4PRd9978rvMOIEKvIZ7oZ2wi0YMOOUAnVU0Ay9uwOd9bCZsqSwUoNIkX9BEhjpBzZPTqi8y6F06-5jQQIqxgc8L6irmEdD5gyFmePWdHyep4hnYqizaJ3ycXYug25KbdDgSSkKAfAI1EW5dFTzRY4o1D8OwsLuyMcZyix8L4SdfmTMsGVJywz8FeISp83HGKDnRyG_YSQK_rT2fxkiLrCupHOxX1_I4OjpTWCR_UlkKW27PJLS3q-59dSqWlKU7z8RbboBR8RTy2pIny_V3wfNElZoV-mV9Gq-wogIhM6GnovMztW6gdlMGJqKnHrrgNFv2-PJjm4fOhIoi4kr2SLBhfmPAZiNB9te_3TZXyrqYg2ZgS1bqKVZLW9T6CMFQdXWzjuWVbxvn8GQ2s2g836-QBwbMz9wQkg6wWrTRtBdYFsSKnEJpzRl_xGAdez83Z4sFgERC6gbZ9mPGlsJrrxxEImWn6L6-agH48jizRk7TGR92cB0pxIu2LC5ivdQ-Lg4rsKrtr2VWqLECW1vRJOvEr-Y1tUQO9cE6gA7o4fY8wsFCHZ3g6NVaAufcYzDx5MlsGjKzP8HRZAelIEyEEdVkXJPCUVXAWVNySNht4oY0sf7qJnynpVTmLSwTJ993PSyAXzQXwW7brv8nMa2nSPLrc5mpLSSFKRwSbeOOGjBcp7NWEKGmmPWsuru4wFmcBBumCkxiauWygNPz_CzWr1okVi_nsNh0VM2nlkkepIJWn67iU3hWdpf-rSPujNEZAnMuzt6iBbcD5gFZq_nk8fU2eCUKLxqAd9yUQ0ZPtgV1MQ5hhA3T6I_Bz1FiE11zQO21cL0vKRsVSRa_B3W0s_gRFJSLWxWudKDz3yEV0TjH5wcufNwy7nJG2n9p4OAqjBoj2fe6qwHjariFYQLfCTLM-h1wPMUQn0WJR2ozmjouqMMTI_rCiJyFjw1MmcXdRNA0C_J9H4MqEG5i\\\\\\\",1]],[\\\\\\\"7CB340F6-610F-4028-A515-9AC8D33E16A1\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:30:04.275Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=763711&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],163715532,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7y5tAKFW7P63oi8gTcg4nMKrUG2meHNxQlTztEORA6cZGJBsknv2OVgtkTuEYZY80Yldih4t8uee3dG7jeKi-frdRKrk7P-rOiqqMkNkBSW_oqN3poIIwYnPsGP0qipxxZ7xbS0UlAqZog55ok1NemZLQuGMw77p__cqUt-d7ttv3BbhkdhoVAr77tHASFQOjEvEobR27gZ5qCVqmNIVmt1pndiJwXozDrwEIpq-ERzh0FfHfnGKFRVW9P5FuHD1p_bVBvkoVoahl77_k-Cv9M19YzMBNdAPrClLszOVyqQCHcdy4YVSF_O64-OGd2g22fJXSFOmvn8bt7_kTCOX_j9vHdmpFfZ-CHuNrN3enT-HwEEWx20_-aVaDKyIeTBigjoRpQeBoOGFs0cQ15euwHBXcigFDZpBxEpUIkt1iedgPGdc0mu_N8Je-gQJ5G8WImGjqdL0nm4bmCMimer4DPnlt8Vpt9om0qjhiNjOxxxnfQ4OzeH2EjcOUWgfx_-dNBVR_lvSqXDlzEC1NLiq9t4C-OXS57rnf7bykT2jBNf6vbgfHNe4xxGlWWtAWHg8_XSd9NLXTM-Sx8C0wSRPY71KAVOynL3q1dr5BPVEbqTAVOeiV94-HDaaRe4dUHo3rGkmYf96_7XkwOW1PpSVgHFBHR8PjSETWWnhA2CRm8Pt-DEaR3t9tdWU32RehwCLACdwDiGn3FLdfvaxG20Uq0eZbMqc6_cGNonhlwAd3f8fCLJXGY7FTwMENXPlld2UyS_4yDvaQE5e6T3tNUXcCaiBoszlA6Z2eIyrm3sIDKq3RsHVH666E7XZwF8BszcBfXOCBZpBoVrbLkCY2yhp09gdoKeSFQRylbjUPrC4z-YOC-4HSxjblLnr6eZQSYCHUjAcdEmI3GFeJr71KjIvAB4hwIHdmLmYgejRUSCcHnRggCQ06tlCKRs7Im6hU3_veW3shxmdMx9CzSUKmmrTJYRKuCH1eGhPAXRyjS89MwArlpkJS-ewdYJ40l-QTLuMfCkySSjR8c4rGKHczJbFDAzy-rBkZYqac6bkP6vKf98oZKyLpoeSnxCpLsqZKJFvneMSscQ4AJdWyubp42_eBIfgSEH01kUT3n1JOnJUxbiuLvT3WzDFQGoS1MZMh5OZwkBPDsrFbZU7thrK2F8sr9D6rEDaJJcn3n2KgbIrtaI_VeUVaPz7ou-yCUbqzpBs9_rk8JHod2ouUdheKazUfMJ06c_UnOluygMT2UEkeJ3y9sG1fPOJ-hWbzh3-vs43o402U7AHCXFLcEBUvmp-JmeGYZJ8r3TbcK9-nWLach73TWgUXPtD_4BEg40xzlox_NbB3IDXGMo3KsdiBwu78zqWoM4UE7pIfG--UPOp1mNae_TWo4eMh4BtDryImQU4Kiu9UbBTTmmHwEezlUoFUNSsfJJ-kTx4zXYbHQBWuaXOrYNZ4ayD0jGTdqPO4uPkEzefihfLxixXlw7RYdYj5Tlx_xe3PxGw8LOdGSgkS4p7Rk5jvgcov-3WpZiEsb_TT9aCkITj3bTv1HFIJwNnjeTYKvrl20DjZ0NNcU4CYUwFOCKUVhSxtBmF5vBYyX8SlEq6ZhX-4o0TrYT6cI8RLP4Dm4P0uLzD0ih26A6HlZ8hpjc9_FNKa-XUYxFWYUpDH92l04JfBNQVDvbWDq55DIYDGMktNTYJ7PUmPOhv_1bDBeaHxfUyWyfhHVLqBoDT0Ht30Ty1Pr4X6b5AQRN15N42pTaSavm0sDE8R0w98zmmhXUQX0h-ybLuQG1EIP3G70dqB3h1B3b7MLgWb99Zojcp7arcB3bKzSmJVopbaf9hWORDkUu-WiPG3UfkiAC-pUoRrGiGUQA76lrN2wtxSP6iqmjXHpsVGksGdEUAtMqIsbfR4pmoTpzhqOP8cMN2KMgfUE0sVMsOg3bEzbWboEGEmbCG3BcYJQ1kR_iQAGAI7HjmUmYrZEL-Rt1vSuyymADqI2oNnfzgasL53ywGTpOFxNXf5L5G8_UnVRLvC4YUEp_cotvd-_TQ6uFsUuV-SHa39POIkNUqO6PyN-VtwjuyufVlgj-gf8jbQiHA0iS_OQt6dSRzubk30R1osem2q-YHvVE-1Av-FcuTSUK5UHvkQAscuov4qJGHqPMWiNNWAAPuOAWyh3QVClfbgrHAusabQyvIXYfmp81kX1dYzdOzHX2xAtMh93fGMqNFJJ1nLhmoGAB_TmpTHsuot7xASd5nkgaYNyslgDEJPw8bADtZzPY2avePwTE70dZTvxffxjxxyLk3pQxpsdalq1CQT_SSpMX5R6CXoeM5mW6G-_Ht7Zr2WPJbjE4bmVmlBjRGuT5ZQts8bN4Dg0-4QRkjed-J3xFa7ecEXluEyjqrjodW8tllKSa9dos0zG5T3yiQSPv73lQpA4xXi99UhfKlvXQJLx\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"3BB9A74B-4C9F-42D9-A274-B3C0DA4F3F70\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7y5tAKFW7P63oi8gTcg4nMKrUG2meHNxQlTztEORA6cZGJBsknv2OVgtkTuEYZY80Yldih4t8uee3dG7jeKi-frdRKrk7P-rOiqqMkNkBSW_oqN3poIIwYnPsGP0qipxxZ7xbS0UlAqZog55ok1NemZLQuGMw77p__cqUt-d7ttv3BbhkdhoVAr77tHASFQOjEvEobR27gZ5qCVqmNIVmt1pndiJwXozDrwEIpq-ERzh0FfHfnGKFRVW9P5FuHD1p_bVBvkoVoahl77_k-Cv9M19YzMBNdAPrClLszOVyqQCHcdy4YVSF_O64-OGd2g22fJXSFOmvn8bt7_kTCOX_j9vHdmpFfZ-CHuNrN3enT-HwEEWx20_-aVaDKyIeTBigjoRpQeBoOGFs0cQ15euwHBXcigFDZpBxEpUIkt1iedgPGdc0mu_N8Je-gQJ5G8WImGjqdL0nm4bmCMimer4DPnlt8Vpt9om0qjhiNjOxxxnfQ4OzeH2EjcOUWgfx_-dNBVR_lvSqXDlzEC1NLiq9t4C-OXS57rnf7bykT2jBNf6vbgfHNe4xxGlWWtAWHg8_XSd9NLXTM-Sx8C0wSRPY71KAVOynL3q1dr5BPVEbqTAVOeiV94-HDaaRe4dUHo3rGkmYf96_7XkwOW1PpSVgHFBHR8PjSETWWnhA2CRm8Pt-DEaR3t9tdWU32RehwCLACdwDiGn3FLdfvaxG20Uq0eZbMqc6_cGNonhlwAd3f8fCLJXGY7FTwMENXPlld2UyS_4yDvaQE5e6T3tNUXcCaiBoszlA6Z2eIyrm3sIDKq3RsHVH666E7XZwF8BszcBfXOCBZpBoVrbLkCY2yhp09gdoKeSFQRylbjUPrC4z-YOC-4HSxjblLnr6eZQSYCHUjAcdEmI3GFeJr71KjIvAB4hwIHdmLmYgejRUSCcHnRggCQ06tlCKRs7Im6hU3_veW3shxmdMx9CzSUKmmrTJYRKuCH1eGhPAXRyjS89MwArlpkJS-ewdYJ40l-QTLuMfCkySSjR8c4rGKHczJbFDAzy-rBkZYqac6bkP6vKf98oZKyLpoeSnxCpLsqZKJFvneMSscQ4AJdWyubp42_eBIfgSEH01kUT3n1JOnJUxbiuLvT3WzDFQGoS1MZMh5OZwkBPDsrFbZU7thrK2F8sr9D6rEDaJJcn3n2KgbIrtaI_VeUVaPz7ou-yCUbqzpBs9_rk8JHod2ouUdheKazUfMJ06c_UnOluygMT2UEkeJ3y9sG1fPOJ-hWbzh3-vs43o402U7AHCXFLcEBUvmp-JmeGYZJ8r3TbcK9-nWLach73TWgUXPtD_4BEg40xzlox_NbB3IDXGMo3KsdiBwu78zqWoM4UE7pIfG--UPOp1mNae_TWo4eMh4BtDryImQU4Kiu9UbBTTmmHwEezlUoFUNSsfJJ-kTx4zXYbHQBWuaXOrYNZ4ayD0jGTdqPO4uPkEzefihfLxixXlw7RYdYj5Tlx_xe3PxGw8LOdGSgkS4p7Rk5jvgcov-3WpZiEsb_TT9aCkITj3bTv1HFIJwNnjeTYKvrl20DjZ0NNcU4CYUwFOCKUVhSxtBmF5vBYyX8SlEq6ZhX-4o0TrYT6cI8RLP4Dm4P0uLzD0ih26A6HlZ8hpjc9_FNKa-XUYxFWYUpDH92l04JfBNQVDvbWDq55DIYDGMktNTYJ7PUmPOhv_1bDBeaHxfUyWyfhHVLqBoDT0Ht30Ty1Pr4X6b5AQRN15N42pTaSavm0sDE8R0w98zmmhXUQX0h-ybLuQG1EIP3G70dqB3h1B3b7MLgWb99Zojcp7arcB3bKzSmJVopbaf9hWORDkUu-WiPG3UfkiAC-pUoRrGiGUQA76lrN2wtxSP6iqmjXHpsVGksGdEUAtMqIsbfR4pmoTpzhqOP8cMN2KMgfUE0sVMsOg3bEzbWboEGEmbCG3BcYJQ1kR_iQAGAI7HjmUmYrZEL-Rt1vSuyymADqI2oNnfzgasL53ywGTpOFxNXf5L5G8_UnVRLvC4YUEp_cotvd-_TQ6uFsUuV-SHa39POIkNUqO6PyN-VtwjuyufVlgj-gf8jbQiHA0iS_OQt6dSRzubk30R1osem2q-YHvVE-1Av-FcuTSUK5UHvkQAscuov4qJGHqPMWiNNWAAPuOAWyh3QVClfbgrHAusabQyvIXYfmp81kX1dYzdOzHX2xAtMh93fGMqNFJJ1nLhmoGAB_TmpTHsuot7xASd5nkgaYNyslgDEJPw8bADtZzPY2avePwTE70dZTvxffxjxxyLk3pQxpsdalq1CQT_SSpMX5R6CXoeM5mW6G-_Ht7Zr2WPJbjE4bmVmlBjRGuT5ZQts8bN4Dg0-4QRkjed-J3xFa7ecEXluEyjqrjodW8tllKSa9dos0zG5T3yiQSPv73lQpA4xXi99UhfKlvXQJLx\\\\\\\",1]],[\\\\\\\"BFEB80D1-0767-4C98-B0B9-D1C7AF03778B\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:30:29.353Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=843390&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],645974132,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7TPwwSQ7nAoqHNGRlqWyJwQh9SpqyU0vufUYvJ8kxdbZ9Z98AZS8d9M-HPAzsOd0aohP0w7IRNFuPot5HgcTonjQseWxLEejWglHd5TyDEcg7bHz0vlH6CM8-MosTGBjVXJQOupDkG2mRWQw5-McQt_9EYvNv1qbrtyUcg4UU8OggY-qzH06pH3Gsqz7jIs_60LLF54dw9-ea92JDTtce0u1YV3sxWnAzZj2Ude0g0GMNBYBRY5FTOgQsDbgWX3ekqXOg-MLmwH48HYPrM1diz07_RmQcOGeaK2lThLJu66NApCqER5inz4ujiE99SmTEXESXgXQIXEtXdWNMYY4Ba4xvkr-D9MwLaqLQxSau9zOsEBsMF_mTxm8NjK2MNvqGVCwGCB44OyfCAzkesaDlKdOtHLapv4TeYG_30_Ms3Q6DS30neMyJhl4gnbcWQaO0I1CDR2RPhujsvGOmv5OMaArR5j9IBhnfADP_W8WLuMuZx7ZyEVobu8FZ2QV8AJkmtloCsplCwe_I5Oe5dUEkeOLdETYThk9R8Ife5nq8rdAOWs7Da8vGUu0vSYJUqzsA1ncNyaX_2u-LtOma-2_oHsIXYgqPVm5wP4LIx02_O-Y3EdRwPUgmyB8VYFl0dMQIWmmrkX9aBQPLesV16QCJnLQr7F00YX1oyb0crXlnbHD6d6r9KVeFL-opTGpDc0Q6oP3_AZPXw-1v3rMpnxzvUM_q7bmonsP4nLzsKXYHIkzUY-BqcY9RsqYtGiayzJv7Nvyt8I_mmCapkQlRLQAkJPO6-sGvkhh0ETAH8sxDteUpl7m10w8nWZ86ofA-OnNzGGOGDWXI9bsmah2uDlyKVFzwOMtkvVdvvcgD89ZHWvrqgOEp-oykiOnAmmCikyap8OMULsAKGiN52EL-ZM5OWrLejCY-xutinKm28vrIA7toAy08S3wdbFjjNyTFADpJqZdeV0NoLVePoR4sRm-6yF0egNgnTJNq8EZaTDT010UAsYk16GCV9olVHoRqn8hM1KB1E8JRfY18KoFtLVpCxl50BmWHyp1D8D6umCnmb2MFnHB33AcBsDxHyN8kTq8TGwp3l7aWcdIuMQCj4BTW_Wcqz_T9wa498vejEj0ge_GAfEQVcwW7ime5E0vLNDHLq0ba4i45W0SKmfBo422cbq4E61WGzoJFGS_X7hu77q5Cy3IF8H8uWZOmy98yBgzaBJ6dVv_Qj2EyYgfp0bNgoAAISeSnhFPbYQaRQnotKamzEAuasZYN-e-6AylUIAgRVrFyIXQYMFpKSRThLi0mwvGWZoLnN6Fxr28apHp1r9mykMcbwsWF_lJzHyAgbNcobF4bla90ivK199VTUA1wPRMRlcPlJsDHIdcZg8OChvewRpTM8RbqmLQnVxjoZ9S3GNvukQdyyta7qTrGEUFjnniZ5xj0WzgRP4dBV3dh3O3X_mJM892ARBm554wZXU7THtT7fr4Fx-sX1xbQW-yUSTQyBQGepnKzU-TJ3NwL_eac5pkitqvOLmSkKDH1-G_GNVvksehkegBiSDPnjNvfdxwYdOdHDvhy37pW110yE6CLPOfXI4hwjoP76emQjVZ9mbsI9Q3ZPTy6bktyaBsvhA8_T0qaWBPPsdqG45Y18jVLI1E_1VjxcnJd-NfcLzdv1x6j1rLqHPy77sYkAnb3I8ZIrLSH8NznlK_eJqhhOTACWwExcqVdS1hpow1qpgRC9FhPe3OrWChd0MLJdE_6_ebeIqMhRWg1KJj7UXalmtwzfpi2dGhFT8mIYT4wndr1OXCjno1MDPsdroBDhwBxJsNjn5tZn2aRYNunDmWQdUKvm8b4WY-755DERXnb3cYXGfWh7Wr4utaENXgv68JQcTEfYhbnWMyku729YhYIiM-2IibQpA-7Vzc4ne70qnSi1sP-YA5Rdjhj_uqKHKERf4wJsWsG62DqMdNXAl97apsFfO3A2s7ED8Mxlgm1VdykCH8lWWj08viAyFulJgcLTJzWQWCIoni5tavqSlZ7OxfRkaDyoH1n6Qm8Zim9nsGI_yIG1pN9vJJ1TPsfIEP6GBMt6wvIy2o09q9dffBjKbSxitnhHtggrT4HBqWb7Hg_WpFVcPVdg69QJp_dHSBmSBULB2Z2r5jteVEc8D1PTb705KU49undkrOU02fuW5rlpPDBl8TNx6hnJrn2yKKezCmA1Ay55hQWMcAZ6VDlm-mtVNyQuxE0xN4mwWIeIQr6aUQIs13VFg3EY6Y0djfrC8PrG06YBpKc3FL289E64-H4cCdv5894xmFO6l2zZ4oyQmW-SBLzujqSJ_6I5vEkSOCUUAsHJ5zEKY5-PUh1ru20Y0GwYgadGzgcFNRAtxqRj45xO1JEiRPv0b2qbVNYfrNt4bAIZU-Ppn6Rykk33ktc9RngUMlRNe9FSLkcszeLK63xAnEU1DWm3NMELBpmHrtfdIg\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"C1BC702C-E7C4-4F57-868A-53AE460909BF\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7TPwwSQ7nAoqHNGRlqWyJwQh9SpqyU0vufUYvJ8kxdbZ9Z98AZS8d9M-HPAzsOd0aohP0w7IRNFuPot5HgcTonjQseWxLEejWglHd5TyDEcg7bHz0vlH6CM8-MosTGBjVXJQOupDkG2mRWQw5-McQt_9EYvNv1qbrtyUcg4UU8OggY-qzH06pH3Gsqz7jIs_60LLF54dw9-ea92JDTtce0u1YV3sxWnAzZj2Ude0g0GMNBYBRY5FTOgQsDbgWX3ekqXOg-MLmwH48HYPrM1diz07_RmQcOGeaK2lThLJu66NApCqER5inz4ujiE99SmTEXESXgXQIXEtXdWNMYY4Ba4xvkr-D9MwLaqLQxSau9zOsEBsMF_mTxm8NjK2MNvqGVCwGCB44OyfCAzkesaDlKdOtHLapv4TeYG_30_Ms3Q6DS30neMyJhl4gnbcWQaO0I1CDR2RPhujsvGOmv5OMaArR5j9IBhnfADP_W8WLuMuZx7ZyEVobu8FZ2QV8AJkmtloCsplCwe_I5Oe5dUEkeOLdETYThk9R8Ife5nq8rdAOWs7Da8vGUu0vSYJUqzsA1ncNyaX_2u-LtOma-2_oHsIXYgqPVm5wP4LIx02_O-Y3EdRwPUgmyB8VYFl0dMQIWmmrkX9aBQPLesV16QCJnLQr7F00YX1oyb0crXlnbHD6d6r9KVeFL-opTGpDc0Q6oP3_AZPXw-1v3rMpnxzvUM_q7bmonsP4nLzsKXYHIkzUY-BqcY9RsqYtGiayzJv7Nvyt8I_mmCapkQlRLQAkJPO6-sGvkhh0ETAH8sxDteUpl7m10w8nWZ86ofA-OnNzGGOGDWXI9bsmah2uDlyKVFzwOMtkvVdvvcgD89ZHWvrqgOEp-oykiOnAmmCikyap8OMULsAKGiN52EL-ZM5OWrLejCY-xutinKm28vrIA7toAy08S3wdbFjjNyTFADpJqZdeV0NoLVePoR4sRm-6yF0egNgnTJNq8EZaTDT010UAsYk16GCV9olVHoRqn8hM1KB1E8JRfY18KoFtLVpCxl50BmWHyp1D8D6umCnmb2MFnHB33AcBsDxHyN8kTq8TGwp3l7aWcdIuMQCj4BTW_Wcqz_T9wa498vejEj0ge_GAfEQVcwW7ime5E0vLNDHLq0ba4i45W0SKmfBo422cbq4E61WGzoJFGS_X7hu77q5Cy3IF8H8uWZOmy98yBgzaBJ6dVv_Qj2EyYgfp0bNgoAAISeSnhFPbYQaRQnotKamzEAuasZYN-e-6AylUIAgRVrFyIXQYMFpKSRThLi0mwvGWZoLnN6Fxr28apHp1r9mykMcbwsWF_lJzHyAgbNcobF4bla90ivK199VTUA1wPRMRlcPlJsDHIdcZg8OChvewRpTM8RbqmLQnVxjoZ9S3GNvukQdyyta7qTrGEUFjnniZ5xj0WzgRP4dBV3dh3O3X_mJM892ARBm554wZXU7THtT7fr4Fx-sX1xbQW-yUSTQyBQGepnKzU-TJ3NwL_eac5pkitqvOLmSkKDH1-G_GNVvksehkegBiSDPnjNvfdxwYdOdHDvhy37pW110yE6CLPOfXI4hwjoP76emQjVZ9mbsI9Q3ZPTy6bktyaBsvhA8_T0qaWBPPsdqG45Y18jVLI1E_1VjxcnJd-NfcLzdv1x6j1rLqHPy77sYkAnb3I8ZIrLSH8NznlK_eJqhhOTACWwExcqVdS1hpow1qpgRC9FhPe3OrWChd0MLJdE_6_ebeIqMhRWg1KJj7UXalmtwzfpi2dGhFT8mIYT4wndr1OXCjno1MDPsdroBDhwBxJsNjn5tZn2aRYNunDmWQdUKvm8b4WY-755DERXnb3cYXGfWh7Wr4utaENXgv68JQcTEfYhbnWMyku729YhYIiM-2IibQpA-7Vzc4ne70qnSi1sP-YA5Rdjhj_uqKHKERf4wJsWsG62DqMdNXAl97apsFfO3A2s7ED8Mxlgm1VdykCH8lWWj08viAyFulJgcLTJzWQWCIoni5tavqSlZ7OxfRkaDyoH1n6Qm8Zim9nsGI_yIG1pN9vJJ1TPsfIEP6GBMt6wvIy2o09q9dffBjKbSxitnhHtggrT4HBqWb7Hg_WpFVcPVdg69QJp_dHSBmSBULB2Z2r5jteVEc8D1PTb705KU49undkrOU02fuW5rlpPDBl8TNx6hnJrn2yKKezCmA1Ay55hQWMcAZ6VDlm-mtVNyQuxE0xN4mwWIeIQr6aUQIs13VFg3EY6Y0djfrC8PrG06YBpKc3FL289E64-H4cCdv5894xmFO6l2zZ4oyQmW-SBLzujqSJ_6I5vEkSOCUUAsHJ5zEKY5-PUh1ru20Y0GwYgadGzgcFNRAtxqRj45xO1JEiRPv0b2qbVNYfrNt4bAIZU-Ppn6Rykk33ktc9RngUMlRNe9FSLkcszeLK63xAnEU1DWm3NMELBpmHrtfdIg\\\\\\\",1]],[\\\\\\\"30C8F3F6-532D-44B7-A99D-AF63A49DCEB9\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:30:54.356Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=501992&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],988425786,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA60etiU9ZtZTl0i6mPqFxAnzpKxqYkLtajfBL-dq70binKLvkfdfsoxUYQGRPrLO0fsdktiRtGV2bfKgoJYL5400onzr-CkVMycBoGFYM55QNo7tvqxyvTapBrlyRnST3DMGutHqmA9I_8wuTp5A4oBGTIYirChByFN_vMOyW7r0U33mvMO9gIpXzqoalWZXnsjbl3-3W5QIWlP5tRHnSSn9C3oS2Vni7sHDVNPmVfNomHHo9A2L5PcdAQzepEqzjd0AQiWSeASz4ANfeS3mk2_U0Uu6WfcHSAFEfC4TAb5V8G8FxePymKLkRmiZgk6HGXMyQsjlkAUAyOjp5gn27vBC6TXax558AzKjp2WT1w-8FMKfzhGtNACC1qEWSgDKAln7sR8WMhfa6QTfIb4a6DY9m-4MCPBYHvXBCKXC0v8zt4cA6sN2MkChfu9LHMuSV-Sb-r5y75WZOcugro78iPKEYDYTBYFwLd6ARb8mI9fl8fRtb-dY8U2erNd32q6aq1dRhW3no9pSwRDdMubLPQDz64YaAzejLIBFjKqfb47_1-ugsU4VisfVFT2HhYn0t-zEYWGP5h4dFLWo0z9TlpXa0RrhRW7WChJLQ9zv4FW3Bu8qXHimRnSIf8oFx3LglNZTHahnl7RS2Jm_MVySAyRmwtD594Crf93htOq2NZG8tqBS-Jwcl9uO-PMDm7T-Pq_iBSB6oJ1hUGLt0ny693MHiNrD5FkadzsiKHQHOc6rXQuThhnhhfdksu0xCQcTRgt2bUo3L5s6onkqzlJuaqOYkPcHecFh4T9U4E-YyEzVfKYmAjhRWvj3KioJhxtl-nS-u3ZdTiW_YwJBejIRRsgJH0vm2WCPbbfSPrag9XgbMoIwVlCy8hRPSQPBeF92FwLMrYFjIgl22proAew87T3xClPdTpjQkgvwJpLomoI1bG-FiRUO0qCOk_cc5C-s-UR8VEb9s4rhQEiDiDbdOfRzng5Fm8yDcf9Lfj_8IIssBTxXBZJIL_H0xIVGmZvHhcyi71xDgEhf7TtkQoL5r3-ZEe94ngJypTmoxGDDOBaqDYp_fU6PNWTLVVQFarqLyngVAnKTHbWgXzbokx063ZieCFKx6I0E5zz1r1MW5iRbu4-yV6FOZmCYrwO9m18jSaO8Djv85pdaQPVFxAJhDOYl_D1tXtDh5LeixZWy39sbpmIQpNmkaC2m33PLmPK-TSBBPGHqfCGzYz7UfkAHXlUS_cE4TiHgEOSUTc4yCppUSPKLhqhJw1uDku5R7xzJEqzqTwNIRVP6-8cjTDUWgzB-ppHGEoilsp51y-KRSaLUU-BVV_nB7ls7yoTxCJxlSVUlWNtUFvJLnmEDD7v38nTZawKuaBDuAUp2Ef83nNpN-ffZb3p2zlkujdm-ZHSswQUxkkysj8WGdzl_X029du_rEhFbrCTbk1r6R7MPEteJAWdctTtlLWksDNmzjSuucs6bveUue3S09JOYfRvoS1RC0WGGrDQjdjSyuVy2PmLIj2BTrnFRfPzpt4WoaDdj0hisGKtQnCdKNxF6agnbQ7zpMS3raxuU-PZ5xwpu87zDzu_mkTRGpM44BWGJckgCK6u6wD8itZ6ALZeOEydFlW73_xwxwcg4L8neajXWkuCUhj2er-_Sm5C4Df3ZaxkDQ781ZhzltFrJHZ2pReJHdeV6xvrZXgd6TXI-PZ7VrZbyswlRSgF3UHRReryr7qAnjBmLFyCwsfloXG20VTfwXav1aPpUC1S6eFBonBXuRi90PP6JH02e2mA1VGQ-AytMvb6aLL5L_2xu058v5KnOVxQo5x3-t6U_gFdNNdY6kZ_811JMQDZOw3ZDemKVI7MLgKW2P6RttUtSkj0zS_2WpuRvIIq5l75taYYU2AD_-2gk4PjZE2jEclV0lez4G125VWKoquWNr3DVmu53ERBbD1giRXs7FxyZs9OX0eo7DFfYxabmDkILe1CFoOi5oA49hmJUK4kKJJVIcmG4ccgpZe_mwi9fI9TwynV2meg9SIvUYlyuoTzO1FFataO2aWck1X2Al2UtR3nJFBYa26IJg-z4gi1Czl1hWNUKJ2_q33zUyh0hRPczJw3Q0C2bYg9y56DALLr_KPw_86mzZdkmQDTGZGEA2ZF79q7b2P2DfGtUoKQEtz10Ns3JLQNMpsJiskFmd3pvgI9AVeBg9GsElJ8xLDmPU9J5x2U8f8n-2FOXyHBZpPtNjqIz1m3WikdRoAd4kHZxoHxcH47qHUQE8XeX3M1FvW7yIV7L936P7ju4_E4fH2wkO_LWn2wihLeGsKympBdkcxdajVBJlAFV1MXIGaiA0yJuwl-neaxxUiB3bAct-03TqnJ1uNqf_PI2l2A06BG7x3WfKJ6YdUJUDuvsRUKx4WNotsr0pmTymXkSIpG-yqV2woh2ZbwaEdCKwWNmBuU\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"E184DD5F-485B-4655-9F2D-9EF01463550F\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA60etiU9ZtZTl0i6mPqFxAnzpKxqYkLtajfBL-dq70binKLvkfdfsoxUYQGRPrLO0fsdktiRtGV2bfKgoJYL5400onzr-CkVMycBoGFYM55QNo7tvqxyvTapBrlyRnST3DMGutHqmA9I_8wuTp5A4oBGTIYirChByFN_vMOyW7r0U33mvMO9gIpXzqoalWZXnsjbl3-3W5QIWlP5tRHnSSn9C3oS2Vni7sHDVNPmVfNomHHo9A2L5PcdAQzepEqzjd0AQiWSeASz4ANfeS3mk2_U0Uu6WfcHSAFEfC4TAb5V8G8FxePymKLkRmiZgk6HGXMyQsjlkAUAyOjp5gn27vBC6TXax558AzKjp2WT1w-8FMKfzhGtNACC1qEWSgDKAln7sR8WMhfa6QTfIb4a6DY9m-4MCPBYHvXBCKXC0v8zt4cA6sN2MkChfu9LHMuSV-Sb-r5y75WZOcugro78iPKEYDYTBYFwLd6ARb8mI9fl8fRtb-dY8U2erNd32q6aq1dRhW3no9pSwRDdMubLPQDz64YaAzejLIBFjKqfb47_1-ugsU4VisfVFT2HhYn0t-zEYWGP5h4dFLWo0z9TlpXa0RrhRW7WChJLQ9zv4FW3Bu8qXHimRnSIf8oFx3LglNZTHahnl7RS2Jm_MVySAyRmwtD594Crf93htOq2NZG8tqBS-Jwcl9uO-PMDm7T-Pq_iBSB6oJ1hUGLt0ny693MHiNrD5FkadzsiKHQHOc6rXQuThhnhhfdksu0xCQcTRgt2bUo3L5s6onkqzlJuaqOYkPcHecFh4T9U4E-YyEzVfKYmAjhRWvj3KioJhxtl-nS-u3ZdTiW_YwJBejIRRsgJH0vm2WCPbbfSPrag9XgbMoIwVlCy8hRPSQPBeF92FwLMrYFjIgl22proAew87T3xClPdTpjQkgvwJpLomoI1bG-FiRUO0qCOk_cc5C-s-UR8VEb9s4rhQEiDiDbdOfRzng5Fm8yDcf9Lfj_8IIssBTxXBZJIL_H0xIVGmZvHhcyi71xDgEhf7TtkQoL5r3-ZEe94ngJypTmoxGDDOBaqDYp_fU6PNWTLVVQFarqLyngVAnKTHbWgXzbokx063ZieCFKx6I0E5zz1r1MW5iRbu4-yV6FOZmCYrwO9m18jSaO8Djv85pdaQPVFxAJhDOYl_D1tXtDh5LeixZWy39sbpmIQpNmkaC2m33PLmPK-TSBBPGHqfCGzYz7UfkAHXlUS_cE4TiHgEOSUTc4yCppUSPKLhqhJw1uDku5R7xzJEqzqTwNIRVP6-8cjTDUWgzB-ppHGEoilsp51y-KRSaLUU-BVV_nB7ls7yoTxCJxlSVUlWNtUFvJLnmEDD7v38nTZawKuaBDuAUp2Ef83nNpN-ffZb3p2zlkujdm-ZHSswQUxkkysj8WGdzl_X029du_rEhFbrCTbk1r6R7MPEteJAWdctTtlLWksDNmzjSuucs6bveUue3S09JOYfRvoS1RC0WGGrDQjdjSyuVy2PmLIj2BTrnFRfPzpt4WoaDdj0hisGKtQnCdKNxF6agnbQ7zpMS3raxuU-PZ5xwpu87zDzu_mkTRGpM44BWGJckgCK6u6wD8itZ6ALZeOEydFlW73_xwxwcg4L8neajXWkuCUhj2er-_Sm5C4Df3ZaxkDQ781ZhzltFrJHZ2pReJHdeV6xvrZXgd6TXI-PZ7VrZbyswlRSgF3UHRReryr7qAnjBmLFyCwsfloXG20VTfwXav1aPpUC1S6eFBonBXuRi90PP6JH02e2mA1VGQ-AytMvb6aLL5L_2xu058v5KnOVxQo5x3-t6U_gFdNNdY6kZ_811JMQDZOw3ZDemKVI7MLgKW2P6RttUtSkj0zS_2WpuRvIIq5l75taYYU2AD_-2gk4PjZE2jEclV0lez4G125VWKoquWNr3DVmu53ERBbD1giRXs7FxyZs9OX0eo7DFfYxabmDkILe1CFoOi5oA49hmJUK4kKJJVIcmG4ccgpZe_mwi9fI9TwynV2meg9SIvUYlyuoTzO1FFataO2aWck1X2Al2UtR3nJFBYa26IJg-z4gi1Czl1hWNUKJ2_q33zUyh0hRPczJw3Q0C2bYg9y56DALLr_KPw_86mzZdkmQDTGZGEA2ZF79q7b2P2DfGtUoKQEtz10Ns3JLQNMpsJiskFmd3pvgI9AVeBg9GsElJ8xLDmPU9J5x2U8f8n-2FOXyHBZpPtNjqIz1m3WikdRoAd4kHZxoHxcH47qHUQE8XeX3M1FvW7yIV7L936P7ju4_E4fH2wkO_LWn2wihLeGsKympBdkcxdajVBJlAFV1MXIGaiA0yJuwl-neaxxUiB3bAct-03TqnJ1uNqf_PI2l2A06BG7x3WfKJ6YdUJUDuvsRUKx4WNotsr0pmTymXkSIpG-yqV2woh2ZbwaEdCKwWNmBuU\\\\\\\",1]],[\\\\\\\"9ACC2134-04F4-4C95-87D5-9972DE9B9D77\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:31:24.410Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=957684&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],19345599,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6E4n3kJ1_ax7NDOtPH7wSVV-z9DsKYLfm9aALzD8vcGseY4YWM_h9OQGdXVoMqz8Q-lrbb_rUlIncYjjQ3sO8qDiZeyNyv7D10UBnhWF7PoTYlFqHjXAJiXk8mDNnLkUSHDiXqNXq9jqpZOLseOtTjr3he9TM7ORA55opAX-ccUHKxa0cvPiRwP3so51319KTQLT4WFkJgji984TWPWBrkkzxMXuQuzvoUzyNGOkVCANiCsxBDtMmnQYJri9lZ5ZI167iQvDBaDS0nXkWFA0jxg4fXyanWInDYbix2iw49R1WSQRyKzewisDl4Col_VY6RwojaoS1izb2_LJxKYnKj26G8zDrPhixSizmsfkvulq4ySxeoELS0UiQU4kuuMqnq6qVjiULE-MfuHdKdwIhQtyjxd_IUjCRipycKp2RULkbuzJ6QFeSYFLBlkXv8GXVWVxvZf9l64dbM_okk0Ecpod-du2ftxaTOczGUtPC_uGSdv_ojpJRmM9Oz8DP1baVug_ZNpTsf1wsJPcEb1ApL9Yn_xtVo_Ct15zkAos__uhXMLh1QY9kf6nsjrwLJgVhI9XiDEphSOc39gpJhmdEUlAErQaFrhX7JOwE1uoya2J21aCZC7ANdpftltSh-GUQpkHQqE2qltd1VN1ZoxEVaw81AmdHvMbDELM9IbVFoj7U20LgLXL7GKOW7qo4H3C2raW6RqjumnOLcZX3GchAoOlVJY1e8cOtGYx2wa2E6DJ8TmS1aZU3JhGfVkFJcsNPfHoAo89QzETPIEBbN-YYdjOsjXhGG46UV7ikbtJpQWI9-bKoigwji_DywFQFZSag3cdZ9YPLmqd5HmbGP-gxlOQhEJAQEMeQQlAVHKhM9gJTaIG2DZk98Jduzes0Mfnq1J_H6HNSErwYvBl2_D44OU6Ua_nEOeXTZY-0ADSh7fPB9dW3w8YxH-Fx1s_HBUYFS2jvf6inDypTnOmJ3YsAxJSHIUqiydcqPcBcaOUD8aCbG-OPf3JMWGj42E8ACyURbv9BsL1LOMCEHQW1h-C6MH2okFgxV1HZuYUcBApDEjkxM_3FrcTqDT1EwDbIhEi-13mZEBf_Gl77VhB8OEFIBgjHUxaFhL80wS5zmGPXG_eC-0Aen4scvNOUDas1LDUZZbwVwpFw_8781FyZA-sNVyg5KcxrFm3JecVmp_Iv3VNtGMF_gwT9HhGq7kBOgNp854OeXN9fOMMl-aVVPGfQmCqTBnx4l8mwNNSX715FTdS0jbp3L1v2hQo3spZmQ4kTLh8KoBS_Z4nVgeuOO46WpxmG805k5n2o3hweA_AZjiKJ1SbpNO3bt6wtANM1X5gQQSg9WdjqybwOzbJLXySc5mgF2STCPLi_jPeUEuBbfmf2crPwQZWcmb_ZlvWCNK4RSifLrI-FomNS3P1SWk1xTtC8t9l5t5VAEFD3WHvMQ91JWE7yxcEw_l8RkxKPFvkF7xawyd7cKL0zhO6TGP1g7hNk8RrFPAEODSlMB_BE80W4O6-gKfxXqW6sfrdhnnxbWxNG_v_dsk9pVOrJgo-9_sx73dt1Ih86XBte_70TC9zkaJBKwgh998f5FIhg-OAyTv-U6aRepb5Z9nqaR8cj_H2N3EyxzAUoCCN_YX1KejouZ0Ddi2POv7y-loowZz3FVNGItk3e5z3sEHzop4eVBZ11KfW-U4Lm_1oMbtmXJs3IsYksb34UvJsd0dJHsQ_fVz2PnqFZvhlv6xSxunGD7PMV-cmfSVq0NawSORBjAmbK7La8nvv59YQDUP6E74PqY0fezt3VRyWDFG_SgOvWSnSXKMtR_Gne1IEE9_2ORCfLdg_Kj8z0R1-YMDj3r-5M_nddZcJ3WRTYQ_MbDxOxGQL7qNshibKwy4hD9hxMued3PBveLAY32VjmMyIlW9m2nG7L-dPEhX5_TUzsGbRDPTwh5wqWMzsgr1fP9dl9DdgR3ZThugFilORENZy0OEHAkWfU9r6JJfsjbB84zHiDlxLtwN49E2EaXbF3CNytRdRw9kDC-6J49tshpUhzg_x0IZs0A8D0xxTirfmM9Iuu6ROdECGOnC_NOj2l4GbMh41rW9hDlmzH4x74tVeF-77NOIeWcr8kdBhn-_ywxCM5ePzQOpYcBo4ydBv6v7-LPVIreZdXG37Txy1-tF9mmKi75FbOH7Z4jxWfdR27uPq6F6-71OwpmMPmJ6O4nKhYMWzDOQAEhWbkhtp3ooSgD1rb1QYhu3g_xS4RIQX2Sso09-Q0WtsS4btH6dSw5IwRNutgzHTlJY1p6PjnpKq-5hCn_t-aDjLtenra7mGLDDU3YXptEdi4Xfz8wLZuvx0o185GesDD9ZFGIUni2ePJ5cTl1pUJN01kknJpY6IoL69U_KVTY_8IyBUpSmCLIXzSfI1QpzmksjxwKJ1ii-xPFFyAJOHmEpTw8f2ePKIDSLXWwWg779g\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies on scorched concrete floor full of deep heat fractures, clutching a bleeding abdominal wound beside a torn empty water pouch and heat-warped debris. In the background, Do Minh Kha stands looming with a cold detached gaze, holding a tactical combat knife, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"F220AC69-D505-41FA-858E-8B732C38C242\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6E4n3kJ1_ax7NDOtPH7wSVV-z9DsKYLfm9aALzD8vcGseY4YWM_h9OQGdXVoMqz8Q-lrbb_rUlIncYjjQ3sO8qDiZeyNyv7D10UBnhWF7PoTYlFqHjXAJiXk8mDNnLkUSHDiXqNXq9jqpZOLseOtTjr3he9TM7ORA55opAX-ccUHKxa0cvPiRwP3so51319KTQLT4WFkJgji984TWPWBrkkzxMXuQuzvoUzyNGOkVCANiCsxBDtMmnQYJri9lZ5ZI167iQvDBaDS0nXkWFA0jxg4fXyanWInDYbix2iw49R1WSQRyKzewisDl4Col_VY6RwojaoS1izb2_LJxKYnKj26G8zDrPhixSizmsfkvulq4ySxeoELS0UiQU4kuuMqnq6qVjiULE-MfuHdKdwIhQtyjxd_IUjCRipycKp2RULkbuzJ6QFeSYFLBlkXv8GXVWVxvZf9l64dbM_okk0Ecpod-du2ftxaTOczGUtPC_uGSdv_ojpJRmM9Oz8DP1baVug_ZNpTsf1wsJPcEb1ApL9Yn_xtVo_Ct15zkAos__uhXMLh1QY9kf6nsjrwLJgVhI9XiDEphSOc39gpJhmdEUlAErQaFrhX7JOwE1uoya2J21aCZC7ANdpftltSh-GUQpkHQqE2qltd1VN1ZoxEVaw81AmdHvMbDELM9IbVFoj7U20LgLXL7GKOW7qo4H3C2raW6RqjumnOLcZX3GchAoOlVJY1e8cOtGYx2wa2E6DJ8TmS1aZU3JhGfVkFJcsNPfHoAo89QzETPIEBbN-YYdjOsjXhGG46UV7ikbtJpQWI9-bKoigwji_DywFQFZSag3cdZ9YPLmqd5HmbGP-gxlOQhEJAQEMeQQlAVHKhM9gJTaIG2DZk98Jduzes0Mfnq1J_H6HNSErwYvBl2_D44OU6Ua_nEOeXTZY-0ADSh7fPB9dW3w8YxH-Fx1s_HBUYFS2jvf6inDypTnOmJ3YsAxJSHIUqiydcqPcBcaOUD8aCbG-OPf3JMWGj42E8ACyURbv9BsL1LOMCEHQW1h-C6MH2okFgxV1HZuYUcBApDEjkxM_3FrcTqDT1EwDbIhEi-13mZEBf_Gl77VhB8OEFIBgjHUxaFhL80wS5zmGPXG_eC-0Aen4scvNOUDas1LDUZZbwVwpFw_8781FyZA-sNVyg5KcxrFm3JecVmp_Iv3VNtGMF_gwT9HhGq7kBOgNp854OeXN9fOMMl-aVVPGfQmCqTBnx4l8mwNNSX715FTdS0jbp3L1v2hQo3spZmQ4kTLh8KoBS_Z4nVgeuOO46WpxmG805k5n2o3hweA_AZjiKJ1SbpNO3bt6wtANM1X5gQQSg9WdjqybwOzbJLXySc5mgF2STCPLi_jPeUEuBbfmf2crPwQZWcmb_ZlvWCNK4RSifLrI-FomNS3P1SWk1xTtC8t9l5t5VAEFD3WHvMQ91JWE7yxcEw_l8RkxKPFvkF7xawyd7cKL0zhO6TGP1g7hNk8RrFPAEODSlMB_BE80W4O6-gKfxXqW6sfrdhnnxbWxNG_v_dsk9pVOrJgo-9_sx73dt1Ih86XBte_70TC9zkaJBKwgh998f5FIhg-OAyTv-U6aRepb5Z9nqaR8cj_H2N3EyxzAUoCCN_YX1KejouZ0Ddi2POv7y-loowZz3FVNGItk3e5z3sEHzop4eVBZ11KfW-U4Lm_1oMbtmXJs3IsYksb34UvJsd0dJHsQ_fVz2PnqFZvhlv6xSxunGD7PMV-cmfSVq0NawSORBjAmbK7La8nvv59YQDUP6E74PqY0fezt3VRyWDFG_SgOvWSnSXKMtR_Gne1IEE9_2ORCfLdg_Kj8z0R1-YMDj3r-5M_nddZcJ3WRTYQ_MbDxOxGQL7qNshibKwy4hD9hxMued3PBveLAY32VjmMyIlW9m2nG7L-dPEhX5_TUzsGbRDPTwh5wqWMzsgr1fP9dl9DdgR3ZThugFilORENZy0OEHAkWfU9r6JJfsjbB84zHiDlxLtwN49E2EaXbF3CNytRdRw9kDC-6J49tshpUhzg_x0IZs0A8D0xxTirfmM9Iuu6ROdECGOnC_NOj2l4GbMh41rW9hDlmzH4x74tVeF-77NOIeWcr8kdBhn-_ywxCM5ePzQOpYcBo4ydBv6v7-LPVIreZdXG37Txy1-tF9mmKi75FbOH7Z4jxWfdR27uPq6F6-71OwpmMPmJ6O4nKhYMWzDOQAEhWbkhtp3ooSgD1rb1QYhu3g_xS4RIQX2Sso09-Q0WtsS4btH6dSw5IwRNutgzHTlJY1p6PjnpKq-5hCn_t-aDjLtenra7mGLDDU3YXptEdi4Xfz8wLZuvx0o185GesDD9ZFGIUni2ePJ5cTl1pUJN01kknJpY6IoL69U_KVTY_8IyBUpSmCLIXzSfI1QpzmksjxwKJ1ii-xPFFyAJOHmEpTw8f2ePKIDSLXWwWg779g\\\\\\\",1]],[\\\\\\\"1CA16167-F48B-42E2-AE9D-DAA04B8973FD\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:31:54.485Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=751536&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],460433625,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7KVgo_CQ1JVvDB5TX-gUy_GMZX-d-ho__8cN3Sw18wgfLihYBuiUA3VAKv9CvCx0BHhmbZvcKQdZtOqeHDoW0hIvJ8Vj9gPywkWBQKqrnKi1fHvFnyurWjjTFdoREcHUmoNuBh0vVBD5SF1kOqDs9Q7WFxRNBRQJfK0a1jtRw020aP_RzR3ghmV08lg7lsEUvAPNsNxHyk6fy_C_pZ798t-XqvasfqwdP7vpKPGB158Ue_ZS6T0Hao59EqsfU4LAp0KnDgYawqU6YKlipRGzxEGMvgSysP_iJ47rp3ANVRewPP-iX-eYFt5SHiMT7YXUMVY_4r1ImWIh0uQLHDkCNaAf991t0hosoz8WHdmKYMyjA2_G3u96aueyK1KVPRVSUbRbTTO9jS_XeEkaSn0htCD_45HqPNnCsoZQgEuDfepoKMNkcacv87icx3RGG2aiygvhRDTrDhPKzO6wAvIQbs_S65RVgGw9hmyKJuR6WKOeMEp3O_-Vrlz8zF_RtNnJ8SYlmLfs66ym2518Wyj9IoJJEc4lzbrD6PLeGn3OrRkyJd1lWUkoVQ8TDFEVRlFyWwbP8vq8CGt2LxwN0IC1TBgEjlqb1zEwg5A9WM_DaQ5Vg0lqTUvT3ZU_ZCsI0C-AquTQc555v9Bp_EdW_hdLGXOD4LcQkK0RQH6VdZ-2ZCaqt5-dBBoxDkm-x0m42K7aSIZMp4FtPtDJsAOhIS_Jcx8VZnl8pX10knyV-VhF5jVfKVMkELmoU56GIvDwZpeA5eFytWzm5SsUrehXB_S09Wh4iS6b8DkjChbJPYMojeZ4A45NUArqA9YjHSZQ945LwdX4A2pxZd6nWeY1yISqUv19RBHiXuCeFtJq86QNUsp7NlSte7N7Q97eVAn6oJYzT0ldtcqrqX-Eu_6thjzKhOOokRIHP6wXPZWb-4t8f6xyLce_xW3wrFit7Ez9E1asAPfq4767bjyOiEMg8VcwhJym6JyKk7-6OvVPjAWeYMBgHysVnKbfR1-hIXUcBkhvtw5PMQ8H70sz1CnMPVW82bL8M5e8Kjqeoae7it7Vl0DDge_MD_vJS-RY1U1-8ubOzaH5g_g9bsbdC0aGKMqXmgTZ138XeNx053xcvPP186F1cg4wy3fFGDiNRc2-zJ5TF-fJipBWui4HWlsZrPRlAUV2mDa-SNUU0fhlC6aUubA5tOGXJdt8sm1L6O6JkR9NtuXm3S2gkzgmQiIQiRGIubx0cwPp6uq3kIOF4jOPVtmcBuIT4z5l4XlgfGZ5DdEMbyrOgCYi2CSLVZW-o2JjuLBAh-F_WD-93uAsAaY0bGn0gDJJnLiqMrnlonXKy0785k90q_2lvM_QYhtawLXqkLY6Gc8ZcVLI5DHifSq9pA1zahuruU1GVFGGlhrZwNwJn7Y2D5N4RfD78aUNlMmObbdauQa_ejYymAr9LN8kdsDakHksR0wGeRLnac9XciMKUhUNOQSMHjLSem9t8g19kyQnmfoX61CXB_FyH7R2AvHQC1d_PiHZr9BirVF0ZoUjyFjdRTCjWLhwKNCapyHkX9xtYATzFqGp5FT2GQchy6ECO1ayP0sSZ0jPzj0Po5TBFxxOBepB_aOpVOM5hg8ft-w-mpy2yM47Fv-os-4OTM_wmh_pElx54-jpUZtX51r6hpSxbZV9s96UjiNKF7babOnWyDABFbFsoktb5p_LPJ9GPQ4WrvW6-dgNmn9X8Fl6BmxkZO7pj60UUApUkA8Nnh-6sOJvq3RTOED8Anf82hfLAh-SfMgC2XfkY_8Uys95-TtYcM89i8vFKt4tKX1YZ3Rn_y5p_tYtFPN4NbJK0294gZjq2tzEMq-m-Sx1jSXKQC1Z7rMEqM3Q1llIJa0o7sRo06rtnsqPsOeOoioOU7-jiSwNS6NsZB867V26c82UQ9Qt5P3n9BKLK9nuc79HGIhwvJP3WPP7Ymhn_QffqYcV5FMV1kd-casXGUESqXO4BMPqQ84AE6czyFqCRT-jLnMJSpEyJpxwRuzLw9pHDotgAMN7LIL4kGXaRJ81ZF636AVXsGJC0ZsRuTXmlCPj7ZlgrLd8UNLhlg6N2CIXuQuXYYXGlgDojj2D2nTpV9YILg363ucCIrlxFn0dYSt2IjyWjrNNU3mgdfQmquyLSFfVo8x2YYScSQX0K6hByFrwnf5B_xg3XC5ItHIzrSfzKSrIQru3hBREowUbTUx3NImL_Va_BY4VKYcR8bKULIvtwhSU8ifOqBE1ll1fpffVtNoRcL46xx16rb2pahnpabhxhYly7cRBKz76AH9y4PtQeM8dtqKwOmGw0WMQQc54Fk6EenZUofOuppacxjhqGJBQ6MgCImiKm627c2z4U3y6PfFbWYlNQYMrFgN0AuEpqYB8xRvwFIg00gcQ_GmJkHbBtHYg0BxOv0rkfweMtDhHfeIbs6Dfgc5x-yeA9PGoK9vbUBVg\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"022BAFB1-B8CF-4934-92D5-D3BF556804B2\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7KVgo_CQ1JVvDB5TX-gUy_GMZX-d-ho__8cN3Sw18wgfLihYBuiUA3VAKv9CvCx0BHhmbZvcKQdZtOqeHDoW0hIvJ8Vj9gPywkWBQKqrnKi1fHvFnyurWjjTFdoREcHUmoNuBh0vVBD5SF1kOqDs9Q7WFxRNBRQJfK0a1jtRw020aP_RzR3ghmV08lg7lsEUvAPNsNxHyk6fy_C_pZ798t-XqvasfqwdP7vpKPGB158Ue_ZS6T0Hao59EqsfU4LAp0KnDgYawqU6YKlipRGzxEGMvgSysP_iJ47rp3ANVRewPP-iX-eYFt5SHiMT7YXUMVY_4r1ImWIh0uQLHDkCNaAf991t0hosoz8WHdmKYMyjA2_G3u96aueyK1KVPRVSUbRbTTO9jS_XeEkaSn0htCD_45HqPNnCsoZQgEuDfepoKMNkcacv87icx3RGG2aiygvhRDTrDhPKzO6wAvIQbs_S65RVgGw9hmyKJuR6WKOeMEp3O_-Vrlz8zF_RtNnJ8SYlmLfs66ym2518Wyj9IoJJEc4lzbrD6PLeGn3OrRkyJd1lWUkoVQ8TDFEVRlFyWwbP8vq8CGt2LxwN0IC1TBgEjlqb1zEwg5A9WM_DaQ5Vg0lqTUvT3ZU_ZCsI0C-AquTQc555v9Bp_EdW_hdLGXOD4LcQkK0RQH6VdZ-2ZCaqt5-dBBoxDkm-x0m42K7aSIZMp4FtPtDJsAOhIS_Jcx8VZnl8pX10knyV-VhF5jVfKVMkELmoU56GIvDwZpeA5eFytWzm5SsUrehXB_S09Wh4iS6b8DkjChbJPYMojeZ4A45NUArqA9YjHSZQ945LwdX4A2pxZd6nWeY1yISqUv19RBHiXuCeFtJq86QNUsp7NlSte7N7Q97eVAn6oJYzT0ldtcqrqX-Eu_6thjzKhOOokRIHP6wXPZWb-4t8f6xyLce_xW3wrFit7Ez9E1asAPfq4767bjyOiEMg8VcwhJym6JyKk7-6OvVPjAWeYMBgHysVnKbfR1-hIXUcBkhvtw5PMQ8H70sz1CnMPVW82bL8M5e8Kjqeoae7it7Vl0DDge_MD_vJS-RY1U1-8ubOzaH5g_g9bsbdC0aGKMqXmgTZ138XeNx053xcvPP186F1cg4wy3fFGDiNRc2-zJ5TF-fJipBWui4HWlsZrPRlAUV2mDa-SNUU0fhlC6aUubA5tOGXJdt8sm1L6O6JkR9NtuXm3S2gkzgmQiIQiRGIubx0cwPp6uq3kIOF4jOPVtmcBuIT4z5l4XlgfGZ5DdEMbyrOgCYi2CSLVZW-o2JjuLBAh-F_WD-93uAsAaY0bGn0gDJJnLiqMrnlonXKy0785k90q_2lvM_QYhtawLXqkLY6Gc8ZcVLI5DHifSq9pA1zahuruU1GVFGGlhrZwNwJn7Y2D5N4RfD78aUNlMmObbdauQa_ejYymAr9LN8kdsDakHksR0wGeRLnac9XciMKUhUNOQSMHjLSem9t8g19kyQnmfoX61CXB_FyH7R2AvHQC1d_PiHZr9BirVF0ZoUjyFjdRTCjWLhwKNCapyHkX9xtYATzFqGp5FT2GQchy6ECO1ayP0sSZ0jPzj0Po5TBFxxOBepB_aOpVOM5hg8ft-w-mpy2yM47Fv-os-4OTM_wmh_pElx54-jpUZtX51r6hpSxbZV9s96UjiNKF7babOnWyDABFbFsoktb5p_LPJ9GPQ4WrvW6-dgNmn9X8Fl6BmxkZO7pj60UUApUkA8Nnh-6sOJvq3RTOED8Anf82hfLAh-SfMgC2XfkY_8Uys95-TtYcM89i8vFKt4tKX1YZ3Rn_y5p_tYtFPN4NbJK0294gZjq2tzEMq-m-Sx1jSXKQC1Z7rMEqM3Q1llIJa0o7sRo06rtnsqPsOeOoioOU7-jiSwNS6NsZB867V26c82UQ9Qt5P3n9BKLK9nuc79HGIhwvJP3WPP7Ymhn_QffqYcV5FMV1kd-casXGUESqXO4BMPqQ84AE6czyFqCRT-jLnMJSpEyJpxwRuzLw9pHDotgAMN7LIL4kGXaRJ81ZF636AVXsGJC0ZsRuTXmlCPj7ZlgrLd8UNLhlg6N2CIXuQuXYYXGlgDojj2D2nTpV9YILg363ucCIrlxFn0dYSt2IjyWjrNNU3mgdfQmquyLSFfVo8x2YYScSQX0K6hByFrwnf5B_xg3XC5ItHIzrSfzKSrIQru3hBREowUbTUx3NImL_Va_BY4VKYcR8bKULIvtwhSU8ifOqBE1ll1fpffVtNoRcL46xx16rb2pahnpabhxhYly7cRBKz76AH9y4PtQeM8dtqKwOmGw0WMQQc54Fk6EenZUofOuppacxjhqGJBQ6MgCImiKm627c2z4U3y6PfFbWYlNQYMrFgN0AuEpqYB8xRvwFIg00gcQ_GmJkHbBtHYg0BxOv0rkfweMtDhHfeIbs6Dfgc5x-yeA9PGoK9vbUBVg\\\\\\\",1]],[\\\\\\\"58A0BCE4-6468-48FD-84C3-669715E893D5\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:32:14.527Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=560765&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],733512044,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4oDmqKzuEXeTT_3PBK38sBodAKIJxC-O5djmCqb1HOp3ITaQE2LemC9PDY0KLyBv70fKI8dK35ldX5UtbriSJ5WVdcYm74Et7vs5SAvebAXJwK-qrf7vUy2SHlQ65LqZVPq0KGfvoI8Ao3M--SW6-h0xsHS-tfZ-y5v-1Hhh8f81sC-e5vFt4500uOwuRcbReg0FAoiwz9Go7YApdkpG7CRwTYmz5mVUKMgTeXG94s_hG_6zXDUVspTERDvAYkSRsBsPVZvD66hHWzWdQuWyHOnoHWjU3GYZYS_v02CFQ7edlbbZ_fNO645X-MJjcG8OP7MlMdmXBiDPB5cDTkORafSn48J8-lhnkDvqzERpYyHCBq-wBo0g_RiU-a_i6_tBS_N_xRknMxM3IPcVZQYp3lOewlGqdL7rN85SVXfmmh2d4kRZvkTkrae7rw4K1CySOleshyLNT-WiNwZnih-OZRKvbLn-RYL919Djb6EM1hdifMKNaKu2AsNWEu-VclXO_OWRPZi_iABxzXyK-RgQF-y7ejhpgzI-molqXBhwE_jOVJnkxm5F-OS-8QyRUspR4b_qb5z1N88ZHFQMuVKghRJU6-vgT79LGXCUBJ2naQj2l2DL6mE9CC4En-k__pPC-c1I2ncombJb6CEq46omV7aZ49jhH0eIkv2Gk0zhD6uazscn1Fr6uVRJld6lprfGMJW0eYATItc7fCLLcGvraWQ-bLf7CYbZvLRK9KQSPGU2MFKGJ0jbe_8oN7FdH_XV4GmwmRPzkwvQOmG6VZ3bEPSnUtCNFI6vAedGxKd4IK_YjSsA-8YGPge7M4xtBQcmJPFzf6UamBwxQ7BxvPskaY6YiV2O-i9Z3FMJteIIFD7vUKCshsX_GoARza4-ttesIXZwTVn9W5vDBOFEH6qd6fygpMcKKgu29UFaW6nbQ02hy0ge0ndkhh7KEaacvS0h-0hLI0iFzlRFwEJPc_mgNS0DBWqW1RHJn7f8LBBpVN5asVS-yE_EgdlO-sJ_TBJ2-1QQaEFRcRsvpWkHZw3dSzL1vQt4GiG69k089JXLe_ZqLIOv0c3iCiPWEPq4Xk50PoENok4R7eEnI1jtbrsKQpvS_0jHajKrU5b6jM_F44cVAcY2QoElW_mXwzm5_-nozzVLKa6TNeSzX2f7Nj9N_OXop3bODkaSTatIE2z_vxNVvfzwuj_-P7QX5p2qGOOshzPhMRKzx9d8PpbnWTgQxq1cHedwYn6DisTS9lX50ZigL0OPn4UOCc9MVjYvp0gKJRDGxY2wh2MPyM3uG3_98Ckz80H626KcoyTL3lNEHO1gmS9n1Iu-la90U37O83fQ711WzN6f_Dk3NOIu-GBzIVT3YBdP3hQBPkfu17g3kxX7nejUzlL8NvsDkhBrbXEWHHOt095omO9GeKy9zyK2g0LIQIpRz08aju8SZTNnuxYW3-5vr8pTedXdjxJyeDTV2n6u_3yMY_cqPGuR5syuLh4WS-u5M7mGct_z_MhznlXJr4-8kWDroJq64duANcINX1LcZmc5GPA6M73FMMXAjfLW6PCgJ5Him2m8Jev92PJ_eCw5m72mYLzXvfDBCpe7PRH5sG1OxNPJ1g-tFCLLT1FQXFMlCmOaaUy7sODYnoZgWUm91M-trlPsO9bQjEa05oDlzeou6GHqroxOcvIeSzbvXl_3lCQ2iWu3x7C7d78tCcwlQkbHQpY8H4ajYC_hvT5nX6-gV6Ritt5DnluG6SAvRqxfgcMVILZVIbCXaimORMQ3MYPfQmNVk61ivk2N2bkNO7plvQclDd9EgR9hkN0aj88f5MiwRbO_5tRpjxLcROxU9Kw_v5fWvMZqoRUi6xJCPsBUSQ-MoWl4SVAfpCOyUTN9lBjfIdheROpMgm4anmyvBquKMqfV_PMJsdtweXd1MJ9NHVyE8VAQPPzQyrnxuPtEJB3gV9dSNjdIL4U21LNIdSnOwdNRtBdQudlrkM5LGYVIdorKxmEd29ydWlWdxeyp-8Oid3avXTxiimpXN64W5CpLQe0t6xea4Uy3Hjgse-h6_vp6QGasqJmOXPpYHXQKC_v_p_BNA5RwlLKx8ofC7bZnvaWoV7MhSLmoltDO_tj3i187umJiht7WZOe-njGtSS_xT7gpXp8kr24itvV5G-1a9O3krgBH7i-LJFkYBsLtJ_iJsAkyud96FCbooAXq7cHgmpIjUmPnV5sSQ0mDUyV-cosnbGxMS2ZuPvN0sF_GNV4UiU7an5EV3TH_b5X5tDhlgieRI836AdLNGyex09JgIt9jUXOGuuJKyb6NWx5TmddCVDvHbmpjbHxuWnLEN-8h1dfNCaAhmJVKx10sQVmWqprTtYTXf4kxJMZLD_7YLDriIB__Dnj-wCAX6tf6LkT9AQZ0qMeRjssQCPlCC_8X4ekQUEJLy0Gpt0wuqCTa9RwzUOEu_-9mk0VCNwIw\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"95F0B7B7-69D8-4535-8738-1ED83E675CA6\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4oDmqKzuEXeTT_3PBK38sBodAKIJxC-O5djmCqb1HOp3ITaQE2LemC9PDY0KLyBv70fKI8dK35ldX5UtbriSJ5WVdcYm74Et7vs5SAvebAXJwK-qrf7vUy2SHlQ65LqZVPq0KGfvoI8Ao3M--SW6-h0xsHS-tfZ-y5v-1Hhh8f81sC-e5vFt4500uOwuRcbReg0FAoiwz9Go7YApdkpG7CRwTYmz5mVUKMgTeXG94s_hG_6zXDUVspTERDvAYkSRsBsPVZvD66hHWzWdQuWyHOnoHWjU3GYZYS_v02CFQ7edlbbZ_fNO645X-MJjcG8OP7MlMdmXBiDPB5cDTkORafSn48J8-lhnkDvqzERpYyHCBq-wBo0g_RiU-a_i6_tBS_N_xRknMxM3IPcVZQYp3lOewlGqdL7rN85SVXfmmh2d4kRZvkTkrae7rw4K1CySOleshyLNT-WiNwZnih-OZRKvbLn-RYL919Djb6EM1hdifMKNaKu2AsNWEu-VclXO_OWRPZi_iABxzXyK-RgQF-y7ejhpgzI-molqXBhwE_jOVJnkxm5F-OS-8QyRUspR4b_qb5z1N88ZHFQMuVKghRJU6-vgT79LGXCUBJ2naQj2l2DL6mE9CC4En-k__pPC-c1I2ncombJb6CEq46omV7aZ49jhH0eIkv2Gk0zhD6uazscn1Fr6uVRJld6lprfGMJW0eYATItc7fCLLcGvraWQ-bLf7CYbZvLRK9KQSPGU2MFKGJ0jbe_8oN7FdH_XV4GmwmRPzkwvQOmG6VZ3bEPSnUtCNFI6vAedGxKd4IK_YjSsA-8YGPge7M4xtBQcmJPFzf6UamBwxQ7BxvPskaY6YiV2O-i9Z3FMJteIIFD7vUKCshsX_GoARza4-ttesIXZwTVn9W5vDBOFEH6qd6fygpMcKKgu29UFaW6nbQ02hy0ge0ndkhh7KEaacvS0h-0hLI0iFzlRFwEJPc_mgNS0DBWqW1RHJn7f8LBBpVN5asVS-yE_EgdlO-sJ_TBJ2-1QQaEFRcRsvpWkHZw3dSzL1vQt4GiG69k089JXLe_ZqLIOv0c3iCiPWEPq4Xk50PoENok4R7eEnI1jtbrsKQpvS_0jHajKrU5b6jM_F44cVAcY2QoElW_mXwzm5_-nozzVLKa6TNeSzX2f7Nj9N_OXop3bODkaSTatIE2z_vxNVvfzwuj_-P7QX5p2qGOOshzPhMRKzx9d8PpbnWTgQxq1cHedwYn6DisTS9lX50ZigL0OPn4UOCc9MVjYvp0gKJRDGxY2wh2MPyM3uG3_98Ckz80H626KcoyTL3lNEHO1gmS9n1Iu-la90U37O83fQ711WzN6f_Dk3NOIu-GBzIVT3YBdP3hQBPkfu17g3kxX7nejUzlL8NvsDkhBrbXEWHHOt095omO9GeKy9zyK2g0LIQIpRz08aju8SZTNnuxYW3-5vr8pTedXdjxJyeDTV2n6u_3yMY_cqPGuR5syuLh4WS-u5M7mGct_z_MhznlXJr4-8kWDroJq64duANcINX1LcZmc5GPA6M73FMMXAjfLW6PCgJ5Him2m8Jev92PJ_eCw5m72mYLzXvfDBCpe7PRH5sG1OxNPJ1g-tFCLLT1FQXFMlCmOaaUy7sODYnoZgWUm91M-trlPsO9bQjEa05oDlzeou6GHqroxOcvIeSzbvXl_3lCQ2iWu3x7C7d78tCcwlQkbHQpY8H4ajYC_hvT5nX6-gV6Ritt5DnluG6SAvRqxfgcMVILZVIbCXaimORMQ3MYPfQmNVk61ivk2N2bkNO7plvQclDd9EgR9hkN0aj88f5MiwRbO_5tRpjxLcROxU9Kw_v5fWvMZqoRUi6xJCPsBUSQ-MoWl4SVAfpCOyUTN9lBjfIdheROpMgm4anmyvBquKMqfV_PMJsdtweXd1MJ9NHVyE8VAQPPzQyrnxuPtEJB3gV9dSNjdIL4U21LNIdSnOwdNRtBdQudlrkM5LGYVIdorKxmEd29ydWlWdxeyp-8Oid3avXTxiimpXN64W5CpLQe0t6xea4Uy3Hjgse-h6_vp6QGasqJmOXPpYHXQKC_v_p_BNA5RwlLKx8ofC7bZnvaWoV7MhSLmoltDO_tj3i187umJiht7WZOe-njGtSS_xT7gpXp8kr24itvV5G-1a9O3krgBH7i-LJFkYBsLtJ_iJsAkyud96FCbooAXq7cHgmpIjUmPnV5sSQ0mDUyV-cosnbGxMS2ZuPvN0sF_GNV4UiU7an5EV3TH_b5X5tDhlgieRI836AdLNGyex09JgIt9jUXOGuuJKyb6NWx5TmddCVDvHbmpjbHxuWnLEN-8h1dfNCaAhmJVKx10sQVmWqprTtYTXf4kxJMZLD_7YLDriIB__Dnj-wCAX6tf6LkT9AQZ0qMeRjssQCPlCC_8X4ekQUEJLy0Gpt0wuqCTa9RwzUOEu_-9mk0VCNwIw\\\\\\\",1]],[\\\\\\\"13FC1CFE-A1B2-46BB-AE26-DC4A69859A6C\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:32:40.678Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=nzlxg&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=2375791&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"nzlxg\\\",\\\"[]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:32:39.561Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=445517&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],529649083,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6dxggxKfo1Cmhmy7G2y9CjxOX9J8a3PFxztcO4_nkaM5h46xPimxT_i1MGHDF2banAHhTNf0465Q8QvvC6VGtb05CwyLImqg9_lk7Ti6wf9L1r62lyoJW7zNS8N8E2ZFV0HQU958vRzoVA2DwxMdybJ45IVHAF8tZ60PPsgq9rWtoo221iRuhgGnwHKtbPF0KVbZFx027QIj4QjNn3UivRimPtpa95V_2lLwkFMVdyNS6-W_5HP035U-i3Azr5fJLuIPRzCvF11R1PcEgWbEjOS3NcSgT-6K0bOf410KfLHTohphOTZo8iq_njsMM2cxBmHcX7Pkrw-6Mrs4H7ssGn-rOxu7D-t_naQl63U4azgwVA8Y4hXE0CWVrUQNIbiKmS2WLyrNRXI2OSPBiZ_BlIwFqkKm879KHa2NWar-jEUmtF_J5-c2xo-3GsZ9rDXVI7dd_hTODd8jeaOxNvAAyk7VT1KLNJlYqq3Co-7reHIFVXCWKEdh2NJoZyAPcn0zrTxjC6VaAxPb5L4LRgdD5f1zefLlTbFDXVefUd4_ITp9PyZlQKI7JB7HVJqqZDLN9c7JLZfC0UMcMgoaVbjHxcJzd9SX8og3ts_B9GF8zK5d6jsZGG_cNO7FktmXkyqEyzLibuxmDIDRuZ-RjAg5_7BpX6_pQ5wX_449POYvAK9ysuNkUodFQXCO_WEIIY7glJCp3RU5t6zgrIzU7ByWSY_7YW8LoushnljdKAhyMukD_VtlGMNSg7AdFp4HX0rxP7HNo1WdfsS5rHeTz443Zf2C6bPfZZ5MeYag-ZPJ-l9uZK9CA9CrUf2_IJrR6CXZI4jj892eoEqwc-mht8NhCvU2hEAKtfkA0GB49sIFr95Q-eQOhCt7ePbpsndTpI_TbwEll_MVHDyVmwG4KaUFLcfSsg1rkw5z4CfjQR0EzEMOwdxhWFk3h12dwTBbZXZjB2hnFdXgbY9csVqdazUgB2B7FETnqnj3i546Jd8i27kzwHAT3KGc2PUp706HYnBo7m4WLMvp4EyXE1kWpAHGiIHMhljXUwTTPrGelVkSNmH92C_ClEDCuWJ7m49tjRjLbp62fRRLGLuX8RUkK5Hc6Y4HnJucYqqujUZ5TVmjc8MQMg7O6OcP4lxSCIpQPRPvyStWnp2bVG4-Rg0O0H3Q-FVgJPlTKFHKvAxQF_JzwiJDiPingfK9CUi6Sbu_Lo1E0UWhKNxs9m_IOfGgWZ1Xf09pEyJnf0n4h1vUuY1oTFKoi7yfNYVw7rw1PYW8AnZrgMMiKKOsDM1B40pCGc7V7bvrHwm7CdnN7LGjSw4DgDYVRsf6xKMN2SMn4g0wPAYhAv6gjQQiraMGmEs9Wu8HCHg8waCjcESViTdPxndtm2VzxLqdaPX5b6Sq7ryTTgDajoguTNH5Vwkx9DS0Emv6NSdYLoMY5MrIbDxmUoY7FOd-rWN8y6T1jg9kcTWmZKfZmNsscaQec2xBOaSVGZG86IKNH0PVn8Sy6zeyxKLW_qbTebrVdiU4dxq2Y5g26D107ycznKHZkbPymlegvTZcRW5iBBQLdfT0adHbSgJ3xilhwDxcdqlu47E7Nw6rZ8Y7EIbxuUmtESpiRvDdM9U3kv3EAnBauBnCcSHrF-wujTE6kbVSGpAbeu801B43rQxEhpZfd9tkJgPFmh8O2J9B5vXa1Fxs79wkKohsT14jM7Vws3fIZbU-QfsgbuxAKZ8zQgK2bd2zbx3PkFuUidQN3TDSL6bfTbMngA-jCp3DgLr8iDTp983nweCgeQCTABKR9HzRRPlSEgCUWIFICpcopjIMvfB9UzEGT5malQUc-MYcgmpEj-h9eh3AiqZfp16gTLeKLR2zvCGU07p8bQauXSF7eKGObQBAFzH8y8HB5VYYqUb9r4KkBXN_xY_EaGytTxhqczTYHsHhmvYggdgo6jck1a1_euTCOP7hvwhkeusGxKc1tbp7Vtaei8BSzi5LLDRSVf8tuzKIVtthuF_kmhpRBabPFAf53zuL2lOh5T6iizBTddnxyXFI_3HC7Wno3S-nA3qMhY1m3VOlVOHQvDqJv41oOCr8fzmwJGpazQeKRIK9vCLm9xNK3GWpqCk54Y55HKvzY1yEoGppB9_BGrdRh9w9TlOZhdqaDqr5kLawUv6-VEC_rBY3Lc51PaCnhu9--a9yx6HzZ0EOty4ZthWFbORkQkaXaC1M_Gf1kNbpd531aE6YviWXrdFuf4yV9cqmFMvM-O_PwgCNWbJ9ealTCDrMIYLZJctHp5uXLda4M6QwpbPVTAPsC7sa9cSSj8hMdN9DnzvVpjD505zTC2idjHJErAgBlntlbd5dopi33yzD3uhw76VprRJQNYCZu1883VKqpxcd10FEqro3LONdBSvje3NTkRIKIJ3CRT6v8gq59MRo-nDBSkmDmsCOFG7meSOsOIA6uxYtDCSTe-YeWKkg\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"BBC48535-B107-4F71-9A61-3F0DEFE800E6\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA6dxggxKfo1Cmhmy7G2y9CjxOX9J8a3PFxztcO4_nkaM5h46xPimxT_i1MGHDF2banAHhTNf0465Q8QvvC6VGtb05CwyLImqg9_lk7Ti6wf9L1r62lyoJW7zNS8N8E2ZFV0HQU958vRzoVA2DwxMdybJ45IVHAF8tZ60PPsgq9rWtoo221iRuhgGnwHKtbPF0KVbZFx027QIj4QjNn3UivRimPtpa95V_2lLwkFMVdyNS6-W_5HP035U-i3Azr5fJLuIPRzCvF11R1PcEgWbEjOS3NcSgT-6K0bOf410KfLHTohphOTZo8iq_njsMM2cxBmHcX7Pkrw-6Mrs4H7ssGn-rOxu7D-t_naQl63U4azgwVA8Y4hXE0CWVrUQNIbiKmS2WLyrNRXI2OSPBiZ_BlIwFqkKm879KHa2NWar-jEUmtF_J5-c2xo-3GsZ9rDXVI7dd_hTODd8jeaOxNvAAyk7VT1KLNJlYqq3Co-7reHIFVXCWKEdh2NJoZyAPcn0zrTxjC6VaAxPb5L4LRgdD5f1zefLlTbFDXVefUd4_ITp9PyZlQKI7JB7HVJqqZDLN9c7JLZfC0UMcMgoaVbjHxcJzd9SX8og3ts_B9GF8zK5d6jsZGG_cNO7FktmXkyqEyzLibuxmDIDRuZ-RjAg5_7BpX6_pQ5wX_449POYvAK9ysuNkUodFQXCO_WEIIY7glJCp3RU5t6zgrIzU7ByWSY_7YW8LoushnljdKAhyMukD_VtlGMNSg7AdFp4HX0rxP7HNo1WdfsS5rHeTz443Zf2C6bPfZZ5MeYag-ZPJ-l9uZK9CA9CrUf2_IJrR6CXZI4jj892eoEqwc-mht8NhCvU2hEAKtfkA0GB49sIFr95Q-eQOhCt7ePbpsndTpI_TbwEll_MVHDyVmwG4KaUFLcfSsg1rkw5z4CfjQR0EzEMOwdxhWFk3h12dwTBbZXZjB2hnFdXgbY9csVqdazUgB2B7FETnqnj3i546Jd8i27kzwHAT3KGc2PUp706HYnBo7m4WLMvp4EyXE1kWpAHGiIHMhljXUwTTPrGelVkSNmH92C_ClEDCuWJ7m49tjRjLbp62fRRLGLuX8RUkK5Hc6Y4HnJucYqqujUZ5TVmjc8MQMg7O6OcP4lxSCIpQPRPvyStWnp2bVG4-Rg0O0H3Q-FVgJPlTKFHKvAxQF_JzwiJDiPingfK9CUi6Sbu_Lo1E0UWhKNxs9m_IOfGgWZ1Xf09pEyJnf0n4h1vUuY1oTFKoi7yfNYVw7rw1PYW8AnZrgMMiKKOsDM1B40pCGc7V7bvrHwm7CdnN7LGjSw4DgDYVRsf6xKMN2SMn4g0wPAYhAv6gjQQiraMGmEs9Wu8HCHg8waCjcESViTdPxndtm2VzxLqdaPX5b6Sq7ryTTgDajoguTNH5Vwkx9DS0Emv6NSdYLoMY5MrIbDxmUoY7FOd-rWN8y6T1jg9kcTWmZKfZmNsscaQec2xBOaSVGZG86IKNH0PVn8Sy6zeyxKLW_qbTebrVdiU4dxq2Y5g26D107ycznKHZkbPymlegvTZcRW5iBBQLdfT0adHbSgJ3xilhwDxcdqlu47E7Nw6rZ8Y7EIbxuUmtESpiRvDdM9U3kv3EAnBauBnCcSHrF-wujTE6kbVSGpAbeu801B43rQxEhpZfd9tkJgPFmh8O2J9B5vXa1Fxs79wkKohsT14jM7Vws3fIZbU-QfsgbuxAKZ8zQgK2bd2zbx3PkFuUidQN3TDSL6bfTbMngA-jCp3DgLr8iDTp983nweCgeQCTABKR9HzRRPlSEgCUWIFICpcopjIMvfB9UzEGT5malQUc-MYcgmpEj-h9eh3AiqZfp16gTLeKLR2zvCGU07p8bQauXSF7eKGObQBAFzH8y8HB5VYYqUb9r4KkBXN_xY_EaGytTxhqczTYHsHhmvYggdgo6jck1a1_euTCOP7hvwhkeusGxKc1tbp7Vtaei8BSzi5LLDRSVf8tuzKIVtthuF_kmhpRBabPFAf53zuL2lOh5T6iizBTddnxyXFI_3HC7Wno3S-nA3qMhY1m3VOlVOHQvDqJv41oOCr8fzmwJGpazQeKRIK9vCLm9xNK3GWpqCk54Y55HKvzY1yEoGppB9_BGrdRh9w9TlOZhdqaDqr5kLawUv6-VEC_rBY3Lc51PaCnhu9--a9yx6HzZ0EOty4ZthWFbORkQkaXaC1M_Gf1kNbpd531aE6YviWXrdFuf4yV9cqmFMvM-O_PwgCNWbJ9ealTCDrMIYLZJctHp5uXLda4M6QwpbPVTAPsC7sa9cSSj8hMdN9DnzvVpjD505zTC2idjHJErAgBlntlbd5dopi33yzD3uhw76VprRJQNYCZu1883VKqpxcd10FEqro3LONdBSvje3NTkRIKIJ3CRT6v8gq59MRo-nDBSkmDmsCOFG7meSOsOIA6uxYtDCSTe-YeWKkg\\\\\\\",1]],[\\\\\\\"5D108930-A9DC-4B47-BCFB-3777EC2101F5\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:33:33.874Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=877763&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],275854649,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4xi_W9dEA6VWMhKDpjOjuJU842zdWXAYitUM9yT2bYZJNSB8OsAURjvBAQZWOflhaTryhcfvkzax8YuyInPOnI0fONiIFBFz7T-Tgkx51xg5X8xv4CEi7--8T3_-Qv9PfBervNe0A2RhKgl0DQQ0J8QWbsE1SgHOY-xctAt_2H2PxNKkcH5Sb-ZaNZoRsCYVDoN21AGX9zZM4BXSGxcloXaVMawExaQ83FlSZ6YM05rl_fSMmebgaAkupQwV8j9TC72_IsPFdPW__-yJEQng_yuwK8fGCMdAEtSquMf_bkXX298C1Om3YlGScIJWgtA0vWrqkZ4EpCMHc5_XT5lGF1t2RCQdh4scdlPs8JnUZIKoTgejcACbAoLLmqyVx4Iy4VJWde8g2JyoWYEotYKL9Xy29MSKLAMpTUxqCkizK0paQqsPi-GxGCzddHODtuRruigG25TwB6_dpNiDl_wlMBXAhpJePauyllTFBvUewuWuVmzbis-4agzh4WczNM_nM2EK7MneN2KF8hPH4pzU-voRJpAbZAMdY33Dt0HXlcbSZcmdgp6trEXgap0qiIMQxYPfwkKU_tt7MnjIP5ezQLta4G_xkn01Xp9iv0Hg5nVQ3DOuPizwwuX2MOjAPoKdEdOtzpSvDc_m9INJoRw6iU-49rpCAAVjF6XLNMz5pSFcSse5wyUF8ekLaE8dUbQsdb0s_FE_n7fYoLK7AWu7_cwHKV_FAjpX1igVfk7dGw3XkdOwHCCAuAT92DnXIQ2kBBSBvIYvO8AHiThfu3u7JF9B3gpSWE6rXprjJSR2V-AC_Qx4WN0HCbdWP0dSxb6yg3TRyspWGzkeyGB5ngKTCoHk8HRtH0v0OXOVhFt24Y5wEiNc9aax0dhbWLbQluirrR6M4n8yNxecL-YyZLdPayFkpe3FxtNElwKhVLcfhRBzZigdCb1ZgYbC6cWAGshkguNzy0CwHFtvL4ItsZHTtQDa8VoiVcyWwu3fR-4KR1Ah-fme7CPb7kiBBMqW3mk2F88kkUld5O-Wpbn58Go0DtcDxoblId89pjexveDJ7PaF-WbKvFrLAEOmwzxoNK1KaaBEDX2v98QrkU2s9zfcIyW4sI2un9gHCzCjv309PD28vWHx6IUo4Hhn2Y-DiTdCVV3LXqEV9JTcli8BWk4Gl3wP3ZmP8UcUWO8k0FGJdKA3SLodAqEKytx35uNOqw1JzB-ulwKPTcVoGhehJggJwUDXGamGMrnSDPGhYtRkUd2fNjCdzXUwBx_mQr5ZuhWEDE6nQmjpc4qTkHFwStuc56SXqQmauTDbXYlZL4ip4z_yrTWrjU1Zzc_zTXYHRzbbWdqxJIwE9lH19Ibw7Ofblg7y_wVASZ9HubAjXLWvYN-oJrU5VF2wKURm77uXCQH_-W1FjcdHr28BOfYF1uDc-07FkSmhMJ3Nw0Ib73MggkrufnFqie46-SgJZSYmzkHwWyUk1o-0Kegi-l-_bYBRPiiDE561LpnDjFM1N5eA5xAiXO-K4vFC8Reo6eb9MK3KQH8Fbc8y--OPsjr5EKl4pncZW0Dz-0bwkXpAt7qtk6blqweoXEv377EAVocQzsXq9LVVDPsS4reJzn9JHM9H59i33RgheKBCVcdJrV8NqpUfnhs5kVVMAZ5TD66o382-vo_lnxAVK_RbyBC29eBLmopfmmEofA4Y7ezKxb3Us20tPlNUAmZ9vRSsJZ5V2Z9KZDGCcfQpz19AqiJJaarpE2n75dxQO6c6GpxAU9oOi0uON9h6GjBAC-CmUB3cWXQYQBN1EHqGxRTqG28LTLI6uHEtuwXE5UNCbhH1OLNkh76tjyJjVdKu3U_BVJ3x43oAlnKHuz2r0euznyaYt8kmnQbEUCpdVFzlU3HExIIHrmEKcKsXabHFlzZpEXQgFRwVhR6eWEDud-j-yu02zGTb0Et-158vJ-1PlLagu6cTuCijA55J29BbDYyECkVYSBurmaEH3payFeHwMwJo8GKb-_XImoMzrtirJTouPiIKisAL-vf73boOGcuTbzqy2N5Lgek3wLgbZMeHOdEDVghuSAFoiRrqQYAKdI8SWezKwTG6sBbJxbH0l-nezkQVZTr2NUuh_q5CRhRaWcGAFtwDruR9WWZEU_Mplk0ILsjlnUcve-yH-H1bzjSrhokypYIY4Wx7w2COo-JpxmvPMDSrM8A6CR2AqzCI2Kzey6Uoo4FDKqpzzwwwrmEa_Zc6lvYha0ZQs0yzseN_OgCqYqalFzZsRi9XSZ07683NtBlsQ2zUuOyL9QVaJa3bETGK-O-6JdVuPZo56Brx_ELWe_TSzOz_o_h-cEq0RQhMgQZ3YW2YKYezS7YlhS0rIBkbGI6mnCd29fqCWXsSAG5S2vCIU1IyAgcwR_uoSLOgFAN37vSbmFALfVNy3O7wx-nAkC5ZGMuAf7YqEMiu865ll-0KjECbnC7A\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"AA74EDC9-428C-4B76-A2CC-A10BFF314455\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4xi_W9dEA6VWMhKDpjOjuJU842zdWXAYitUM9yT2bYZJNSB8OsAURjvBAQZWOflhaTryhcfvkzax8YuyInPOnI0fONiIFBFz7T-Tgkx51xg5X8xv4CEi7--8T3_-Qv9PfBervNe0A2RhKgl0DQQ0J8QWbsE1SgHOY-xctAt_2H2PxNKkcH5Sb-ZaNZoRsCYVDoN21AGX9zZM4BXSGxcloXaVMawExaQ83FlSZ6YM05rl_fSMmebgaAkupQwV8j9TC72_IsPFdPW__-yJEQng_yuwK8fGCMdAEtSquMf_bkXX298C1Om3YlGScIJWgtA0vWrqkZ4EpCMHc5_XT5lGF1t2RCQdh4scdlPs8JnUZIKoTgejcACbAoLLmqyVx4Iy4VJWde8g2JyoWYEotYKL9Xy29MSKLAMpTUxqCkizK0paQqsPi-GxGCzddHODtuRruigG25TwB6_dpNiDl_wlMBXAhpJePauyllTFBvUewuWuVmzbis-4agzh4WczNM_nM2EK7MneN2KF8hPH4pzU-voRJpAbZAMdY33Dt0HXlcbSZcmdgp6trEXgap0qiIMQxYPfwkKU_tt7MnjIP5ezQLta4G_xkn01Xp9iv0Hg5nVQ3DOuPizwwuX2MOjAPoKdEdOtzpSvDc_m9INJoRw6iU-49rpCAAVjF6XLNMz5pSFcSse5wyUF8ekLaE8dUbQsdb0s_FE_n7fYoLK7AWu7_cwHKV_FAjpX1igVfk7dGw3XkdOwHCCAuAT92DnXIQ2kBBSBvIYvO8AHiThfu3u7JF9B3gpSWE6rXprjJSR2V-AC_Qx4WN0HCbdWP0dSxb6yg3TRyspWGzkeyGB5ngKTCoHk8HRtH0v0OXOVhFt24Y5wEiNc9aax0dhbWLbQluirrR6M4n8yNxecL-YyZLdPayFkpe3FxtNElwKhVLcfhRBzZigdCb1ZgYbC6cWAGshkguNzy0CwHFtvL4ItsZHTtQDa8VoiVcyWwu3fR-4KR1Ah-fme7CPb7kiBBMqW3mk2F88kkUld5O-Wpbn58Go0DtcDxoblId89pjexveDJ7PaF-WbKvFrLAEOmwzxoNK1KaaBEDX2v98QrkU2s9zfcIyW4sI2un9gHCzCjv309PD28vWHx6IUo4Hhn2Y-DiTdCVV3LXqEV9JTcli8BWk4Gl3wP3ZmP8UcUWO8k0FGJdKA3SLodAqEKytx35uNOqw1JzB-ulwKPTcVoGhehJggJwUDXGamGMrnSDPGhYtRkUd2fNjCdzXUwBx_mQr5ZuhWEDE6nQmjpc4qTkHFwStuc56SXqQmauTDbXYlZL4ip4z_yrTWrjU1Zzc_zTXYHRzbbWdqxJIwE9lH19Ibw7Ofblg7y_wVASZ9HubAjXLWvYN-oJrU5VF2wKURm77uXCQH_-W1FjcdHr28BOfYF1uDc-07FkSmhMJ3Nw0Ib73MggkrufnFqie46-SgJZSYmzkHwWyUk1o-0Kegi-l-_bYBRPiiDE561LpnDjFM1N5eA5xAiXO-K4vFC8Reo6eb9MK3KQH8Fbc8y--OPsjr5EKl4pncZW0Dz-0bwkXpAt7qtk6blqweoXEv377EAVocQzsXq9LVVDPsS4reJzn9JHM9H59i33RgheKBCVcdJrV8NqpUfnhs5kVVMAZ5TD66o382-vo_lnxAVK_RbyBC29eBLmopfmmEofA4Y7ezKxb3Us20tPlNUAmZ9vRSsJZ5V2Z9KZDGCcfQpz19AqiJJaarpE2n75dxQO6c6GpxAU9oOi0uON9h6GjBAC-CmUB3cWXQYQBN1EHqGxRTqG28LTLI6uHEtuwXE5UNCbhH1OLNkh76tjyJjVdKu3U_BVJ3x43oAlnKHuz2r0euznyaYt8kmnQbEUCpdVFzlU3HExIIHrmEKcKsXabHFlzZpEXQgFRwVhR6eWEDud-j-yu02zGTb0Et-158vJ-1PlLagu6cTuCijA55J29BbDYyECkVYSBurmaEH3payFeHwMwJo8GKb-_XImoMzrtirJTouPiIKisAL-vf73boOGcuTbzqy2N5Lgek3wLgbZMeHOdEDVghuSAFoiRrqQYAKdI8SWezKwTG6sBbJxbH0l-nezkQVZTr2NUuh_q5CRhRaWcGAFtwDruR9WWZEU_Mplk0ILsjlnUcve-yH-H1bzjSrhokypYIY4Wx7w2COo-JpxmvPMDSrM8A6CR2AqzCI2Kzey6Uoo4FDKqpzzwwwrmEa_Zc6lvYha0ZQs0yzseN_OgCqYqalFzZsRi9XSZ07683NtBlsQ2zUuOyL9QVaJa3bETGK-O-6JdVuPZo56Brx_ELWe_TSzOz_o_h-cEq0RQhMgQZ3YW2YKYezS7YlhS0rIBkbGI6mnCd29fqCWXsSAG5S2vCIU1IyAgcwR_uoSLOgFAN37vSbmFALfVNy3O7wx-nAkC5ZGMuAf7YqEMiu865ll-0KjECbnC7A\\\\\\\",1]],[\\\\\\\"80C1FA03-ADB4-40CA-9951-38805F82B63D\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:33:56.661Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=482647&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1],[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1]],314608653,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7ckwhKx-bYZ4frukWjFRRGvjp4Hh8RuDJ3Mxn6PFwQEyPpzSi2YkTEXTID66RphZgqG6poKHTum42a6WzxKxzTSwVeAJ2iDqXai9ZagWkAeT0CrQTzs55iKo0-mSX81ttQuZDZmVyEpLNngE5--VZ5aJrsEt3NAl7fLaddxkOKNrWjUpMhrCOZQrLVGmfr-p7KIyn7V9KMmzdknEAnc4XULqvCazamiZVGCTd4iq0P6-Nl8Hh2_tqTCAXwr9Bsw_ughrEeEhGX3S5zIEPF3zphM7KOfWBZ-rsOIq9IWvTh9Tc9nShrIeE8FTlWl5Y4eM7eMbcYS35ZcNQGTTHns_kH-KcaX0cjDjOaPt4sGGn0-wY5rgLJlQ7Pg9iyySQA97V37CDxQUeeX7ecqoWVhv_ad33rGNtmYw2DNm1XQER70LulSDVZMq_zDDzCZG3nZ_vQLUe0WosAnYv2_nm96pOIR8UuyWwYFG8Fjx2TTNfMqhT1-PydNLXsNqiAHdzE_n8ZcGSGlsDyAszx7vu6GHDAi5RDzP3AUQtf70iSMVkhJNjY_BxyAd9e-kVL9ZN4crxQDZM2GIDF-ZnGB5HUdvJ5QXwvqdVEjDY73lFt753D0b2sNB0yqiQjTsOcDBi43DUB82x388IGxXNtBTdWiIRFzD-cPC0ibF0QGEKfsC_SFRDbrpBmPOfxgVY9AsqyGvZVPaYU5-8Nxliq1zLXqBuQMFLHJm9MdQWUuUHBkb9mmjuPkSroRpz_x7sJAQWtmS4URo0BEQlziTKfTnFi8H2NQuX285avBGTmgqGY2piKitsrJW_nK3YEcvlbQLMTh8iyNp71yE18pAfRRYa8l1BN690zP33Nbxdd9Ik1M-tmcvANu-niiGaD_eOs4DjPF5i5w0mLs_u3sju2juZZVqjENlrG93W177dLcEjGMXEpiaia12Tt3_-eW41AporjlwdWgwnG-PiZOqhZ7pAts_ENXU2W8SXL_SO2qbXjIqPliTL0ENtAl1lBCS8xgpWh3MGLLkhzu3fMyGZshpzxczOLXlf6qFB2t59XuIT78DGeNd3JA_A0Dtt5S9AXiXfMXnbJ1H248H1D71bgkZvD-128v4ewMpshQMpH8I3Gik9xivH20zX39f3Z_7GJcHk02uZL11ro8gSyOPQrmnjZRWLcWBX6bgIRKYegNdfsO8tEfdB0A64DiY4fYogczj9uoKHszfvFbiSY9_TMbuejUTbZ8PBHglEwuzTN4HTEgQ7bRZgv8dpCmbVOy6FDMvUwq1dH6hKHvidNcb5sq0qk-M8dDZ3i8dgLpgNeg9KtpshwvojcAoO6H1wgkrx61i9mq0r691UpgBa7xUNiN-p5azbKbDGPR0nyqHeRXjUCudcg4jYViT4pb6dESr_UDHc24BW-vMcfIsPTk6ABWWpyPhy4h0joGFDONlSvLBe6y7whDK_gyddNRLkJJtEYpGDHmRVL97EHaLKINqZtPzytvKDjJKilQrwUULvA7GHnFAVEfyyT2RNQQo4WI5ggx_AVU_AeHy4tJuyfTXXLRPc_SMqjMGINYGfEn18L5HF0jTX1PM8EBOKTzVMVsV7sFIw67De4vNeeZASiqiFxjUlVKm5hZ8Rtua7uDJ9_qfFe5_hebBrhoII3F3pf_3x72vtoq21MOtwFeKzBXIEyRcpSeflUytjeErdRBZNl_kKoFfPzsBpCgdihuQVOomcnjOhizyYrboVi_4fqpbhSBHmJ2SeYmiUtTk89QxRzsGCTvbo_EIIjMBup8WRkAcVoXbLgrXKQkljfh7ETzWCjJshB6Xseqh3z5cnN32wy1Dzc48TACHzl1sX9wHjP7oGLJc7Lvne6VN-X90Q3aBTGJo6SuHCKA1TczKSTJ_6hVU8yKy16zfVgweUMLL1bMKpXwYrIMn60GwhOlcblpD4v_0jKqG8BKMOqGISTrWvF3v4YD_yFxQBH49CZRlpx1lHL8KlOdfxFaXl87nb3MfR2zrkdiTGwLtC-USTtEs8VN-0ibWAgqFolwSh7MY-Jrqb1wXWJidbXy87jHqBWl9A2QiZwvxH2jtKeKzv8yEk-AoiCKm23KdQCELRWEbRm7TmP7mrigZfuXAOTR9yjYg9TDKpXCsYTo866Eua7knozrhw2h1e2BpfblHQyrMuczQiSAoZH_Z38b-lxn5QEvTs4kgxyfNQ1WmhB6CeFCx7niNTsoSFFdMXTaxC1Y86eb6CrFy46-zDwZDB9kdjbVhTc1L2liKt3QwhHhXA1YXzhawZwHQ3JiRtOJsaGpZ9YmHg4jZbRa8hKHWUoH15hFGHErAXgOcv9bZltLCUwEkO0oDXSBlP2At-Vh6WosezwwpFcwAJLSilIkLVYMxdp94kOXWHI4Kijj9NIcXZdCUWVGiNBQSdpJ-M57Qnv3CMhIY73De62vtj6Z5YTUY7oh798oqA8ycrr4kGzDQ\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot inside subterranean B3 basement parking at Me Tri during extreme heatwave. Le Quoc Tien slumps against a cracked concrete pillar in defeat beside a torn empty water pouch and heat-warped debris. Do Minh Kha looms over him in the background with a cold detached expression, silhouette backlit by an ominous beam of deep crimson sunlight piercing through a fractured ceiling fissure. Chiaroscuro high contrast cinematic lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"658FB113-ABCC-4436-899B-B885C9020EFE\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7ckwhKx-bYZ4frukWjFRRGvjp4Hh8RuDJ3Mxn6PFwQEyPpzSi2YkTEXTID66RphZgqG6poKHTum42a6WzxKxzTSwVeAJ2iDqXai9ZagWkAeT0CrQTzs55iKo0-mSX81ttQuZDZmVyEpLNngE5--VZ5aJrsEt3NAl7fLaddxkOKNrWjUpMhrCOZQrLVGmfr-p7KIyn7V9KMmzdknEAnc4XULqvCazamiZVGCTd4iq0P6-Nl8Hh2_tqTCAXwr9Bsw_ughrEeEhGX3S5zIEPF3zphM7KOfWBZ-rsOIq9IWvTh9Tc9nShrIeE8FTlWl5Y4eM7eMbcYS35ZcNQGTTHns_kH-KcaX0cjDjOaPt4sGGn0-wY5rgLJlQ7Pg9iyySQA97V37CDxQUeeX7ecqoWVhv_ad33rGNtmYw2DNm1XQER70LulSDVZMq_zDDzCZG3nZ_vQLUe0WosAnYv2_nm96pOIR8UuyWwYFG8Fjx2TTNfMqhT1-PydNLXsNqiAHdzE_n8ZcGSGlsDyAszx7vu6GHDAi5RDzP3AUQtf70iSMVkhJNjY_BxyAd9e-kVL9ZN4crxQDZM2GIDF-ZnGB5HUdvJ5QXwvqdVEjDY73lFt753D0b2sNB0yqiQjTsOcDBi43DUB82x388IGxXNtBTdWiIRFzD-cPC0ibF0QGEKfsC_SFRDbrpBmPOfxgVY9AsqyGvZVPaYU5-8Nxliq1zLXqBuQMFLHJm9MdQWUuUHBkb9mmjuPkSroRpz_x7sJAQWtmS4URo0BEQlziTKfTnFi8H2NQuX285avBGTmgqGY2piKitsrJW_nK3YEcvlbQLMTh8iyNp71yE18pAfRRYa8l1BN690zP33Nbxdd9Ik1M-tmcvANu-niiGaD_eOs4DjPF5i5w0mLs_u3sju2juZZVqjENlrG93W177dLcEjGMXEpiaia12Tt3_-eW41AporjlwdWgwnG-PiZOqhZ7pAts_ENXU2W8SXL_SO2qbXjIqPliTL0ENtAl1lBCS8xgpWh3MGLLkhzu3fMyGZshpzxczOLXlf6qFB2t59XuIT78DGeNd3JA_A0Dtt5S9AXiXfMXnbJ1H248H1D71bgkZvD-128v4ewMpshQMpH8I3Gik9xivH20zX39f3Z_7GJcHk02uZL11ro8gSyOPQrmnjZRWLcWBX6bgIRKYegNdfsO8tEfdB0A64DiY4fYogczj9uoKHszfvFbiSY9_TMbuejUTbZ8PBHglEwuzTN4HTEgQ7bRZgv8dpCmbVOy6FDMvUwq1dH6hKHvidNcb5sq0qk-M8dDZ3i8dgLpgNeg9KtpshwvojcAoO6H1wgkrx61i9mq0r691UpgBa7xUNiN-p5azbKbDGPR0nyqHeRXjUCudcg4jYViT4pb6dESr_UDHc24BW-vMcfIsPTk6ABWWpyPhy4h0joGFDONlSvLBe6y7whDK_gyddNRLkJJtEYpGDHmRVL97EHaLKINqZtPzytvKDjJKilQrwUULvA7GHnFAVEfyyT2RNQQo4WI5ggx_AVU_AeHy4tJuyfTXXLRPc_SMqjMGINYGfEn18L5HF0jTX1PM8EBOKTzVMVsV7sFIw67De4vNeeZASiqiFxjUlVKm5hZ8Rtua7uDJ9_qfFe5_hebBrhoII3F3pf_3x72vtoq21MOtwFeKzBXIEyRcpSeflUytjeErdRBZNl_kKoFfPzsBpCgdihuQVOomcnjOhizyYrboVi_4fqpbhSBHmJ2SeYmiUtTk89QxRzsGCTvbo_EIIjMBup8WRkAcVoXbLgrXKQkljfh7ETzWCjJshB6Xseqh3z5cnN32wy1Dzc48TACHzl1sX9wHjP7oGLJc7Lvne6VN-X90Q3aBTGJo6SuHCKA1TczKSTJ_6hVU8yKy16zfVgweUMLL1bMKpXwYrIMn60GwhOlcblpD4v_0jKqG8BKMOqGISTrWvF3v4YD_yFxQBH49CZRlpx1lHL8KlOdfxFaXl87nb3MfR2zrkdiTGwLtC-USTtEs8VN-0ibWAgqFolwSh7MY-Jrqb1wXWJidbXy87jHqBWl9A2QiZwvxH2jtKeKzv8yEk-AoiCKm23KdQCELRWEbRm7TmP7mrigZfuXAOTR9yjYg9TDKpXCsYTo866Eua7knozrhw2h1e2BpfblHQyrMuczQiSAoZH_Z38b-lxn5QEvTs4kgxyfNQ1WmhB6CeFCx7niNTsoSFFdMXTaxC1Y86eb6CrFy46-zDwZDB9kdjbVhTc1L2liKt3QwhHhXA1YXzhawZwHQ3JiRtOJsaGpZ9YmHg4jZbRa8hKHWUoH15hFGHErAXgOcv9bZltLCUwEkO0oDXSBlP2At-Vh6WosezwwpFcwAJLSilIkLVYMxdp94kOXWHI4Kijj9NIcXZdCUWVGiNBQSdpJ-M57Qnv3CMhIY73De62vtj6Z5YTUY7oh798oqA8ycrr4kGzDQ\\\\\\\",1]],[\\\\\\\"85FCAB29-DD00-4032-8AD2-15F7B36A484D\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:34:03.919Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=ogiZ0b&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=476601&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"ogiZ0b\\\",\\\"[null,[[null,null,[[\\\\\\\"78e46231-e6cf-43fb-99bc-a4cb96196e24\\\\\\\",null,null,null,1],[\\\\\\\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\\\\\\\",null,null,null,1]],785346768,3,\\\\\\\"GEM_PIX_2\\\\\\\",null,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4PfOLAYyYtYTiDl5oPpG4VKwQ1N40yiI_2WEBcz-Twxgnr6BkmQmkFHtbnW2apZi89ctGksIEjVq3mU2MaZKFmQf3an-jGBDScmNVifAV40MxTtg9iABfPxluF1D2WGa2KoHb6ZgD6xA_iDQ9hw8wX7TwlnEnO2rGJb-zNyXYOcX_kWbiGLz_OpUmYqwp5coyICWUDmniqW7n9WVT87WNv3szVFjDwGRnnBHvYQBIjf2Qut6PbyU9392tzj0xCDpWh48sEfRo0Y__3_UPf3D56czuFq7kErXIYVgRpghjMUO3l6--QS5xdRD7j2aComCKMOLO0sQuCMSJuMx7kqBIZkJvtF7OxsFsa8g0iS6972eDpc0EplmmdMkmb5p1SRxJGIFnSMk_gYtHlwC3hkvg4EnJOhrpdDxrrkGVEr9_LqWcTO7vEYPM6s-ojX7uWJ2GmFYtu9uUPeLNb4mu34PG7EM92-Mi4R9L1EDHBvqcU2naXWg2Ukf77QlZCdq9OxhczeGxTARS6w78XtIWevHCFEikDqdmE0Up6nlifK1R5tjWYLxbHOw6xaj67rOqqgr8G6ln6ofSptQs5ODtwoWTPNGSlDgVEPcP9DG7sUOuBdMMrFEuDU6iyUwTys0h2kV6HOlFhb8zVQHtiFpa7YmYaaJRwgD9WdoHfQadMX-XvpacAafS0MfiVqShuR3r2sddr0n14w-9YROD3WWUszTukyDZIissyBdqNvfY20ZaeFcfTMBJeOklcWs1RhGfWNpPXbPC8Vp3zOOZbh5-a9HjMzPA0acbYyF3L9FCzL9koHiIXPcyJMK2m1ozCSpT6HhHqSrU6RvYuZ4cINTWygQe4GlZiTwmGhjQjs1WsmcGnOxtX-Jx5hKIh6MUrdjO0SVMlc-A_oUqawBGSSxnp1wC9OGmmbcC9bQDnrpiNo8A6r7OBZd6M3ubKif1QJ8nGy1B63oq2KozVvfiv-6uPTvxEHUGkLvUwJ_HoPsZYKD1uavHXNXom-ad0H2NPAURb38dOpitedthwV0czqOe0CRVpPkhTXxzH-A8zDh35eYA5s_rR1sasxi7tn0y8cKCnia3ZlTSQV7O24tFXR3YYyynC57LBpsEtDQ5LQ4P3XXhImzmFppEGgTMx8Y-ckPSVXYlTSBzealkQ_ZRYsGciDXblEKM5gk6hptu-BG1o8InZdfAcm9N5lqE89mO9iQuvOnmw4D1EQOOWhLMgXBAe35CW2Pyb8-i5v3X6tjibiuieyW7jNBgI7422hieUSmbm1wLx-hE-xafrmdUE0y7VjXzFABSoyohmAAOz7Ls4raHb2oPeJVf5wT8d9KVmhXAbwmC-3wWtYCcvLbUMNF1MCtLk1FE81AO9ALEc_8Jo6msssubOWjVnVaGyXLLKKKvQ8wLF9KcECd8vqd-f7t6a-N18YY5o_gAPosdwq8diyEIIocM6n9rRT6xQUGJ_aleyrWYSzb2LTqeP8pWwkxEGjcXHu2fV-fRKITQuOCKxmAlXKG-6xUHT4XJ38PsD6Vhc1WMLW93oum2zSfEm1gozvoagZAxZwoWPxb2WH1VFO5MpzATCDjxAXFfWQD3lejYNg6K0JpXjZtY6yn7bJJhbjnEdrA6s_EtB2I9W7k3WADPscOXNREWASpg7c6fV_KoiOf2QHhn3DQoGcyYAPsE5P000S6ZpotiEQRtA07oRgpZh-q8wzG72jndrmjc4lD3pZ3pf1GhMddzsYNx2K7P6h6nIdkqGe2sxLeYW7-J_qwA1BUJqQUWlwdJr6now7FWA9RVNRsH6SB6Fz8cH-d1dW4nYom96pDO9_mPKdp9tZ7NOJOoVJZ8LWkNtXl1LSYzHxXBunnisGvv35GgnMfjoEXhCsroHtItacHTxsnK09owgIOnX9K-P_ZVXPyWp18wB3eIKBZ-kewcQYN_gR_H9_VlDVKsGwfEmJ9GGvIsaMwWh1UUI_BhLLz4vA3aBhoRVq5zptyNe6bbt7QHK6R9mTXxcc3O8nG8pu6OCwguxhhaZz2dmmFpcoRe5hSlJQEF0OUHOvJPCYQ-kpp4Kt--vi-VO_gA9Pwh-LDdfHDUBBEYkuVqoodt2-9vIU0QXD8Pc5TSze7MNKiU2HDrVBQe981hknSHwZXTZ7sTYPb3cXwQFJDlP0KYuPGnas_jGFAuYdPhrETQQ49zrF_Q_g4EqZ-SVrbxMOiPaVOS4Hhc7VWZqjog3yRE8D4UGv7MTgIu2hwGGGeau-gFUtXL4YsHxpWFYVwMFimcQK-4aP9Ul0l67Q8Uo_zul5bENAkMKCAMRXR9vmy2o6By9WPiimqcJ8aF70Udlj1-bq_0sZ2aH85fSSx-ZW_rMbYmmyhxLFDeThQfMbdjiPpR9grxA--VkcOpMmcn1a01tOs3myDaV9D2UU18rhIb2ifDvJ2tg4xkdMDmTb_kJDjnLG9dQwuPcu30oESgY9A\\\\\\\",1]],[[[\\\\\\\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\\\\\\\"]]],null,null,null,null,\\\\\\\"2BE60259-0587-4B76-909B-A36EE82522F3\\\\\\\"]],1,[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA4PfOLAYyYtYTiDl5oPpG4VKwQ1N40yiI_2WEBcz-Twxgnr6BkmQmkFHtbnW2apZi89ctGksIEjVq3mU2MaZKFmQf3an-jGBDScmNVifAV40MxTtg9iABfPxluF1D2WGa2KoHb6ZgD6xA_iDQ9hw8wX7TwlnEnO2rGJb-zNyXYOcX_kWbiGLz_OpUmYqwp5coyICWUDmniqW7n9WVT87WNv3szVFjDwGRnnBHvYQBIjf2Qut6PbyU9392tzj0xCDpWh48sEfRo0Y__3_UPf3D56czuFq7kErXIYVgRpghjMUO3l6--QS5xdRD7j2aComCKMOLO0sQuCMSJuMx7kqBIZkJvtF7OxsFsa8g0iS6972eDpc0EplmmdMkmb5p1SRxJGIFnSMk_gYtHlwC3hkvg4EnJOhrpdDxrrkGVEr9_LqWcTO7vEYPM6s-ojX7uWJ2GmFYtu9uUPeLNb4mu34PG7EM92-Mi4R9L1EDHBvqcU2naXWg2Ukf77QlZCdq9OxhczeGxTARS6w78XtIWevHCFEikDqdmE0Up6nlifK1R5tjWYLxbHOw6xaj67rOqqgr8G6ln6ofSptQs5ODtwoWTPNGSlDgVEPcP9DG7sUOuBdMMrFEuDU6iyUwTys0h2kV6HOlFhb8zVQHtiFpa7YmYaaJRwgD9WdoHfQadMX-XvpacAafS0MfiVqShuR3r2sddr0n14w-9YROD3WWUszTukyDZIissyBdqNvfY20ZaeFcfTMBJeOklcWs1RhGfWNpPXbPC8Vp3zOOZbh5-a9HjMzPA0acbYyF3L9FCzL9koHiIXPcyJMK2m1ozCSpT6HhHqSrU6RvYuZ4cINTWygQe4GlZiTwmGhjQjs1WsmcGnOxtX-Jx5hKIh6MUrdjO0SVMlc-A_oUqawBGSSxnp1wC9OGmmbcC9bQDnrpiNo8A6r7OBZd6M3ubKif1QJ8nGy1B63oq2KozVvfiv-6uPTvxEHUGkLvUwJ_HoPsZYKD1uavHXNXom-ad0H2NPAURb38dOpitedthwV0czqOe0CRVpPkhTXxzH-A8zDh35eYA5s_rR1sasxi7tn0y8cKCnia3ZlTSQV7O24tFXR3YYyynC57LBpsEtDQ5LQ4P3XXhImzmFppEGgTMx8Y-ckPSVXYlTSBzealkQ_ZRYsGciDXblEKM5gk6hptu-BG1o8InZdfAcm9N5lqE89mO9iQuvOnmw4D1EQOOWhLMgXBAe35CW2Pyb8-i5v3X6tjibiuieyW7jNBgI7422hieUSmbm1wLx-hE-xafrmdUE0y7VjXzFABSoyohmAAOz7Ls4raHb2oPeJVf5wT8d9KVmhXAbwmC-3wWtYCcvLbUMNF1MCtLk1FE81AO9ALEc_8Jo6msssubOWjVnVaGyXLLKKKvQ8wLF9KcECd8vqd-f7t6a-N18YY5o_gAPosdwq8diyEIIocM6n9rRT6xQUGJ_aleyrWYSzb2LTqeP8pWwkxEGjcXHu2fV-fRKITQuOCKxmAlXKG-6xUHT4XJ38PsD6Vhc1WMLW93oum2zSfEm1gozvoagZAxZwoWPxb2WH1VFO5MpzATCDjxAXFfWQD3lejYNg6K0JpXjZtY6yn7bJJhbjnEdrA6s_EtB2I9W7k3WADPscOXNREWASpg7c6fV_KoiOf2QHhn3DQoGcyYAPsE5P000S6ZpotiEQRtA07oRgpZh-q8wzG72jndrmjc4lD3pZ3pf1GhMddzsYNx2K7P6h6nIdkqGe2sxLeYW7-J_qwA1BUJqQUWlwdJr6now7FWA9RVNRsH6SB6Fz8cH-d1dW4nYom96pDO9_mPKdp9tZ7NOJOoVJZ8LWkNtXl1LSYzHxXBunnisGvv35GgnMfjoEXhCsroHtItacHTxsnK09owgIOnX9K-P_ZVXPyWp18wB3eIKBZ-kewcQYN_gR_H9_VlDVKsGwfEmJ9GGvIsaMwWh1UUI_BhLLz4vA3aBhoRVq5zptyNe6bbt7QHK6R9mTXxcc3O8nG8pu6OCwguxhhaZz2dmmFpcoRe5hSlJQEF0OUHOvJPCYQ-kpp4Kt--vi-VO_gA9Pwh-LDdfHDUBBEYkuVqoodt2-9vIU0QXD8Pc5TSze7MNKiU2HDrVBQe981hknSHwZXTZ7sTYPb3cXwQFJDlP0KYuPGnas_jGFAuYdPhrETQQ49zrF_Q_g4EqZ-SVrbxMOiPaVOS4Hhc7VWZqjog3yRE8D4UGv7MTgIu2hwGGGeau-gFUtXL4YsHxpWFYVwMFimcQK-4aP9Ul0l67Q8Uo_zul5bENAkMKCAMRXR9vmy2o6By9WPiimqcJ8aF70Udlj1-bq_0sZ2aH85fSSx-ZW_rMbYmmyhxLFDeThQfMbdjiPpR9grxA--VkcOpMmcn1a01tOs3myDaV9D2UU18rhIb2ifDvJ2tg4xkdMDmTb_kJDjnLG9dQwuPcu30oESgY9A\\\\\\\",1]],[\\\\\\\"E1EBBB69-0118-4F27-ADD1-F71D29C1C559\\\\\\\"]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:34:59.051Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=eb1hJf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=836687&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"eb1hJf\\\",\\\"[[[[null,null,[[[\\\\\\\"0-3s: Low-angle tracking shot through heat-warped plastic debris and scorched concrete in subterranean B3 basement at Me Tri as Do Minh Kha walks slowly past motionless casualties, boots coated in red dust. 3-6s: Camera tilts down as Do Minh Kha crouches over Le Quoc Tien who slumps against a cracked concrete pillar beside a torn empty water pouch. Do Minh Kha speaks in a hoarse parched voice \\\\\\\\\\\\\\\"L\u00ea Qu\u1ed1c Ti\u1ebfn, m\u00e0y v\u1ed1n kh\u00f4ng n\u00ean s\u1ed1ng l\u00e2u \u0111\u1ebfn th\u1ebf.\\\\\\\\\\\\\\\" 6-8s: Close-up of Do Minh Kha raising a gleaming tactical blade reflecting the deep crimson sunlight bleeding through a fractured ceiling slab, then plunging the blade downward into pitch black darkness. Audio: Stifled gasping breath, slow crunching footsteps on gravel, hoarse menacing dialogue, sharp metallic blade unsheath, deep sub-bass cinematic hit. Negative: subtitles, watermark, text overlay.\\\\\\\"]]]],\\\\\\\"veo_3_1_i2v_lite\\\\\\\",2,null,[null,\\\\\\\"bdcbe55a-ee7b-497d-a414-25d22d04c096\\\\\\\",null,null,null,[null,0.0038759689922481244,1,0.9961240310077519]],[null,null,null,null,\\\\\\\"ED10EBF6-DCFB-4D9F-A450-6E0B1AEEFCA5\\\\\\\",\\\\\\\"7C58CE0F-81E0-4079-944A-9F28392F5CE8\\\\\\\"]]],[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA7UoedpUZQQ9pVdbXQw18opVHeTxleUPvaQwIFTFbfTmys1ZH5_i-xR_hYnesuvf-XgDhHgbACVJ3SJ_8W6fjuY8dCxTLR-JJemy9B5dd0xB6_RpOrJPm4oy_E3Io_K_P5V4fOMuW46fhST0_pElCzQntwQSSxnE3MFBh7K_Loh4KAL2yxraH-JXyQ3bRXzwxZJXy5R4PUxMHLigCh4IoOShkxwpjj4ZwZjeyqgK1lrO3hT9ocHd-Ax-UWdDME-WTltiCVORyXLZQ6Vsasp8-NPsbcQnIglRCQu8hMmMGNB8gbxDz79cx0XNaPytVFw0HK3LZyzEY9hXsuf7JYESnOHqUoga3OyWKwpOF4Y6vy3pEeE3cpSJ5YWVqgezWhP8YMVeyFucV-kvhBIClwQMLJa2U2KZD4wLy-MiDmsJa3inHJ1qF-YgImGVXNU2s6FkREFebh53jISOjy-JDT2PQ3F7Ue7BY2_wFeJRrKEuX1Sxejh_eWCH5VcdVnNB9Xv4cwzN4YEVbts_6vtFzaaYD4utR0wfQJdXo4vUOB0BWUGU2-ZDlOJEgtI1323IOrx2WxUOMYfueT4EtGseOgrucogHLFmpjGilUiN3vdgXVjDPxAXxjgDdU2cDZg7UsVNtzMK6j7nfOvEDR9_QXxW97JuJvu94SQ5YSfmWW9y-xXkWbnwGPwZF74Y7YV9LM3xLu5j8J-b78FxA1F3fTXrVZ_uqe6SOeNNUVBmedBKGuEonMIttgYsc0bqR2wvDS2504lbQzIdCgjQkpS4uXhWHBz45YgkgCTKKm-MlPK5gjGAGIYTAqK3WLQi2QQHD8mzjKy0kFXktkVekYaDEOI3VBsyWDMVIwWTiJcdtLLuXKQP5gJm8uxUoKLsndv_b7gfEVYFQ-m8Mgxe4ThPMHrwxsPGRQ7ZGBx83seCGoO2SyLifxUrWwiu6gc5kxQvjZklbcdCudIuVcKK-DUDJcAJ2cnUkLh5ujmm5hT31bSPAtoOhXc2-vRuy9LFivxF-bx7QNjx4pcm4qXEsuOMyOkY-ObR2TLMqDyVpXJH1AY6EVJFCY06EIUQD5jllXFIcUQmpAUFpKApFs8XcT7M8lelBI4nHoTyTbg7m5HH_g8wpv-XouCk0YTHPIq3gs7FHtoaYOHOuLgIPA0w9ILZ-gr2Yw43gTZ3zCET6rL4mSYm0nSrSM87kakPfNnt8ADk841k0oVqSkL2xp0t357rO_z1j5gUZcHJ6zD13pHM8l2xoc_SPDqwwNCk8sWl_6xQ8_MxSN0RyD3tGmsDQsGDQrFupG1DnEUnSN8xhsJ8Wzm2v-ZjAbbeB613JsKecqivpsmh3QU_jCqHJdcdhjioPorEXl_iMvh6zJykI2iVchg11Ko6q46WdSMcTb1KRuKDQxaDtPR1f_fJkIiguukPYc840JOM9OSy-ICekyvk8Id_ybdlNjTgPiLmjLaJU8jR5sKDuslRsawpFQjg8ZDTBYHs-dy2JBmHGNfT63wCKg-EUG27on0sbRQ_eqR1e3kz-Jidz0eoP3Sknoh1ax4p8TSBbcZ21KqlThhJXNSe5HXW__Tab8wIOKaU-FT0s832VQY3aBQ4gmyXpoiS3D7pFM1nXzGDyeNTpqnnP-YyEFtY7SZx5hMuniW-hywDGETHlTb9CjxXjUXgIso0C3oQpSru2eVkWX4d0NxAAupYxYWqe2HDGIP0wFWI1GLVONZIny6uNypI_W5nuQt0pmuXnK0Ta3fAq-PtDXah1jyv5YLkPtYHYSoD3WZeN2qY4Y-kytKDKZKEYUmCuhvx7JbgMX68xeSzmL9oCX8lvi2H4cJJ6psXnukSfuJwGcud8dar-6MDI0D2k-ydlih3g0_vKzfnJIg59NXJ-yTM_DBwNayA9okEIaCok5gh9l8iy64E8256JxPDtUzDTswQSCkrEW3oN5-Ktrcw4dsNlL8x4k9tpYkySOk22C5-QYaaYZgy9R-PnJd6eeGH9k3XOD9Q6J6bcDWhwHPuYOyzIvW7CM0AMXbSO_yltFUJwdT_XlwHPKlfiHlS1LODOYtlL5cpHkLumcusF-AESq-RbiNEtFWFvsBgoR9BUMzmVGWhU8ERwJNO7j5P7XqVZM2coT4hXotdQ7fsSCNKTCv8bHvmYSa0zEsL22x9GLMjPJHXYldyQM-ujiG8vZqd09GJx4Ac2Sq6WyxLDUQcn9vXLHzhTiwOcBxXlL77oETNOa4-5oSviT-3L3Czi6l989g25CslxJ8Un2Z8lBsVocDCadl4fHQW7khgNMby9nHj6M50Lk0uG0bl65TuDedaca8Afk31LpniczWKco2-nT6EaZFvNf9rw1-6P69YS2aSuAlfPSBcHzDiKPqXA5s4Rjb3D881nVboJ3XEPjIixd3lWXpqM66o7Ml1GYSKZqX90QYK0ugNz4AJ1uhIHQkb1MyC2wOz2-nB3EkXzF83BG0v8AUS2hU1gCKtdF6eqkBnT6omxSi8wfgP0nNbjndK\\\\\\\",1]],[\\\\\\\"431391A8-8AD9-495B-B597-B48EFC110EE1\\\\\\\",2]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:35:13.860Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=120836&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:35:14.419Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=519275&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:35:15.657Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=767004&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"acfab455-1ea6-4342-9f77-6980931191e9\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:35:26.075Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=881040&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"acfab455-1ea6-4342-9f77-6980931191e9\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:35:36.511Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=793277&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"acfab455-1ea6-4342-9f77-6980931191e9\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:35:47.011Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=507785&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"acfab455-1ea6-4342-9f77-6980931191e9\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:35:57.400Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=as29s&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=484103&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"as29s\\\",\\\"[\\\\\\\"acfab455-1ea6-4342-9f77-6980931191e9\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:36:07.776Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=133832&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:36:08.354Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=687365&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:36:19.507Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=846490&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:36:20.039Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=307656&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:36:31.240Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=204772&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:36:31.846Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=126862&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:36:43.128Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=274645&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:36:43.672Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=550696&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:36:54.917Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=902395&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:36:55.524Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=735343&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:37:06.579Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=732662&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:37:07.164Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=428849&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:37:18.297Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=403016&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:37:18.869Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=482869&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:37:30.407Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=943611&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:37:30.968Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=635711&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:37:42.333Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=130904&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:37:42.906Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=449576&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:37:54.021Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=141389&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:37:54.709Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=662206&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:38:05.860Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=514666&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:38:06.478Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=672489&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:38:17.674Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=284421&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:38:18.310Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=672217&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:38:29.476Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=830575&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:38:30.038Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=228952&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:38:41.240Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=869891&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:38:41.801Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=903508&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:38:52.908Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=635587&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:38:53.481Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=281464&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:39:05.251Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=982190&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:39:05.857Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=713378&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:39:16.987Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=514501&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:39:17.587Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=212790&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:39:29.907Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=220095&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:39:30.555Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=573135&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:39:41.677Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=842271&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:39:42.269Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=979840&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:39:53.451Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=598114&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:39:54.002Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=429825&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:40:05.147Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=129932&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:40:05.720Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=377093&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:40:16.777Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=589057&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:40:17.422Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=332572&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:40:28.494Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=573674&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:40:29.087Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=126423&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:40:40.207Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=875866&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:40:40.764Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=482156&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:40:47.463Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=331165&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:40:51.932Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=714688&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:40:52.506Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=253399&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:41:03.532Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=358774&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:41:04.158Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=999531&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:41:15.352Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=356379&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:41:15.954Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=234202&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:41:27.269Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=385323&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:41:27.886Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=232235&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:41:38.907Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=310126&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:41:39.479Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=788694&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:41:50.598Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=516710&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:41:51.184Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=776562&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:42:02.437Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=319540&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:42:03.037Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=915775&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:42:14.103Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=752966&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:42:14.666Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=653216&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:42:25.704Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=152111&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:42:26.299Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=990870&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:42:37.372Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=583673&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:42:38.046Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=933835&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:42:49.540Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=547072&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:42:50.132Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=158498&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:01.243Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=927915&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:01.906Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=233382&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:13.175Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=670629&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:13.762Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=249295&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:15.488Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=maseQ&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=377839&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"maseQ\\\",\\\"[[null,22,null,null,null,\\\\\\\"594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,null,[\\\\\\\"0cAFcWeA5sSvd8B977BDkEJiTttL1GNyyHbcqoTKrV-qQDVafR-aA1XD9xGEBapDM_0Bq88_NE7WOdRjCNto6fvEz6Ndk6LRuSx_fyc2Bpgf7YNN00EzmqJCqS_Sci0-PCiki9s8D8xcFA0LH1Cz5X_jlRpVaOIYcbZ3BCBsFxGgBZJuYo0B0QFuzbhwl8vstyW4qjAQfen9-TRAXdQz_mxnwW-v8qOrJUUpgBqktV0jUcmPMC0x71Lgv8YSCVbLIKA0s2WWuPEPc9t4w7pYB3oz158No18L09LdwT5xj2LkVLrlmCId45zO-QVF1JxlpjUabO6O5_VSNzlnHXc2EMC__ig0cYtIc6jJOpkFYpl1OT_F6eZ_YJzuB7Q3qY4aya3yso-7U4mcnBz01qG7B5hOjOgk0XV2E_O6OV6vfQEoEfodZFg-tm9DpQ0vjS8xrFfsR67OaWG_lk-LrBHDPuAuEwQife5EJIUG-4QRvhELIDja6nUZtZJmIbf8-l-u-JB-edWgooTUIOoDEan41sTXp9GZgI0gt6EB-yzJcTSsVc4omHAh_OyzCds_qrOwa5awYBhCcdMpV-PbV49ZoQizBYTcTEzb9S3b_gplfIgkAHdii5jNSBqoAHWYE_h2wSsGBISB5uuan6bnLpaKOJpHRZFx9dv8bXtlF92BO-BuFUv-zSt-I8XEUISv8qUkB6xef5t9ErNh92ZBcHX9adkVSVTB9jq2QWS5VQrtD5wJz30pvOhTcRiQPabJu_8fz7U8gEYMrQm_oEEYr2LqIIskllksoevrzQhMsSxjjp-kiV87a4B8nJJuvWvliaPImcxb0sJDN4F4knDcs_N7RpAEUSXS6UL6-NGs0HyRKpmQ4Ant73haBmGMehmlKANKJLygOpuTkP9jaY9kkH2kgSFVlKHN-oDVd0WhzOMqE2IWpza5uZD_W5f_7VgMN2LdRwUB-1OCO_5NGBjkFRXeK7CPinyJ44Ol0iT4UT_vvnmxUTIzHIQswIE7EV5VLSf38td9DNilDvzyDNnaIM-smxQRxFZ9wMddQIxoVye7WbYGzoW0G2pBXfjG-kOM505K-sei-bPbRTugfqHx6EzuIEkILkPHgi0L97JL6s12leIYXcj4QrfHy8wjG2yud62R-kIKsE_5O06oGuXimbRHgTwJbfbg5Jxbs29RRed6gh6LyDOjgXSO9VcvvmKRvJZ3Wn_l-kj7j1wrBNf2-20n_CIhH6qjmVUxT1tjGR8Eb2sUEnoOiPib8GRiBe67e639bKFSISFoFlitq-Wg9fpxBMM1K0UCA8E21G-e6PdtVFnRAtrfm5Rr1iuw8Np3uWNmO2lGQK9Gs8KGYnUO77oSdLYDU6itNhyZCFgn-gzxocjlLFtEvBgPq1AAR7-l3p4P--EJrY9XsF6hAHimudCxTYtA-MlxYE2x9YeHip_WCeN0HteRt0nphPGVihLpKMu8GzX-IMJyHa2ckxkOZpqMtSlXZEmPtjRZnGmEKeuL4G_khynDY_cHWueR7X-1M8duVOERwPkmo4roXWp21pufR9DhPEbTGis-4d0ZnWxuX_-4Vq_AMOLaX6gF6H8jFqf7OWWaOwC0DlXQIx5uQbwL2dPapG4Nq4jRHyzZFMhb_eIP4lhh09Gw5fMTLQzsBR7PzHVvkjfLmAP6P2q_obz59Bar11PN9cwd2vwIHhH032c-CGGE8S-Y9VLSgzq8rk2e8qJ17n14c2bidUozetXk3peR6BXl3YfsWtc_c_puZnCDWnGk5ekLqd8Re1lBWQLb0p3cZaUDJk7ZrvNtcyZpHjcyZu_nWnSVcvMAkfR2nJ1DhGeOVdeQm3FVY_fbhsqwFqHDbfxTAulrWZ0kf89cvhFndBjC5xl_t0gXCRHirnw8hVrK7HPVMPrF5XREZE4OGYRGrXInuRc5jcOxexMyG-8uMl789GE2P1Fzs8CjFd4-c87YjmW4ZmZCdRKg2kfhOpg1DZ88eu0cNEjvDv8T7I72cxRLqPlnTc8qRKBzkElscAazsBe0ngZ4g0mjt4SVk_TyvSn1wYNbVzlA-L_zHvE_shJiN5JqHHKMPiZKULCBF7D-DHP0ss7-HZDvxe27-tyi6IuWAPIYOFnerY-JDYL-tHvHHKj4nb2jNhbbEM_0OAWmaoAgEVylGokC8S3fu-C8mofWQXCHAJGQ6zmaV8zOrfrMMjHEBUEeUdNrsI6omcdBfQ9JR2fCMs3y7P5_JwpFvE5fDOoL_1L89P-pPj1jmgYPqTy7lMDfSvy7MAkdWDcvqVaiMuwIeciva2-JsJIXfLIQy8nxS1yAMinOwp_qlwos46mZf7Kopkx6gIQ5O9EzPODcd8beyQNiZsJG_QJx8eQtfJPDvOOSPb07vbESA6dW9899sCuDqfJ6dWkuEk-OkBbY9aA9vuMe_S3CNnT9ot1isAlnYrabTVk5A0lKMKP3oYb-8-OUfWPU72eFryQCDDtEEVetE\\\\\\\",1]],\\\\\\\"/9j/4AAQSkZJRgABAQAAAQABAAD/7QBQUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAABgcAm4AE01hZGUgd2l0aCBHb29nbGUgQUk4QklNBCUAAAAAABDIs4lltEU3qRin51mYyOP2/+EDAWh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNy4wLWMwMDAiPgo8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIgeG1sbnM6eG1sPSJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiIHhtbG5zOklwdGM0eG1wRXh0PSJodHRwOi8vaXB0Yy5vcmcvc3RkL0lwdGM0eG1wRXh0LzIwMDgtMDItMjkvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIElwdGM0eG1wRXh0OkRpZ2l0YWxTb3VyY2VGaWxlVHlwZT0iaHR0cDovL2N2LmlwdGMub3JnL25ld3Njb2Rlcy9kaWdpdGFsc291cmNldHlwZS90cmFpbmVkQWxnb3JpdGhtaWNNZWRpYSIgSXB0YzR4bXBFeHQ6RGlnaXRhbFNvdXJjZVR5cGU9Imh0dHA6Ly9jdi5pcHRjLm9yZy9uZXdzY29kZXMvZGlnaXRhbHNvdXJjZXR5cGUvdHJhaW5lZEFsZ29yaXRobWljTWVkaWEiIHBob3Rvc2hvcDpDcmVkaXQ9Ik1hZGUgd2l0aCBHb29nbGUgQUkiLz4KPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4K/+sZ90pQAAEAAAABAAAZ7Wp1bWIAAAAeanVt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L2MycGEuYWN0aW9ucy52MmRoYXNoWCB5q0Xq9rF01iglhf65S6khCMK+kydWOnLL1OvmXsVMqqJjdXJseClzZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmhhc2guZGF0YWRoYXNoWCAPSDdU4ZjgSfyxw66Idj7Rtq7EMYqf+6moerr73uH0gmlzaWduYXR1cmV4GXNlbGYjanVtYmY9YzJwYS5zaWduYXR1cmVjYWxnZnNoYTI1NgAABAhqdW1iAAAAKWp1bWRjMmFzABEAEIAAAKoAOJtxA2MycGEuYXNzZXJ0aW9ucwAAAACcanVtYgAAAChqdW1kY2JvcgARABCAAACqADibcQNjMnBhLmhhc2guZGF0YQAAAABsY2JvcqRqZXhjbHVzaW9uc4GiZXN0YXJ0GQNpZmxlbmd0aBkZ+WNhbGdmc2hhMjU2ZGhhc2hYIId95Tk+Ud8rnWXsew1hnNIjvKmUVOhx9o9/rY0j6vGHY3BhZEwAAAAAAAAAAAAAAAAAAAJWanVtYgAAAClqdW1kY2JvcgARABCAAACqADibcQNjMnBhLmFjdGlvbnMudjIAAAACJWNib3KhZ2FjdGlvbnOCpGZhY3Rpb25sYzJwYS5jcmVhdGVka2Rlc2NyaXB0aW9ueCBDcmVhdGVkIGJ5IEdvb2dsZSBHZW5lcmF0aXZlIEFJLnFkaWdpdGFsU291cmNlVHlwZXhGaHR0cDovL2N2LmlwdGMub3JnL25ld3Njb2Rlcy9kaWdpdGFsc291cmNldHlwZS90cmFpbmVkQWxnb3JpdGhtaWNNZWRpYWpwYXJhbWV0ZXJzoWtpbmdyZWRpZW50c4KiY3VybHgtc2VsZiNqdW1iZj1jMnBhLmFzc2VydGlvbnMvYzJwYS5pbmdyZWRpZW50LnYzZGhhc2hYIEPPQQUmfu68wdIEHLdRNcwvAGFseCftiCe5+857WDmWomN1cmx4MHNlbGYjanVtYmY9YzJwYS5hc3NlcnRpb25zL2MycGEuaW5ncmVkaWVudC52M19fMWRoYXNoWCAVclPWZvmGvl1yJJJFIKVjMTldBPijflMgnfw2JSGnp6NmYWN0aW9ua2MycGEuZWRpdGVka2Rlc2NyaXB0aW9ueChBcHBsaWVkIGltcGVyY2VwdGlibGUgU3ludGhJRCB3YXRlcm1h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\\\\\\\",\\\\\\\"image/jpeg\\\\\\\",1,null,null,null,null,\\\\\\\"image.jpg\\\\\\\",null,\\\\\\\"DDE5D2A5-FE61-45F0-8DEB-644FD661D8FE\\\\\\\",\\\\\\\"32984960-0203-4A83-A40A-38AA1CB72B49\\\\\\\"]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:30.002Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=516290&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:34.708Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=457940&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:35.371Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=836706&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:46.411Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=712321&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:47.045Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=679753&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:46.993Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=270832&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:58.096Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=348558&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:43:58.651Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=850002&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:44:09.691Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=941613&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:44:10.325Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=763002&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:44:21.404Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=249676&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:44:21.924Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=226901&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:44:33.059Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=351509&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:44:33.716Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=731350&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:44:44.837Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=761095&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:44:45.421Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=649427&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:44:56.580Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=234206&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:44:57.218Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=505695&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:44:58.925Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=693767&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:45:08.375Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=216527&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:45:08.960Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=864349&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:45:20.042Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=598093&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:45:20.593Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=Zzl0ze&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=459315&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"Zzl0ze\\\",\\\"[\\\\\\\"projects/594758cc-11f5-4f92-8b3c-1213686591f4\\\\\\\",null,null,null,[1]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:45:44.892Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=326329&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:45:55.470Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=160041&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:46:06.184Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=538126&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:46:16.785Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=425860&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:46:27.392Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=882427&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:46:37.972Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=896469&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:46:48.558Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=654551&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:46:59.105Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=437717&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:47:09.662Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=820538&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:47:20.258Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=224749&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:47:30.891Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=997797&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:47:41.499Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=447250&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:47:52.175Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=613362&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:48:02.794Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=130278&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:48:13.370Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=954209&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:48:24.046Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=128013&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:48:34.673Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=419970&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:48:45.209Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=678757&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:48:55.800Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=922184&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:49:06.369Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=949639&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:49:26.737Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=664766&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:49:37.403Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=170642&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:49:47.947Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=716638&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:49:59.396Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=491729&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:50:09.951Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=838757&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:50:20.534Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=868651&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:50:31.102Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=136891&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:50:41.704Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=755022&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:50:52.273Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=364569&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:51:02.831Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=643020&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:51:13.402Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=262067&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:51:23.981Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=302529&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:51:34.540Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=176657&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:51:45.141Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=198295&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:51:55.784Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=387145&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:52:06.364Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=729924&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:52:16.960Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=789506&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:52:27.561Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=272150&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:52:38.115Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=796219&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:52:48.727Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=287705&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:52:59.272Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=451205&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:53:09.891Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=546454&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:53:20.734Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=651180&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:53:31.365Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=455957&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:53:41.988Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=722873&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:53:52.602Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=572083&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:54:03.210Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=796153&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:54:13.775Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=534261&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:54:24.368Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=595405&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:54:34.934Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=987190&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:54:45.501Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=183779&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:54:56.107Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=220694&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:55:06.711Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=152543&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:55:17.278Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=326182&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:55:27.881Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=817338&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:55:38.445Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=621124&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:55:49.045Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=461769&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:55:59.639Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=513854&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:56:10.277Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=546890&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:56:20.892Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=386300&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:56:31.569Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=119744&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:56:42.098Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=661519&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:56:52.662Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=827093&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:57:03.253Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=733686&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:57:13.808Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=902402&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:57:24.390Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=583328&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:57:34.981Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=592196&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:57:45.570Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=962876&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:57:56.224Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=330832&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:58:06.828Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=749968&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:58:17.450Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=256317&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:58:28.051Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=133287&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:58:38.594Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=190807&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:58:49.208Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=549301&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:58:59.787Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=876609&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:59:10.396Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=424315&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:59:20.988Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=891089&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:59:31.632Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=172988&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:59:42.174Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=566179&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T14:59:52.741Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=502020&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:00:03.320Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=568950&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:00:17.227Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=108961&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:00:30.621Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=697403&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:00:41.291Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=906598&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:00:56.513Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=930311&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:01:07.132Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=659070&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:01:17.723Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=489037&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:01:28.348Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=788214&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:01:38.911Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=201581&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:01:49.542Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=567273&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:02:00.179Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=704154&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:02:10.776Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=807511&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:02:21.418Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=584917&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:02:32.114Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=497819&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:02:42.684Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=860563&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:02:53.329Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=891712&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:03:03.932Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=577369&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:03:14.519Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=666831&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:03:25.158Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=309121&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:03:35.767Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=343200&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:03:46.364Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=453303&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:03:56.924Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=644318&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} -{"ts": "2026-09-23T15:04:07.617Z", "url": "https://flow.google.com/_/AiSandboxAngularFrontend/data/batchexecute?rpcids=jwpduf&source-path=%2Fproject%2F594758cc-11f5-4f92-8b3c-1213686591f4&bl=boq_labs-ai-sandbox-frontend_20260922.00_p0&f.sid=4710374552478052088&hl=vi&_reqid=395220&rt=c", "method": "POST", "body": "{\"at\":[\"AIQ-s5gZcrFuOkJ46PkSuXUQbO_I:1790172189612\"],\"f.req\":[\"[[[\\\"jwpduf\\\",\\\"[null,null,[[\\\\\\\"ec675e90-a9e3-4c4a-b64f-77672c87d1d0\\\\\\\"]]]\\\",null,\\\"generic\\\"]]]\"]}", "statusCode": 200} diff --git a/scratch/project_media_dump.txt b/scratch/project_media_dump.txt deleted file mode 100644 index cd27a6d3b..000000000 --- a/scratch/project_media_dump.txt +++ /dev/null @@ -1,8 +0,0 @@ -)]}' - -163908 -[["wrb.fr","Zzl0ze","[[[\"0a42ed66-8a7f-4b28-abfb-4586a39f4b52\",\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",[\"03_APPROVED\",null,null,[1784529350,72144000],null,[1784529355,462807000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"0c211a47-5991-43e8-8142-a390e0daa4a8\",null,[\"03_PROPS_TECH\",null,null,[1784529293,146542000],null,[1784529297,460541000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"1139ff90-563d-4843-92ac-3a35fbecae86\",null,[\"09_ARCHIVE\",null,null,[1784529463,78960000],null,[1784529475,558401000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"1845d995-1a46-48ed-8c43-c91c9cc28ef2\",\"ccd7cdd3-bb43-4ba5-8cbc-0c7b75381109\",[\"99_REJECTED\",null,null,[1784529240,97665000],null,[1784529245,759339000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"1fdfac50-bbad-4622-b43b-0ab2d15d37ff\",\"d57bfef1-e345-42be-8be5-244c58752988\",[\"02_SELECT\",null,null,[1784529418,744451000],null,[1784529428,627263000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"4b8dcbae-1bbe-484f-9459-708233502798\",\"95d2e37f-c851-4122-8825-e4b4d7d71e8e\",[\"01_VARIANTS\",null,null,[1784529272,754511000],null,[1784529277,491788000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"5500f781-66f4-44f1-9ce5-47f0a90c04d0\",\"d57bfef1-e345-42be-8be5-244c58752988\",[\"03_APPROVED\",null,null,[1784529420,112190000],null,[1784529432,949574000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"881fa2e3-3396-4c33-ab58-941204d5a869\",\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",[\"00_FRAMES\",null,null,[1784529320,39941000],null,[1784529323,799385000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"909ad3fe-a510-4d46-9a35-641144cc276e\",\"95d2e37f-c851-4122-8825-e4b4d7d71e8e\",[\"99_REJECTED\",null,null,[1784529282,196777000],null,[1784529287,686348000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"95d2e37f-c851-4122-8825-e4b4d7d71e8e\",null,[\"02_LOCATIONS\",null,null,[1784529252,245818000],null,[1784529256,242132000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"a55a169d-3f7e-40d7-b9be-50a3abe4182a\",null,[\"04_STYLE_LOCK\",null,null,[1784529301,392131000],null,[1784529305,947850000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"adf37d8f-38a0-4198-b1e4-26efbf46bcf0\",null,[\"00_CANON\",null,null,[1784529050,206104000],null,[1784529171,248849000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"b6e65c65-d1f0-46e0-899e-91a442806fc9\",\"ccd7cdd3-bb43-4ba5-8cbc-0c7b75381109\",[\"02_VOICE_MASTERS\",null,null,[1784529231,661607000],null,[1784529237,672168000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"b9f3fb92-e22b-4a39-b126-f0ca914eca14\",\"d57bfef1-e345-42be-8be5-244c58752988\",[\"00_FRAMES\",null,null,[1784529405,117346000],null,[1784529411,260369000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"bcb1aa9b-b47a-4ff3-9c09-92369ca02355\",\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",[\"01_DRAFT\",null,null,[1784529328,990912000],null,[1784529333,198253000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"be966234-d647-4699-bc33-a0e13177c153\",\"ccd7cdd3-bb43-4ba5-8cbc-0c7b75381109\",[\"01_VARIANTS\",null,null,[1784529217,532896000],null,[1784529228,620221000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"c3e324f9-e875-4284-a2cc-357b31c22d31\",\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",[\"02_SELECT\",null,null,[1784529339,230340000],null,[1784529344,560943000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",null,[\"05_TRAILER\",null,null,[1784529311,526839000],null,[1784529316,590851000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"ccd7cdd3-bb43-4ba5-8cbc-0c7b75381109\",null,[\"01_CHARACTERS\",null,null,[1784529188,643203000],null,[1784529196,685227000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"cf1a4e1e-0b55-4944-89b6-f019381d74d6\",\"c9d32e61-b53a-48d0-b8ef-4a8c6d073aa2\",[\"04_SCENE\",null,null,[1784529360,286453000],null,[1784529376,577028000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d4b9f61e-164e-41bc-ab33-73533207a219\",\"d57bfef1-e345-42be-8be5-244c58752988\",[\"04_SCENE\",null,null,[1784529438,238663000],null,[1784529444,283791000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d57bfef1-e345-42be-8be5-244c58752988\",null,[\"06_EP01\",null,null,[1784529394,651678000],null,[1784529400,751158000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"eae3b1f7-5964-4041-a509-c289180d05eb\",\"d57bfef1-e345-42be-8be5-244c58752988\",[\"01_DRAFT\",null,null,[1784529416,61894000],null,[1784529423,404539000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"ebfe3ef1-604d-4ba0-8f17-c4f18b0e3dc7\",\"ccd7cdd3-bb43-4ba5-8cbc-0c7b75381109\",[\"00_FACE_MASTERS\",null,null,[1784529204,622353000],null,[1784529212,77567000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"f07fddb4-950f-4b09-9b45-c534be4b10c8\",null,[\"08_POST_REFERENCES\",null,null,[1784529461,149740000],null,[1784529469,73331000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"f859aae4-e394-4924-bb6d-12b9eaa93663\",null,[\"07_EPISODES\",null,null,[1784529450,853966000],null,[1784529457,442839000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"fc0eb04a-aa2c-4556-8852-45f034b9f232\",\"95d2e37f-c851-4122-8825-e4b4d7d71e8e\",[\"00_MASTERS\",null,null,[1784529262,28805000],null,[1784529268,688191000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"]],[[\"18462c7e-40cf-4217-964d-980db21dac35\",null,null,[\"Train gliding over Hanoi traffic\",[1790099234,21793000],null,null,\"a029279b-cc59-465f-98d5-0fa8b78187ba\",\"DDD5C8EB-ECF1-4A0F-BB97-8EF2A1FDF396\",[1790099256,112919000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"23070ed9-c3a8-4070-a111-318ef1ed4f3a\",null,null,[\"image.jpg\",[1790174596,878212000],null,null,\"c436b109-dd00-498d-806d-b6bddc9a3bbf\",null,[1790174602,244051000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"2c817534-e7d9-4711-ba06-8da52e020080\",null,null,[\"Camera pans cracked asphalt sun\",[1790099773,817655000],true,null,\"c8939cac-021c-4000-a355-ec23628e5ea0\",\"649876A2-0594-4ACD-80A2-35CC61E50C6B\",[1790103884,48657000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"3197d46b-0a13-463c-8aaf-9dd5f1416e6e\",null,null,[\"Hands slamming against glass doors\",[1790099933,333177000],null,null,\"c86e9fac-57bb-4fc3-a85f-d751ecefdcc8\",\"2CAEE570-CE42-462F-A46F-D5731297D999\",[1790099941,95849000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"337d7d27-bc09-4ca1-9f11-1b9253d15cbb\",null,null,[\"Overgrown bridge over river\",[1790104423,640950000],null,null,\"3d1052dd-2332-48f6-81c3-73adb6d4ff09\",\"c3a99ab1-0f8d-4d1b-ba0c-8f354bd9fc13\",[1790104447,312420000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"3ab07549-ccbb-410a-a97d-08b8a4627f84\",null,null,[\"Vietnamese engineer with abdomen…\",[1784546411,930438000],null,true,\"684e27a9-a16c-480e-95ce-8cb540798659\",\"a5f6c049-2f1d-40d4-b16f-3d96f24b1fe8\",[1784546442,385675000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"3bd39545-26f0-4165-883c-528e119207fc\",null,null,[\"Woman standing in ruins\",[1790105718,172947000],true,null,\"03bb0401-4b95-485b-906c-f5f8b0195547\",null,[1790105731,783423000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"3ddd6fbc-8834-4868-a7fa-5e1dc68d04d7\",null,null,[\"Sun shining over cracked asphalt\",[1790099782,85545000],null,null,\"d9a829c4-cd2d-491c-8773-7bee1eeb0aba\",\"0CCA1636-A823-4656-9E94-3234A72452ED\",[1790099861,528437000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"420931e8-d444-4a59-8ba8-a745cbeead17\",\"ebfe3ef1-604d-4ba0-8f17-c4f18b0e3dc7\",null,[\"HNTL_CHR_TIEN_2028_FACE_MASTER_v001_APPROVED\",[1784545966,119130000],null,null,\"cd20c077-1f3e-4432-9bbc-6d19af7a5a16\",null,[1784545986,933851000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"431da3f0-96a9-4cc7-8384-937287b72c6e\",null,null,[\"Commander standing facing camera\",[1790098978,830949000],null,null,\"78e46231-e6cf-43fb-99bc-a4cb96196e24\",\"389D74E5-56CC-4283-B7BE-E20A2DCA261B\",[1790099002,862715000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"482b99b0-f4ee-40f9-a31b-c4f76ddd2af7\",null,null,[\"Man standing over exhausted man\",[1790174045,451631000],null,null,\"25704835-1c43-4c10-a718-9f77ab2e9cd6\",\"E1EBBB69-0118-4F27-ADD1-F71D29C1C559\",[1790174068,910540000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"4b6e1f6c-ad29-4c79-ac8b-840e0ff929c4\",null,null,[\"Bustling open-air market with la…\",[1790098607,247715000],true,null,\"dc6cb5cb-1515-4607-8d63-35b7d4c79df9\",\"33C47DC5-F835-4F3A-94CA-0BA140F9EF51\",[1790103911,506021000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"4fb9e862-d995-4f49-9eb6-d00b1f2ee767\",null,null,[\"Vietnamese engineer with abdomen…\",[1784546541,545693000],null,null,\"9aea7396-dc22-4b69-947f-7d1dcc5c1e3c\",null,[1784546548,573950000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"ad4b3ad9-a282-478e-957e-6fcc47a2b5e4\"],[\"50ce51e4-768e-4eb0-abce-1df3f94acae6\",null,null,[\"Wooden market stall with scale\",[1790098627,137046000],true,null,\"deb54d26-dbdb-4351-99f5-04400fef123c\",\"6D44D38D-F81B-4CC1-9ED4-5CC9C5A58E57\",[1790103919,140646000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"52274337-3f1e-499b-b404-022ff18196d3\",null,null,[\"Metallic structures rising from …\",[1790099028,206353000],null,null,\"9daace9a-a99c-4a5a-bce5-e9aaedcb1980\",\"836A8983-2CBB-4570-B679-C6E43A2EBE73\",[1790099051,404977000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"6ddbd597-0a88-4e3c-b31a-7d20443c0dab\",null,null,[\"Engineer standing facing camera\",[1790098968,283242000],null,null,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\",\"D690B37C-62E0-4E9D-A68E-D0B96D91BCDB\",[1790098990,362027000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,null,[\"Woman standing in ruins\",[1790105368,68953000],true,null,\"2e1227e3-7cb3-4213-8574-503bc667c75e\",\"dc42af28-a7ef-440d-81ab-ca9d701c8e7f\",[1790105725,873145000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",null,null,[\"Woman sitting near cooling fan\",[1790106045,1406000],true,null,\"567984bd-c3ff-46de-ad25-353be60e6188\",\"1a289c4e-464f-4aee-9114-f9d9cd93c6ff\",[1790106200,882061000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"82ddef0b-fced-4a18-a039-240a66c111d2\",null,null,[\"Woman wearing coat in sun\",[1790105368,716850000],true,null,\"78266bba-b106-47e7-80e3-c152822e1ca9\",\"3df1fee0-6b2c-447a-b83a-5a4fded17d43\",[1790105435,349518000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"87cfaa04-a192-405e-aa3b-137fa3d20ccb\",null,null,[\"Journalist standing for referenc…\",[1790098988,593315000],null,null,\"65993027-0037-4f25-9fb7-7bd4d301ee7b\",\"1A445D6E-8380-4BBC-AE96-FA2C39BB7DBB\",[1790099012,265973000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"8a636ea0-c501-40c7-b8a3-74ebcb14ba74\",null,null,[\"tạo video intro\",[1789492421,692307000],true,null,\"1b832287-df4c-429a-b3b2-46d8f818d284\",\"e2e9ea1a-0fed-4c90-9ab3-1cd282ba672b\",[1790103876,68469000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"9139a337-e6df-474c-90f1-e4e48dca69a9\",null,null,[\"Man holding knife over seated ma…\",[1790099323,542997000],null,null,\"a6010398-57c9-4e27-a89f-31ed0ddf2d1a\",\"B3178C0F-6E72-49C4-9912-0EC1B6A0AB7A\",[1790099346,133587000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"99a9b9fa-2091-4429-b192-476892fad1e8\",null,null,[\"Mountain landscape in northern V…\",[1790104961,385705000],null,null,\"1fa5e13c-e74f-45da-adc7-311e9e27c140\",\"c48a378f-6f86-4a32-8bb4-6c0c236fa92f\",[1790104983,162792000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"9c487a71-fc76-4e0e-bdc3-98eee2bc25da\",null,null,[\"Man jolting awake in bed\",[1790099223,430583000],null,null,\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\",\"A08F6255-349C-4E2F-9AC3-1577284BBC2F\",[1790099244,889973000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"9e8ede1b-4f8f-4354-aecb-a7759421bf13\",null,null,[\"Person shining flashlight on hatch\",[1790099253,589865000],null,null,\"30b5f32e-3918-4b68-acf8-7f7b0afafd0d\",\"55BC5782-6E26-45E4-AC92-44BBAEFAA7D2\",[1790099279,51856000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"a5fbb9e9-b0d0-48f4-89ea-277444ec27c4\",null,null,[\"Deserted street with abandoned s…\",[1790104424,188616000],null,null,\"76a03ec4-6340-4e25-9e8a-5009942893b9\",\"821131e5-6a0a-498b-9215-628a6f727127\",[1790104446,58271000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"ad778284-c548-4428-9386-24491b893682\",null,null,[\"Cat peering through rainy window\",[1790098625,39575000],true,null,\"310d92fb-dd8e-4e33-b061-4750fcbeeeaa\",\"7fe69dc0-a68f-4e64-bad1-877baf14334e\",[1790103909,73177000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"b00ceb65-a125-49c4-91ff-49f0af1e2356\",null,null,[\"HNTL_CHR_TIEN_2028_FACE_MASTER_v001_APPROVED\",[1784545698,613155000],null,true,\"ac5f92cb-b55e-4db9-b800-0dd1dbe759ef\",\"74c99d95-363a-4479-b0b2-35b92c0e44b6\",[1784545880,528045000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"b58780b6-8218-433c-bdca-6fb13f9e9cd6\",null,null,[\"Vietnamese engineer character re…\",[1784545738,781156000],true,null,\"acf87cab-c8f4-46c4-b305-5d57a5be19fa\",\"c1a2084f-d5ca-42f0-8070-1031049fb44f\",[1784545790,489539000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"b84f96ab-d2b2-414b-b4ed-912a9e3e2859\",null,null,[\"Concrete warehouse with metal hatch\",[1790099018,2158000],null,null,\"5a919b50-566c-4cfb-97b6-4e481650dc0a\",\"D4B2CCDB-02A8-4678-9613-0A507F273D92\",[1790099039,863469000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"bba71aa9-a24c-43bc-a42e-e0f140a426e3\",null,null,[\"Cat wearing apron walking upright\",[1790098596,970493000],true,null,\"c6bef467-362b-4d7d-86bd-7734cf16379f\",\"64A9C999-320D-43D0-A3FB-DB954A6CEADA\",[1790103914,136184000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"bd7eacf9-d385-4561-bf0b-62e3e8a253dc\",null,null,[\"Commuter traffic on urban avenue\",[1790098998,48960000],null,null,\"e12021b9-1f91-4a65-a9e2-f1ddbffbf42d\",\"DD98F4BD-09EF-4A49-8064-8F684F842216\",[1790099021,546266000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"be5c73e8-269a-4fdf-a1a5-d2265179a8be\",null,null,[\"Vietnamese engineer with abdomen…\",[1784546459,807750000],true,null,\"732c7e1a-7267-462f-8f58-1bf43694428e\",\"8814c820-2648-41d8-8971-f12d6ef4992c\",[1784565183,289884000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"c3b02b33-da87-410c-88ce-c3896028c8a6\",null,null,[\"Green metro train and commuters\",[1790099923,331786000],null,null,\"1d72b8c7-7c9f-477c-bbf2-0f3a24cdc9a1\",\"44483D79-04FD-487B-AEAF-CB7269FA6C44\",[1790099930,87223000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"c7fee095-6829-4801-94c8-3eb9bcaf060f\",null,null,[\"Le Quoc Tien.png\",[1785255350,725479000],null,null,\"4630aeab-cd27-4457-96b6-24045de2504e\",null,[1785255359,823385000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"11a89444-ca45-45a2-a890-feab388ba4ae\"],[\"d0e3e32c-df9c-4641-bce4-dd9ca73a4f9b\",null,null,[\"Industrial outpost on mountain r…\",[1790104962,53428000],null,null,\"ca9eac0a-7816-4104-af03-8f98001f2915\",\"ae1cd228-257c-4806-8c6e-865d878e4140\",[1790104983,167759000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d19f6811-455b-4838-bdc2-b908aeb7bd36\",null,null,[\"Man standing in workshop\",[1790169824,340307000],null,null,\"666bc47c-1fa1-4167-83cc-3088840b3146\",\"119296d0-39e6-4e6c-96a9-b713a2e3d50d\",[1790169845,203797000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d5719db7-7c9a-42eb-a9dc-a13028690a3b\",null,null,[\"People standing near metallic ruins\",[1790099263,649996000],null,null,\"2c14fdf3-bb10-4603-bb76-ca483c23db87\",\"AABC7A39-2CBE-469B-B9DF-A97AAC85E9EC\",[1790099288,639522000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d6e35829-f7a1-43aa-b12c-7172309cf84c\",null,null,[\"Golden koi fish swimming\",[1790098617,113716000],true,null,\"a661bfc5-873f-4f71-862b-b76958cdda91\",\"47A1B759-7F96-4085-ADC3-5E648AD69AAE\",[1790103915,929616000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"d7c54686-02ce-4344-ac22-2888ccf9c76e\",null,null,[\"HNTL_CHR_TIEN_2028_FACE_MASTER_v001_APPROVED\",[1784546032,956328000],null,null,\"6aa915c7-1123-4e12-b75f-6d5e6d40d0fe\",null,[1784546039,629998000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"f4d9c731-41f2-4b51-9dd2-edd20c1dc7f1\"],[\"d9102dd3-bb7b-4a6b-8135-90e9e3455f30\",null,null,[\"Heatwave apocalypse in Hanoi\",[1790104505,133221000],null,null,\"b5b2415a-b104-4e53-bf22-1bd940d2186b\",\"7310a95b-660a-402a-b3cd-58af71069ea2\",[1790104527,311732000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"da045c4a-d318-46ce-9d05-2b902878dc90\",null,null,[\"Abandoned vehicles at Hanoi inte…\",[1790104504,482062000],null,null,\"27cf3d47-aae9-4035-9324-32bb65509721\",\"ec0e0a52-b4dd-4102-a4e8-b468c857b069\",[1790104524,768009000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"e03db69f-0402-4e01-8d10-20a700e1d064\",null,null,[\"Cat sitting on wooden stool\",[1790098624,387715000],true,null,\"ffd129ac-2cb2-4c5d-a059-e37be9782118\",\"a72a8dac-99eb-4daa-8359-511e4239b0c8\",[1790103906,77570000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"e2367807-01e9-4bf4-a522-1f8549998e20\",null,null,[\"Modern shopping mall under red s…\",[1790099008,171508000],null,null,\"c38a6066-9d26-44da-8a14-8c7e260f7f8d\",\"2035D763-8320-4737-8083-E9AA31E42FF4\",[1790099030,317790000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"e516fce6-a049-4a7f-b414-5db3660b52fc\",null,null,[\"Man slumps against concrete pillar\",[1790174038,296806000],null,null,\"bdcbe55a-ee7b-497d-a414-25d22d04c096\",\"85FCAB29-DD00-4032-8AD2-15F7B36A484D\",[1790174057,857105000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"f69d66c7-9cd6-459d-a883-753390a8cb25\",null,null,[\"Woman standing in post-apocalypt…\",[1790106044,585720000],true,null,\"b6900ed9-ed42-4b6c-80c1-74db6fc6132d\",\"b2676050-a010-4f75-be4c-ee62a94baae3\",[1790106099,407867000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"],[\"fb28016d-5ed3-47b0-9a38-6f98eaa8b439\",null,null,[\"Crowd escaping heat trap\",[1790099243,507045000],null,null,\"ce812adb-5fef-42cb-9a38-97b2e1bac60b\",\"E1B67B78-288F-4B11-8704-AFA083A24D40\",[1790099265,47155000]],\"594758cc-11f5-4f92-8b3c-1213686591f4\"]],[[\"03bb0401-4b95-485b-906c-f5f8b0195547\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"3bd39545-26f0-4165-883c-528e119207fc\",\"CAE\",null,[[1790105718,172947000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaXm49Rdt0OZndhpTMPGANW864qQpmzS_pSUrYkrucaLudt-rN0ShHnS-M-QNIG-4Qz4sgOdUl3Xdmhii8QZ_8qjXlSyq-vwEbLdl7Y0ZoqpSGEwyjBPn2jf0upCg2b7KcOsuH3E-DIyv0v7YJnXWi3LulKmDegyPxS4tfzsg\",[null,null,[[\"Large breasts, subtly revealed.\",null,[[[\"ngực to, lộ một cách tinh tế\"]]]]],[[[null,2,\"6e6be6ca-d2c5-477c-b025-8ceac859aa54\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUaXm49Rdt0OZndhpTMPGANW864qQpmzS_pSUrYkrucaLudt-rN0ShHnS-M-QNIG-4Qz4sgOdUl3Xdmhii8QZ_8qjXlSyq-vwEbLdl7Y0ZoqpSGEwyjBPn2jf0upCg2b7KcOsuH3E-DIyv0v7YJnXWi3LulKmDegyPxS4tfzsg\"],[[null,1786455158,null,null,null,null,null,\"Large breasts, subtly revealed.\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUaXm49Rdt0OZndhpTMPGANW864qQpmzS_pSUrYkrucaLudt-rN0ShHnS-M-QNIG-4Qz4sgOdUl3Xdmhii8QZ_8qjXlSyq-vwEbLdl7Y0ZoqpSGEwyjBPn2jf0upCg2b7KcOsuH3E-DIyv0v7YJnXWi3LulKmDegyPxS4tfzsg\",3],null,[1376,768]]],[\"07f97f41-209d-458b-ad17-55606514eb6a\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAI\",null,[[1790105455,367014000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUY-2d81GEQpaR39zIjXEN0Qf5BJONrNE_elkcl7eS4oOY_qd5T8WxpFbwNOowomiZHprFvFxce8dHYOacQn-XE5qj-m_zL5h9gTeuAAw7zTU5Y80OEuwDM16UCPB9eQcCwu1GlRll_QEtosdSd_HSZ6k6iis1w7jUVzKrdFGQ\",[null,null,[[\"sexier\",null,[[[\"sexy hơn\"]]]]],[[[null,2,\"e0ca950b-db30-416a-b2d2-fe98a9bf1344\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUY-2d81GEQpaR39zIjXEN0Qf5BJONrNE_elkcl7eS4oOY_qd5T8WxpFbwNOowomiZHprFvFxce8dHYOacQn-XE5qj-m_zL5h9gTeuAAw7zTU5Y80OEuwDM16UCPB9eQcCwu1GlRll_QEtosdSd_HSZ6k6iis1w7jUVzKrdFGQ\",null,null,205489],[[null,1851291174,null,null,null,null,null,\"sexier\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUY-2d81GEQpaR39zIjXEN0Qf5BJONrNE_elkcl7eS4oOY_qd5T8WxpFbwNOowomiZHprFvFxce8dHYOacQn-XE5qj-m_zL5h9gTeuAAw7zTU5Y80OEuwDM16UCPB9eQcCwu1GlRll_QEtosdSd_HSZ6k6iis1w7jUVzKrdFGQ\",3],null,[1376,768]]],[\"1b832287-df4c-429a-b3b2-46d8f818d284\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"8a636ea0-c501-40c7-b8a3-74ebcb14ba74\",\"CAE\",null,[[1789492421,692307000],\"tạo video intro\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZE4T_NKjDNPXQs7RqIQ9p_8tFB4mf1_97DodcibQfzOWTgqgWPIlVw2rkG_10HP7LmxYCNI_NZH3JZb3CkZ4pNpySGBZG1oZRB7CRdGIj3u0Xcib07jGNzZFpdqLKCUBYNv_PXHIy-SFW56O3R3r790U3XfsvC1dgFuCSE\",[null,[[\"abra_t2v_10s\",1,null,null,1,1]],[[null,null,[[[\"tạo video intro\"]]]]],null,3],null,[3],1,\"https://lh3.googleusercontent.com/asb/AB-nOUZE4T_NKjDNPXQs7RqIQ9p_8tFB4mf1_97DodcibQfzOWTgqgWPIlVw2rkG_10HP7LmxYCNI_NZH3JZb3CkZ4pNpySGBZG1oZRB7CRdGIj3u0Xcib07jGNzZFpdqLKCUBYNv_PXHIy-SFW56O3R3r790U3XfsvC1dgFuCSE\",null,null,4851883],null,[[null,362440,null,null,null,null,null,\"create intro video\",\"https://lh3.googleusercontent.com/asb/AB-nOUZE4T_NKjDNPXQs7RqIQ9p_8tFB4mf1_97DodcibQfzOWTgqgWPIlVw2rkG_10HP7LmxYCNI_NZH3JZb3CkZ4pNpySGBZG1oZRB7CRdGIj3u0Xcib07jGNzZFpdqLKCUBYNv_PXHIy-SFW56O3R3r790U3XfsvC1dgFuCSE\",null,null,null,\"abra_t2v_10s\",\"\",null,false,1],[null,null,[10]],[\"1b832287-df4c-429a-b3b2-46d8f818d284\"]]],[\"1d72b8c7-7c9f-477c-bbf2-0f3a24cdc9a1\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"c3b02b33-da87-410c-88ce-c3896028c8a6\",\"CAE\",null,[[1790099923,331786000],\"0-3s: Elevated wide cinematic shot following the green metro train gliding on concrete viaducts. 3-6s: Camera cranes down toward dense streams of morning motorbike commuters on Nguyen Trai Avenue. 6-8s: Golden sunlight reflects brilliantly off modern glass skyscrapers under a blue sky. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZqIAmzmzMR_fmc351j70xfMg5cfzXWRb4LV5TceF0Cn_GHe5N0D5N6095ca207VHFVchQ3VclIyqZffsLTSsU3Ll2XmhUxXMllVI9XIj6QesNqFTh_iimSNkOx_WES37vQLZeEvaL7OnmtAsHl3m6AeRJmI1DZhFwjeXiuvQ\",[null,[[\"veo_3_1_i2v_lite\",2,[1],null,2,1],[[null,1,\"a029279b-cc59-465f-98d5-0fa8b78187ba\",[null,0.0038759689922481244,1,0.9961240310077519]]]],[[null,null,[[[\"0-3s: Elevated wide cinematic shot following the green metro train gliding on concrete viaducts. 3-6s: Camera cranes down toward dense streams of morning motorbike commuters on Nguyen Trai Avenue. 6-8s: Golden sunlight reflects brilliantly off modern glass skyscrapers under a blue sky. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\"]]]]],null,1],null,[3],1,\"https://lh3.googleusercontent.com/asb/AB-nOUZqIAmzmzMR_fmc351j70xfMg5cfzXWRb4LV5TceF0Cn_GHe5N0D5N6095ca207VHFVchQ3VclIyqZffsLTSsU3Ll2XmhUxXMllVI9XIj6QesNqFTh_iimSNkOx_WES37vQLZeEvaL7OnmtAsHl3m6AeRJmI1DZhFwjeXiuvQ\",null,null,7171738],null,[[null,916049,null,null,null,null,null,\"\\u003croot\\u003e\\n \\u003ccontext\\u003e\\n \\u003c/context\\u003e\\n \\u003cinstruction\\u003e\\n \\u003cprompt\\u003e0-3s: Elevated wide cinematic shot following the green metro train gliding on concrete viaducts. 3-6s: Camera cranes down toward dense streams of morning motorbike commuters on Nguyen Trai Avenue. 6-8s: Golden sunlight reflects brilliantly off modern glass skyscrapers under a blue sky. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\u003c/prompt\\u003e\\n \\u003c/instruction\\u003e\\n\\u003c/root\\u003e\",\"https://lh3.googleusercontent.com/asb/AB-nOUZqIAmzmzMR_fmc351j70xfMg5cfzXWRb4LV5TceF0Cn_GHe5N0D5N6095ca207VHFVchQ3VclIyqZffsLTSsU3Ll2XmhUxXMllVI9XIj6QesNqFTh_iimSNkOx_WES37vQLZeEvaL7OnmtAsHl3m6AeRJmI1DZhFwjeXiuvQ\",null,null,null,\"veo_3_1_i2v_lite\",\"\",null,false,2],[null,null,[8]],[\"1d72b8c7-7c9f-477c-bbf2-0f3a24cdc9a1\"]]],[\"1fa5e13c-e74f-45da-adc7-311e9e27c140\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"99a9b9fa-2091-4429-b192-476892fad1e8\",\"CAE\",null,[[1790104961,385705000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaXPOuTcr9v1Xh6abZRqn2Ql8xcTpW82xihiklrDHB8VhvQETdxL8CzVnM9FdQQqzonyyRegb8I8y7157a2asZfRJcj4tQHIcvoreX4HDwKESDAs8CRggLZawu_RjK81UwnVa6ySOYqcwXcmjMIqp1Pb1e-F1zRn35qU3s_\",[null,null,[[\"Grounded cinematic realism, a scenic mountain landscape in northern Vietnam near the border. Towering limestone karsts rise sharply from a parched, dusty valley under a harsh, scorching 2028 sun. Visible heat haze shimmers across the rugged terrain. Authentic northern Vietnamese vegetation, parched and withered. Near-future techno-thriller atmosphere, muted high-contrast color palette, subtle film grain, natural harsh lighting. No fantasy elements.\",null,[[[\"Grounded cinematic realism, a scenic mountain landscape in northern Vietnam near the border. Towering limestone karsts rise sharply from a parched, dusty valley under a harsh, scorching 2028 sun. Visible heat haze shimmers across the rugged terrain. Authentic northern Vietnamese vegetation, parched and withered. Near-future techno-thriller atmosphere, muted high-contrast color palette, subtle film grain, natural harsh lighting. No fantasy elements.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUaXPOuTcr9v1Xh6abZRqn2Ql8xcTpW82xihiklrDHB8VhvQETdxL8CzVnM9FdQQqzonyyRegb8I8y7157a2asZfRJcj4tQHIcvoreX4HDwKESDAs8CRggLZawu_RjK81UwnVa6ySOYqcwXcmjMIqp1Pb1e-F1zRn35qU3s_\",null,null,334094],[[null,567356,null,null,null,null,null,\"Grounded cinematic realism, a scenic mountain landscape in northern Vietnam near the border. Towering limestone karsts rise sharply from a parched, dusty valley under a harsh, scorching 2028 sun. Visible heat haze shimmers across the rugged terrain. Authentic northern Vietnamese vegetation, parched and withered. Near-future techno-thriller atmosphere, muted high-contrast color palette, subtle film grain, natural harsh lighting. No fantasy elements.\",25,\"\",null,\"99a9b9fa-2091-4429-b192-476892fad1e8\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUaXPOuTcr9v1Xh6abZRqn2Ql8xcTpW82xihiklrDHB8VhvQETdxL8CzVnM9FdQQqzonyyRegb8I8y7157a2asZfRJcj4tQHIcvoreX4HDwKESDAs8CRggLZawu_RjK81UwnVa6ySOYqcwXcmjMIqp1Pb1e-F1zRn35qU3s_\",3],null,[1376,768]]],[\"25704835-1c43-4c10-a718-9f77ab2e9cd6\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"482b99b0-f4ee-40f9-a31b-c4f76ddd2af7\",\"CAE\",null,[[1790174045,451631000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbv96PVxcN2PbifMQLbnfBljuWf4Xiu5nDiPGArpO0tyJYXHdrObt1q-0gOdtpRBQDoTJoVFo676vQBLUKK7WbuzryMkfcJSs9xB7ZWWKW8qfp2Nxu4OrbxkHjMCKlHYF_0t5UqhdHWoG3gINiTcdb13Wsssk-KF_FjORBFaQ\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\"]]]]],[[[null,1,\"78e46231-e6cf-43fb-99bc-a4cb96196e24\"],[null,1,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbv96PVxcN2PbifMQLbnfBljuWf4Xiu5nDiPGArpO0tyJYXHdrObt1q-0gOdtpRBQDoTJoVFo676vQBLUKK7WbuzryMkfcJSs9xB7ZWWKW8qfp2Nxu4OrbxkHjMCKlHYF_0t5UqhdHWoG3gINiTcdb13Wsssk-KF_FjORBFaQ\",null,null,194645],[[null,785346768,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in subterranean B3 basement parking at Me Tri under extreme heat. Le Quoc Tien lies exhausted on scorched concrete floor full of deep heat fractures, clutching his painful side beside a torn empty water canteen and heat-warped debris. In the background, Do Minh Kha stands looming over him with a cold detached gaze, holding a gleaming tactical blade, backlit by an ominous beam of deep crimson sunlight piercing through a jagged collapsed ceiling fissure. Chiaroscuro high contrast lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\",25,\"\",null,\"482b99b0-f4ee-40f9-a31b-c4f76ddd2af7\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbv96PVxcN2PbifMQLbnfBljuWf4Xiu5nDiPGArpO0tyJYXHdrObt1q-0gOdtpRBQDoTJoVFo676vQBLUKK7WbuzryMkfcJSs9xB7ZWWKW8qfp2Nxu4OrbxkHjMCKlHYF_0t5UqhdHWoG3gINiTcdb13Wsssk-KF_FjORBFaQ\",3],null,[1376,768]]],[\"279b944e-5348-4ecc-91d4-f356b9271132\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAQ\",null,[[1790105556,47573000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZvnfLi4e_wIQIorBBWTJ68UhPPAGCGyMM1bGCslA4p0p3FPmZaErkcCJYOWZAU45AtW9O6ltyL0rvw2djSHFrWD5qQSNo0YvIoExryJLJri_WXrIastNeDraPmM1lNKPSF3KgOHu71rkSRSh_Dczg-c1R657r9-mQNa93KkQ\",[null,null,[[\"deep cut-out top, revealing cleavage\",null,[[[\"áo khoét sâu, lộ ngực\"]]]]],[[[null,2,\"cea6d7a9-29a2-4b36-aa89-60358b4998b5\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZvnfLi4e_wIQIorBBWTJ68UhPPAGCGyMM1bGCslA4p0p3FPmZaErkcCJYOWZAU45AtW9O6ltyL0rvw2djSHFrWD5qQSNo0YvIoExryJLJri_WXrIastNeDraPmM1lNKPSF3KgOHu71rkSRSh_Dczg-c1R657r9-mQNa93KkQ\",null,null,181343],[[null,2021215439,null,null,null,null,null,\"deep cut-out top, revealing cleavage\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZvnfLi4e_wIQIorBBWTJ68UhPPAGCGyMM1bGCslA4p0p3FPmZaErkcCJYOWZAU45AtW9O6ltyL0rvw2djSHFrWD5qQSNo0YvIoExryJLJri_WXrIastNeDraPmM1lNKPSF3KgOHu71rkSRSh_Dczg-c1R657r9-mQNa93KkQ\",3],null,[1376,768]]],[\"27cf3d47-aae9-4035-9324-32bb65509721\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"da045c4a-d318-46ce-9d05-2b902878dc90\",\"CAE\",null,[[1790104504,482062000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaFSHfD2PqGyT1oHU6O0EbyvRHBQu_z7dP3bo91wcegBn8L2viTM_ntW_NoGAq0eebQ8yYP2V-H_P4AsXf_55A1NCdBuJPm9nEi6JyjvG_OGCPVk4McB5eeTavReqR7FdSnH6SaY61Zueutr1LWVRHArV8DgqyHVX_3ZRkEMQ\",[null,null,[[\"A post-apocalyptic Hanoi intersection under a blistering, golden-hour sun that feels oppressive. The air is thick with dust and heat haze. Abandoned 2028 industrial equipment and vehicles sit on parched, sun-baked earth where a road once was. Authentic Vietnamese infrastructure, weathered and worn by extreme temperatures. Cinematic realism, high dynamic range, natural harsh lighting, restrained motion.\",null,[[[\"A post-apocalyptic Hanoi intersection under a blistering, golden-hour sun that feels oppressive. The air is thick with dust and heat haze. Abandoned 2028 industrial equipment and vehicles sit on parched, sun-baked earth where a road once was. Authentic Vietnamese infrastructure, weathered and worn by extreme temperatures. Cinematic realism, high dynamic range, natural harsh lighting, restrained motion.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUaFSHfD2PqGyT1oHU6O0EbyvRHBQu_z7dP3bo91wcegBn8L2viTM_ntW_NoGAq0eebQ8yYP2V-H_P4AsXf_55A1NCdBuJPm9nEi6JyjvG_OGCPVk4McB5eeTavReqR7FdSnH6SaY61Zueutr1LWVRHArV8DgqyHVX_3ZRkEMQ\",null,null,263504],[[null,92604,null,null,null,null,null,\"A post-apocalyptic Hanoi intersection under a blistering, golden-hour sun that feels oppressive. The air is thick with dust and heat haze. Abandoned 2028 industrial equipment and vehicles sit on parched, sun-baked earth where a road once was. Authentic Vietnamese infrastructure, weathered and worn by extreme temperatures. Cinematic realism, high dynamic range, natural harsh lighting, restrained motion.\",25,\"\",null,\"da045c4a-d318-46ce-9d05-2b902878dc90\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUaFSHfD2PqGyT1oHU6O0EbyvRHBQu_z7dP3bo91wcegBn8L2viTM_ntW_NoGAq0eebQ8yYP2V-H_P4AsXf_55A1NCdBuJPm9nEi6JyjvG_OGCPVk4McB5eeTavReqR7FdSnH6SaY61Zueutr1LWVRHArV8DgqyHVX_3ZRkEMQ\",3],null,[1376,768]]],[\"2c14fdf3-bb10-4603-bb76-ca483c23db87\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d5719db7-7c9a-42eb-a9dc-a13028690a3b\",\"CAE\",null,[[1790099263,649996000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYqNeb67_wZna9RODkkM_u9IGAIMApuPePBoUySVzv1CL88DZu91GdGX6ncOx5U93Kjx5ZunD20cJgcr6M6YUnE2PhN6IAYuvVSdNQKQccEtHXu2lFcFkLeJJR2svbQWzb4RiihDKCpJQ_gPZ-1ZJISs6lIw2Xvu7Ei7rufVA\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Epic cinematic wide shot of Dried West Lake Colossus in Hanoi under a dark apocalyptic red sun. Cracked black mud lakebed exposes colossal ancient dark metallic ribbed structures resembling giant dragon bones protruding from the earth. Tran Thanh Thuy and Do Minh Kha stand on the distant embankment silhouetted against the colossal metallic ruins and crimson haze. Masterpiece cinematic photography, 16:9 ultra-wide, atmospheric scale.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Epic cinematic wide shot of Dried West Lake Colossus in Hanoi under a dark apocalyptic red sun. Cracked black mud lakebed exposes colossal ancient dark metallic ribbed structures resembling giant dragon bones protruding from the earth. Tran Thanh Thuy and Do Minh Kha stand on the distant embankment silhouetted against the colossal metallic ruins and crimson haze. Masterpiece cinematic photography, 16:9 ultra-wide, atmospheric scale.\"]]]]],[[[null,1,\"65993027-0037-4f25-9fb7-7bd4d301ee7b\"],[null,1,\"78e46231-e6cf-43fb-99bc-a4cb96196e24\"],[null,1,\"9daace9a-a99c-4a5a-bce5-e9aaedcb1980\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYqNeb67_wZna9RODkkM_u9IGAIMApuPePBoUySVzv1CL88DZu91GdGX6ncOx5U93Kjx5ZunD20cJgcr6M6YUnE2PhN6IAYuvVSdNQKQccEtHXu2lFcFkLeJJR2svbQWzb4RiihDKCpJQ_gPZ-1ZJISs6lIw2Xvu7Ei7rufVA\",null,null,176367],[[null,434962038,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Epic cinematic wide shot of Dried West Lake Colossus in Hanoi under a dark apocalyptic red sun. Cracked black mud lakebed exposes colossal ancient dark metallic ribbed structures resembling giant dragon bones protruding from the earth. Tran Thanh Thuy and Do Minh Kha stand on the distant embankment silhouetted against the colossal metallic ruins and crimson haze. Masterpiece cinematic photography, 16:9 ultra-wide, atmospheric scale.\",25,\"\",null,\"d5719db7-7c9a-42eb-a9dc-a13028690a3b\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYqNeb67_wZna9RODkkM_u9IGAIMApuPePBoUySVzv1CL88DZu91GdGX6ncOx5U93Kjx5ZunD20cJgcr6M6YUnE2PhN6IAYuvVSdNQKQccEtHXu2lFcFkLeJJR2svbQWzb4RiihDKCpJQ_gPZ-1ZJISs6lIw2Xvu7Ei7rufVA\",3],null,[1376,768]]],[\"2e1227e3-7cb3-4213-8574-503bc667c75e\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAg\",null,[[1790105692,921386000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbmtaLvJBYFzG_Nu8SGXyCkpETTdaEe-GEQdQcMp6ZwhV0aup7aSHYh_yQZgOAFFIeivnJODySrIpprwMd1_VwH8racXWFZI7_sHEgex2j0TlCMr6upaH5hmazd5AjtL_JTn2dAR4NTD8WmRxiiwg31GI2Px3pPZQ1BoHnpyw\",[null,null,[[\"Large breasts, subtly revealed.\",null,[[[\"ngực to, lộ một cách tinh tế\"]]]]],[[[null,2,\"6e6be6ca-d2c5-477c-b025-8ceac859aa54\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbmtaLvJBYFzG_Nu8SGXyCkpETTdaEe-GEQdQcMp6ZwhV0aup7aSHYh_yQZgOAFFIeivnJODySrIpprwMd1_VwH8racXWFZI7_sHEgex2j0TlCMr6upaH5hmazd5AjtL_JTn2dAR4NTD8WmRxiiwg31GI2Px3pPZQ1BoHnpyw\",null,null,180851],[[null,1786455158,null,null,null,null,null,\"Large breasts, subtly revealed.\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbmtaLvJBYFzG_Nu8SGXyCkpETTdaEe-GEQdQcMp6ZwhV0aup7aSHYh_yQZgOAFFIeivnJODySrIpprwMd1_VwH8racXWFZI7_sHEgex2j0TlCMr6upaH5hmazd5AjtL_JTn2dAR4NTD8WmRxiiwg31GI2Px3pPZQ1BoHnpyw\",3],null,[1376,768]]],[\"30b5f32e-3918-4b68-acf8-7f7b0afafd0d\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"9e8ede1b-4f8f-4354-aecb-a7759421bf13\",\"CAE\",null,[[1790099253,589865000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUalNn_NTUPRfEuX9bDo48haCw-YN8O0Sswn60OUCB8dMrwu1yeFAx3Cnj7659Olp76dD9_IrOClicqzqKt7N0wH4Zz1tGyQYc9I9Uu7EQy4bZpcwkPEXYU3fQ3-u6CW8eVS5Ix8h_J2Zq697efFTosxZWK0d-aBd1q415_TYQ\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Atmospheric cinematic shot inside Ngoc Truc Warehouse. Le Quoc Tien shines a flashlight onto a heavy dark metal hatch embedded in the concrete floor. The circular sun emblem with twelve rays on the hatch glows with an ominous deep red bioluminescent light. Dense cold vapor rising from the metallic seams. 35mm cinematic photograph, moody volumetric shadows.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Atmospheric cinematic shot inside Ngoc Truc Warehouse. Le Quoc Tien shines a flashlight onto a heavy dark metal hatch embedded in the concrete floor. The circular sun emblem with twelve rays on the hatch glows with an ominous deep red bioluminescent light. Dense cold vapor rising from the metallic seams. 35mm cinematic photograph, moody volumetric shadows.\"]]]]],[[[null,1,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\"],[null,1,\"5a919b50-566c-4cfb-97b6-4e481650dc0a\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUalNn_NTUPRfEuX9bDo48haCw-YN8O0Sswn60OUCB8dMrwu1yeFAx3Cnj7659Olp76dD9_IrOClicqzqKt7N0wH4Zz1tGyQYc9I9Uu7EQy4bZpcwkPEXYU3fQ3-u6CW8eVS5Ix8h_J2Zq697efFTosxZWK0d-aBd1q415_TYQ\",null,null,222634],[[null,91251415,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Atmospheric cinematic shot inside Ngoc Truc Warehouse. Le Quoc Tien shines a flashlight onto a heavy dark metal hatch embedded in the concrete floor. The circular sun emblem with twelve rays on the hatch glows with an ominous deep red bioluminescent light. Dense cold vapor rising from the metallic seams. 35mm cinematic photograph, moody volumetric shadows.\",25,\"\",null,\"9e8ede1b-4f8f-4354-aecb-a7759421bf13\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUalNn_NTUPRfEuX9bDo48haCw-YN8O0Sswn60OUCB8dMrwu1yeFAx3Cnj7659Olp76dD9_IrOClicqzqKt7N0wH4Zz1tGyQYc9I9Uu7EQy4bZpcwkPEXYU3fQ3-u6CW8eVS5Ix8h_J2Zq697efFTosxZWK0d-aBd1q415_TYQ\",3],null,[1376,768]]],[\"310d92fb-dd8e-4e33-b061-4750fcbeeeaa\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"ad778284-c548-4428-9386-24491b893682\",\"CAE\",null,[[1790098625,39575000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUa_gg6Ycay8_6RD99svCFCHJYSmlGmV8rQw6rG5cSWSwG7uND9QTQa1Ehcv6ZyyJTetHv_LnKZyDs_NcAa1OoH-AuPdDUnRcXBtHFNiBESXr2Kq-n1shgnzI2s11MABmqWSQmKnrTqIyG_3EvOJvhMRAFhWn0kDrLllaK0rdA\",[null,null,[[\"Close-up of a cute, fluffy cat peering through a rainy window overlooking a busy Hanoi street at dusk. Grounded cinematic realism, natural skin and fur texture, physically believable rain droplets on glass. Near-future techno-thriller mood, muted color palette, high dynamic range.\",null,[[[\"Close-up of a cute, fluffy cat peering through a rainy window overlooking a busy Hanoi street at dusk. Grounded cinematic realism, natural skin and fur texture, physically believable rain droplets on glass. Near-future techno-thriller mood, muted color palette, high dynamic range.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUa_gg6Ycay8_6RD99svCFCHJYSmlGmV8rQw6rG5cSWSwG7uND9QTQa1Ehcv6ZyyJTetHv_LnKZyDs_NcAa1OoH-AuPdDUnRcXBtHFNiBESXr2Kq-n1shgnzI2s11MABmqWSQmKnrTqIyG_3EvOJvhMRAFhWn0kDrLllaK0rdA\",null,null,296927],[[null,132288,null,null,null,null,null,\"Close-up of a cute, fluffy cat peering through a rainy window overlooking a busy Hanoi street at dusk. Grounded cinematic realism, natural skin and fur texture, physically believable rain droplets on glass. Near-future techno-thriller mood, muted color palette, high dynamic range.\",25,\"\",null,\"ad778284-c548-4428-9386-24491b893682\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUa_gg6Ycay8_6RD99svCFCHJYSmlGmV8rQw6rG5cSWSwG7uND9QTQa1Ehcv6ZyyJTetHv_LnKZyDs_NcAa1OoH-AuPdDUnRcXBtHFNiBESXr2Kq-n1shgnzI2s11MABmqWSQmKnrTqIyG_3EvOJvhMRAFhWn0kDrLllaK0rdA\",3],null,[1376,768]]],[\"3d1052dd-2332-48f6-81c3-73adb6d4ff09\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"337d7d27-bc09-4ca1-9f11-1b9253d15cbb\",\"CAE\",null,[[1790104423,640950000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUY6KFmaKl70oB4q2qP1ELQeDAA8KXk9MyYhaeYv76CDntBP943rdON5zdngOz1at2IiBnKsjqI7820q-FrpHiUnR5-Ub9vrGSqaQMYxLtCYvPgV-0tpDcgftURMYtur9WCj3PDKwtSd3pASvjZk6Ta3QiPOcSLaJKKq1d5JPQ\",[null,null,[[\"Grounded cinematic realism, post-apocalyptic Hanoi in 2028. An overgrown, crumbling Long Bien Bridge spans the Red River under a heavy, ash-colored sky. Distant skeletal skyscrapers of the city are shrouded in thick mist. The scene is quiet, devoid of life, featuring authentic Vietnamese architecture and infrastructure. Muted color palette, subtle film grain, physically believable heat haze. No generic cyberpunk neon or glowing holograms.\",null,[[[\"Grounded cinematic realism, post-apocalyptic Hanoi in 2028. An overgrown, crumbling Long Bien Bridge spans the Red River under a heavy, ash-colored sky. Distant skeletal skyscrapers of the city are shrouded in thick mist. The scene is quiet, devoid of life, featuring authentic Vietnamese architecture and infrastructure. Muted color palette, subtle film grain, physically believable heat haze. No generic cyberpunk neon or glowing holograms.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUY6KFmaKl70oB4q2qP1ELQeDAA8KXk9MyYhaeYv76CDntBP943rdON5zdngOz1at2IiBnKsjqI7820q-FrpHiUnR5-Ub9vrGSqaQMYxLtCYvPgV-0tpDcgftURMYtur9WCj3PDKwtSd3pASvjZk6Ta3QiPOcSLaJKKq1d5JPQ\",null,null,210059],[[null,14483,null,null,null,null,null,\"Grounded cinematic realism, post-apocalyptic Hanoi in 2028. An overgrown, crumbling Long Bien Bridge spans the Red River under a heavy, ash-colored sky. Distant skeletal skyscrapers of the city are shrouded in thick mist. The scene is quiet, devoid of life, featuring authentic Vietnamese architecture and infrastructure. Muted color palette, subtle film grain, physically believable heat haze. No generic cyberpunk neon or glowing holograms.\",25,\"\",null,\"337d7d27-bc09-4ca1-9f11-1b9253d15cbb\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUY6KFmaKl70oB4q2qP1ELQeDAA8KXk9MyYhaeYv76CDntBP943rdON5zdngOz1at2IiBnKsjqI7820q-FrpHiUnR5-Ub9vrGSqaQMYxLtCYvPgV-0tpDcgftURMYtur9WCj3PDKwtSd3pASvjZk6Ta3QiPOcSLaJKKq1d5JPQ\",3],null,[1376,768]]],[\"41627dd9-5c3f-427f-845c-d83fc277b5e9\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",\"CAU\",null,[[1790173506,107885000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYFcUMTsOE6AhppE7lm8Km-427PJN-lzcsRm9dXuzxq_Oz2csumv9AW2j7tWm26WKmuyj0EcwC1p66xonLxbGvi_eMfuNxdJ3MGkOzXrVF98hzfJgvKPgbio2koOurKIkqXyyX13neV96slX51nSH_SEU_b9bWQ4Q8T2vS2uQ\",[null,null,[[\"A dramatic cinematic shot of a young man in subterranean B3 basement parking at Me Tri under extreme heat, 35mm RAW photograph\",null,[[[\"A dramatic cinematic shot of a young man in subterranean B3 basement parking at Me Tri under extreme heat, 35mm RAW photograph\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYFcUMTsOE6AhppE7lm8Km-427PJN-lzcsRm9dXuzxq_Oz2csumv9AW2j7tWm26WKmuyj0EcwC1p66xonLxbGvi_eMfuNxdJ3MGkOzXrVF98hzfJgvKPgbio2koOurKIkqXyyX13neV96slX51nSH_SEU_b9bWQ4Q8T2vS2uQ\",null,null,135878],[[null,981155251,null,null,null,null,null,\"A dramatic cinematic shot of a young man in subterranean B3 basement parking at Me Tri under extreme heat, 35mm RAW photograph\",25,\"\",null,\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYFcUMTsOE6AhppE7lm8Km-427PJN-lzcsRm9dXuzxq_Oz2csumv9AW2j7tWm26WKmuyj0EcwC1p66xonLxbGvi_eMfuNxdJ3MGkOzXrVF98hzfJgvKPgbio2koOurKIkqXyyX13neV96slX51nSH_SEU_b9bWQ4Q8T2vS2uQ\",3],null,[1376,768]]],[\"4630aeab-cd27-4457-96b6-24045de2504e\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"c7fee095-6829-4801-94c8-3eb9bcaf060f\",\"CAE\",null,[[1785255350,725479000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYvD5DO21C7peFe1MSdZ6wqPFz5qUEGBLbNmQua_4kKt72r5w1J1pTtaEVZkZHRJuymy5QmAZbcuUlPtLKMfNspIFve3bv0wBudRZKXFkpzeNWXjBaLce4BsfYKnfBjOL39eT2dqSe0O-omDru0BPOWjUKobLnXTNFht_Mo\",[null,null,null,null,1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYvD5DO21C7peFe1MSdZ6wqPFz5qUEGBLbNmQua_4kKt72r5w1J1pTtaEVZkZHRJuymy5QmAZbcuUlPtLKMfNspIFve3bv0wBudRZKXFkpzeNWXjBaLce4BsfYKnfBjOL39eT2dqSe0O-omDru0BPOWjUKobLnXTNFht_Mo\",null,null,521906],[null,[null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYvD5DO21C7peFe1MSdZ6wqPFz5qUEGBLbNmQua_4kKt72r5w1J1pTtaEVZkZHRJuymy5QmAZbcuUlPtLKMfNspIFve3bv0wBudRZKXFkpzeNWXjBaLce4BsfYKnfBjOL39eT2dqSe0O-omDru0BPOWjUKobLnXTNFht_Mo\",0],[1448,1086]]],[\"538cd93f-52d5-4c9e-9924-7a66b8dd016f\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"9c487a71-fc76-4e0e-bdc3-98eee2bc25da\",\"CAE\",null,[[1790099223,430583000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUba9TAxJHa3p4QWzvlYmJ5i7dpuV6jEiNtC564dOPzPAw7dW9NGpUqfzrn_6Ivz6G4P_bL5YXozCmEzILHaVB1zttr6ECAC07TOmehktY-El0n-bkrD_5vuWlUntB7Txd6R0cYh8IDxUttuP1KdAXF_hs2zzKOeNt2LghGpUA\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Cinematic close-up of Le Quoc Tien jolting awake in bed, eyes wide with intense shock and cold sweat on his face. In background, a desktop setup with multiple glowing monitors and a digital clock displaying 07:13 AM. Soft morning golden sunlight streaming through half-open blinds. Photorealistic RAW photograph, Canon EOS R5, shallow depth of field.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Cinematic close-up of Le Quoc Tien jolting awake in bed, eyes wide with intense shock and cold sweat on his face. In background, a desktop setup with multiple glowing monitors and a digital clock displaying 07:13 AM. Soft morning golden sunlight streaming through half-open blinds. Photorealistic RAW photograph, Canon EOS R5, shallow depth of field.\"]]]]],[[[null,1,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUba9TAxJHa3p4QWzvlYmJ5i7dpuV6jEiNtC564dOPzPAw7dW9NGpUqfzrn_6Ivz6G4P_bL5YXozCmEzILHaVB1zttr6ECAC07TOmehktY-El0n-bkrD_5vuWlUntB7Txd6R0cYh8IDxUttuP1KdAXF_hs2zzKOeNt2LghGpUA\",null,null,122156],[[null,658411800,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Cinematic close-up of Le Quoc Tien jolting awake in bed, eyes wide with intense shock and cold sweat on his face. In background, a desktop setup with multiple glowing monitors and a digital clock displaying 07:13 AM. Soft morning golden sunlight streaming through half-open blinds. Photorealistic RAW photograph, Canon EOS R5, shallow depth of field.\",25,\"\",null,\"9c487a71-fc76-4e0e-bdc3-98eee2bc25da\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUba9TAxJHa3p4QWzvlYmJ5i7dpuV6jEiNtC564dOPzPAw7dW9NGpUqfzrn_6Ivz6G4P_bL5YXozCmEzILHaVB1zttr6ECAC07TOmehktY-El0n-bkrD_5vuWlUntB7Txd6R0cYh8IDxUttuP1KdAXF_hs2zzKOeNt2LghGpUA\",3],null,[1376,768]]],[\"567984bd-c3ff-46de-ad25-353be60e6188\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",\"CAQ\",null,[[1790106174,785955000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUY3VK7qOJVbMaIhPKY_538QExrPFVsUwang-UkP9AxM4VJ0zZqmSIQrj94nZEGslM812hnfTt7kaMwBDwxw-zuRAcwNIB56Ar5VZvOZSt6vshgGNvwiLFL86HzoaNBeqnjCV2Vrtq6EHz3TM6xejHsV95G-JZI5XnUdnX7WEg\",[null,null,[[\"\\\"Front-facing person, posing, sensual face\\\"\",null,[[[\"quy người chính diện, tạo dáng , khuôn mặt gợi cảm\"]]]]],[[[null,2,\"b4d91c90-5b01-4472-aab2-1bcacb892fa4\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUY3VK7qOJVbMaIhPKY_538QExrPFVsUwang-UkP9AxM4VJ0zZqmSIQrj94nZEGslM812hnfTt7kaMwBDwxw-zuRAcwNIB56Ar5VZvOZSt6vshgGNvwiLFL86HzoaNBeqnjCV2Vrtq6EHz3TM6xejHsV95G-JZI5XnUdnX7WEg\",null,null,119798],[[null,1871434922,null,null,null,null,null,\"\\\"Front-facing person, posing, sensual face\\\"\",25,\"\",null,\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUY3VK7qOJVbMaIhPKY_538QExrPFVsUwang-UkP9AxM4VJ0zZqmSIQrj94nZEGslM812hnfTt7kaMwBDwxw-zuRAcwNIB56Ar5VZvOZSt6vshgGNvwiLFL86HzoaNBeqnjCV2Vrtq6EHz3TM6xejHsV95G-JZI5XnUdnX7WEg\",3],null,[1376,768]]],[\"5a919b50-566c-4cfb-97b6-4e481650dc0a\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"b84f96ab-d2b2-414b-b4ed-912a9e3e2859\",\"CAE\",null,[[1790099018,2158000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbwQe77Y4OkTtNco2H0sStQ2-qp7379h4bZeORSYvXZ-589lAjp7xPmFYzHFU1vG90yU_ywYBY5mO31QkaIeR3nixA7xpN2X20jzDi-VLeGn4-WvG4lHkMtVu1SDjQHnbwmluL1DkulB8QpEx7KDLTaQTsuVVKGTZmN7ZCu\",[null,null,[[\"Single reference image of Secluded industrial concrete warehouse on Hanoi outskirts, weathered corrugated metal roof, dusty grey concrete floor with faint cracks, heavy circular dark metal floor hatch with an etched twelve-ray sun emblem hidden beneath metal shelving. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of Secluded industrial concrete warehouse on Hanoi outskirts, weathered corrugated metal roof, dusty grey concrete floor with faint cracks, heavy circular dark metal floor hatch with an etched twelve-ray sun emblem hidden beneath metal shelving. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbwQe77Y4OkTtNco2H0sStQ2-qp7379h4bZeORSYvXZ-589lAjp7xPmFYzHFU1vG90yU_ywYBY5mO31QkaIeR3nixA7xpN2X20jzDi-VLeGn4-WvG4lHkMtVu1SDjQHnbwmluL1DkulB8QpEx7KDLTaQTsuVVKGTZmN7ZCu\",null,null,175386],[[null,288261536,null,null,null,null,null,\"Single reference image of Secluded industrial concrete warehouse on Hanoi outskirts, weathered corrugated metal roof, dusty grey concrete floor with faint cracks, heavy circular dark metal floor hatch with an etched twelve-ray sun emblem hidden beneath metal shelving. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"b84f96ab-d2b2-414b-b4ed-912a9e3e2859\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbwQe77Y4OkTtNco2H0sStQ2-qp7379h4bZeORSYvXZ-589lAjp7xPmFYzHFU1vG90yU_ywYBY5mO31QkaIeR3nixA7xpN2X20jzDi-VLeGn4-WvG4lHkMtVu1SDjQHnbwmluL1DkulB8QpEx7KDLTaQTsuVVKGTZmN7ZCu\",3],null,[1376,768]]],[\"65993027-0037-4f25-9fb7-7bd4d301ee7b\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"87cfaa04-a192-405e-aa3b-137fa3d20ccb\",\"CAE\",null,[[1790098988,593315000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYuW_MBkm_rvBXuqLf9k9WJJNEP4pGgLOd-2Jqy0aTRKvG65KC4qe8iDn4enPIs9r4yCr_21dXJQBparb-V7KAeIvF5wNzz3-SnX9PX1KZ7hrQhzwo-pBD3coVHYYvCoqLjMy1IFs_fBWo8e_GTg2Iyb9o6dypoboRnDId8jA\",[null,null,[[\"Single reference image of 27-year-old Vietnamese investigative journalist, smart analytical expression, hair tied back in a neat ponytail, wearing a light beige utility shirt, olive multi-pocket reporter vest, canvas shoulder bag carrying a compact camera, intelligent perceptive dark eyes. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of 27-year-old Vietnamese investigative journalist, smart analytical expression, hair tied back in a neat ponytail, wearing a light beige utility shirt, olive multi-pocket reporter vest, canvas shoulder bag carrying a compact camera, intelligent perceptive dark eyes. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYuW_MBkm_rvBXuqLf9k9WJJNEP4pGgLOd-2Jqy0aTRKvG65KC4qe8iDn4enPIs9r4yCr_21dXJQBparb-V7KAeIvF5wNzz3-SnX9PX1KZ7hrQhzwo-pBD3coVHYYvCoqLjMy1IFs_fBWo8e_GTg2Iyb9o6dypoboRnDId8jA\",null,null,138007],[[null,998613419,null,null,null,null,null,\"Single reference image of 27-year-old Vietnamese investigative journalist, smart analytical expression, hair tied back in a neat ponytail, wearing a light beige utility shirt, olive multi-pocket reporter vest, canvas shoulder bag carrying a compact camera, intelligent perceptive dark eyes. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"87cfaa04-a192-405e-aa3b-137fa3d20ccb\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYuW_MBkm_rvBXuqLf9k9WJJNEP4pGgLOd-2Jqy0aTRKvG65KC4qe8iDn4enPIs9r4yCr_21dXJQBparb-V7KAeIvF5wNzz3-SnX9PX1KZ7hrQhzwo-pBD3coVHYYvCoqLjMy1IFs_fBWo8e_GTg2Iyb9o6dypoboRnDId8jA\",2],null,[768,1376]]],[\"666bc47c-1fa1-4167-83cc-3088840b3146\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d19f6811-455b-4838-bdc2-b908aeb7bd36\",\"CAE\",null,[[1790169824,340307000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbpaVpfKL6IfiRICiDfApjUpVXD_I6HbglLUIxQbvzERuEEQErKZyuIkr9BWioME_zJXXY3Ot16fKfEw5YoALNDuctrP6QFnojDlP16MlfiJR2OObhXloM4hGy7Qi8x2C8XZpNwApq_plSPJXSAZjcsavE6mbTYYlSRQxiaMQ\",[null,null,[[\"Grounded cinematic realism, an older Vietnamese male character in post-apocalyptic Hanoi 2028. He has rugged, weathered features, short grey hair, and intense eyes. He is wearing a practical, sweat-stained industrial worker's jumpsuit with tech-utility pouches. Natural skin texture, visible sweat and grime from the extreme heatwave. He stands in a dim, cluttered workshop filled with high-tech salvage. Near-future techno-thriller style, restrained acting, subtle film grain, natural lighting, high dynamic range. No fantasy spectacle.\",null,[[[\"Grounded cinematic realism, an older Vietnamese male character in post-apocalyptic Hanoi 2028. He has rugged, weathered features, short grey hair, and intense eyes. He is wearing a practical, sweat-stained industrial worker's jumpsuit with tech-utility pouches. Natural skin texture, visible sweat and grime from the extreme heatwave. He stands in a dim, cluttered workshop filled with high-tech salvage. Near-future techno-thriller style, restrained acting, subtle film grain, natural lighting, high dynamic range. No fantasy spectacle.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbpaVpfKL6IfiRICiDfApjUpVXD_I6HbglLUIxQbvzERuEEQErKZyuIkr9BWioME_zJXXY3Ot16fKfEw5YoALNDuctrP6QFnojDlP16MlfiJR2OObhXloM4hGy7Qi8x2C8XZpNwApq_plSPJXSAZjcsavE6mbTYYlSRQxiaMQ\",null,null,169345],[[null,707997,null,null,null,null,null,\"Grounded cinematic realism, an older Vietnamese male character in post-apocalyptic Hanoi 2028. He has rugged, weathered features, short grey hair, and intense eyes. He is wearing a practical, sweat-stained industrial worker's jumpsuit with tech-utility pouches. Natural skin texture, visible sweat and grime from the extreme heatwave. He stands in a dim, cluttered workshop filled with high-tech salvage. Near-future techno-thriller style, restrained acting, subtle film grain, natural lighting, high dynamic range. No fantasy spectacle.\",25,\"\",null,\"d19f6811-455b-4838-bdc2-b908aeb7bd36\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbpaVpfKL6IfiRICiDfApjUpVXD_I6HbglLUIxQbvzERuEEQErKZyuIkr9BWioME_zJXXY3Ot16fKfEw5YoALNDuctrP6QFnojDlP16MlfiJR2OObhXloM4hGy7Qi8x2C8XZpNwApq_plSPJXSAZjcsavE6mbTYYlSRQxiaMQ\",3],null,[1376,768]]],[\"684e27a9-a16c-480e-95ce-8cb540798659\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"3ab07549-ccbb-410a-a97d-08b8a4627f84\",\"CAE\",null,[[1784546411,930438000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUb_QujW3NDPoer97t_RbrFOtFLtMDC-jX49qb8CXY7dI1IdXHvhFoyk9WtQaUZunQm2XyQK2Wrx530dtfCNPv_b9m3ppqNaiXcDBB5HN7COGvoIBa_CPqKx98-KEOw_9SSP_KMjpOSvSP2krJY_RL6kv-KFBwuk06SqhiGOPg\",[null,null,[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",null,[[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\"]]]]],[null,[[\"f4d9c731-41f2-4b51-9dd2-edd20c1dc7f1\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUb_QujW3NDPoer97t_RbrFOtFLtMDC-jX49qb8CXY7dI1IdXHvhFoyk9WtQaUZunQm2XyQK2Wrx530dtfCNPv_b9m3ppqNaiXcDBB5HN7COGvoIBa_CPqKx98-KEOw_9SSP_KMjpOSvSP2krJY_RL6kv-KFBwuk06SqhiGOPg\",null,null,614197],[[null,922697,\"CAMSJDU5NDc1OGNjLTExZjUtNGY5Mi04YjNjLTEyMTM2ODY1OTFmNBokMTQ5NmMyYWUtNTAyNy00NGQ0LWE2M2UtM2VmM2MxNzYzZTI0IgNDQUUqJDY4NGUyN2E5LWExNmMtNDgwZS05NWNlLThjYjU0MDc5ODY1OQ\",null,null,null,null,\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",25,\"\",null,\"3ab07549-ccbb-410a-a97d-08b8a4627f84\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUb_QujW3NDPoer97t_RbrFOtFLtMDC-jX49qb8CXY7dI1IdXHvhFoyk9WtQaUZunQm2XyQK2Wrx530dtfCNPv_b9m3ppqNaiXcDBB5HN7COGvoIBa_CPqKx98-KEOw_9SSP_KMjpOSvSP2krJY_RL6kv-KFBwuk06SqhiGOPg\",3],null,[1376,768]]],[\"6aa915c7-1123-4e12-b75f-6d5e6d40d0fe\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d7c54686-02ce-4344-ac22-2888ccf9c76e\",\"CAE\",null,[[1784546032,956328000],\"Man in black shirt and pants\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUa0Hu8CuBjBs_H1OHD0zbJ6ZyQhx1Hx0z1fdSfPWo778yvuntmjnGeBneX5oRmxo12rL4ebKQlklWgX6TmVuwqp8rBlNdWXHAkIDSKkyqIO38lMbR9EsRrp1fydpam1-1EGOvRRDEA4ds17HnIBQ-iIpCzpHEfOq_-YjCmO4A\",[null,null,null,null,1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUa0Hu8CuBjBs_H1OHD0zbJ6ZyQhx1Hx0z1fdSfPWo778yvuntmjnGeBneX5oRmxo12rL4ebKQlklWgX6TmVuwqp8rBlNdWXHAkIDSKkyqIO38lMbR9EsRrp1fydpam1-1EGOvRRDEA4ds17HnIBQ-iIpCzpHEfOq_-YjCmO4A\",null,\"A man with short dark hair stands against a plain gray background, shown from multiple angles. He wears a black button-up shirt over a dark t-shirt, dark cargo pants, and a crossbody bag. He has a watch on his left wrist.\"],[null,[null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUa0Hu8CuBjBs_H1OHD0zbJ6ZyQhx1Hx0z1fdSfPWo778yvuntmjnGeBneX5oRmxo12rL4ebKQlklWgX6TmVuwqp8rBlNdWXHAkIDSKkyqIO38lMbR9EsRrp1fydpam1-1EGOvRRDEA4ds17HnIBQ-iIpCzpHEfOq_-YjCmO4A\",0],[1376,768]]],[\"6e6be6ca-d2c5-477c-b025-8ceac859aa54\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAU\",null,[[1790105600,764469000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZ5hXeejQlQWInv3-Nk6t2Os8Ny-BBsbgmhlE9LmsbSyiPXjGPU9Eenh2ayA97QstKkBFb3OVzZBoiEyffvhPkMOTUIijGjPNYm-pYc8mtJAu39C3mO8ivKlsXdSiopxKxiTDsQPdEMQRRT-ieg1Nv6VgX92UoHk7ralpuQ\",[null,null,[[\"two-piece outfit, camisole, many torn spots\",null,[[[\"áo 2 mảnh , 2 dây, có nhiều vết rách\"]]]]],[[[null,2,\"279b944e-5348-4ecc-91d4-f356b9271132\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZ5hXeejQlQWInv3-Nk6t2Os8Ny-BBsbgmhlE9LmsbSyiPXjGPU9Eenh2ayA97QstKkBFb3OVzZBoiEyffvhPkMOTUIijGjPNYm-pYc8mtJAu39C3mO8ivKlsXdSiopxKxiTDsQPdEMQRRT-ieg1Nv6VgX92UoHk7ralpuQ\",null,null,181689],[[null,166472867,null,null,null,null,null,\"two-piece outfit, camisole, many torn spots\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZ5hXeejQlQWInv3-Nk6t2Os8Ny-BBsbgmhlE9LmsbSyiPXjGPU9Eenh2ayA97QstKkBFb3OVzZBoiEyffvhPkMOTUIijGjPNYm-pYc8mtJAu39C3mO8ivKlsXdSiopxKxiTDsQPdEMQRRT-ieg1Nv6VgX92UoHk7ralpuQ\",3],null,[1376,768]]],[\"732c7e1a-7267-462f-8f58-1bf43694428e\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"be5c73e8-269a-4fdf-a1a5-d2265179a8be\",\"CAE\",null,[[1784546459,807750000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUb5ap5IbDPwWp5-DGrbazcb9T_G-aOu9nN3g7ib3dMMRXskaJ6jaihFAztr4lIRjSOFZCDgBhfGvvkmqUxqXxUdQtNNnARmrm5vl4Q9vWVTtVHAKPxZGJfphs0xlOYhLL6xrDPIkT3b-1dd0mapyQ-nFne_v6Vmi_MEQZgtFg\",[null,null,[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",null,[[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\"]]]]],[null,[[\"f4d9c731-41f2-4b51-9dd2-edd20c1dc7f1\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUb5ap5IbDPwWp5-DGrbazcb9T_G-aOu9nN3g7ib3dMMRXskaJ6jaihFAztr4lIRjSOFZCDgBhfGvvkmqUxqXxUdQtNNnARmrm5vl4Q9vWVTtVHAKPxZGJfphs0xlOYhLL6xrDPIkT3b-1dd0mapyQ-nFne_v6Vmi_MEQZgtFg\",null,null,655260],[[null,599389,\"CAMSJDU5NDc1OGNjLTExZjUtNGY5Mi04YjNjLTEyMTM2ODY1OTFmNBokMTMyMDVkOTQtYTQ2Mi00MjE5LWI5MjQtMzdhNjFiNjY2MzIxIgNDQUUqJDczMmM3ZTFhLTcyNjctNDYyZi04ZjU4LTFiZjQzNjk0NDI4ZQ\",null,null,null,null,\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",25,\"\",null,\"be5c73e8-269a-4fdf-a1a5-d2265179a8be\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUb5ap5IbDPwWp5-DGrbazcb9T_G-aOu9nN3g7ib3dMMRXskaJ6jaihFAztr4lIRjSOFZCDgBhfGvvkmqUxqXxUdQtNNnARmrm5vl4Q9vWVTtVHAKPxZGJfphs0xlOYhLL6xrDPIkT3b-1dd0mapyQ-nFne_v6Vmi_MEQZgtFg\",3],null,[1376,768]]],[\"76a03ec4-6340-4e25-9e8a-5009942893b9\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"a5fbb9e9-b0d0-48f4-89ea-277444ec27c4\",\"CAE\",null,[[1790104424,188616000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZyRbtbzcGUezd3ygh-aozo8PeVAlRLEKABEn0N0fDPqLBG5uL0xC4YycYgSDi9TOTperhgoMI6GJWmGv5QXTmlsA4TzK1yYdOeJF_5xxGj9U8Oh-g93r_A9laQ7LC1RvLfh8nVouNkPZlw5DiPSkCNehYo6N1bwxkx1ZXd_A\",[null,null,[[\"A deserted, dust-covered street in Hanoi's Old Quarter after a near-future catastrophe. Abandoned 2028-style electric scooters are half-buried in debris and overgrown vines. Tall, narrow buildings show signs of structural decay under a dim, overcast sun. Grounded live-action aesthetic, cinematic realism, authentic Vietnamese everyday objects. Darker, atmospheric lighting with high dynamic range.\",null,[[[\"A deserted, dust-covered street in Hanoi's Old Quarter after a near-future catastrophe. Abandoned 2028-style electric scooters are half-buried in debris and overgrown vines. Tall, narrow buildings show signs of structural decay under a dim, overcast sun. Grounded live-action aesthetic, cinematic realism, authentic Vietnamese everyday objects. Darker, atmospheric lighting with high dynamic range.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZyRbtbzcGUezd3ygh-aozo8PeVAlRLEKABEn0N0fDPqLBG5uL0xC4YycYgSDi9TOTperhgoMI6GJWmGv5QXTmlsA4TzK1yYdOeJF_5xxGj9U8Oh-g93r_A9laQ7LC1RvLfh8nVouNkPZlw5DiPSkCNehYo6N1bwxkx1ZXd_A\",null,null,281615],[[null,755263,null,null,null,null,null,\"A deserted, dust-covered street in Hanoi's Old Quarter after a near-future catastrophe. Abandoned 2028-style electric scooters are half-buried in debris and overgrown vines. Tall, narrow buildings show signs of structural decay under a dim, overcast sun. Grounded live-action aesthetic, cinematic realism, authentic Vietnamese everyday objects. Darker, atmospheric lighting with high dynamic range.\",25,\"\",null,\"a5fbb9e9-b0d0-48f4-89ea-277444ec27c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZyRbtbzcGUezd3ygh-aozo8PeVAlRLEKABEn0N0fDPqLBG5uL0xC4YycYgSDi9TOTperhgoMI6GJWmGv5QXTmlsA4TzK1yYdOeJF_5xxGj9U8Oh-g93r_A9laQ7LC1RvLfh8nVouNkPZlw5DiPSkCNehYo6N1bwxkx1ZXd_A\",3],null,[1376,768]]],[\"78266bba-b106-47e7-80e3-c152822e1ca9\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"82ddef0b-fced-4a18-a039-240a66c111d2\",\"CAE\",null,[[1790105368,716850000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaWhR4c9CHlZw_wiJwoNlZJDs8mzOrvAB-X2XljYNHpxlP3snah_vertyktxnovuo81KPz7UqZpVPoXsJWw4fx5iwYnChh9FZ9dEUTEBZTXi7c3F9PMYVPnPhkdTdsrraejL2gyMA0NH0gPESKQazHrNYgJDxTFXzY35Uhk\",[null,null,[[\"A beautiful Vietnamese female character in a grounded 2028 techno-thriller setting. She is wearing sleek, tight-fitting industrial-chic clothing with a long, flowing tech-fabric coat that trails behind her. Her face is authentically Vietnamese, with a determined expression. Cinematic realism, natural lighting under a harsh, hot sun, visible heat haze in the background. Physically believable textures, no fantasy spectacle, subtle film grain. High-quality live-action aesthetic.\",null,[[[\"A beautiful Vietnamese female character in a grounded 2028 techno-thriller setting. She is wearing sleek, tight-fitting industrial-chic clothing with a long, flowing tech-fabric coat that trails behind her. Her face is authentically Vietnamese, with a determined expression. Cinematic realism, natural lighting under a harsh, hot sun, visible heat haze in the background. Physically believable textures, no fantasy spectacle, subtle film grain. High-quality live-action aesthetic.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUaWhR4c9CHlZw_wiJwoNlZJDs8mzOrvAB-X2XljYNHpxlP3snah_vertyktxnovuo81KPz7UqZpVPoXsJWw4fx5iwYnChh9FZ9dEUTEBZTXi7c3F9PMYVPnPhkdTdsrraejL2gyMA0NH0gPESKQazHrNYgJDxTFXzY35Uhk\",null,null,169250],[[null,475867,null,null,null,null,null,\"A beautiful Vietnamese female character in a grounded 2028 techno-thriller setting. She is wearing sleek, tight-fitting industrial-chic clothing with a long, flowing tech-fabric coat that trails behind her. Her face is authentically Vietnamese, with a determined expression. Cinematic realism, natural lighting under a harsh, hot sun, visible heat haze in the background. Physically believable textures, no fantasy spectacle, subtle film grain. High-quality live-action aesthetic.\",25,\"\",null,\"82ddef0b-fced-4a18-a039-240a66c111d2\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUaWhR4c9CHlZw_wiJwoNlZJDs8mzOrvAB-X2XljYNHpxlP3snah_vertyktxnovuo81KPz7UqZpVPoXsJWw4fx5iwYnChh9FZ9dEUTEBZTXi7c3F9PMYVPnPhkdTdsrraejL2gyMA0NH0gPESKQazHrNYgJDxTFXzY35Uhk\",3],null,[1376,768]]],[\"78e46231-e6cf-43fb-99bc-a4cb96196e24\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"431da3f0-96a9-4cc7-8384-937287b72c6e\",\"CAE\",null,[[1790098978,830949000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUarwgaECQHTDEn00eyt70D2PN5pVA_w2IGU7iU5N8W9UmWPaozySZboiA15dJttaxxWVKJG3E8A0lhxYJg9dw9MOG1Y7EbFshxazXjJ4KuZEKA_1Pg5ItXC1YxZXtTl2Q4oJPpTmXT_gQGJC-ytNPkvug_1jJlgv3DCzLo0rA\",[null,null,[[\"Single reference image of 34-year-old Vietnamese logistics commander, tall imposing authoritative posture, slicked-back dark hair, wearing an unbuttoned black button-down shirt with rolled-up sleeves, dark trousers, distinctive matte black ring on his left ring finger, piercing cold calculated gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of 34-year-old Vietnamese logistics commander, tall imposing authoritative posture, slicked-back dark hair, wearing an unbuttoned black button-down shirt with rolled-up sleeves, dark trousers, distinctive matte black ring on his left ring finger, piercing cold calculated gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUarwgaECQHTDEn00eyt70D2PN5pVA_w2IGU7iU5N8W9UmWPaozySZboiA15dJttaxxWVKJG3E8A0lhxYJg9dw9MOG1Y7EbFshxazXjJ4KuZEKA_1Pg5ItXC1YxZXtTl2Q4oJPpTmXT_gQGJC-ytNPkvug_1jJlgv3DCzLo0rA\",null,null,93667],[[null,610053073,null,null,null,null,null,\"Single reference image of 34-year-old Vietnamese logistics commander, tall imposing authoritative posture, slicked-back dark hair, wearing an unbuttoned black button-down shirt with rolled-up sleeves, dark trousers, distinctive matte black ring on his left ring finger, piercing cold calculated gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"431da3f0-96a9-4cc7-8384-937287b72c6e\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUarwgaECQHTDEn00eyt70D2PN5pVA_w2IGU7iU5N8W9UmWPaozySZboiA15dJttaxxWVKJG3E8A0lhxYJg9dw9MOG1Y7EbFshxazXjJ4KuZEKA_1Pg5ItXC1YxZXtTl2Q4oJPpTmXT_gQGJC-ytNPkvug_1jJlgv3DCzLo0rA\",2],null,[768,1376]]],[\"7b965b5d-e710-4d9a-9d24-253ba6e48286\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",\"CAE\",null,[[1790106045,1406000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZNkJAU3A3mTXxfRB3z5XcrRTmYMsW-vXve1HwCrASZ9FQV4ibEcqbVitT5TOALfwxiJPbzh3tlfUqPYtmD9oWIM7iOPBjjBa9P5RryK2ULhlECqLZPH3qop6s6GDIor3LD2vWhMhnIFeJa4MeityYUYIM4Vpqf1IShoOFEdw\",[null,null,[[\"Grounded cinematic realism, a beautiful 19-year-old Vietnamese woman in a high-tech Hanoi apartment, 2028. She is wearing a practical yet stylish dark lace-trimmed camisole with thin straps. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heatwave. She is sitting near a cooling fan, parched atmosphere, soft tungsten lighting. Near-future techno-thriller style, restrained pose, high dynamic range, subtle film grain. High-quality live-action aesthetic.\",null,[[[\"Grounded cinematic realism, a beautiful 19-year-old Vietnamese woman in a high-tech Hanoi apartment, 2028. She is wearing a practical yet stylish dark lace-trimmed camisole with thin straps. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heatwave. She is sitting near a cooling fan, parched atmosphere, soft tungsten lighting. Near-future techno-thriller style, restrained pose, high dynamic range, subtle film grain. High-quality live-action aesthetic.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZNkJAU3A3mTXxfRB3z5XcrRTmYMsW-vXve1HwCrASZ9FQV4ibEcqbVitT5TOALfwxiJPbzh3tlfUqPYtmD9oWIM7iOPBjjBa9P5RryK2ULhlECqLZPH3qop6s6GDIor3LD2vWhMhnIFeJa4MeityYUYIM4Vpqf1IShoOFEdw\",null,null,110676],[[null,933615,null,null,null,null,null,\"Grounded cinematic realism, a beautiful 19-year-old Vietnamese woman in a high-tech Hanoi apartment, 2028. She is wearing a practical yet stylish dark lace-trimmed camisole with thin straps. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heatwave. She is sitting near a cooling fan, parched atmosphere, soft tungsten lighting. Near-future techno-thriller style, restrained pose, high dynamic range, subtle film grain. High-quality live-action aesthetic.\",25,\"\",null,\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZNkJAU3A3mTXxfRB3z5XcrRTmYMsW-vXve1HwCrASZ9FQV4ibEcqbVitT5TOALfwxiJPbzh3tlfUqPYtmD9oWIM7iOPBjjBa9P5RryK2ULhlECqLZPH3qop6s6GDIor3LD2vWhMhnIFeJa4MeityYUYIM4Vpqf1IShoOFEdw\",3],null,[1376,768]]],[\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"6ddbd597-0a88-4e3c-b31a-7d20443c0dab\",\"CAE\",null,[[1790098968,283242000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbhiJ7Q-tv7QWwFzi6tGAmgMIu1r_dO4r_B_kxrnFLdG36DSsN0umqPKqOvAMUO3nsSCUDC0_IEF28r16pH0Zii3hc_qIQ5Lo9K1Sb1tTDHyihLBTIml_gnOVk2mQ6MvY9nicNueJLGUo4mD4gIVQSFbJAgwes--GeQH1zbPg\",[null,null,[[\"Single reference image of 29-year-old Vietnamese system infrastructure engineer, lean athletic build, sharp determined Asian features, short clean black hair, wearing dark charcoal tactical t-shirt and grey cargo pants, digital wrist gauge, observant survivalist gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of 29-year-old Vietnamese system infrastructure engineer, lean athletic build, sharp determined Asian features, short clean black hair, wearing dark charcoal tactical t-shirt and grey cargo pants, digital wrist gauge, observant survivalist gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbhiJ7Q-tv7QWwFzi6tGAmgMIu1r_dO4r_B_kxrnFLdG36DSsN0umqPKqOvAMUO3nsSCUDC0_IEF28r16pH0Zii3hc_qIQ5Lo9K1Sb1tTDHyihLBTIml_gnOVk2mQ6MvY9nicNueJLGUo4mD4gIVQSFbJAgwes--GeQH1zbPg\",null,null,89857],[[null,891120892,null,null,null,null,null,\"Single reference image of 29-year-old Vietnamese system infrastructure engineer, lean athletic build, sharp determined Asian features, short clean black hair, wearing dark charcoal tactical t-shirt and grey cargo pants, digital wrist gauge, observant survivalist gaze. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that does not distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"6ddbd597-0a88-4e3c-b31a-7d20443c0dab\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbhiJ7Q-tv7QWwFzi6tGAmgMIu1r_dO4r_B_kxrnFLdG36DSsN0umqPKqOvAMUO3nsSCUDC0_IEF28r16pH0Zii3hc_qIQ5Lo9K1Sb1tTDHyihLBTIml_gnOVk2mQ6MvY9nicNueJLGUo4mD4gIVQSFbJAgwes--GeQH1zbPg\",2],null,[768,1376]]],[\"9aea7396-dc22-4b69-947f-7d1dcc5c1e3c\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"4fb9e862-d995-4f49-9eb6-d00b1f2ee767\",\"CAE\",null,[[1784546541,545693000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZFIbtXJLDv6vN3PaWjcgQNioAMhpjK2Ql39Er-I-WMoJQd73VCsQ-iooNVWRAhl2-hJkFnmVoeLEdylQDFdINmaYMaUi-XsOgXe3MLW2t57PHaAeg2u76BCcDFr8hLCxAhpcOGDgXNykCzJKDRgRaXQRDfHWCm7mi_lvATTw\",[null,null,[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",null,[[[\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\"]]]]],[null,[[\"f4d9c731-41f2-4b51-9dd2-edd20c1dc7f1\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZFIbtXJLDv6vN3PaWjcgQNioAMhpjK2Ql39Er-I-WMoJQd73VCsQ-iooNVWRAhl2-hJkFnmVoeLEdylQDFdINmaYMaUi-XsOgXe3MLW2t57PHaAeg2u76BCcDFr8hLCxAhpcOGDgXNykCzJKDRgRaXQRDfHWCm7mi_lvATTw\"],[[null,922697,\"CAMSJDU5NDc1OGNjLTExZjUtNGY5Mi04YjNjLTEyMTM2ODY1OTFmNBokMTQ5NmMyYWUtNTAyNy00NGQ0LWE2M2UtM2VmM2MxNzYzZTI0IgNDQUUqJDY4NGUyN2E5LWExNmMtNDgwZS05NWNlLThjYjU0MDc5ODY1OQ\",null,null,null,null,\"Live-action cinematic character reference of Lê Quốc Tiến. A 29-year-old Vietnamese systems engineer. Emaciated, dehydrated, with patched and worn clothing, and a visible abdomen wound. Preserve the exact facial geometry, eye shape, nose, jaw, hairline, and body proportions of the identity in reference 1. Clean full-body neutral standing view and one clear three-quarter portrait. Plain segmented grey background, soft neutral studio lighting. Grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast, natural skin texture, physically believable heat haze and sweat, restrained expression. Subtle film grain, high dynamic range. No anime, no illustration, no glossy rendering, no generic cyberpunk neon, no holograms. No face drift, no age drift, no hairstyle drift, no costume drift. No generated readable text, no watermark.\",25,\"\",null,\"3ab07549-ccbb-410a-a97d-08b8a4627f84\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZFIbtXJLDv6vN3PaWjcgQNioAMhpjK2Ql39Er-I-WMoJQd73VCsQ-iooNVWRAhl2-hJkFnmVoeLEdylQDFdINmaYMaUi-XsOgXe3MLW2t57PHaAeg2u76BCcDFr8hLCxAhpcOGDgXNykCzJKDRgRaXQRDfHWCm7mi_lvATTw\",3],null,[1376,768]]],[\"9daace9a-a99c-4a5a-bce5-e9aaedcb1980\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"52274337-3f1e-499b-b404-022ff18196d3\",\"CAE\",null,[[1790099028,206353000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbBWzfZ5pUAubqSywQv5NKZAUwOs50giX-KmoZuAR7ompcy1pXcwfXxRX7Zeb7piHJUMus9W2WJiC1ZA_1XK-FnvPOkh2uB-H1cm8dh7lOE_hBeWhkl2rnFRdJzQhoucBcGFjwfbxZPB8ivZG5_kb3ooeknfUJYV0mJefLbpQ\",[null,null,[[\"Single reference image of Dried-up West Lake lakebed under a scorching apocalyptic deep crimson sun and hazy red sky, cracked black mud terrain revealing gigantic ancient dark metallic curved rib structures rising from the earth like colossal dragon bones, rising hot thermal steam. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of Dried-up West Lake lakebed under a scorching apocalyptic deep crimson sun and hazy red sky, cracked black mud terrain revealing gigantic ancient dark metallic curved rib structures rising from the earth like colossal dragon bones, rising hot thermal steam. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbBWzfZ5pUAubqSywQv5NKZAUwOs50giX-KmoZuAR7ompcy1pXcwfXxRX7Zeb7piHJUMus9W2WJiC1ZA_1XK-FnvPOkh2uB-H1cm8dh7lOE_hBeWhkl2rnFRdJzQhoucBcGFjwfbxZPB8ivZG5_kb3ooeknfUJYV0mJefLbpQ\",null,null,160958],[[null,405094559,null,null,null,null,null,\"Single reference image of Dried-up West Lake lakebed under a scorching apocalyptic deep crimson sun and hazy red sky, cracked black mud terrain revealing gigantic ancient dark metallic curved rib structures rising from the earth like colossal dragon bones, rising hot thermal steam. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"52274337-3f1e-499b-b404-022ff18196d3\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbBWzfZ5pUAubqSywQv5NKZAUwOs50giX-KmoZuAR7ompcy1pXcwfXxRX7Zeb7piHJUMus9W2WJiC1ZA_1XK-FnvPOkh2uB-H1cm8dh7lOE_hBeWhkl2rnFRdJzQhoucBcGFjwfbxZPB8ivZG5_kb3ooeknfUJYV0mJefLbpQ\",3],null,[1376,768]]],[\"a029279b-cc59-465f-98d5-0fa8b78187ba\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"18462c7e-40cf-4217-964d-980db21dac35\",\"CAE\",null,[[1790099234,21793000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbj3WTNo1mFGeojoYJZAShsPnLL6w-ur3gkupXE_3MK-jxP7yPJTourA0Na4FngoD_NNrbyPpFak1wd8Z1evCFlDK7m0HWMeguqv2zwofKtaY6LEg6Cp4AG3EQGtBmJZTN-y-Yd4Roulc6sEJ9dnCMTKnK8Eb-x_JkLKPPCoA\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Wide establishing cinematic shot of Nguyen Trai Avenue in Hanoi during morning rush hour. The green Cat Linh - Ha Dong elevated metro train glides smoothly on elevated concrete tracks above dense streams of motorbikes and cars. Clear blue sky with gentle morning sun, modern city backdrop. RAW photograph, wide-angle 24mm, vibrant urban atmosphere.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Wide establishing cinematic shot of Nguyen Trai Avenue in Hanoi during morning rush hour. The green Cat Linh - Ha Dong elevated metro train glides smoothly on elevated concrete tracks above dense streams of motorbikes and cars. Clear blue sky with gentle morning sun, modern city backdrop. RAW photograph, wide-angle 24mm, vibrant urban atmosphere.\"]]]]],[[[null,1,\"e12021b9-1f91-4a65-a9e2-f1ddbffbf42d\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbj3WTNo1mFGeojoYJZAShsPnLL6w-ur3gkupXE_3MK-jxP7yPJTourA0Na4FngoD_NNrbyPpFak1wd8Z1evCFlDK7m0HWMeguqv2zwofKtaY6LEg6Cp4AG3EQGtBmJZTN-y-Yd4Roulc6sEJ9dnCMTKnK8Eb-x_JkLKPPCoA\",null,null,303857],[[null,237436999,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Wide establishing cinematic shot of Nguyen Trai Avenue in Hanoi during morning rush hour. The green Cat Linh - Ha Dong elevated metro train glides smoothly on elevated concrete tracks above dense streams of motorbikes and cars. Clear blue sky with gentle morning sun, modern city backdrop. RAW photograph, wide-angle 24mm, vibrant urban atmosphere.\",25,\"\",null,\"18462c7e-40cf-4217-964d-980db21dac35\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbj3WTNo1mFGeojoYJZAShsPnLL6w-ur3gkupXE_3MK-jxP7yPJTourA0Na4FngoD_NNrbyPpFak1wd8Z1evCFlDK7m0HWMeguqv2zwofKtaY6LEg6Cp4AG3EQGtBmJZTN-y-Yd4Roulc6sEJ9dnCMTKnK8Eb-x_JkLKPPCoA\",3],null,[1376,768]]],[\"a6010398-57c9-4e27-a89f-31ed0ddf2d1a\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"9139a337-e6df-474c-90f1-e4e48dca69a9\",\"CAE\",null,[[1790099323,542997000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbT2FIiqZl8L2GBCDBj5OKGpxhMUlACgmVKCw7fpaV5OJFyCHSKHS4AZQ_jNGc13Da0FQPpmF5WJ-Acvk2WQw7n6gpcYQP5RqL2qDhlKMoazbO4SsFboSoKj2e2_iuGAywHBr5vT6ytdtGh6HbAtVZMcmDnAXxQcTCOVQP8\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in a shattered underground basement. Le Quoc Tien in dark torn clothes slumps against cracked burning concrete. Do Minh Kha stands over him holding a gleaming tactical knife, silhouette backlit by deep crimson sunlight piercing through fractured ceiling slabs. RAW photograph, 35mm lens, intense chiaroscuro lighting, floating embers and dust particles.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in a shattered underground basement. Le Quoc Tien in dark torn clothes slumps against cracked burning concrete. Do Minh Kha stands over him holding a gleaming tactical knife, silhouette backlit by deep crimson sunlight piercing through fractured ceiling slabs. RAW photograph, 35mm lens, intense chiaroscuro lighting, floating embers and dust particles.\"]]]]],[[[null,1,\"78e46231-e6cf-43fb-99bc-a4cb96196e24\"],[null,1,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbT2FIiqZl8L2GBCDBj5OKGpxhMUlACgmVKCw7fpaV5OJFyCHSKHS4AZQ_jNGc13Da0FQPpmF5WJ-Acvk2WQw7n6gpcYQP5RqL2qDhlKMoazbO4SsFboSoKj2e2_iuGAywHBr5vT6ytdtGh6HbAtVZMcmDnAXxQcTCOVQP8\",null,null,173527],[[null,226935734,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot in a shattered underground basement. Le Quoc Tien in dark torn clothes slumps against cracked burning concrete. Do Minh Kha stands over him holding a gleaming tactical knife, silhouette backlit by deep crimson sunlight piercing through fractured ceiling slabs. RAW photograph, 35mm lens, intense chiaroscuro lighting, floating embers and dust particles.\",25,\"\",null,\"9139a337-e6df-474c-90f1-e4e48dca69a9\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbT2FIiqZl8L2GBCDBj5OKGpxhMUlACgmVKCw7fpaV5OJFyCHSKHS4AZQ_jNGc13Da0FQPpmF5WJ-Acvk2WQw7n6gpcYQP5RqL2qDhlKMoazbO4SsFboSoKj2e2_iuGAywHBr5vT6ytdtGh6HbAtVZMcmDnAXxQcTCOVQP8\",3],null,[1376,768]]],[\"a661bfc5-873f-4f71-862b-b76958cdda91\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d6e35829-f7a1-43aa-b12c-7172309cf84c\",\"CAE\",null,[[1790098617,113716000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbRQ_Bp4QhsU1Iu84cZ-r5y2ZhYCzF3AYTam8eKNwGcW9aKvYsPy8wkabi2M6RcWcVfzv9RHeFbYP9C6dJNgxaTsqqTwpzDQnPHqnDGMNSSnGdTiQ9y3zAAYHU0LZ_AWwPH-skO-aEWWB0ZBhgaO1i8zfdqnZ9fsGRMwYHwWA\",[null,null,[[\"Single reference image of Magnificent golden koi fish with shimmering iridescent scales, elegant fins, slight magical glow.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Clear detailed view showing the asset's complete form. Appropriate angle to showcase distinctive features and functional elements. Centered with proper scale reference. Neutral background. Show key details, materials, and surface textures. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",null,[[[\"Single reference image of Magnificent golden koi fish with shimmering iridescent scales, elegant fins, slight magical glow.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Clear detailed view showing the asset's complete form. Appropriate angle to showcase distinctive features and functional elements. Centered with proper scale reference. Neutral background. Show key details, materials, and surface textures. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbRQ_Bp4QhsU1Iu84cZ-r5y2ZhYCzF3AYTam8eKNwGcW9aKvYsPy8wkabi2M6RcWcVfzv9RHeFbYP9C6dJNgxaTsqqTwpzDQnPHqnDGMNSSnGdTiQ9y3zAAYHU0LZ_AWwPH-skO-aEWWB0ZBhgaO1i8zfdqnZ9fsGRMwYHwWA\",null,null,71315],[[null,865186350,null,null,null,null,null,\"Single reference image of Magnificent golden koi fish with shimmering iridescent scales, elegant fins, slight magical glow.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Clear detailed view showing the asset's complete form. Appropriate angle to showcase distinctive features and functional elements. Centered with proper scale reference. Neutral background. Show key details, materials, and surface textures. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",25,\"\",null,\"d6e35829-f7a1-43aa-b12c-7172309cf84c\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbRQ_Bp4QhsU1Iu84cZ-r5y2ZhYCzF3AYTam8eKNwGcW9aKvYsPy8wkabi2M6RcWcVfzv9RHeFbYP9C6dJNgxaTsqqTwpzDQnPHqnDGMNSSnGdTiQ9y3zAAYHU0LZ_AWwPH-skO-aEWWB0ZBhgaO1i8zfdqnZ9fsGRMwYHwWA\",2],null,[768,1376]]],[\"ac5f92cb-b55e-4db9-b800-0dd1dbe759ef\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"b00ceb65-a125-49c4-91ff-49f0af1e2356\",\"CAE\",null,[[1784545698,613155000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYU9yBwTqRhuBqi4Sq7neRHGAdzXTSk4Jbt4JKNBO0_NTcu_Bym4j5YCMNenazSJ9djSeRzF0p5-QKF4AfNoHQdJDY4RSI9b_pa_5fKvtNJ09GrtO97eqRuzqofh5L2LjMjFzSWYuNYpUastYCDucqB24U_KWAlNxhc7SkHkw\",[null,null,[[\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\",null,[[[\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYU9yBwTqRhuBqi4Sq7neRHGAdzXTSk4Jbt4JKNBO0_NTcu_Bym4j5YCMNenazSJ9djSeRzF0p5-QKF4AfNoHQdJDY4RSI9b_pa_5fKvtNJ09GrtO97eqRuzqofh5L2LjMjFzSWYuNYpUastYCDucqB24U_KWAlNxhc7SkHkw\",null,null,626799],[[null,562848,\"CAMSJDU5NDc1OGNjLTExZjUtNGY5Mi04YjNjLTEyMTM2ODY1OTFmNBokZGExZTY3YWYtYmI2OS00Njg4LWJhMzYtZGRiNTFiZjg4MjNkIgNDQUUqJGFjNWY5MmNiLWI1NWUtNGRiOS1iODAwLTBkZDFkYmU3NTllZg\",null,null,null,null,\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\",25,\"\",null,\"b00ceb65-a125-49c4-91ff-49f0af1e2356\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYU9yBwTqRhuBqi4Sq7neRHGAdzXTSk4Jbt4JKNBO0_NTcu_Bym4j5YCMNenazSJ9djSeRzF0p5-QKF4AfNoHQdJDY4RSI9b_pa_5fKvtNJ09GrtO97eqRuzqofh5L2LjMjFzSWYuNYpUastYCDucqB24U_KWAlNxhc7SkHkw\",3],null,[1376,768]]],[\"acf87cab-c8f4-46c4-b305-5d57a5be19fa\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"b58780b6-8218-433c-bdca-6fb13f9e9cd6\",\"CAE\",null,[[1784545738,781156000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZRZ0X8_gAC7eBzRHdccFMzFSVKpAjlYJj6gkxZm6voFpniFQxGgmu64zF0-pMBuihjmsUXMFj-QZEKDHe2fvD3zTqI9i-yHmfHTIXoJJ-iOI7XwN6Vv7cQragFr-DkewKeiOqeRHTx2Mn3fEvhgcypfX5FGNpIFqTfCuFOCA\",[null,null,[[\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\",null,[[[\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZRZ0X8_gAC7eBzRHdccFMzFSVKpAjlYJj6gkxZm6voFpniFQxGgmu64zF0-pMBuihjmsUXMFj-QZEKDHe2fvD3zTqI9i-yHmfHTIXoJJ-iOI7XwN6Vv7cQragFr-DkewKeiOqeRHTx2Mn3fEvhgcypfX5FGNpIFqTfCuFOCA\",null,null,694462],[[null,571904,\"CAMSJDU5NDc1OGNjLTExZjUtNGY5Mi04YjNjLTEyMTM2ODY1OTFmNBokMDllNjYyZGUtOGQxNy00NWU5LTg5MWYtZWViYWEzNDY5MTdiIgNDQUUqJGFjZjg3Y2FiLWM4ZjQtNDZjNC1iMzA1LTVkNTdhNWJlMTlmYQ\",null,null,null,null,\"Live-action cinematic character reference sheet. A 29-year-old Vietnamese infrastructure and systems engineer, lean athletic but not muscular, light tan skin, short slightly messy black hair, tired focused dark eyes, restrained expression, charcoal crew-neck T-shirt, lightweight black technical overshirt, dark cargo trousers, black field watch and simple cross-body utility bag. He looks like someone who notices exits and electrical panels before people. Front portrait, three-quarter portrait, left and right profile, and full-body neutral standing view. Plain segmented grey background, soft neutral studio lighting, exact identity consistency across all views, authentic Vietnamese facial features, natural skin texture and anatomy. grounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle. no anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark.\",25,\"\",null,\"b58780b6-8218-433c-bdca-6fb13f9e9cd6\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZRZ0X8_gAC7eBzRHdccFMzFSVKpAjlYJj6gkxZm6voFpniFQxGgmu64zF0-pMBuihjmsUXMFj-QZEKDHe2fvD3zTqI9i-yHmfHTIXoJJ-iOI7XwN6Vv7cQragFr-DkewKeiOqeRHTx2Mn3fEvhgcypfX5FGNpIFqTfCuFOCA\",3],null,[1376,768]]],[\"b4d91c90-5b01-4472-aab2-1bcacb892fa4\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",\"CAI\",null,[[1790106092,630331000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbWF5CgIMSnMgw6esBRNn9yOAnIIO3zTaaZSw403meT4lIMC7DGlMaWND-o4l1jC2FYzS_BKIn4zgJHF0X5DJdiPMPnClnsUV8zYKQaV3DOcrSi80NivCeUQcSk0ksCZTLRUGVpaExY0oljfF4gHz_d95OMI-6AD5IlgEDkUg\",[null,null,[[\"Big breasts?\",null,[[[\"ngực to mà ?\"]]]]],[[[null,2,\"7b965b5d-e710-4d9a-9d24-253ba6e48286\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbWF5CgIMSnMgw6esBRNn9yOAnIIO3zTaaZSw403meT4lIMC7DGlMaWND-o4l1jC2FYzS_BKIn4zgJHF0X5DJdiPMPnClnsUV8zYKQaV3DOcrSi80NivCeUQcSk0ksCZTLRUGVpaExY0oljfF4gHz_d95OMI-6AD5IlgEDkUg\",null,null,120695],[[null,10322356,null,null,null,null,null,\"Big breasts?\",25,\"\",null,\"80fcf81d-8e09-4a04-a22d-1de8c8569a46\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbWF5CgIMSnMgw6esBRNn9yOAnIIO3zTaaZSw403meT4lIMC7DGlMaWND-o4l1jC2FYzS_BKIn4zgJHF0X5DJdiPMPnClnsUV8zYKQaV3DOcrSi80NivCeUQcSk0ksCZTLRUGVpaExY0oljfF4gHz_d95OMI-6AD5IlgEDkUg\",3],null,[1376,768]]],[\"b5b2415a-b104-4e53-bf22-1bd940d2186b\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d9102dd3-bb7b-4a6b-8135-90e9e3455f30\",\"CAE\",null,[[1790104505,133221000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUazu0_Xip0Px8230pDZrhmBE6DcbMBlniQH7V3twUTrLf7SO7Vcvj1z_3QOPC08UlD4gQbfZXoeZW-fMErVIyyHGUNr0MPTv_7tY7_KCVQP9XpX_oHtJUOAlgvcmjWLvAPWqBwJcs8Pdefn4Ynw46NmLWrke6x_1Qla1iKvCw\",[null,null,[[\"Grounded cinematic realism, extreme heatwave apocalypse in Hanoi 2028. Intense, scorching sunlight creates a visible, shimmering heat haze over a deserted Ba Dinh Square. The asphalt is cracked and dry. Tall, modern Vietnamese government buildings look bleached under a relentless, white-hot sun. Physically believable sweat and parched textures, muted but high-contrast color palette, subtle film grain. No holograms or neon.\",null,[[[\"Grounded cinematic realism, extreme heatwave apocalypse in Hanoi 2028. Intense, scorching sunlight creates a visible, shimmering heat haze over a deserted Ba Dinh Square. The asphalt is cracked and dry. Tall, modern Vietnamese government buildings look bleached under a relentless, white-hot sun. Physically believable sweat and parched textures, muted but high-contrast color palette, subtle film grain. No holograms or neon.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUazu0_Xip0Px8230pDZrhmBE6DcbMBlniQH7V3twUTrLf7SO7Vcvj1z_3QOPC08UlD4gQbfZXoeZW-fMErVIyyHGUNr0MPTv_7tY7_KCVQP9XpX_oHtJUOAlgvcmjWLvAPWqBwJcs8Pdefn4Ynw46NmLWrke6x_1Qla1iKvCw\",null,null,206966],[[null,479066,null,null,null,null,null,\"Grounded cinematic realism, extreme heatwave apocalypse in Hanoi 2028. Intense, scorching sunlight creates a visible, shimmering heat haze over a deserted Ba Dinh Square. The asphalt is cracked and dry. Tall, modern Vietnamese government buildings look bleached under a relentless, white-hot sun. Physically believable sweat and parched textures, muted but high-contrast color palette, subtle film grain. No holograms or neon.\",25,\"\",null,\"d9102dd3-bb7b-4a6b-8135-90e9e3455f30\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUazu0_Xip0Px8230pDZrhmBE6DcbMBlniQH7V3twUTrLf7SO7Vcvj1z_3QOPC08UlD4gQbfZXoeZW-fMErVIyyHGUNr0MPTv_7tY7_KCVQP9XpX_oHtJUOAlgvcmjWLvAPWqBwJcs8Pdefn4Ynw46NmLWrke6x_1Qla1iKvCw\",3],null,[1376,768]]],[\"b6900ed9-ed42-4b6c-80c1-74db6fc6132d\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"f69d66c7-9cd6-459d-a883-753390a8cb25\",\"CAE\",null,[[1790106044,585720000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUazFzv8j1epY7qODet9rTfh2aglcrIHhLR6BCxhOPSdCZWGuwI5HApIMFeeCrOPgGVVzHuVPeNVEqWf15Lw57IN68AMR9kGtEbAb-bLlLSWzY-pKmCfWmQHmS7rrWSzHGEdvOBu5w7xzQWIVyxfJUiPmcW60g5IMDWkW2vkCw\",[null,null,[[\"A beautiful young Vietnamese woman, aged 18-20, in a grounded post-apocalyptic Hanoi setting. She wears a sleek, form-fitting top with thin straps and delicate lace details, suitable for the oppressive heat. Her expression is calm yet determined. Cinematic realism, natural harsh lighting from the blistering sun, visible heat haze in the background. Physically believable textures, authentic Vietnamese face, subtle film grain. Near-future techno-thriller aesthetic.\",null,[[[\"A beautiful young Vietnamese woman, aged 18-20, in a grounded post-apocalyptic Hanoi setting. She wears a sleek, form-fitting top with thin straps and delicate lace details, suitable for the oppressive heat. Her expression is calm yet determined. Cinematic realism, natural harsh lighting from the blistering sun, visible heat haze in the background. Physically believable textures, authentic Vietnamese face, subtle film grain. Near-future techno-thriller aesthetic.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUazFzv8j1epY7qODet9rTfh2aglcrIHhLR6BCxhOPSdCZWGuwI5HApIMFeeCrOPgGVVzHuVPeNVEqWf15Lw57IN68AMR9kGtEbAb-bLlLSWzY-pKmCfWmQHmS7rrWSzHGEdvOBu5w7xzQWIVyxfJUiPmcW60g5IMDWkW2vkCw\",null,null,197433],[[null,766422,null,null,null,null,null,\"A beautiful young Vietnamese woman, aged 18-20, in a grounded post-apocalyptic Hanoi setting. She wears a sleek, form-fitting top with thin straps and delicate lace details, suitable for the oppressive heat. Her expression is calm yet determined. Cinematic realism, natural harsh lighting from the blistering sun, visible heat haze in the background. Physically believable textures, authentic Vietnamese face, subtle film grain. Near-future techno-thriller aesthetic.\",25,\"\",null,\"f69d66c7-9cd6-459d-a883-753390a8cb25\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUazFzv8j1epY7qODet9rTfh2aglcrIHhLR6BCxhOPSdCZWGuwI5HApIMFeeCrOPgGVVzHuVPeNVEqWf15Lw57IN68AMR9kGtEbAb-bLlLSWzY-pKmCfWmQHmS7rrWSzHGEdvOBu5w7xzQWIVyxfJUiPmcW60g5IMDWkW2vkCw\",3],null,[1376,768]]],[\"bdcbe55a-ee7b-497d-a414-25d22d04c096\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"e516fce6-a049-4a7f-b414-5db3660b52fc\",\"CAE\",null,[[1790174038,296806000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUY_2RMjbW4Qrd71immM795La14bTfiQSqYUlm2w480hqwU_Ctv3Yz_jYRewqNieAa_g3bGZpkUYeoFsilY8ZOD0-67hsSWF23WzrQWffIvc5nmpeyS_iuj_ZO4NcUD2bAbpfNRHE1iFpt-z-sRgb_pA42pkZl5rYIzwfyNz\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot inside subterranean B3 basement parking at Me Tri during extreme heatwave. Le Quoc Tien slumps against a cracked concrete pillar in defeat beside a torn empty water pouch and heat-warped debris. Do Minh Kha looms over him in the background with a cold detached expression, silhouette backlit by an ominous beam of deep crimson sunlight piercing through a fractured ceiling fissure. Chiaroscuro high contrast cinematic lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot inside subterranean B3 basement parking at Me Tri during extreme heatwave. Le Quoc Tien slumps against a cracked concrete pillar in defeat beside a torn empty water pouch and heat-warped debris. Do Minh Kha looms over him in the background with a cold detached expression, silhouette backlit by an ominous beam of deep crimson sunlight piercing through a fractured ceiling fissure. Chiaroscuro high contrast cinematic lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\"]]]]],[[[null,1,\"9416e9ba-eeed-43c3-b5d7-15774851c6ae\"],[null,1,\"78e46231-e6cf-43fb-99bc-a4cb96196e24\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUY_2RMjbW4Qrd71immM795La14bTfiQSqYUlm2w480hqwU_Ctv3Yz_jYRewqNieAa_g3bGZpkUYeoFsilY8ZOD0-67hsSWF23WzrQWffIvc5nmpeyS_iuj_ZO4NcUD2bAbpfNRHE1iFpt-z-sRgb_pA42pkZl5rYIzwfyNz\",null,null,127848],[[null,314608653,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Dramatic low-angle cinematic shot inside subterranean B3 basement parking at Me Tri during extreme heatwave. Le Quoc Tien slumps against a cracked concrete pillar in defeat beside a torn empty water pouch and heat-warped debris. Do Minh Kha looms over him in the background with a cold detached expression, silhouette backlit by an ominous beam of deep crimson sunlight piercing through a fractured ceiling fissure. Chiaroscuro high contrast cinematic lighting, floating soot embers, atmospheric heat distortion waves, 35mm RAW photograph.\",25,\"\",null,\"e516fce6-a049-4a7f-b414-5db3660b52fc\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUY_2RMjbW4Qrd71immM795La14bTfiQSqYUlm2w480hqwU_Ctv3Yz_jYRewqNieAa_g3bGZpkUYeoFsilY8ZOD0-67hsSWF23WzrQWffIvc5nmpeyS_iuj_ZO4NcUD2bAbpfNRHE1iFpt-z-sRgb_pA42pkZl5rYIzwfyNz\",3],null,[1376,768]]],[\"c38a6066-9d26-44da-8a14-8c7e260f7f8d\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"e2367807-01e9-4bf4-a522-1f8549998e20\",\"CAE\",null,[[1790099008,171508000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZ3qYdMe-lNRWEyiCcRXUZHs63NHB40gTE6N-0m8iqcLmWSyC4r_1Z4Md8IxwyEcv5P0EKu2uV1I3IjqOS1Igx3DfYAf1yBknNKtYX8UprHaSK2_snwMqM_jJj9pZS0oe-BnymuvNBefI88hk32_ynKCPEVEMhuYwyRYOi4\",[null,null,[[\"Single reference image of Massive modern glass shopping mall in Ha Dong district under a terrifying dark crimson sun and apocalyptic red sky, giant glass windows completely fogged with thick condensation from dark boiling interior, heat ripples warping the melting empty asphalt parking lot outside. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of Massive modern glass shopping mall in Ha Dong district under a terrifying dark crimson sun and apocalyptic red sky, giant glass windows completely fogged with thick condensation from dark boiling interior, heat ripples warping the melting empty asphalt parking lot outside. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZ3qYdMe-lNRWEyiCcRXUZHs63NHB40gTE6N-0m8iqcLmWSyC4r_1Z4Md8IxwyEcv5P0EKu2uV1I3IjqOS1Igx3DfYAf1yBknNKtYX8UprHaSK2_snwMqM_jJj9pZS0oe-BnymuvNBefI88hk32_ynKCPEVEMhuYwyRYOi4\",null,null,129129],[[null,998037757,null,null,null,null,null,\"Single reference image of Massive modern glass shopping mall in Ha Dong district under a terrifying dark crimson sun and apocalyptic red sky, giant glass windows completely fogged with thick condensation from dark boiling interior, heat ripples warping the melting empty asphalt parking lot outside. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"e2367807-01e9-4bf4-a522-1f8549998e20\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUZ3qYdMe-lNRWEyiCcRXUZHs63NHB40gTE6N-0m8iqcLmWSyC4r_1Z4Md8IxwyEcv5P0EKu2uV1I3IjqOS1Igx3DfYAf1yBknNKtYX8UprHaSK2_snwMqM_jJj9pZS0oe-BnymuvNBefI88hk32_ynKCPEVEMhuYwyRYOi4\",3],null,[1376,768]]],[\"c436b109-dd00-498d-806d-b6bddc9a3bbf\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"23070ed9-c3a8-4070-a111-318ef1ed4f3a\",\"CAE\",null,[[1790174596,878212000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZvtcb7JKMsKXiWhau9tVOeTFhjL4Ghoh6Kh4I4MQPtgEmvFGWAPJvNHNNIbMyebj-1fSKG39c6HZISwcaOP4f75m_p5pah9K1wN-8kjHbBnZKSExqM2sxlSm7azZeQo6QCVEPTbZ1uuvb0IqjXkcliAd1-vzhtBjLkY-iA_A\",[null,null,null,null,1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUZvtcb7JKMsKXiWhau9tVOeTFhjL4Ghoh6Kh4I4MQPtgEmvFGWAPJvNHNNIbMyebj-1fSKG39c6HZISwcaOP4f75m_p5pah9K1wN-8kjHbBnZKSExqM2sxlSm7azZeQo6QCVEPTbZ1uuvb0IqjXkcliAd1-vzhtBjLkY-iA_A\",null,null,188067],[null,[null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUZvtcb7JKMsKXiWhau9tVOeTFhjL4Ghoh6Kh4I4MQPtgEmvFGWAPJvNHNNIbMyebj-1fSKG39c6HZISwcaOP4f75m_p5pah9K1wN-8kjHbBnZKSExqM2sxlSm7azZeQo6QCVEPTbZ1uuvb0IqjXkcliAd1-vzhtBjLkY-iA_A\",0],[1376,768]]],[\"c6bef467-362b-4d7d-86bd-7734cf16379f\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"bba71aa9-a24c-43bc-a42e-e0f140a426e3\",\"CAE\",null,[[1790098596,970493000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUb-BM8_6ESYGjjbTxXeNk_s7oGQUYcYM8w7CJ6WDywp6AfgVUQKZyZxAJTYBSIUzVJ4H54m29duffz8TMPQK7m2dXU3R0qTRNFmyoieSqpTWXCIFmOj03LYg0UpjvrOzP0OLv1REt6rmxPyY3WQzR3DSqSNPZ3-046KxxNfOA\",[null,null,[[\"Single reference image of Chubby orange tabby cat with big green eyes, blue apron, straw hat. Walks upright. Pixar-style 3D.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that doesn't distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",null,[[[\"Single reference image of Chubby orange tabby cat with big green eyes, blue apron, straw hat. Walks upright. Pixar-style 3D.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that doesn't distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUb-BM8_6ESYGjjbTxXeNk_s7oGQUYcYM8w7CJ6WDywp6AfgVUQKZyZxAJTYBSIUzVJ4H54m29duffz8TMPQK7m2dXU3R0qTRNFmyoieSqpTWXCIFmOj03LYg0UpjvrOzP0OLv1REt6rmxPyY3WQzR3DSqSNPZ3-046KxxNfOA\",null,null,133223],[[null,924792756,null,null,null,null,null,\"Single reference image of Chubby orange tabby cat with big green eyes, blue apron, straw hat. Walks upright. Pixar-style 3D.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Full body shot from head to toe, standing upright and straight (not tilted or leaning). Centered in frame with balanced composition. Front-facing view, looking directly at camera. Neutral simple background that doesn't distract from the subject. Proper proportions and anatomy. Character perfectly vertical, not skewed or rotated. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",25,\"\",null,\"bba71aa9-a24c-43bc-a42e-e0f140a426e3\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUb-BM8_6ESYGjjbTxXeNk_s7oGQUYcYM8w7CJ6WDywp6AfgVUQKZyZxAJTYBSIUzVJ4H54m29duffz8TMPQK7m2dXU3R0qTRNFmyoieSqpTWXCIFmOj03LYg0UpjvrOzP0OLv1REt6rmxPyY3WQzR3DSqSNPZ3-046KxxNfOA\",2],null,[768,1376]]],[\"c86e9fac-57bb-4fc3-a85f-d751ecefdcc8\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"3197d46b-0a13-463c-8aaf-9dd5f1416e6e\",\"CAE\",null,[[1790099933,333177000],\"0-3s: Camera pushes rapidly toward fogged glass doors as desperate hands slam against the condensation from steaming dark interiors of Dai Ha Mall Heat Trap. 3-6s: Pan up sharply to the terrifying dark crimson sun blazing in a blood-red hazy sky. 6-8s: Violent heat waves distort the melting asphalt parking lot in the foreground. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYvaqvdsuNtIAJuK_1bJx2k71A4qAsIBGQl4y-gYfvW33GRcSoTKs7OZyN32kVyQhFqsM6j7V_KUbwVNcbeHEGPsuAjft_N_JFjAChQSe4C54ksgm701PhETzSBgURwCqA-4tqYmwmm1tCnJ27AiVlaulcyjlbfqRt8j4pA8A\",[null,[[\"veo_3_1_i2v_lite\",2,[1],null,2,1],[[null,1,\"ce812adb-5fef-42cb-9a38-97b2e1bac60b\",[null,0.0038759689922481244,1,0.9961240310077519]]]],[[null,null,[[[\"0-3s: Camera pushes rapidly toward fogged glass doors as desperate hands slam against the condensation from steaming dark interiors of Dai Ha Mall Heat Trap. 3-6s: Pan up sharply to the terrifying dark crimson sun blazing in a blood-red hazy sky. 6-8s: Violent heat waves distort the melting asphalt parking lot in the foreground. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\"]]]]],null,1],null,[3],1,\"https://lh3.googleusercontent.com/asb/AB-nOUYvaqvdsuNtIAJuK_1bJx2k71A4qAsIBGQl4y-gYfvW33GRcSoTKs7OZyN32kVyQhFqsM6j7V_KUbwVNcbeHEGPsuAjft_N_JFjAChQSe4C54ksgm701PhETzSBgURwCqA-4tqYmwmm1tCnJ27AiVlaulcyjlbfqRt8j4pA8A\",null,null,6169385],null,[[null,423232,null,null,null,null,null,\"\\u003croot\\u003e\\n \\u003ccontext\\u003e\\n \\u003c/context\\u003e\\n \\u003cinstruction\\u003e\\n \\u003cprompt\\u003e0-3s: Camera pushes rapidly toward fogged glass doors as desperate hands slam against the condensation from steaming dark interiors of Dai Ha Mall Heat Trap. 3-6s: Pan up sharply to the terrifying dark crimson sun blazing in a blood-red hazy sky. 6-8s: Violent heat waves distort the melting asphalt parking lot in the foreground. Audio: natural ambient sounds only, no background music, no narration, no voiceover. Negative: subtitles, captions, watermark, text on screen, logo, blurry faces, distorted hands.\\u003c/prompt\\u003e\\n \\u003c/instruction\\u003e\\n\\u003c/root\\u003e\",\"https://lh3.googleusercontent.com/asb/AB-nOUYvaqvdsuNtIAJuK_1bJx2k71A4qAsIBGQl4y-gYfvW33GRcSoTKs7OZyN32kVyQhFqsM6j7V_KUbwVNcbeHEGPsuAjft_N_JFjAChQSe4C54ksgm701PhETzSBgURwCqA-4tqYmwmm1tCnJ27AiVlaulcyjlbfqRt8j4pA8A\",null,null,null,\"veo_3_1_i2v_lite\",\"\",null,false,2],[null,null,[8]],[\"c86e9fac-57bb-4fc3-a85f-d751ecefdcc8\"]]],[\"c8939cac-021c-4000-a355-ec23628e5ea0\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"2c817534-e7d9-4711-ba06-8da52e020080\",\"CAE\",null,[[1790099773,817655000],\"Camera pans slowly across cracked asphalt under a red burning sun.\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaV1tO8-xovmpV_inv5eoc_0bAl-yyrighrAbfO8zIk73RGamYKaeVuga4GD2bcsrLYdhKRXIt66KXFrZsejmiexvPi7-afxasqy3H7bww-Qkjmp4oH8wyG3GSmUoHN9gkQCGwdWdWLFLJ2ekmHX6paaHtQr8WMqiJSoaouCg\",[null,[[\"veo_3_1_i2v_lite\",2,[1],null,2,1],[[null,1,\"a6010398-57c9-4e27-a89f-31ed0ddf2d1a\",[null,0.0038759689922481244,1,0.9961240310077519]]]],[[null,null,[[[\"Camera pans slowly across cracked asphalt under a red burning sun.\"]]]]],null,1],null,[3],1,\"https://lh3.googleusercontent.com/asb/AB-nOUaV1tO8-xovmpV_inv5eoc_0bAl-yyrighrAbfO8zIk73RGamYKaeVuga4GD2bcsrLYdhKRXIt66KXFrZsejmiexvPi7-afxasqy3H7bww-Qkjmp4oH8wyG3GSmUoHN9gkQCGwdWdWLFLJ2ekmHX6paaHtQr8WMqiJSoaouCg\",null,null,5280152],null,[[null,876437,null,null,null,null,null,\"\\u003croot\\u003e\\n \\u003ccontext\\u003e\\n \\u003c/context\\u003e\\n \\u003cinstruction\\u003e\\n \\u003cprompt\\u003eCamera pans slowly across cracked asphalt under a red burning sun.\\u003c/prompt\\u003e\\n \\u003c/instruction\\u003e\\n\\u003c/root\\u003e\",\"https://lh3.googleusercontent.com/asb/AB-nOUaV1tO8-xovmpV_inv5eoc_0bAl-yyrighrAbfO8zIk73RGamYKaeVuga4GD2bcsrLYdhKRXIt66KXFrZsejmiexvPi7-afxasqy3H7bww-Qkjmp4oH8wyG3GSmUoHN9gkQCGwdWdWLFLJ2ekmHX6paaHtQr8WMqiJSoaouCg\",null,null,null,\"veo_3_1_i2v_lite\",\"\",null,false,2],[null,null,[8]],[\"c8939cac-021c-4000-a355-ec23628e5ea0\"]]],[\"ca9eac0a-7816-4104-af03-8f98001f2915\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"d0e3e32c-df9c-4641-bce4-dd9ca73a4f9b\",\"CAE\",null,[[1790104962,53428000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYsXiMFzL5yVqksvdhx4KnzGYCJp6UsTDwP5jhnKxaFKjYDQB6mdF-T7yCiHl3H3zd4p-jeqcajDOxceub52tl7jRl6hV0Fd-17OIpT4adugt1wAvZifAo0-GgZCAoLY0mGjuPsbs7yVYOaY5yZD9UagJKgIrt8dn3VwLP5xA\",[null,null,[[\"A wide cinematic shot of a scorched mountain range in Vietnam, 2028. The peaks are jagged and dry, with deep shadows and brilliant, oppressive sunlight hitting the sun-baked rock faces. A lone, abandoned 2028 industrial outpost sits precariously on a ridge. Physically believable heat haze and atmospheric dust. Grounded live-action aesthetic, high dynamic range, restrained camera feel, subtle film grain.\",null,[[[\"A wide cinematic shot of a scorched mountain range in Vietnam, 2028. The peaks are jagged and dry, with deep shadows and brilliant, oppressive sunlight hitting the sun-baked rock faces. A lone, abandoned 2028 industrial outpost sits precariously on a ridge. Physically believable heat haze and atmospheric dust. Grounded live-action aesthetic, high dynamic range, restrained camera feel, subtle film grain.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYsXiMFzL5yVqksvdhx4KnzGYCJp6UsTDwP5jhnKxaFKjYDQB6mdF-T7yCiHl3H3zd4p-jeqcajDOxceub52tl7jRl6hV0Fd-17OIpT4adugt1wAvZifAo0-GgZCAoLY0mGjuPsbs7yVYOaY5yZD9UagJKgIrt8dn3VwLP5xA\",null,null,228740],[[null,593792,null,null,null,null,null,\"A wide cinematic shot of a scorched mountain range in Vietnam, 2028. The peaks are jagged and dry, with deep shadows and brilliant, oppressive sunlight hitting the sun-baked rock faces. A lone, abandoned 2028 industrial outpost sits precariously on a ridge. Physically believable heat haze and atmospheric dust. Grounded live-action aesthetic, high dynamic range, restrained camera feel, subtle film grain.\",25,\"\",null,\"d0e3e32c-df9c-4641-bce4-dd9ca73a4f9b\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYsXiMFzL5yVqksvdhx4KnzGYCJp6UsTDwP5jhnKxaFKjYDQB6mdF-T7yCiHl3H3zd4p-jeqcajDOxceub52tl7jRl6hV0Fd-17OIpT4adugt1wAvZifAo0-GgZCAoLY0mGjuPsbs7yVYOaY5yZD9UagJKgIrt8dn3VwLP5xA\",3],null,[1376,768]]],[\"cd20c077-1f3e-4432-9bbc-6d19af7a5a16\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"420931e8-d444-4a59-8ba8-a745cbeead17\",\"CAE\",null,[[1784545966,119130000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUb6YBqsZvC6YSp7nU_rOBQxAnxihDc4VD35WLn8YcPT3q_SCJSlgwvQJ3CdE0qb91Oi2-UZwI1qqLEd2DAYspddAksc_5ENYcQOTzUX10TfAiX1LEY0Q2iQPSTWY3YP9vKJNDOzhgbkudjm8jXPdFkApTZKB-Fx9rCzHLdnBw\",[null,null,null,null,1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUb6YBqsZvC6YSp7nU_rOBQxAnxihDc4VD35WLn8YcPT3q_SCJSlgwvQJ3CdE0qb91Oi2-UZwI1qqLEd2DAYspddAksc_5ENYcQOTzUX10TfAiX1LEY0Q2iQPSTWY3YP9vKJNDOzhgbkudjm8jXPdFkApTZKB-Fx9rCzHLdnBw\",null,null,368502],[null,[null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUb6YBqsZvC6YSp7nU_rOBQxAnxihDc4VD35WLn8YcPT3q_SCJSlgwvQJ3CdE0qb91Oi2-UZwI1qqLEd2DAYspddAksc_5ENYcQOTzUX10TfAiX1LEY0Q2iQPSTWY3YP9vKJNDOzhgbkudjm8jXPdFkApTZKB-Fx9rCzHLdnBw\",0],[1376,768]]],[\"ce812adb-5fef-42cb-9a38-97b2e1bac60b\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"fb28016d-5ed3-47b0-9a38-6f98eaa8b439\",\"CAE\",null,[[1790099243,507045000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUa57Zw_aDZZh7dEML9KwifC0P9iCfIcqGFwOpGOrXeeVr4qKEIoSLoiHYLi0b8HGFAkBvJ4lLDe8834nZVL3Vz2FMZpOKmWgjtk7dhxbULSdfKVglbE0JcrZ9l-7WKOWCfYh8Z0Bb7A7htprMxyYbipRgLnmMhTprA-P6f1\",[null,null,[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Terrifying apocalyptic cinematic shot of Dai Ha Mall Heat Trap in Ha Dong under an eerie blood-red sky with a massive dark crimson sun. Dense crowd of panicked people inside banging frantically against fogged-up glass doors from dark steaming interiors. Heat ripples distorting the melting asphalt road outside. High contrast dramatic disaster lighting, 35mm RAW photograph.\",null,[[[\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Terrifying apocalyptic cinematic shot of Dai Ha Mall Heat Trap in Ha Dong under an eerie blood-red sky with a massive dark crimson sun. Dense crowd of panicked people inside banging frantically against fogged-up glass doors from dark steaming interiors. Heat ripples distorting the melting asphalt road outside. High contrast dramatic disaster lighting, 35mm RAW photograph.\"]]]]],[[[null,1,\"c38a6066-9d26-44da-8a14-8c7e260f7f8d\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUa57Zw_aDZZh7dEML9KwifC0P9iCfIcqGFwOpGOrXeeVr4qKEIoSLoiHYLi0b8HGFAkBvJ4lLDe8834nZVL3Vz2FMZpOKmWgjtk7dhxbULSdfKVglbE0JcrZ9l-7WKOWCfYh8Z0Bb7A7htprMxyYbipRgLnmMhTprA-P6f1\",null,null,180541],[[null,505891029,null,null,null,null,null,\"Real RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light. Terrifying apocalyptic cinematic shot of Dai Ha Mall Heat Trap in Ha Dong under an eerie blood-red sky with a massive dark crimson sun. Dense crowd of panicked people inside banging frantically against fogged-up glass doors from dark steaming interiors. Heat ripples distorting the melting asphalt road outside. High contrast dramatic disaster lighting, 35mm RAW photograph.\",25,\"\",null,\"fb28016d-5ed3-47b0-9a38-6f98eaa8b439\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUa57Zw_aDZZh7dEML9KwifC0P9iCfIcqGFwOpGOrXeeVr4qKEIoSLoiHYLi0b8HGFAkBvJ4lLDe8834nZVL3Vz2FMZpOKmWgjtk7dhxbULSdfKVglbE0JcrZ9l-7WKOWCfYh8Z0Bb7A7htprMxyYbipRgLnmMhTprA-P6f1\",3],null,[1376,768]]],[\"cea6d7a9-29a2-4b36-aa89-60358b4998b5\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAM\",null,[[1790105496,336772000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUYqY6WvjH9Nb5EcXdBRV5tdz2uVg78eCJBIcy9oVHWOucDn97oglDoPI_XHdGOkbubZiMnhhKV0xszCiYedZ1835CntABzIvo3q80yr6-vpoQNnlcItGHwmqpOHYgMVsABu6J8cjUvAr4Gkf2VWyQKcbYEqUtJC_AdWVT7hSA\",[null,null,[[\"Larger breasts, fair skin, beautiful.\",null,[[[\"ngực to hơn, da trắng, xinh đẹp\"]]]]],[[[null,2,\"07f97f41-209d-458b-ad17-55606514eb6a\"]]],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUYqY6WvjH9Nb5EcXdBRV5tdz2uVg78eCJBIcy9oVHWOucDn97oglDoPI_XHdGOkbubZiMnhhKV0xszCiYedZ1835CntABzIvo3q80yr6-vpoQNnlcItGHwmqpOHYgMVsABu6J8cjUvAr4Gkf2VWyQKcbYEqUtJC_AdWVT7hSA\",null,null,186887],[[null,1743582705,null,null,null,null,null,\"Larger breasts, fair skin, beautiful.\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUYqY6WvjH9Nb5EcXdBRV5tdz2uVg78eCJBIcy9oVHWOucDn97oglDoPI_XHdGOkbubZiMnhhKV0xszCiYedZ1835CntABzIvo3q80yr6-vpoQNnlcItGHwmqpOHYgMVsABu6J8cjUvAr4Gkf2VWyQKcbYEqUtJC_AdWVT7hSA\",3],null,[1376,768]]],[\"d9a829c4-cd2d-491c-8773-7bee1eeb0aba\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"3ddd6fbc-8834-4868-a7fa-5e1dc68d04d7\",\"CAE\",null,[[1790099782,85545000],\"Camera pans slowly across cracked asphalt under a red burning sun.\",null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUaC3tTzV--XzTAPQrbDeZ3rkuvfi-pkS_r-ihnrwiZYTS8MA54E8ZEckDexBIvVpkSo6Ixcn836oVlM7UxkkClKQ4ByaAHSQlTBdMZphK_JSy-xQoCjm1moUrC1SUjAaw0AlApHShO6nrzZZpB5VZPZ5ixm6vaOlSMOnu-UCQ\",[null,[[\"abra_i2v_8s\",2,[1],null,2,1],[[null,1,\"a6010398-57c9-4e27-a89f-31ed0ddf2d1a\",[null,0.0038759689922481244,1,0.9961240310077519]]]],[[null,null,[[[\"Camera pans slowly across cracked asphalt under a red burning sun.\"]]]]],null,1],null,[3],1,\"https://lh3.googleusercontent.com/asb/AB-nOUaC3tTzV--XzTAPQrbDeZ3rkuvfi-pkS_r-ihnrwiZYTS8MA54E8ZEckDexBIvVpkSo6Ixcn836oVlM7UxkkClKQ4ByaAHSQlTBdMZphK_JSy-xQoCjm1moUrC1SUjAaw0AlApHShO6nrzZZpB5VZPZ5ixm6vaOlSMOnu-UCQ\",null,null,4125539],null,[[null,97176,null,null,null,null,null,\"Camera pans slowly across cracked asphalt under a red burning sun.\",\"https://lh3.googleusercontent.com/asb/AB-nOUaC3tTzV--XzTAPQrbDeZ3rkuvfi-pkS_r-ihnrwiZYTS8MA54E8ZEckDexBIvVpkSo6Ixcn836oVlM7UxkkClKQ4ByaAHSQlTBdMZphK_JSy-xQoCjm1moUrC1SUjAaw0AlApHShO6nrzZZpB5VZPZ5ixm6vaOlSMOnu-UCQ\",null,null,null,\"abra_i2v_8s\",\"\",null,false,2],[null,null,[8]],[\"d9a829c4-cd2d-491c-8773-7bee1eeb0aba\"]]],[\"dc6cb5cb-1515-4607-8d63-35b7d4c79df9\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"4b6e1f6c-ad29-4c79-ac8b-840e0ff929c4\",\"CAE\",null,[[1790098607,247715000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUa47Pmq4072nP_MLX-4PwDgU4CSJh7ObtKVwohLDOenLL8qVxLVLj9UorLogrMvxxTxCV3CBKkI7t68FzlaMUVKZ4r0tdNPB6_A5itIZrlWy67cxEJC20v9h96h03WMVSy0VNUxLqJ0j4-Gv6dMERM61ANPz5ev8h-1bwFlCA\",[null,null,[[\"Single reference image of Bustling Southeast Asian open-air market with colorful awnings, hanging lanterns, stone walkway.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",null,[[[\"Single reference image of Bustling Southeast Asian open-air market with colorful awnings, hanging lanterns, stone walkway.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUa47Pmq4072nP_MLX-4PwDgU4CSJh7ObtKVwohLDOenLL8qVxLVLj9UorLogrMvxxTxCV3CBKkI7t68FzlaMUVKZ4r0tdNPB6_A5itIZrlWy67cxEJC20v9h96h03WMVSy0VNUxLqJ0j4-Gv6dMERM61ANPz5ev8h-1bwFlCA\",null,null,247630],[[null,366821445,null,null,null,null,null,\"Single reference image of Bustling Southeast Asian open-air market with colorful awnings, hanging lanterns, stone walkway.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",25,\"\",null,\"4b6e1f6c-ad29-4c79-ac8b-840e0ff929c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUa47Pmq4072nP_MLX-4PwDgU4CSJh7ObtKVwohLDOenLL8qVxLVLj9UorLogrMvxxTxCV3CBKkI7t68FzlaMUVKZ4r0tdNPB6_A5itIZrlWy67cxEJC20v9h96h03WMVSy0VNUxLqJ0j4-Gv6dMERM61ANPz5ev8h-1bwFlCA\",3],null,[1376,768]]],[\"deb54d26-dbdb-4351-99f5-04400fef123c\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"50ce51e4-768e-4eb0-abce-1df3f94acae6\",\"CAE\",null,[[1790098627,137046000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbMphQQcSl58Ttg-OlIDBH04v5kearkZeAm6d_vRZsNqS0TDb74HWc2iFxhg9YxcBwC3rotyzkMI39CFSQsQVkDy_ELePDKdpGkiMQNZhC-tvgsHsioLk3c3H-wkz8Bp-E25iNrmDYW0i7xD8GAPlZ30WLg5jbGUDTebkc8rg\",[null,null,[[\"Single reference image of Small rustic wooden market stall with thatched bamboo roof, crushed ice display, hanging brass scale.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",null,[[[\"Single reference image of Small rustic wooden market stall with thatched bamboo roof, crushed ice display, hanging brass scale.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbMphQQcSl58Ttg-OlIDBH04v5kearkZeAm6d_vRZsNqS0TDb74HWc2iFxhg9YxcBwC3rotyzkMI39CFSQsQVkDy_ELePDKdpGkiMQNZhC-tvgsHsioLk3c3H-wkz8Bp-E25iNrmDYW0i7xD8GAPlZ30WLg5jbGUDTebkc8rg\",null,null,215090],[[null,784456559,null,null,null,null,null,\"Single reference image of Small rustic wooden market stall with thatched bamboo roof, crushed ice display, hanging brass scale.. 3D animated style, Pixar-quality rendering, Disney-Pixar aesthetic. Smooth subsurface scattering skin, expressive cartoon eyes, stylized proportions, vibrant saturated colors. NOT photorealistic, NOT photograph, NOT live action, NOT anime, NOT flat 2D. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, global illumination, highly detailed\",25,\"\",null,\"50ce51e4-768e-4eb0-abce-1df3f94acae6\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbMphQQcSl58Ttg-OlIDBH04v5kearkZeAm6d_vRZsNqS0TDb74HWc2iFxhg9YxcBwC3rotyzkMI39CFSQsQVkDy_ELePDKdpGkiMQNZhC-tvgsHsioLk3c3H-wkz8Bp-E25iNrmDYW0i7xD8GAPlZ30WLg5jbGUDTebkc8rg\",3],null,[1376,768]]],[\"e0ca950b-db30-416a-b2d2-fe98a9bf1344\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",\"CAE\",null,[[1790105368,68953000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbMYl1paWIcyMwF6QXtlWmzejB8hrgL0xEqJSL56e5IJ75xju1wzTsWagCZZSct_UdMP7ECL3NKurifqhEoD10Jgas-w6K4i9YeCw1Wa3GUlaeoVdcXw9YDTkl5yrVEj4eig4AqIIIHVLVREPROwsdjvdGinXZCC_ndP9cb\",[null,null,[[\"Grounded cinematic realism, a beautiful young Vietnamese woman in post-apocalyptic Hanoi 2028. She wears a sleek, form-fitting practical tactical bodysuit made of dark moisture-wicking material, with a lightweight, semi-translucent flowing silk scarf catching a dry breeze. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heat. She stands amidst parched ruins, restrained pose, high dynamic range, subtle film grain. Near-future techno-thriller style.\",null,[[[\"Grounded cinematic realism, a beautiful young Vietnamese woman in post-apocalyptic Hanoi 2028. She wears a sleek, form-fitting practical tactical bodysuit made of dark moisture-wicking material, with a lightweight, semi-translucent flowing silk scarf catching a dry breeze. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heat. She stands amidst parched ruins, restrained pose, high dynamic range, subtle film grain. Near-future techno-thriller style.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbMYl1paWIcyMwF6QXtlWmzejB8hrgL0xEqJSL56e5IJ75xju1wzTsWagCZZSct_UdMP7ECL3NKurifqhEoD10Jgas-w6K4i9YeCw1Wa3GUlaeoVdcXw9YDTkl5yrVEj4eig4AqIIIHVLVREPROwsdjvdGinXZCC_ndP9cb\",null,null,196693],[[null,589694,null,null,null,null,null,\"Grounded cinematic realism, a beautiful young Vietnamese woman in post-apocalyptic Hanoi 2028. She wears a sleek, form-fitting practical tactical bodysuit made of dark moisture-wicking material, with a lightweight, semi-translucent flowing silk scarf catching a dry breeze. Authentic Vietnamese features, natural skin texture with subtle sweat from the extreme heat. She stands amidst parched ruins, restrained pose, high dynamic range, subtle film grain. Near-future techno-thriller style.\",25,\"\",null,\"7212e0d2-229b-4032-95e3-4c363d2b46c4\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbMYl1paWIcyMwF6QXtlWmzejB8hrgL0xEqJSL56e5IJ75xju1wzTsWagCZZSct_UdMP7ECL3NKurifqhEoD10Jgas-w6K4i9YeCw1Wa3GUlaeoVdcXw9YDTkl5yrVEj4eig4AqIIIHVLVREPROwsdjvdGinXZCC_ndP9cb\",3],null,[1376,768]]],[\"e12021b9-1f91-4a65-a9e2-f1ddbffbf42d\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"bd7eacf9-d385-4561-bf0b-62e3e8a253dc\",\"CAE\",null,[[1790098998,48960000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbjscyiBm8tBkbaaSe-QeXK6klPWhc2iKUqI52AmLRwvT9mN9ejkVihSUECOFmu9Q8YoXlQbMd3vBhtklNwBhjfPxk_EVVcHx8Tyg9UPQ-7TcijRX5gLI6yl8HRpIQQo6gFuAu_2rRaMyeb1dGrgspXV1O9lgAOWh_6ohaiwA\",[null,null,[[\"Single reference image of Wide bustling urban avenue in Hanoi during morning rush hour, elevated concrete metro tracks overhead with modern green Cat Linh - Ha Dong passenger train gliding past sleek glass skyscrapers and dense commuter traffic under a clear morning sky. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",null,[[[\"Single reference image of Wide bustling urban avenue in Hanoi during morning rush hour, elevated concrete metro tracks overhead with modern green Cat Linh - Ha Dong passenger train gliding past sleek glass skyscrapers and dense commuter traffic under a clear morning sky. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbjscyiBm8tBkbaaSe-QeXK6klPWhc2iKUqI52AmLRwvT9mN9ejkVihSUECOFmu9Q8YoXlQbMd3vBhtklNwBhjfPxk_EVVcHx8Tyg9UPQ-7TcijRX5gLI6yl8HRpIQQo6gFuAu_2rRaMyeb1dGrgspXV1O9lgAOWh_6ohaiwA\",null,null,256980],[[null,369755011,null,null,null,null,null,\"Single reference image of Wide bustling urban avenue in Hanoi during morning rush hour, elevated concrete metro tracks overhead with modern green Cat Linh - Ha Dong passenger train gliding past sleek glass skyscrapers and dense commuter traffic under a clear morning sky. Photorealistic RAW photograph, shot on Canon EOS R5, 35mm lens, natural available light, real footage. NOT 3D render, NOT CGI, NOT digital art, NOT illustration, NOT anime, NOT painting, NOT cartoon. COMPOSITION: Establishing shot showing the full environment. Balanced level composition with straight horizon. Clear focal point. Atmospheric and richly detailed. Show depth and spatial layout. ONE single image only, NOT a multi-panel grid or multiple views. Studio lighting, highly detailed\",25,\"\",null,\"bd7eacf9-d385-4561-bf0b-62e3e8a253dc\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbjscyiBm8tBkbaaSe-QeXK6klPWhc2iKUqI52AmLRwvT9mN9ejkVihSUECOFmu9Q8YoXlQbMd3vBhtklNwBhjfPxk_EVVcHx8Tyg9UPQ-7TcijRX5gLI6yl8HRpIQQo6gFuAu_2rRaMyeb1dGrgspXV1O9lgAOWh_6ohaiwA\",3],null,[1376,768]]],[\"ffd129ac-2cb2-4c5d-a059-e37be9782118\",\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"e03db69f-0402-4e01-8d10-20a700e1d064\",\"CAE\",null,[[1790098624,387715000],null,null,null,null,\"https://lh3.googleusercontent.com/asb/AB-nOUbGns3Wmho3ZegUvxq-tGhm-YgFyDUJCtY0CVQ6zTAniolbts8gYzxsyhCvu4B5zsexyN9cxdHiga8CAp31bM_IjVI0Hjt-aS_qO-xy-F1vRHLLMgLry6Fvomu67tGtnrmOenoqmDByq4Yrw5BPdAlacY0z58Ahjzp74ZwmJw\",[null,null,[[\"A cute Vietnamese shorthair cat sitting on a weathered wooden stool in a dimly lit, high-tech Hanoi apartment. Cinematic realism, grounded live-action aesthetic, subtle film grain, soft tungsten lighting from a nearby monitor reflecting in the cat's eyes. Authentic textures, near-future techno-thriller atmosphere.\",null,[[[\"A cute Vietnamese shorthair cat sitting on a weathered wooden stool in a dimly lit, high-tech Hanoi apartment. Cinematic realism, grounded live-action aesthetic, subtle film grain, soft tungsten lighting from a nearby monitor reflecting in the cat's eyes. Authentic textures, near-future techno-thriller atmosphere.\"]]]]],[],1],null,null,1,\"https://lh3.googleusercontent.com/asb/AB-nOUbGns3Wmho3ZegUvxq-tGhm-YgFyDUJCtY0CVQ6zTAniolbts8gYzxsyhCvu4B5zsexyN9cxdHiga8CAp31bM_IjVI0Hjt-aS_qO-xy-F1vRHLLMgLry6Fvomu67tGtnrmOenoqmDByq4Yrw5BPdAlacY0z58Ahjzp74ZwmJw\",null,null,176855],[[null,754164,null,null,null,null,null,\"A cute Vietnamese shorthair cat sitting on a weathered wooden stool in a dimly lit, high-tech Hanoi apartment. Cinematic realism, grounded live-action aesthetic, subtle film grain, soft tungsten lighting from a nearby monitor reflecting in the cat's eyes. Authentic textures, near-future techno-thriller atmosphere.\",25,\"\",null,\"e03db69f-0402-4e01-8d10-20a700e1d064\",null,\"https://lh3.googleusercontent.com/asb/AB-nOUbGns3Wmho3ZegUvxq-tGhm-YgFyDUJCtY0CVQ6zTAniolbts8gYzxsyhCvu4B5zsexyN9cxdHiga8CAp31bM_IjVI0Hjt-aS_qO-xy-F1vRHLLMgLry6Fvomu67tGtnrmOenoqmDByq4Yrw5BPdAlacY0z58Ahjzp74ZwmJw\",3],null,[1376,768]]]],[[\"achernar\",3,\"Achernar\",[\"achernar\",null,null,null,null,null,null,null,null,null,[[\"Achernar\",\"Female, soft, high pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Achernar.wav\"]]]],[\"achird\",3,\"Achird\",[\"achird\",null,null,null,null,null,null,null,null,null,[[\"Achird\",\"Male, friendly, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Achird.wav\"]]]],[\"algenib\",3,\"Algenib\",[\"algenib\",null,null,null,null,null,null,null,null,null,[[\"Algenib\",\"Male, gravelly, low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Algenib.wav\"]]]],[\"algieba\",3,\"Algieba\",[\"algieba\",null,null,null,null,null,null,null,null,null,[[\"Algieba\",\"Male, easy-going, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Algieba.wav\"]]]],[\"alnilam\",3,\"Alnilam\",[\"alnilam\",null,null,null,null,null,null,null,null,null,[[\"Alnilam\",\"Male, firm, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Alnilam.wav\"]]]],[\"aoede\",3,\"Aoede\",[\"aoede\",null,null,null,null,null,null,null,null,null,[[\"Aoede\",\"Female, breezy, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Aoede.wav\"]]]],[\"autonoe\",3,\"Autonoe\",[\"autonoe\",null,null,null,null,null,null,null,null,null,[[\"Autonoe\",\"Female, bright, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Autonoe.wav\"]]]],[\"callirrhoe\",3,\"Callirrhoe\",[\"callirrhoe\",null,null,null,null,null,null,null,null,null,[[\"Callirrhoe\",\"Female, easy-going, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Callirrhoe.wav\"]]]],[\"charon\",3,\"Charon\",[\"charon\",null,null,null,null,null,null,null,null,null,[[\"Charon\",\"Male, informative, lower pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Charon.wav\"]]]],[\"despina\",3,\"Despina\",[\"despina\",null,null,null,null,null,null,null,null,null,[[\"Despina\",\"Female, smooth, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Despina.wav\"]]]],[\"enceladus\",3,\"Enceladus\",[\"enceladus\",null,null,null,null,null,null,null,null,null,[[\"Enceladus\",\"Male, breathy, lower pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Enceladus.wav\"]]]],[\"erinome\",3,\"Erinome\",[\"erinome\",null,null,null,null,null,null,null,null,null,[[\"Erinome\",\"Female, clear, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Erinome.wav\"]]]],[\"fenrir\",3,\"Fenrir\",[\"fenrir\",null,null,null,null,null,null,null,null,null,[[\"Fenrir\",\"Male, excitable, younger pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Fenrir.wav\"]]]],[\"gacrux\",3,\"Gacrux\",[\"gacrux\",null,null,null,null,null,null,null,null,null,[[\"Gacrux\",\"Female, mature, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Gacrux.wav\"]]]],[\"iapetus\",3,\"Iapetus\",[\"iapetus\",null,null,null,null,null,null,null,null,null,[[\"Iapetus\",\"Male, clear, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Iapetus.wav\"]]]],[\"kore\",3,\"Kore\",[\"kore\",null,null,null,null,null,null,null,null,null,[[\"Kore\",\"Female, firm, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Kore.wav\"]]]],[\"laomedeia\",3,\"Laomedeia\",[\"laomedeia\",null,null,null,null,null,null,null,null,null,[[\"Laomedeia\",\"Female, upbeat, mid-high pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Laomedeia.wav\"]]]],[\"leda\",3,\"Leda\",[\"leda\",null,null,null,null,null,null,null,null,null,[[\"Leda\",\"Female, youthful, mid-high pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Leda.wav\"]]]],[\"orus\",3,\"Orus\",[\"orus\",null,null,null,null,null,null,null,null,null,[[\"Orus\",\"Male, firm, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Orus.wav\"]]]],[\"puck\",3,\"Puck\",[\"puck\",null,null,null,null,null,null,null,null,null,[[\"Puck\",\"Male, upbeat, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Puck.wav\"]]]],[\"pulcherrima\",3,\"Pulcherrima\",[\"pulcherrima\",null,null,null,null,null,null,null,null,null,[[\"Pulcherrima\",\"Ungendered, forward, mid-high pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Pulcherrima.wav\"]]]],[\"rasalgethi\",3,\"Rasalgethi\",[\"rasalgethi\",null,null,null,null,null,null,null,null,null,[[\"Rasalgethi\",\"Male, informative, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Rasalgethi.wav\"]]]],[\"sadachbia\",3,\"Sadachbia\",[\"sadachbia\",null,null,null,null,null,null,null,null,null,[[\"Sadachbia\",\"Male, lively, low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Sadachbia.wav\"]]]],[\"sadaltager\",3,\"Sadaltager\",[\"sadaltager\",null,null,null,null,null,null,null,null,null,[[\"Sadaltager\",\"Male, knowledgeable, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Sadaltager.wav\"]]]],[\"schedar\",3,\"Schedar\",[\"schedar\",null,null,null,null,null,null,null,null,null,[[\"Schedar\",\"Male, even, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Schedar.wav\"]]]],[\"sulafat\",3,\"Sulafat\",[\"sulafat\",null,null,null,null,null,null,null,null,null,[[\"Sulafat\",\"Female, warm, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Sulafat.wav\"]]]],[\"umbriel\",3,\"Umbriel\",[\"umbriel\",null,null,null,null,null,null,null,null,null,[[\"Umbriel\",\"Male, smooth, lower pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Umbriel.wav\"]]]],[\"vindemiatrix\",3,\"Vindemiatrix\",[\"vindemiatrix\",null,null,null,null,null,null,null,null,null,[[\"Vindemiatrix\",\"Female, gentle, mid pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Vindemiatrix.wav\"]]]],[\"zephyr\",3,\"Zephyr\",[\"zephyr\",null,null,null,null,null,null,null,null,null,[[\"Zephyr\",\"Female, bright, mid-high pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Zephyr.wav\"]]]],[\"zubenelgenubi\",3,\"Zubenelgenubi\",[\"zubenelgenubi\",null,null,null,null,null,null,null,null,null,[[\"Zubenelgenubi\",\"Male, casual, mid-low pitch\",true,\"https://gstatic.com/aitestkitchen/voices/samples/Zubenelgenubi.wav\"]]]]],null,[[\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"11a89444-ca45-45a2-a890-feab388ba4ae\",null,[1,\"Untitled Character\",[[[\"c7fee095-6829-4801-94c8-3eb9bcaf060f\"]]]],\"4630aeab-cd27-4457-96b6-24045de2504e\",[1448,1086],[1785255345,366015000],[1785255350,725479000]],[\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"ad4b3ad9-a282-478e-957e-6fcc47a2b5e4\",null,[1,\"Tien_2031_B3\",[[[\"4fb9e862-d995-4f49-9eb6-d00b1f2ee767\"],[]]]],\"9aea7396-dc22-4b69-947f-7d1dcc5c1e3c\",[1376,768],[1784546541,129258000],[1784546568,859181000]],[\"594758cc-11f5-4f92-8b3c-1213686591f4\",\"f4d9c731-41f2-4b51-9dd2-edd20c1dc7f1\",null,[1,\"Tien_2028_PREP\",[[[\"d7c54686-02ce-4344-ac22-2888ccf9c76e\"],[]],null,\"Lê Quốc Tiến, 29-year-old Vietnamese infrastructure engineer.\\nPre-Red-Sun 2028 preparation state.\"]],\"6aa915c7-1123-4e12-b75f-6d5e6d40d0fe\",[1376,768],[1784546032,509474000],[1784546353,571992000]]],null,[null,[true,[[\"e55378b8-ca5a-4a67-b6e3-351246bc1986\",\"Tiêu đề hướng dẫn\",\"PROJECT: HỒNG NHẬT THĂNG LONG — HNTL_MASTER_LIVE_ACTION\\n\\nYou are the project organizer and creative assistant for a grounded live-action Vietnamese near-future techno-thriller.\\n\\nNON-NEGOTIABLE VISUAL RULES\\n- Live-action cinematic realism only.\\n- Authentic Vietnamese faces, Hanoi architecture, infrastructure, vehicles and everyday objects.\\n- Restrained acting and physically believable motion.\\n- Practical 2028 clothing and industrial equipment.\\n- No anime, illustration, comic, glossy game rendering, fantasy armor, magical glow, generic cyberpunk neon or holograms.\\n- Never use assets marked STORYBOARD_ONLY as identity or video Ingredients.\\n\\nPRODUCTION RULES\\n- One main action per generated clip.\\n- Never invent a new costume, injury, prop or age for an APPROVED Character.\\n- Never modify or overwrite an asset whose filename ends in APPROVED or FINAL.\\n- Exact dates, clocks, terminal text, logos and subtitles are post-production overlays; keep screens clean.\\n- Use Character references and location references exactly as named.\\n- When asked to organize, use filename prefixes and move assets to the matching Collection.\\n- Ask for confirmation before any generation that spends credits.\\n- For locked render cards, do not choose the model automatically; the user will use the standard prompt box.\\n\\nMASTER STYLE\\ngrounded live-action Vietnamese near-future techno-thriller, cinematic realism, authentic Vietnamese cast and Hanoi architecture, natural skin texture, practical 2028 clothing and industrial equipment, physically believable heat haze and sweat, restrained acting, controlled camera movement, 24 fps cinematic motion, subtle film grain, high dynamic range, no fantasy spectacle\\n\\nMASTER NEGATIVE\\nno anime, no illustration, no comic-book rendering, no glossy video-game look, no superhero armor, no magic glow, no Chinese imperial costume, no Japanese historical styling, no European medieval architecture, no generic cyberpunk neon, no holograms, no face drift, no age drift, no hairstyle drift, no costume drift, no extra fingers, no duplicated main characters, no generated readable text, no watermark\",true]]],[[null,3,2,null,\"nano_banana_pro\"],[null,2,1,null,\"abra\"]],1,1]]",null,null,null,"generic"]] -57 -[["di",695],["af.httprm",694,"3185932965805684473",25]] -28 -[["e",4,null,null,164172]] diff --git a/scripts/build_master_film.py b/scripts/build_master_film.py new file mode 100644 index 000000000..3efbdd3c9 --- /dev/null +++ b/scripts/build_master_film.py @@ -0,0 +1,450 @@ +#!/usr/bin/env python3 +""" +FlowKit — Multi-Chapter Cinematic Master Film Compiler +Assembles independent chapter videos into a seamless, Hollywood-grade Master Film. + +Features: +1. Dynamic Interstitial Chapter Bumpers (obsidian canvas, antique gold typography, 40-60Hz sub-bass drone). +2. Micro Ken Burns zoom (1.0x -> 1.04x) on chapter cards. +3. Dip-to-black video & audio crossfades (0.8s standard). +4. Automated YouTube Chapter Timestamps generation for video descriptions. +5. Codec-safe normalization & concatenation. + +Usage: + python scripts/build_master_film.py --project-dir output/hong_nhat_thang_long --chapters 1 2 3 4 5 + python scripts/build_master_film.py --config config/master_film_config.json +""" + +import argparse +import json +import math +import os +import re +import subprocess +import sys +from pathlib import Path + +try: + from PIL import Image, ImageDraw, ImageFont + HAS_PIL = True +except ImportError: + HAS_PIL = False + + +def run_command(cmd, desc=""): + """Execute subprocess and return success status and output.""" + if desc: + print(f" [EXEC] {desc}") + res = subprocess.run(cmd, capture_output=True, text=True) + if res.returncode != 0: + print(f" [ERROR] {res.stderr.strip()}", file=sys.stderr) + return False, res.stderr + return True, res.stdout + + +def get_media_duration(file_path): + """Retrieve media duration in seconds via ffprobe.""" + cmd = [ + 'ffprobe', '-v', 'error', + '-show_entries', 'format=duration', + '-of', 'default=noprint_wrappers=1:nokey=1', + str(file_path) + ] + res = subprocess.run(cmd, capture_output=True, text=True) + try: + return float(res.stdout.strip()) + except Exception: + return 0.0 + + +def format_timestamp(seconds): + """Convert seconds into MM:SS or HH:MM:SS format.""" + total_sec = int(round(seconds)) + hrs = total_sec // 3600 + mins = (total_sec % 3600) // 60 + secs = total_sec % 60 + if hrs > 0: + return f"{hrs:02d}:{mins:02d}:{secs:02d}" + return f"{mins:02d}:{secs:02d}" + + +def create_bumper_card_pil( + category_text, + main_title, + subtitle_text, + output_path, + width=1280, + height=720, + accent_color=(212, 175, 55), # Antique Gold + glow_color=(180, 50, 30) # Crimson Ambience +): + """Render a cinematic chapter interstitial title card using PIL.""" + img = Image.new('RGB', (width, height), color=(10, 8, 12)) + pixels = img.load() + cx, cy = width / 2.0, height / 2.0 + max_dist = math.sqrt(cx**2 + cy**2) + + for y in range(height): + for x in range(width): + dist = math.sqrt((x - cx)**2 + (y - cy)**2) / max_dist + radial = max(0.0, 1.0 - dist * 1.3) + r = int(10 + radial * glow_color[0] * 0.22) + g = int(8 + radial * glow_color[1] * 0.12) + b = int(12 + radial * glow_color[2] * 0.12) + pixels[x, y] = (min(255, r), min(255, g), min(255, b)) + + draw = ImageDraw.Draw(img) + + # Resolve fonts (with Windows fallback) + font_cat_path = 'C:/Windows/Fonts/timesbd.ttf' if os.name == 'nt' else '/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf' + font_sub_path = 'C:/Windows/Fonts/arial.ttf' if os.name == 'nt' else '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf' + + try: + scale = height / 720.0 + font_cat = ImageFont.truetype(font_cat_path, int(26 * scale)) + font_title = ImageFont.truetype(font_cat_path, int(50 * scale)) + font_sub = ImageFont.truetype(font_sub_path, int(24 * scale)) + font_dec = ImageFont.truetype(font_cat_path, int(18 * scale)) + except Exception: + font_cat = font_title = font_sub = font_dec = ImageFont.load_default() + + y_cat = int(height * 0.35) + y_line1 = y_cat + int(35 * (height / 720.0)) + y_title = int(height * 0.50) + y_line2 = y_title + int(45 * (height / 720.0)) + y_sub = int(height * 0.65) + + # Series Header + draw.text((cx, y_cat), category_text, font=font_cat, fill=accent_color, anchor='mm') + + # Accent Dividers + line_w = int(280 * (width / 1280.0)) + draw.line([(cx - line_w, y_line1), (cx + line_w, y_line1)], fill=(120, 95, 40), width=1) + draw.text((cx, y_line1), "◆", font=font_dec, fill=accent_color, anchor='mm') + + # Main Chapter Title + draw.text((cx, y_title), main_title, font=font_title, fill=(255, 255, 255), anchor='mm') + + draw.line([(cx - line_w, y_line2), (cx + line_w, y_line2)], fill=(120, 95, 40), width=1) + draw.text((cx, y_line2), "◆", font=font_dec, fill=accent_color, anchor='mm') + + # Narrative Context / Subtitle + if subtitle_text: + draw.text((cx, y_sub), subtitle_text, font=font_sub, fill=(200, 205, 215), anchor='mm') + + # Letterbox border framing + margin_x = int(60 * (width / 1280.0)) + margin_y = int(40 * (height / 720.0)) + draw.rectangle([margin_x, margin_y, width - margin_x, height - margin_y], outline=(45, 38, 25), width=1) + draw.rectangle([margin_x + 4, margin_y + 4, width - margin_x - 4, height - margin_y - 4], outline=(25, 20, 15), width=1) + + os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True) + img.save(output_path, quality=95) + return True + + +def render_bumper_video(card_img_path, output_video_path, duration=3.5, width=1280, height=720, fps=24): + """Render a dynamic bumper video with Ken Burns micro-zoom and sub-bass brown drone.""" + if os.path.exists(output_video_path) and os.path.getsize(output_video_path) > 10000: + return True + + os.makedirs(os.path.dirname(os.path.abspath(output_video_path)), exist_ok=True) + num_frames = int(duration * fps) + + # 0.8s fade in, 1.0s fade out + fade_out_start = max(0.5, duration - 1.0) + filter_complex = ( + f"[0:v]zoompan=z='min(zoom+0.0006,1.05)':d={num_frames}:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':s={width}x{height}:fps={fps}," + f"fade=t=in:st=0:d=0.8,fade=t=out:st={fade_out_start:.2f}:d=1.0[vout];" + f"[1:a]lowpass=f=160,volume=3.2,afade=t=in:ss=0:d=0.8,afade=t=out:st={fade_out_start:.2f}:d=1.0[aout]" + ) + + cmd = [ + 'ffmpeg', '-y', + '-i', str(card_img_path), + '-f', 'lavfi', '-t', str(duration), '-i', f'anoisesrc=d={duration}:c=brown:r=48000:a=0.12', + '-filter_complex', filter_complex, + '-map', '[vout]', '-map', '[aout]', + '-c:v', 'libx264', '-preset', 'medium', '-crf', '18', '-pix_fmt', 'yuv420p', + '-c:a', 'aac', '-b:a', '192k', '-ar', '48000', + '-t', str(duration), + str(output_video_path) + ] + ok, _ = run_command(cmd, f"Rendering bumper video: {output_video_path}") + return ok + + +def apply_fades_to_chapter(input_video_path, output_video_path, fade_dur=0.8): + """Apply head/tail video and audio dips to black.""" + if os.path.exists(output_video_path) and os.path.getsize(output_video_path) > 10000: + return True + + dur = get_media_duration(input_video_path) + if dur <= 0: + return False + + fade_out_st = max(0.0, dur - fade_dur) + filter_complex = ( + f"[0:v]fade=t=in:st=0:d={fade_dur},fade=t=out:st={fade_out_st:.2f}:d={fade_dur}[vout];" + f"[0:a]afade=t=in:ss=0:d={fade_dur},afade=t=out:st={fade_out_st:.2f}:d={fade_dur}[aout]" + ) + + os.makedirs(os.path.dirname(os.path.abspath(output_video_path)), exist_ok=True) + cmd = [ + 'ffmpeg', '-y', + '-i', str(input_video_path), + '-filter_complex', filter_complex, + '-map', '[vout]', '-map', '[aout]', + '-c:v', 'libx264', '-preset', 'fast', '-crf', '18', '-pix_fmt', 'yuv420p', + '-c:a', 'aac', '-b:a', '192k', '-ar', '48000', + str(output_video_path) + ] + ok, _ = run_command(cmd, f"Fading chapter: {input_video_path} -> {output_video_path}") + return ok + + +def build_master_film( + project_dir, + chapters, + series_title="HỒNG NHẬT THĂNG LONG", + chapter_metadata=None, + output_master=None, + width=1280, + height=720, + fps=24, + bumper_dur=3.5, + fade_dur=0.8, + skip_bumpers=False +): + """Main orchestration function for building a master film.""" + project_path = Path(project_dir) + slug = project_path.name + temp_dir = project_path / ".master_film_cache" + temp_dir.mkdir(parents=True, exist_ok=True) + + if not output_master: + output_master = str(project_path / f"{slug}_CINEMATIC_MASTER.mp4") + + print(f"\n=======================================================") + print(f"🎬 FLOWKIT CINEMATIC MASTER FILM COMPILER") + print(f"Series: {series_title}") + print(f"Project Directory: {project_dir}") + print(f"Chapters Count: {len(chapters)}") + print(f"Output Master: {output_master}") + print(f"=======================================================\n") + + # Resolve chapter files + chapter_entries = [] + for ch in chapters: + # Check standard filename patterns + candidates = [ + project_path / f"{slug}_ch{ch}_final.mp4", + project_path / f"ch{ch}_final.mp4", + project_path / f"chapter_{ch}.mp4", + project_path / f"ch{ch}.mp4", + ] + found = None + for cand in candidates: + if cand.exists(): + found = cand + break + + if not found: + # Fallback search by pattern + matches = list(project_path.glob(f"*ch{ch}*.mp4")) + if matches: + found = matches[0] + + if not found: + print(f"❌ Error: Cannot find chapter video for chapter '{ch}' in {project_dir}", file=sys.stderr) + return False + + meta = {} + if chapter_metadata and str(ch) in chapter_metadata: + meta = chapter_metadata[str(ch)] + elif chapter_metadata and ch in chapter_metadata: + meta = chapter_metadata[ch] + + title = meta.get("title", f"CHƯƠNG {ch}") + subtitle = meta.get("subtitle", "") + chapter_entries.append({ + "chapter": ch, + "raw_video": found, + "title": title, + "subtitle": subtitle + }) + + playback_sequence = [] + current_timeline_sec = 0.0 + youtube_timestamps = [] + + # 1. Bumpers and Transitions + for idx, item in enumerate(chapter_entries, 1): + ch = item["chapter"] + raw_video = item["raw_video"] + + if not skip_bumpers: + card_img = temp_dir / f"card_ch{ch}.png" + bumper_mp4 = temp_dir / f"bumper_ch{ch}.mp4" + + if not card_img.exists(): + if HAS_PIL: + create_bumper_card_pil( + category_text=series_title, + main_title=item["title"], + subtitle_text=item["subtitle"], + output_path=str(card_img), + width=width, + height=height + ) + + render_bumper_video( + card_img_path=str(card_img), + output_video_path=str(bumper_mp4), + duration=bumper_dur, + width=width, + height=height, + fps=fps + ) + + # Record timestamp for YouTube + ts_str = format_timestamp(current_timeline_sec) + youtube_timestamps.append(f"{ts_str} - {item['title']}: {item['subtitle']}" if item['subtitle'] else f"{ts_str} - {item['title']}") + + playback_sequence.append(str(bumper_mp4)) + current_timeline_sec += bumper_dur + + # Faded chapter + faded_mp4 = temp_dir / f"ch{ch}_smooth.mp4" + apply_fades_to_chapter(str(raw_video), str(faded_mp4), fade_dur=fade_dur) + playback_sequence.append(str(faded_mp4)) + + ch_dur = get_media_duration(str(raw_video)) + current_timeline_sec += ch_dur + + # Outro Bumper if provided + outro_meta = chapter_metadata.get("outro") if chapter_metadata else None + if outro_meta and not skip_bumpers: + card_outro = temp_dir / "card_outro.png" + bumper_outro = temp_dir / "bumper_outro.mp4" + if HAS_PIL and not card_outro.exists(): + create_bumper_card_pil( + category_text=series_title, + main_title=outro_meta.get("title", "HẾT PHẦN 1"), + subtitle_text=outro_meta.get("subtitle", "Đón xem Phần 2"), + output_path=str(card_outro), + width=width, + height=height + ) + render_bumper_video(str(card_outro), str(bumper_outro), duration=bumper_dur, width=width, height=height, fps=fps) + ts_str = format_timestamp(current_timeline_sec) + youtube_timestamps.append(f"{ts_str} - {outro_meta.get('title', 'KẾT THÚC')}") + playback_sequence.append(str(bumper_outro)) + current_timeline_sec += bumper_dur + + # 2. Concat + concat_txt = temp_dir / "master_concat_list.txt" + with open(concat_txt, "w", encoding="utf-8") as f: + for p in playback_sequence: + abs_p = Path(p).resolve().as_posix() + f.write(f"file '{abs_p}'\n") + + print(f"\n[STITCH] Concatenating {len(playback_sequence)} video blocks into final master...") + cmd_concat = [ + 'ffmpeg', '-y', + '-f', 'concat', + '-safe', '0', + '-i', str(concat_txt), + '-c', 'copy', + str(output_master) + ] + ok, _ = run_command(cmd_concat, "FFmpeg stream copy concat") + if not ok: + print("Falling back to re-encoding concat...", file=sys.stderr) + cmd_concat_reencode = [ + 'ffmpeg', '-y', + '-f', 'concat', + '-safe', '0', + '-i', str(concat_txt), + '-c:v', 'libx264', '-crf', '18', '-preset', 'fast', + '-c:a', 'aac', '-b:a', '192k', + str(output_master) + ] + ok, _ = run_command(cmd_concat_reencode, "FFmpeg re-encode concat") + if not ok: + return False + + final_size_mb = os.path.getsize(output_master) / (1024 * 1024) + final_dur = get_media_duration(output_master) + + # 3. Print Results & YouTube Chapters + yt_file = project_path / f"{slug}_YOUTUBE_CHAPTERS.txt" + with open(yt_file, "w", encoding="utf-8") as f: + f.write("\n".join(youtube_timestamps)) + + print(f"\n=======================================================") + print(f"✅ CINEMATIC MASTER FILM GENERATED SUCCESSFULLY!") + print(f"Output File: {output_master}") + print(f"Total Size: {final_size_mb:.2f} MB") + print(f"Total Duration: {final_dur:.1f}s ({final_dur/60:.2f} minutes)") + print(f"YouTube Chapters File: {yt_file}") + print(f"-------------------------------------------------------") + print("📋 YouTube Chapter Timestamps for Description:") + for line in youtube_timestamps: + print(f" {line}") + print(f"=======================================================\n") + return True + + +def main(): + parser = argparse.ArgumentParser(description="FlowKit Multi-Chapter Master Film Compiler") + parser.add_argument("--project-dir", required=True, help="Directory containing chapter video files") + parser.add_argument("--chapters", nargs="+", default=["1", "2", "3", "4", "5"], help="List of chapter identifiers") + parser.add_argument("--title", default="HỒNG NHẬT THĂNG LONG", help="Series or movie main title") + parser.add_argument("--config", help="Optional JSON config file with chapter titles and subtitles") + parser.add_argument("--output", help="Output path for the master film MP4") + parser.add_argument("--resolution", default="1280x720", help="Resolution WxH (e.g. 1280x720 or 1920x1080)") + parser.add_argument("--fps", type=int, default=24, help="Target frames per second") + parser.add_argument("--bumper-duration", type=float, default=3.5, help="Duration of chapter interstitial card (sec)") + parser.add_argument("--fade-duration", type=float, default=0.8, help="Fade duration for crossfades/dips (sec)") + parser.add_argument("--no-bumpers", action="store_true", help="Skip bumper title cards") + + args = parser.parse_args() + + width, height = [int(x) for x in args.resolution.split("x")] + + chapter_meta = {} + if args.config and os.path.exists(args.config): + with open(args.config, "r", encoding="utf-8") as f: + chapter_meta = json.load(f) + + # Built-in default metadata for Hong Nhat Thang Long if not provided + if not chapter_meta and "hong_nhat" in args.project_dir.lower(): + chapter_meta = { + "1": {"title": "CHƯƠNG I: NGÀY TRỞ VỀ", "subtitle": "Tầng hầm B3 Mễ Trì — Khởi đầu chuỗi ngày sinh tồn"}, + "2": {"title": "CHƯƠNG II: NGÀY NGỌC TRẦM", "subtitle": "Bốn mươi bốn ngày trước thảm họa — Bão nhiệt 65°C tấn công"}, + "3": {"title": "CHƯƠNG III: LA PHÙ KHÔNG CÒN LỬA", "subtitle": "Ba mươi ngày trước thảm họa — Bí mật chuỗi cung ứng ngầm"}, + "4": {"title": "CHƯƠNG IV: HỒNG NHẬT GIỮA ĐÊM ĐEN", "subtitle": "Mười lăm ngày trước thảm họa — Trận chiến cống ngầm Đại Hà"}, + "5": {"title": "CHƯƠNG V: THĂNG LONG PHÒNG TUYẾN", "subtitle": "Bảy ngày trước thảm họa — Lời thề giữ đất Thăng Long"}, + "outro": {"title": "HẾT PHẦN 1 — CHUỖI 5 CHƯƠNG ĐẦU", "subtitle": "Đón xem Phần 2: Ngày Tận Thế Thăng Long"} + } + + ok = build_master_film( + project_dir=args.project_dir, + chapters=args.chapters, + series_title=args.title, + chapter_metadata=chapter_meta, + output_master=args.output, + width=width, + height=height, + fps=args.fps, + bumper_dur=args.bumper_duration, + fade_dur=args.fade_duration, + skip_bumpers=args.no_bumpers + ) + + sys.exit(0 if ok else 1) + + +if __name__ == '__main__': + main() diff --git a/scripts/generate_subtitles.py b/scripts/generate_subtitles.py new file mode 100644 index 000000000..936a4a1d6 --- /dev/null +++ b/scripts/generate_subtitles.py @@ -0,0 +1,282 @@ +#!/usr/bin/env python3 +""" +FlowKit — Subtitle (.srt / .vtt) Generator & Hardsub Burner +Extracts narrator text and timing from scenes or local project files to generate: +1. SubRip (.srt) subtitle files (for YouTube captions and VLC) +2. WebVTT (.vtt) subtitle files (for web players) +3. Hardsub Burning: Directly burns stylized, cinematic subtitles into video frames via FFmpeg. + +Styles: +- cinematic_gold: Antique gold text (&H0080C2E6), dark outline, elegant margins +- clean_white: Crisp white text (&H00FFFFFF), 1.8px dark outline, subtle shadow +- cyber_amber: Glowing amber text (&H0000D7FF), high-contrast outline +- emerald_hud: Military sci-fi HUD light-green (&H00C0FFC0) + +Usage: + python scripts/generate_subtitles.py --video-id --output output//subtitles.srt + python scripts/generate_subtitles.py --project-dir output/hong_nhat_thang_long --burn-subtitles --input-video output/hong_nhat_thang_long/hong_nhat_thang_long_CINEMATIC_MASTER.mp4 +""" + +import argparse +import json +import os +import re +import subprocess +import sys +import urllib.request +from pathlib import Path + + +SUBTITLE_STYLES = { + "cinematic_gold": "FontName=Arial,FontSize=20,PrimaryColour=&H0080C2E6,OutlineColour=&H0008080A,BorderStyle=1,Outline=2.0,Shadow=1.5,MarginV=35", + "clean_white": "FontName=Arial,FontSize=20,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,BorderStyle=1,Outline=1.8,Shadow=1.0,MarginV=30", + "cyber_amber": "FontName=Arial,FontSize=20,PrimaryColour=&H0000D7FF,OutlineColour=&H00000020,BorderStyle=1,Outline=2.2,Shadow=1.5,MarginV=35", + "emerald_hud": "FontName=Arial,FontSize=20,PrimaryColour=&H00C0FFC0,OutlineColour=&H00002000,BorderStyle=1,Outline=2.0,Shadow=1.5,MarginV=35", +} + + +def format_srt_time(seconds): + """Format seconds into SRT timestamp: HH:MM:SS,mmm""" + millis = int(round((seconds - int(seconds)) * 1000)) + total_sec = int(seconds) + hrs = total_sec // 3600 + mins = (total_sec % 3600) // 60 + secs = total_sec % 60 + return f"{hrs:02d}:{mins:02d}:{secs:02d},{millis:03d}" + + +def format_vtt_time(seconds): + """Format seconds into WebVTT timestamp: HH:MM:SS.mmm""" + millis = int(round((seconds - int(seconds)) * 1000)) + total_sec = int(seconds) + hrs = total_sec // 3600 + mins = (total_sec % 3600) // 60 + secs = total_sec % 60 + return f"{hrs:02d}:{mins:02d}:{secs:02d}.{millis:03d}" + + +def wrap_subtitle_text(text, max_chars=42): + """Split long subtitle text into max 2 readable lines.""" + words = text.strip().split() + if not words: + return "" + + lines = [] + cur_line = [] + cur_len = 0 + + for w in words: + if cur_len + len(w) + (1 if cur_line else 0) > max_chars and cur_line: + lines.append(" ".join(cur_line)) + cur_line = [w] + cur_len = len(w) + else: + cur_line.append(w) + cur_len += len(w) + (1 if cur_len > 0 else 0) + + if cur_line: + lines.append(" ".join(cur_line)) + + # Return at most 2 lines per subtitle card, joined by newline + return "\n".join(lines[:2]) + + +def get_audio_duration(file_path): + """Get audio duration in seconds using ffprobe.""" + if not os.path.exists(file_path): + return 0.0 + cmd = [ + 'ffprobe', '-v', 'error', + '-show_entries', 'format=duration', + '-of', 'default=noprint_wrappers=1:nokey=1', + str(file_path) + ] + res = subprocess.run(cmd, capture_output=True, text=True) + try: + return float(res.stdout.strip()) + except Exception: + return 0.0 + + +def fetch_scenes_api(video_id, base_url="http://127.0.0.1:8100"): + """Fetch scenes for a given video_id from FlowKit API.""" + url = f"{base_url}/api/scenes?video_id={video_id}" + req = urllib.request.Request(url, headers={"User-Agent": "FlowKit-Subtitle"}) + try: + with urllib.request.urlopen(req, timeout=10) as resp: + data = json.loads(resp.read().decode("utf-8")) + return sorted(data, key=lambda s: s.get("display_order", 0)) + except Exception as e: + print(f"Error fetching scenes from API: {e}", file=sys.stderr) + return [] + + +def generate_subtitles_from_scenes(scenes, output_base, buffer_sec=0.5, default_scene_dur=8.0): + """Generate .srt and .vtt files given scene metadata list.""" + srt_entries = [] + vtt_entries = ["WEBVTT\n"] + + current_time = 0.0 + sub_index = 1 + + for sc in scenes: + narrator = sc.get("narrator_text", "").strip() + dur = sc.get("duration") or default_scene_dur + + # If there's narrator text + if narrator: + start_t = current_time + end_t = current_time + max(2.0, dur - buffer_sec) + + wrapped = wrap_subtitle_text(narrator) + + srt_entries.append( + f"{sub_index}\n" + f"{format_srt_time(start_t)} --> {format_srt_time(end_t)}\n" + f"{wrapped}\n" + ) + + vtt_entries.append( + f"{sub_index}\n" + f"{format_vtt_time(start_t)} --> {format_vtt_time(end_t)}\n" + f"{wrapped}\n" + ) + sub_index += 1 + + current_time += dur + + srt_path = output_base.with_suffix(".srt") + vtt_path = output_base.with_suffix(".vtt") + + srt_path.write_text("\n".join(srt_entries), encoding="utf-8") + vtt_path.write_text("\n".join(vtt_entries), encoding="utf-8") + + print(f"✅ Generated SRT subtitles: {srt_path} ({sub_index - 1} entries)") + print(f"✅ Generated VTT subtitles: {vtt_path}") + return srt_path, vtt_path + + +def burn_subtitles_to_video(input_video_path, srt_path, output_video_path=None, style="cinematic_gold"): + """Burn subtitles directly into video frames using FFmpeg libass subtitles filter.""" + in_p = Path(input_video_path) + if not in_p.exists(): + print(f"❌ Input video not found: {input_video_path}", file=sys.stderr) + return False + + if not output_video_path: + output_video_path = in_p.parent / f"{in_p.stem}_hardsub.mp4" + else: + output_video_path = Path(output_video_path) + + style_str = SUBTITLE_STYLES.get(style, SUBTITLE_STYLES["cinematic_gold"]) + + # Format srt path for FFmpeg filter: + # Use forward slashes and escape colon for Windows drives (e.g. D\:/path) + clean_srt = str(Path(srt_path).resolve()).replace('\\', '/') + clean_srt = clean_srt.replace(':', '\\:') + + vf = f"subtitles='{clean_srt}':force_style='{style_str}'" + + print(f"\n🎬 Burning subtitles into video: {input_video_path}") + print(f" Style: {style}") + print(f" Output: {output_video_path}") + + cmd = [ + 'ffmpeg', '-y', + '-i', str(in_p), + '-vf', vf, + '-c:v', 'libx264', '-crf', '18', '-preset', 'medium', '-pix_fmt', 'yuv420p', + '-c:a', 'copy', + str(output_video_path) + ] + + res = subprocess.run(cmd, capture_output=True, text=True) + if res.returncode != 0: + print(f"❌ Error burning subtitles: {res.stderr.strip()}", file=sys.stderr) + return False + + size_mb = os.path.getsize(output_video_path) / (1024 * 1024) + print(f"✅ Subtitles burned successfully: {output_video_path} ({size_mb:.2f} MB)") + return True + + +def main(): + parser = argparse.ArgumentParser(description="FlowKit Subtitle (.srt / .vtt) Generator & Hardsub Burner") + parser.add_argument("--video-id", help="FlowKit Video ID to fetch scenes via API") + parser.add_argument("--project-dir", help="Project output directory containing project metadata or scenes") + parser.add_argument("--output", help="Output path (without extension or .srt)") + parser.add_argument("--buffer", type=float, default=0.5, help="Audio tail buffer in seconds") + parser.add_argument("--api-url", default="http://127.0.0.1:8100", help="FlowKit base URL") + parser.add_argument("--burn-subtitles", "--burn", action="store_true", help="Burn subtitles directly into video") + parser.add_argument("--input-video", help="Input video file to burn subtitles into") + parser.add_argument("--output-video", help="Output path for video with burned subtitles") + parser.add_argument("--style", choices=list(SUBTITLE_STYLES.keys()), default="cinematic_gold", help="Visual subtitle style") + + args = parser.parse_args() + + if not args.video_id and not args.project_dir and not args.input_video: + print("Error: Either --video-id, --project-dir, or --input-video must be specified.", file=sys.stderr) + sys.exit(1) + + scenes = [] + output_base = None + + if args.video_id: + scenes = fetch_scenes_api(args.video_id, base_url=args.api_url) + if not scenes: + print(f"No scenes found for video_id {args.video_id}", file=sys.stderr) + sys.exit(1) + if args.output: + output_base = Path(args.output) + else: + output_base = Path(f"output/subtitles_{args.video_id[:8]}") + + elif args.project_dir: + proj_dir = Path(args.project_dir) + scenes_json = proj_dir / "scenes.json" + if not scenes_json.exists(): + scenes_json = proj_dir / "meta.json" + + if scenes_json.exists(): + with open(scenes_json, "r", encoding="utf-8") as f: + data = json.load(f) + scenes = data if isinstance(data, list) else data.get("scenes", []) + + if not scenes: + print(f"Could not load scenes from {proj_dir}", file=sys.stderr) + sys.exit(1) + + output_base = Path(args.output) if args.output else proj_dir / f"{proj_dir.name}_subtitles" + + srt_path = None + if scenes and output_base: + output_base.parent.mkdir(parents=True, exist_ok=True) + srt_path, _ = generate_subtitles_from_scenes(scenes, output_base, buffer_sec=args.buffer) + elif args.output and Path(args.output).exists() and Path(args.output).suffix == ".srt": + srt_path = Path(args.output) + + # If burn requested + if args.burn_subtitles: + in_vid = args.input_video + if not in_vid and args.project_dir: + proj_p = Path(args.project_dir) + # Find candidate master video + candidates = list(proj_p.glob("*CINEMATIC_MASTER.mp4")) + list(proj_p.glob("*final.mp4")) + if candidates: + in_vid = str(candidates[0]) + + if not in_vid: + print("Error: --burn-subtitles requires --input-video or an existing master video in --project-dir", file=sys.stderr) + sys.exit(1) + + if not srt_path: + print("Error: No SRT subtitle file found to burn.", file=sys.stderr) + sys.exit(1) + + ok = burn_subtitles_to_video(in_vid, srt_path, output_video_path=args.output_video, style=args.style) + if not ok: + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/scripts/series_manifest.py b/scripts/series_manifest.py new file mode 100644 index 000000000..69f1f8aed --- /dev/null +++ b/scripts/series_manifest.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python3 +""" +FlowKit — Batch Episode Series Manifest Manager +Manages per-project series manifests (`output//series_manifest.json`). + +Features: +1. Per-Project Manifest Architecture: Each project stores its own `series_manifest.json` + directly inside `output//series_manifest.json`. +2. Automatic Synchronization: Automatically generated and kept in sync with FlowKit backend. +3. `sync` / `export`: Generates or pulls the latest manifest from FlowKit API into `output//series_manifest.json`. +4. `show`: Renders an overview table of characters, locations, and episode progress. +5. `bootstrap`: Creates a new chapter in FlowKit API reusing pre-existing shared entity UUIDs. + +Usage: + python scripts/series_manifest.py sync --project-id + python scripts/series_manifest.py show --project-dir output/hong_nhat_thang_long + python scripts/series_manifest.py bootstrap --project-dir output/hong_nhat_thang_long --episode 6 --title "Chương VI: Huyết Nguyệt" +""" + +import argparse +import json +import os +import sys +import urllib.request +from pathlib import Path + + +def api_request(url, method="GET", payload=None): + """Perform JSON HTTP request against FlowKit API.""" + data = None + headers = {"User-Agent": "FlowKit-SeriesManifest"} + if payload is not None: + data = json.dumps(payload).encode("utf-8") + headers["Content-Type"] = "application/json" + + req = urllib.request.Request(url, data=data, headers=headers, method=method) + try: + with urllib.request.urlopen(req, timeout=15) as resp: + content = resp.read().decode("utf-8") + return json.loads(content) if content else {} + except urllib.error.HTTPError as e: + err_msg = e.read().decode("utf-8") if e.fp else str(e) + print(f"API Error ({e.code}) on {url}: {err_msg}", file=sys.stderr) + return None + except Exception as e: + print(f"Connection Error on {url}: {e}", file=sys.stderr) + return None + + +def resolve_manifest_path(project_dir=None, project_id=None, manifest=None, base_url="http://127.0.0.1:8100"): + """Resolve the path to the per-project series_manifest.json.""" + if manifest: + return Path(manifest) + + if project_dir: + p_dir = Path(project_dir) + return p_dir / "series_manifest.json" + + if project_id: + # Fetch output-dir from API + res = api_request(f"{base_url}/api/projects/{project_id}/output-dir") + if res and "path" in res: + return Path(res["path"]) / "series_manifest.json" + + # Default fallback: check common project directory + candidates = list(Path("output").glob("*/series_manifest.json")) + if candidates: + return candidates[0] + + return Path("output/default/series_manifest.json") + + +def sync_from_project_api(project_id, base_url="http://127.0.0.1:8100"): + """Trigger API to auto-generate and return per-project series_manifest.json.""" + print(f"🔄 Syncing series manifest from API for project {project_id}...") + manifest_data = api_request(f"{base_url}/api/projects/{project_id}/manifest") + if not manifest_data: + print(f"❌ Failed to sync manifest for project {project_id}", file=sys.stderr) + return False + + slug = manifest_data.get("slug", "project") + target_path = Path(f"output/{slug}/series_manifest.json") + print(f"✅ Series manifest automatically synced and saved to: {target_path}") + print(f" Title: {manifest_data.get('series_title')}") + print(f" Characters: {len(manifest_data.get('shared_entities', {}).get('characters', []))}") + print(f" Locations: {len(manifest_data.get('shared_entities', {}).get('locations', []))}") + print(f" Episodes: {len(manifest_data.get('episodes', []))}") + return True + + +def show_manifest(manifest_path): + """Print an overview of the series manifest.""" + m_path = Path(manifest_path) + if not m_path.exists(): + print(f"❌ Manifest not found at: {manifest_path}", file=sys.stderr) + return False + + data = json.loads(m_path.read_text(encoding="utf-8")) + print("\n=======================================================") + print(f"📚 PER-PROJECT SERIES MANIFEST: {data.get('series_title')}") + print(f"Location: {m_path}") + print(f"Slug: {data.get('slug')}") + print(f"Material: {data.get('material')}") + print(f"Orientation: {data.get('orientation')}") + print(f"Default TTS: {data.get('default_voice')}") + print("=======================================================\n") + + chars = data.get("shared_entities", {}).get("characters", []) + print(f"🎭 Shared Characters ({len(chars)}):") + for c in chars: + m_id = c.get("media_id", "NO MEDIA ID") + print(f" • {c.get('name'):<22} | UUID: {m_id}") + + locs = data.get("shared_entities", {}).get("locations", []) + print(f"\n🏛️ Shared Locations ({len(locs)}):") + for l in locs: + m_id = l.get("media_id", "NO MEDIA ID") + print(f" • {l.get('name'):<25} | UUID: {m_id}") + + episodes = data.get("episodes", []) + print(f"\n🎬 Episode Roadmap ({len(episodes)} episodes):") + for ep in episodes: + num = ep.get("episode", "?") + title = ep.get("title", "") + status = ep.get("status", "PLANNING") + vid_id = ep.get("video_id", "N/A")[:8] + print(f" [{status:<10}] Ep {num:<2}: {title:<35} (VID: {vid_id})") + + print("=======================================================\n") + return True + + +def bootstrap_episode(manifest_path, episode_num, episode_title, base_url="http://127.0.0.1:8100"): + """Create a new chapter project in FlowKit with all shared entities pre-linked.""" + m_path = Path(manifest_path) + if not m_path.exists(): + print(f"❌ Manifest not found: {manifest_path}", file=sys.stderr) + return False + + data = json.loads(m_path.read_text(encoding="utf-8")) + series_title = data.get("series_title", "Series") + material = data.get("material", "realistic") + + project_name = f"{series_title} — Ep {episode_num}: {episode_title}" + story_summary = f"Episode {episode_num} of {series_title}. {data.get('story_bible', '')}" + + all_entities = [] + shared = data.get("shared_entities", {}) + for cat in ["characters", "locations", "key_props"]: + for item in shared.get(cat, []): + all_entities.append({ + "name": item.get("name"), + "description": item.get("description"), + "entity_type": item.get("entity_type", "character"), + "image_prompt": item.get("image_prompt"), + "media_id": item.get("media_id") # Reuses existing UUID! + }) + + payload = { + "name": project_name, + "story": story_summary, + "material": material, + "entities": all_entities + } + + print(f"\n🚀 Bootstrapping new episode project via API:") + print(f" Name: {project_name}") + print(f" Reusing {len(all_entities)} shared entity references...") + + res = api_request(f"{base_url}/api/projects", method="POST", payload=payload) + if not res or "id" not in res: + print("Failed to create project in FlowKit API", file=sys.stderr) + return False + + new_pid = res["id"] + print(f"✅ Episode project created successfully!") + print(f" Project ID: {new_pid}") + print(f" Pre-linked entities: {len(res.get('characters', []))}") + + # Auto-initialize output directory and project manifest + api_request(f"{base_url}/api/projects/{new_pid}/output-dir") + + print(f"\nNext Steps:") + print(f" 1. Create video: POST /api/videos (project_id={new_pid})") + print(f" 2. Create scenes: POST /api/scenes (using character_names)") + print(f" 3. Skip ref generation! All shared entities already have media_ids.") + return True + + +def main(): + parser = argparse.ArgumentParser(description="FlowKit Per-Project Series Manifest Manager") + subparsers = parser.add_subparsers(dest="command", required=True) + + # sync + p_sync = subparsers.add_parser("sync", help="Auto-sync series_manifest.json from FlowKit API") + p_sync.add_argument("--project-id", required=True, help="FlowKit project ID to sync") + p_sync.add_argument("--api-url", default="http://127.0.0.1:8100", help="FlowKit base URL") + + # show + p_show = subparsers.add_parser("show", help="Display manifest summary") + p_show.add_argument("--project-dir", help="Project directory (e.g. output/hong_nhat_thang_long)") + p_show.add_argument("--project-id", help="Project ID") + p_show.add_argument("--manifest", help="Direct path to series_manifest.json") + p_show.add_argument("--api-url", default="http://127.0.0.1:8100", help="FlowKit base URL") + + # bootstrap + p_boot = subparsers.add_parser("bootstrap", help="Create new episode project reusing shared entities") + p_boot.add_argument("--project-dir", help="Source project directory (e.g. output/hong_nhat_thang_long)") + p_boot.add_argument("--manifest", help="Direct path to series_manifest.json") + p_boot.add_argument("--episode", type=int, required=True, help="Episode number (e.g. 6)") + p_boot.add_argument("--title", required=True, help="Episode title") + p_boot.add_argument("--api-url", default="http://127.0.0.1:8100", help="FlowKit base URL") + + args = parser.parse_args() + + if args.command == "sync": + ok = sync_from_project_api(args.project_id, base_url=args.api_url) + sys.exit(0 if ok else 1) + elif args.command == "show": + m_path = resolve_manifest_path(project_dir=args.project_dir, project_id=args.project_id, manifest=args.manifest, base_url=args.api_url) + ok = show_manifest(m_path) + sys.exit(0 if ok else 1) + elif args.command == "bootstrap": + m_path = resolve_manifest_path(project_dir=args.project_dir, manifest=args.manifest, base_url=args.api_url) + ok = bootstrap_episode(m_path, args.episode, args.title, base_url=args.api_url) + sys.exit(0 if ok else 1) + + +if __name__ == '__main__': + main() diff --git a/scripts/sfx_layering.py b/scripts/sfx_layering.py new file mode 100644 index 000000000..bd111c965 --- /dev/null +++ b/scripts/sfx_layering.py @@ -0,0 +1,262 @@ +#!/usr/bin/env python3 +""" +FlowKit — Audio SFX & Foley Layering Engine +Analyzes scene actions, video prompts, and descriptions to procedurally synthesize +and mix appropriate sound effects (metal clashing, underground rumbling, impacts, sirens, heartbeat). + +Features: +1. Zero-dependency procedural audio synthesis using FFmpeg lavfi filters. +2. Local asset override: Checks `assets/sfx//` for user-provided studio WAV samples. +3. Sub-clip timeline synchronization (detects 0-3s, 3-6s, 6-8s action triggers). +4. Audio mastering with dynamic limiting and ducking to preserve narrator intelligibility. + +Usage: + python scripts/sfx_layering.py --input-video input.mp4 --prompt "Tactical knife thrust against concrete" --output output_sfx.mp4 + python scripts/sfx_layering.py --video-id --scene-id +""" + +import argparse +import json +import os +import re +import subprocess +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +ASSETS_SFX_DIR = ROOT / "assets" / "sfx" + +# Action sound design mapping +KEYWORD_SFX_MAP = { + "metal_clash": { + "keywords": ["knife", "blade", "sword", "dao", "kiếm", "chém", "kim loại", "clash", "steel", "vũ khí"], + "desc": "Metallic blade impact / sword clash", + "synth": "aevalsrc=sin(2*PI*1200*t)*exp(-12*t)+sin(2*PI*2400*t)*exp(-16*t):d=0.8:s=48000,volume=1.8" + }, + "heavy_impact": { + "keywords": ["strike", "slam", "punch", "ngã", "đấm", "va chạm", "thud", "gục", "va đập", "impact", "knock"], + "desc": "Low-end punch / physical blunt impact", + "synth": "aevalsrc=sin(2*PI*65*t)*exp(-7*t)+0.4*sin(2*PI*130*t)*exp(-10*t):d=1.0:s=48000,volume=2.5" + }, + "explosion_blast": { + "keywords": ["explosion", "blast", "nổ", "bomb", "bom", "lựu đạn", "shockwave", "sóng xung kích", "detonate"], + "desc": "Deep detonation / explosion burst", + "synth": "anoisesrc=d=2.5:c=brown:r=48000:a=0.8,lowpass=f=140,volume=3.0,afade=t=out:st=1.0:d=1.5" + }, + "underground_drone": { + "keywords": ["tầng hầm", "b3", "cống ngầm", "underground", "tunnel", "hầm", "bóng tối", "mễ trì"], + "desc": "Subterranean ambient drone / 45Hz room tone", + "synth": "anoisesrc=d=8.0:c=brown:r=48000:a=0.25,lowpass=f=90,volume=1.4" + }, + "alarm_siren": { + "keywords": ["báo động", "siren", "alarm", "klaxon", "còi báo", "nguy hiểm", "emergency"], + "desc": "Modulated tactical warning siren", + "synth": "aevalsrc=sin(2*PI*(750+200*sin(2*PI*1.5*t))*t):d=4.0:s=48000,volume=0.8" + }, + "heartbeat_tension": { + "keywords": ["tim đập", "nghẹt thở", "tension", "gasping", "thở dốc", "lo sợ", "heartbeat", "hồi hộp"], + "desc": "60 BPM physiological heartbeat pulse", + "synth": "aevalsrc=sin(2*PI*55*t)*exp(-8*mod(t\\,1.0)):d=6.0:s=48000,lowpass=f=120,volume=2.5" + }, + "fire_crackle": { + "keywords": ["cháy", "lửa", "burning", "flames", "hỏa hoạn", "rực lửa", "tàn lửa", "embers"], + "desc": "Subtle acoustic fire crackle", + "synth": "anoisesrc=d=8.0:c=pink:r=48000:a=0.2,bandpass=f=2500:w=1200,volume=0.6" + } +} + + +def detect_sfx_events(text): + """Scan text for sound design triggers and estimate timing.""" + text_lower = text.lower() + events = [] + + # Detect subclip timing blocks if present: 0-3s, 3-6s, 6-8s + segments = [ + ("0-3s", 0.0, 3.0, 1.0), + ("3-6s", 3.0, 6.0, 3.8), + ("6-8s", 6.0, 8.0, 6.2), + ] + + found_in_segments = False + for seg_label, start_s, end_s, default_t in segments: + m = re.search(rf'{seg_label}:?\s*([^.\n]+)', text_lower) + if m: + found_in_segments = True + seg_text = m.group(1) + for category, data in KEYWORD_SFX_MAP.items(): + if any(kw in seg_text for kw in data["keywords"]): + events.append({ + "category": category, + "time_offset": default_t, + "desc": data["desc"], + "source": f"Segment {seg_label}" + }) + + # If no segmented prompt, scan whole text + if not found_in_segments: + for category, data in KEYWORD_SFX_MAP.items(): + if any(kw in text_lower for kw in data["keywords"]): + events.append({ + "category": category, + "time_offset": 1.5, + "desc": data["desc"], + "source": "Full text keyword" + }) + + return events + + +def synthesize_sfx_track(events, total_duration, output_wav_path): + """Synthesize and mix an audio track containing all detected SFX events.""" + os.makedirs(os.path.dirname(os.path.abspath(output_wav_path)), exist_ok=True) + + if not events: + # Generate silent track + cmd = [ + 'ffmpeg', '-y', + '-f', 'lavfi', '-t', str(total_duration), + '-i', 'anullsrc=r=48000:cl=stereo', + '-c:a', 'pcm_s16le', + str(output_wav_path) + ] + subprocess.run(cmd, capture_output=True, text=True) + return True + + inputs = [] + filter_chains = [] + mix_labels = [] + + # 1. Base silence canvas + inputs.extend(['-f', 'lavfi', '-t', str(total_duration), '-i', 'anullsrc=r=48000:cl=stereo']) + mix_labels.append("[0:a]") + + for idx, ev in enumerate(events, 1): + cat = ev["category"] + delay_ms = int(ev["time_offset"] * 1000) + sfx_config = KEYWORD_SFX_MAP[cat] + + # Check local sample override + local_sample = None + if ASSETS_SFX_DIR.exists(): + cat_dir = ASSETS_SFX_DIR / cat + if cat_dir.exists(): + samples = list(cat_dir.glob("*.wav")) + list(cat_dir.glob("*.mp3")) + if samples: + local_sample = samples[0] + + if local_sample: + inputs.extend(['-i', str(local_sample)]) + filter_chains.append(f"[{idx}:a]adelay={delay_ms}|{delay_ms},volume=0.9[sfx{idx}]") + else: + synth_expr = sfx_config["synth"] + inputs.extend(['-f', 'lavfi', '-i', synth_expr]) + filter_chains.append(f"[{idx}:a]adelay={delay_ms}|{delay_ms}[sfx{idx}]") + + mix_labels.append(f"[sfx{idx}]") + + num_inputs = len(mix_labels) + all_inputs_str = "".join(mix_labels) + filter_complex = ";".join(filter_chains) + if filter_complex: + filter_complex += f";{all_inputs_str}amix=inputs={num_inputs}:duration=first:dropout_transition=2,alimiter=limit=0.95[aout]" + else: + filter_complex = f"{all_inputs_str}amix=inputs={num_inputs}:duration=first[aout]" + + cmd = [ + 'ffmpeg', '-y', + *inputs, + '-filter_complex', filter_complex, + '-map', '[aout]', + '-c:a', 'pcm_s16le', + '-t', str(total_duration), + str(output_wav_path) + ] + res = subprocess.run(cmd, capture_output=True, text=True) + if res.returncode != 0: + print(f"Error synthesizing SFX track: {res.stderr.strip()}", file=sys.stderr) + return False + return True + + +def apply_sfx_to_video(input_video_path, prompt_text, output_video_path=None, sfx_volume=0.6): + """Extract prompt cues, synthesize SFX, and mix into video audio.""" + in_p = Path(input_video_path) + if not in_p.exists(): + print(f"Input video not found: {input_video_path}", file=sys.stderr) + return False + + if not output_video_path: + output_video_path = in_p.parent / f"{in_p.stem}_sfx.mp4" + else: + output_video_path = Path(output_video_path) + + # Get duration + cmd_dur = ['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', str(in_p)] + dur_res = subprocess.run(cmd_dur, capture_output=True, text=True) + try: + dur = float(dur_res.stdout.strip()) + except Exception: + dur = 8.0 + + events = detect_sfx_events(prompt_text) + print(f"\n🎧 Sound Design Analysis for: {in_p.name}") + print(f" Duration: {dur:.2f}s") + print(f" Detected SFX Cues: {len(events)}") + for ev in events: + print(f" - [{ev['time_offset']:.1f}s] {ev['category']}: {ev['desc']} ({ev['source']})") + + temp_sfx_wav = in_p.parent / f"temp_sfx_{in_p.stem}.wav" + if not synthesize_sfx_track(events, dur, temp_sfx_wav): + return False + + # Check if input video has an audio stream + cmd_has_audio = ['ffprobe', '-v', 'error', '-select_streams', 'a', '-show_entries', 'stream=codec_type', '-of', 'default=noprint_wrappers=1:nokey=1', str(in_p)] + has_audio = bool(subprocess.run(cmd_has_audio, capture_output=True, text=True).stdout.strip()) + + if has_audio: + filter_complex = f"[0:a]volume=1.0[orig];[1:a]volume={sfx_volume}[sfx];[orig][sfx]amix=inputs=2:duration=first[aout]" + map_audio = '[aout]' + else: + filter_complex = f"[1:a]volume={sfx_volume}[aout]" + map_audio = '[aout]' + + cmd_mix = [ + 'ffmpeg', '-y', + '-i', str(in_p), + '-i', str(temp_sfx_wav), + '-filter_complex', filter_complex, + '-map', '0:v', + '-map', map_audio, + '-c:v', 'copy', + '-c:a', 'aac', '-b:a', '192k', '-ar', '48000', + str(output_video_path) + ] + res_mix = subprocess.run(cmd_mix, capture_output=True, text=True) + + # Cleanup temp wav + if temp_sfx_wav.exists(): + temp_sfx_wav.unlink() + + if res_mix.returncode != 0: + print(f"Error mixing SFX with video: {res_mix.stderr.strip()}", file=sys.stderr) + return False + + print(f"✅ Video with Foley/SFX generated: {output_video_path}") + return True + + +def main(): + parser = argparse.ArgumentParser(description="FlowKit Audio SFX & Foley Layering Engine") + parser.add_argument("--input-video", required=True, help="Path to input scene or chapter video") + parser.add_argument("--prompt", required=True, help="Scene prompt or action description to extract sound cues") + parser.add_argument("--output", help="Output path for final video with SFX") + parser.add_argument("--volume", type=float, default=0.6, help="SFX mix volume relative to main audio (default: 0.6)") + + args = parser.parse_args() + ok = apply_sfx_to_video(args.input_video, args.prompt, args.output, sfx_volume=args.volume) + sys.exit(0 if ok else 1) + + +if __name__ == '__main__': + main() diff --git a/scripts/sync_skills.py b/scripts/sync_skills.py new file mode 100644 index 000000000..e32b94af1 --- /dev/null +++ b/scripts/sync_skills.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +""" +Sync skills from skills/fk-*.md to: +1. .agents/skills/fk-/SKILL.md (for Antigravity IDE) +2. .claude/commands/fk-.md (for Claude Code) +3. AGENTS.md (for Codex CLI) +""" + +import re +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +SKILLS_DIR = ROOT / "skills" +AGENTS_SKILLS_DIR = ROOT / ".agents" / "skills" + +def discover_skills(): + skills = [] + for path in sorted(SKILLS_DIR.glob("fk-*.md")): + name = path.stem[len("fk-"):] + content = path.read_text(encoding="utf-8") + + # Check description + desc = "" + for line in content.splitlines(): + line = line.strip() + if line and not line.startswith("---"): + desc = re.sub(r'^[#\s\-*]+', '', line).strip() + break + if not desc: + desc = f"{name} workflow skill" + + skills.append({"name": name, "description": desc, "path": path, "content": content}) + return skills + +def sync_antigravity(skills): + AGENTS_SKILLS_DIR.mkdir(parents=True, exist_ok=True) + count = 0 + for s in skills: + name = s["name"] + skill_id = f"fk-{name}" + desc = s["description"].replace("'", "''").replace("\n", " ").strip() + content = s["content"] + + # Strip existing frontmatter if any + if content.startswith("---"): + parts = content.split("---", 2) + if len(parts) >= 3: + body = parts[2].lstrip() + else: + body = content + else: + body = content + + dest_dir = AGENTS_SKILLS_DIR / skill_id + dest_dir.mkdir(parents=True, exist_ok=True) + dest_file = dest_dir / "SKILL.md" + + skill_md = ( + f"---\n" + f"name: {skill_id}\n" + f"description: '{desc}'\n" + f"---\n\n" + f"{body}\n" + ) + dest_file.write_text(skill_md, encoding="utf-8") + count += 1 + print(f" [OK] .agents/skills/{skill_id}/SKILL.md") + print(f"Synchronized {count} skills to Antigravity (.agents/skills/)") + return count + +if __name__ == "__main__": + skills = discover_skills() + print(f"Discovered {len(skills)} skills in skills/") + sync_antigravity(skills) diff --git a/scripts/validate_skills.py b/scripts/validate_skills.py new file mode 100644 index 000000000..2b1544562 --- /dev/null +++ b/scripts/validate_skills.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +""" +FlowKit — Skills Validator & Quality Assurance Linter +Validates the entire skill suite to enforce: +1. 100% unified English language purity across all instructions. +2. Heading and metadata consistency. +3. Cross-reference markdown link validity. +4. Sync parity between skills/, .agents/skills/, and .claude/commands/. +""" + +import re +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +SKILLS_DIR = ROOT / "skills" +AGENTS_SKILLS_DIR = ROOT / ".agents" / "skills" +CLAUDE_COMMANDS_DIR = ROOT / ".claude" / "commands" + +# Vietnamese instructional keywords that should NEVER appear as instructions +VI_INSTRUCTIONAL_PATTERN = re.compile( + r'\b(hướng dẫn|thực hiện|lưu ý|yêu cầu|bước 1|bước 2|bước 3|bước 4|bước 5|' + r'tổng quan|cách dùng|chú ý|kiểm tra|thiết lập|kịch bản|nhân vật|chuyển cảnh)\b', + re.IGNORECASE +) + + +def validate_skills(): + print("=======================================================") + print("🔍 FLOWKIT SKILLS QUALITY ASSURANCE VALIDATOR") + print("=======================================================\n") + + skill_files = sorted(SKILLS_DIR.glob("fk-*.md")) + print(f"Discovered {len(skill_files)} skill files in {SKILLS_DIR}") + + errors = [] + warnings = [] + + for path in skill_files: + name = path.name + content = path.read_text(encoding="utf-8") + lines = content.splitlines() + + # 1. Heading check + if not lines or not (lines[0].startswith("#") or (len(lines) > 1 and lines[1].startswith("#")) or lines[0].strip()): + warnings.append(f"[{name}] Missing top header or description.") + + # 2. Check for mixed Vietnamese instruction text (ignoring explicit quotes/code blocks containing data) + in_code_block = False + for line_idx, line in enumerate(lines, 1): + if line.strip().startswith("```"): + in_code_block = not in_code_block + continue + + # Skip code blocks and lines that are explicit sample quotes or dialogue examples + if in_code_block or '"' in line or '“' in line or '`' in line: + continue + + vi_match = VI_INSTRUCTIONAL_PATTERN.search(line) + if vi_match: + errors.append(f"[{name}:L{line_idx}] Mixed Vietnamese keyword in instruction: '{vi_match.group(0)}'") + + # 3. Check markdown links + links = re.findall(r'\[([^\]]+)\]\(([^)]+)\)', content) + for link_text, link_target in links: + if link_target.startswith("http") or link_target.startswith("#") or link_target.startswith("mailto:"): + continue + # Strip anchors + target_file = link_target.split("#")[0] + if target_file: + target_path = (SKILLS_DIR / target_file).resolve() + if not target_path.exists(): + # check relative to project root + if not (ROOT / target_file).resolve().exists(): + warnings.append(f"[{name}] Broken markdown link: '{link_target}'") + + # 4. Check sync parity + antigravity_skills = list(AGENTS_SKILLS_DIR.glob("fk-*/SKILL.md")) if AGENTS_SKILLS_DIR.exists() else [] + claude_commands = list(CLAUDE_COMMANDS_DIR.glob("fk-*.md")) if CLAUDE_COMMANDS_DIR.exists() else [] + + print(f"\nTool Sync Parity Check:") + print(f" skills/ Source: {len(skill_files)}") + print(f" .agents/skills/ (AGY): {len(antigravity_skills)}") + print(f" .claude/commands/ (Claude): {len(claude_commands)}") + + if len(skill_files) != len(antigravity_skills): + errors.append(f"Antigravity sync mismatch: {len(skill_files)} vs {len(antigravity_skills)}. Run 'python setup.py sync'.") + + if len(skill_files) != len(claude_commands): + errors.append(f"Claude sync mismatch: {len(skill_files)} vs {len(claude_commands)}. Run 'python setup.py sync'.") + + print("\n-------------------------------------------------------") + if warnings: + print(f"⚠️ {len(warnings)} Warnings:") + for w in warnings: + print(f" - {w}") + else: + print("✅ No warnings detected.") + + if errors: + print(f"\n❌ {len(errors)} Errors Found:") + for e in errors: + print(f" - {e}") + print("\nValidator FAILED.") + return False + else: + print("\n✅ All 41 skills passed quality validation! 100% English compliant.") + return True + + +if __name__ == '__main__': + ok = validate_skills() + sys.exit(0 if ok else 1) diff --git a/setup.py b/setup.py index 15ea35074..08dd54ecc 100644 --- a/setup.py +++ b/setup.py @@ -35,6 +35,7 @@ SKILLS_DIR = ROOT / "skills" CLAUDE_COMMANDS_DIR = ROOT / ".claude" / "commands" AGENTS_MD = ROOT / "AGENTS.md" +ANTIGRAVITY_SKILLS_DIR = ROOT / ".agents" / "skills" STATE_FILE = ROOT / ".fk-setup.json" # Nothing generates these any more; `clean` still removes them so an install @@ -84,6 +85,46 @@ def generate_claude(skills): return count +def generate_antigravity(skills): + """Create .agents/skills/fk-/SKILL.md for Antigravity IDE.""" + ANTIGRAVITY_SKILLS_DIR.mkdir(parents=True, exist_ok=True) + count = 0 + for skill in skills: + name = skill["name"] + skill_id = f"fk-{name}" + desc = skill["description"] + src = Path(skill["path"]) + content = src.read_text(encoding="utf-8") + + # Strip existing frontmatter if any + if content.startswith("---"): + parts = content.split("---", 2) + if len(parts) >= 3: + body = parts[2].lstrip() + else: + body = content + else: + body = content + + dest_dir = ANTIGRAVITY_SKILLS_DIR / skill_id + dest_dir.mkdir(parents=True, exist_ok=True) + dest = dest_dir / "SKILL.md" + + escaped_desc = desc.replace("'", "''").replace("\n", " ").strip() + skill_md = ( + f"---\n" + f"name: {skill_id}\n" + f"description: '{escaped_desc}'\n" + f"---\n\n" + f"{body}\n" + ) + dest.write_text(skill_md, encoding="utf-8") + count += 1 + print(f"Generated {count} Antigravity skills in .agents/skills/") + return count + + + ## ── Inline content for AGENTS.md ── # Inlined so a non-Claude tool sees the rules directly instead of following a # "read CLAUDE.md" pointer. @@ -221,6 +262,7 @@ def load_state(): TOOLS = { "claude": generate_claude, "codex": generate_codex, + "antigravity": generate_antigravity, } @@ -241,20 +283,18 @@ def do_interactive(skills): """Interactive mode: prompt user to pick tools.""" print("\nFlow Kit — AI Tool Setup\n") print("Which AI tool do you drive this project from?") - print(" [1] Claude Code (.claude/commands/)") - print(" [2] Codex CLI (AGENTS.md)") - print(" [3] Both") - print() - print(" (agy / Antigravity reads none of these — it is configured as a") - print(" video-review provider instead, via /fk-change-provider.)") + print(" [1] Claude Code (.claude/commands/)") + print(" [2] Codex CLI (AGENTS.md)") + print(" [3] Antigravity IDE (.agents/skills/)") + print(" [4] All tools") print() - raw = input("Select (comma-separated, e.g. 1,2): ").strip() + raw = input("Select (comma-separated, e.g. 1,2,3): ").strip() if not raw: print("No selection made. Exiting.") return - mapping = {"1": "claude", "2": "codex", "3": "all"} + mapping = {"1": "claude", "2": "codex", "3": "antigravity", "4": "all"} choices = [c.strip() for c in raw.split(",")] tools = [] @@ -315,6 +355,15 @@ def do_clean(): f.unlink() removed.append(str(f)) + # Antigravity skills + if ANTIGRAVITY_SKILLS_DIR.exists(): + for d in ANTIGRAVITY_SKILLS_DIR.glob("fk-*"): + if d.is_dir(): + for f in d.glob("*"): + f.unlink() + d.rmdir() + removed.append(str(d)) + # Whatever the retired Gemini target left behind. Removed here even # though nothing writes it any more — an install from before v1.3.1 has # these files, and `clean` is the only thing that will ever take them away. diff --git a/skills/README.md b/skills/README.md index 257a4df24..5da9f8ae5 100644 --- a/skills/README.md +++ b/skills/README.md @@ -2,37 +2,76 @@ Workflow skills for AI agents and humans. Each skill is a step-by-step recipe. -## Pipeline (run in order) +## Core Production Pipeline | # | Skill | File | Description | |---|-------|------|-------------| -| 1 | `fk-create-project` | [fk-create-project.md](fk-create-project.md) | Create project + entities + video + scenes | -| 2 | `fk-gen-refs` | [fk-gen-refs.md](fk-gen-refs.md) | Generate reference images for all entities | -| 3 | `fk-gen-images` | [fk-gen-images.md](fk-gen-images.md) | Generate scene images with character refs | -| 4 | `fk-gen-videos` | [fk-gen-videos.md](fk-gen-videos.md) | Generate videos from scene images | -| 5 | `fk-concat` | [fk-concat.md](fk-concat.md) | Download + merge all scene videos | +| 0 | `fk-research` | [fk-research.md](fk-research.md) | Fact-check events and research historical/story lore before scripting | +| 1 | `fk-scriptwriter` | [fk-scriptwriter.md](fk-scriptwriter.md) | The Ultimate AI Screenplay Bible (10 Archetypes, 8s Arcs, Quality Gates) | +| 2 | `fk-create-project` | [fk-create-project.md](fk-create-project.md) | Create project + entities + video + scenes | +| 3 | `fk-gen-refs` | [fk-gen-refs.md](fk-gen-refs.md) | Generate reference images for all entities | +| 4 | `fk-gen-images` | [fk-gen-images.md](fk-gen-images.md) | Generate scene images with character refs bound | +| 5 | `fk-gen-videos` | [fk-gen-videos.md](fk-gen-videos.md) | Generate videos from scene images via Veo 3 / Flow | +| 6 | `fk-review-video` | [fk-review-video.md](fk-review-video.md) | AI Vision quality check with prompt healing loop (pass score >= 7.5) | +| 7 | `fk-concat-fit-narrator` | [fk-concat-fit-narrator.md](fk-concat-fit-narrator.md) | Trim scene videos to TTS duration, burn hardsubs, assemble multi-chapter film | +| 8 | `fk-concat` | [fk-concat.md](fk-concat.md) | Download + merge all scene videos (basic stream concat) | + +## Cinematography, Direction & Choreography -## Advanced Video +| Skill | File | Description | +|-------|------|-------------| +| `fk-camera-guide` | [fk-camera-guide.md](fk-camera-guide.md) | Lens packages, Hollywood lighting & color grading matrix, 180° rule | +| `fk-action-choreography` | [fk-action-choreography.md](fk-action-choreography.md) | Physics-safe combat direction & 3-phase motion invariants for Veo 3 | +| `fk-cinematic-transitions` | [fk-cinematic-transitions.md](fk-cinematic-transitions.md) | Chapter bumpers (Ken Burns + sub-bass drone), match cuts, J-cut/L-cut | +| `fk-gen-chain-videos` | [fk-gen-chain-videos.md](fk-gen-chain-videos.md) | Auto start+end frame chaining for continuous transitions | +| `fk-insert-scene` | [fk-insert-scene.md](fk-insert-scene.md) | Multi-angle shots, cutaways, close-ups insertion | +| `fk-creative-mix` | [fk-creative-mix.md](fk-creative-mix.md) | Analyze story + suggest optimal combination of all cinematic techniques | + +## Character & World Consistency + +| Skill | File | Description | +|-------|------|-------------| +| `fk-character-bible` | [fk-character-bible.md](fk-character-bible.md) | Biometric anchor sheets, wardrobe state matrices & series manifest engine | +| `fk-add-material` | [fk-add-material.md](fk-add-material.md) | Image material management (realistic, 3d_pixar, anime, etc.) | +| `fk-upload-image` | [fk-upload-image.md](fk-upload-image.md) | Upload local images to Google Flow to get UUID media_ids | +| `fk-fix-uuids` | [fk-fix-uuids.md](fk-fix-uuids.md) | Repair legacy CAMS... media_ids to standard UUID format | +| `fk-refresh-urls` | [fk-refresh-urls.md](fk-refresh-urls.md) | Re-sign expired media URLs for scenes and entity reference images | + +## Audio, Voice & Sound Design | Skill | File | Description | |-------|------|-------------| -| `fk-gen-chain-videos` | [fk-gen-chain-videos.md](fk-gen-chain-videos.md) | Auto start+end frame chaining for smooth transitions | -| `fk-insert-scene` | [fk-insert-scene.md](fk-insert-scene.md) | Multi-angle shots, cutaways, close-ups | -| `fk-creative-mix` | [fk-creative-mix.md](fk-creative-mix.md) | Analyze story + suggest all techniques combined | +| `fk-sound-design` | [fk-sound-design.md](fk-sound-design.md) | 4-layer audio design, sidechain ducking (-14dB), sub-bass drone, procedural SFX | +| `fk-gen-music` | [fk-gen-music.md](fk-gen-music.md) | Generate soundtracks & orchestral scores via Suno AI | +| `fk-gen-narrator` | [fk-gen-narrator.md](fk-gen-narrator.md) | Edge-TTS neural narration with pacing punctuation & voice profiles | +| `fk-gen-tts-template` | [fk-gen-tts-template.md](fk-gen-tts-template.md) | Generate consistent voice templates for narration | +| `fk-import-voice` | [fk-import-voice.md](fk-import-voice.md) | Import existing voice recordings as templates | +| `fk-gen-text-overlays` | [fk-gen-text-overlays.md](fk-gen-text-overlays.md) | Extract dates, names, casualty statistics for on-screen text overlays | -## Reference +## Distribution, YouTube SEO & Branding | Skill | File | Description | |-------|------|-------------| -| `fk-camera-guide` | [fk-camera-guide.md](fk-camera-guide.md) | Camera angles, movements, lighting, DOF for cinematic video prompts | -| `fk-provider` | [fk-provider.md](fk-provider.md) | Media providers: choose the generation backend, run the assistant worker, troubleshoot provider jobs | +| `fk-brand-logo` | [fk-brand-logo.md](fk-brand-logo.md) | Channel intro/outro bumpers, corner watermark logo, 4K resolution badge | +| `fk-thumbnail-guide` | [fk-thumbnail-guide.md](fk-thumbnail-guide.md) | YouTube thumbnail rules, high-CTR composition & 3-second hook principles | +| `fk-thumbnail` | [fk-thumbnail.md](fk-thumbnail.md) | Generate 4 YouTube thumbnail variants with high-impact typography | +| `fk-youtube-seo` | [fk-youtube-seo.md](fk-youtube-seo.md) | Generate high-converting hook titles, 3-zone descriptions, tags & AI disclosures | +| `fk-youtube-upload` | [fk-youtube-upload.md](fk-youtube-upload.md) | Automated YouTube API video upload (Shorts & Long-form) | -## Utilities +## Operations, Monitoring & Provider Management | Skill | File | Description | |-------|------|-------------| -| `fk-status` | [fk-status.md](fk-status.md) | Full project dashboard + next action | -| `fk-fix-uuids` | [fk-fix-uuids.md](fk-fix-uuids.md) | Repair any CAMS... media_ids to UUID format | +| `fk-status` | [fk-status.md](fk-status.md) | Comprehensive project status dashboard + recommended next action | +| `fk-dashboard` | [fk-dashboard.md](fk-dashboard.md) | Terminal statusline monitor for GLA and active tasks | +| `fk-monitor` | [fk-monitor.md](fk-monitor.md) | Full pipeline queue monitor with live background polling | +| `fk-doctor` | [fk-doctor.md](fk-doctor.md) | End-to-end diagnostic suite & error taxonomy resolver | +| `fk-pipeline` | [fk-pipeline.md](fk-pipeline.md) | Autonomous full-pipeline orchestrator from research to final concat | +| `fk-provider` | [fk-provider.md](fk-provider.md) | Select and manage media generation backend (Flow vs Assistant) | +| `fk-change-provider` | [fk-change-provider.md](fk-change-provider.md) | Switch AI vision review backend (Claude, Antigravity, Codex) | +| `fk-change-model` | [fk-change-model.md](fk-change-model.md) | View and configure image and video generation model keys | +| `fk-switch-project` | [fk-switch-project.md](fk-switch-project.md) | Switch active working project context | +| `fk-review-board` | [fk-review-board.md](fk-review-board.md) | Launch visual scene review board web app | ## Cross-Tool Compatibility @@ -49,11 +88,7 @@ python setup.py clean # Remove generated configs |------|-----------------|------------------|------------| | Claude Code | `.claude/commands/fk-.md` (stubs) | `CLAUDE.md` (committed) | `/fk-` | | Codex CLI | — | `AGENTS.md` (generated) | Read `skills/fk-.md` | - -`agy` (Antigravity) is not a target here: it expands neither `.gemini/commands/*.toml` -nor `.claude/commands/*.md`, and does not auto-load `AGENTS.md`, `GEMINI.md` or -`CLAUDE.md` in print mode. It is supported as a **video-review provider** -instead — see `/fk-change-provider`. +| Antigravity IDE | `.agents/skills/fk-/SKILL.md` | Workspace Skills | `/fk-` or Skill Discovery | **Adding a new skill:** Create `skills/fk-.md`, then run `python setup.py sync`. diff --git a/skills/fk-action-choreography.md b/skills/fk-action-choreography.md new file mode 100644 index 000000000..4106d628a --- /dev/null +++ b/skills/fk-action-choreography.md @@ -0,0 +1,100 @@ +# Action Choreography — AI Cinematic Combat & Motion Direction + +Technical manual for choreographing physics-safe action sequences, duels, and epic battle dynamics optimized specifically for generative AI video models (Google Veo 3, Flow, Sora). Eliminates anatomical morphing, limb fusion, and weapon clipping. + +--- + +## 1. Physical Principles of Generative AI Video + +Unlike traditional 3D CGI or live-action stunt work, generative AI video possesses no underlying skeletal rig, collision meshes, or Newtonian physics simulation. The model predicts sequential pixel manifolds based on training probabilities. + +### High-Risk Deformation Traps: +- **360-Degree Continuous Spins:** The model fails to maintain simultaneous dorsal and ventral memory, frequently rendering a second face on the back of the head. +- **Direct Head-On Sprints Toward Camera:** Rapid focal scale expansion distorts biometric proportions and liquefies facial features. +- **Intricate Physical Grappling:** Close-contact wrestling blends skin textures, generating fused limbs, three-armed mutants, or rubbery appendages. +- **Deep Penetration Wounds (Impaling):** Triggers safety moderation filters or results in rubberized, bending weapons. + +### Strengths to Maximize: +- **Unidirectional Trajectories:** Clean linear, diagonal, or arc-based kinetic paths. +- **Environmental Momentum:** Billowing cloaks, turbulent hair, kicking dust clouds, sparks flying from steel collisions. +- **Camera-Assisted Kinetic Energy:** Dynamic tracking and push-ins synchronized to the blow to amplify visual force without complex character movement. + +--- + +## 2. The 3-Phase Motion Invariant + +Every 8-second Veo 3 video clip (yielding 7.0 seconds of pristine footage after a 1.0s head trim) must be structured into three distinct temporal phases: + +``` +[0–3s: PREPARATION & KINETIC TENSION] ──► [3–6s: KINETIC STRIKE & TRAJECTORY] ──► [6–8s: RECOIL & ANCHOR POSE] +(Stance, grip, eye lock, coiled potential) (Unidirectional release, camera assist) (Follow-through, sparks, dust settle) +``` + +### Phase 1 (0–3s) — Preparation & Kinetic Tension +- **Objective:** Establish physical balance, lower the center of gravity, lock eye contact onto the target. +- **Safe Prompt Verbs:** `lowers stance into a firm combat crouch`, `tightens white-knuckled grip on the sword hilt`, `draws heavy recurve bowstring backward smoothly to the cheekbone`. +- **Camera Dynamic:** Slow deliberate dolly-in or static locked-off shot to build coiled tension. + +### Phase 2 (3–6s) — Kinetic Strike & Spatial Trajectory +- **Objective:** Execute the primary strike along a **single distinct vector**. +- **Golden Rule:** Describe weapon trajectory and environmental impact, NEVER soft-tissue penetration. +- **Safe Prompt Verbs:** `lunges forward in a powerful diagonal downward slash`, `sweeps the iron spear across in a broad horizontal crescent arc`, `releases the arrow which streaks forward leaving an air ripple`. +- **Camera Dynamic:** Camera rapidly tracking alongside the strike to amplify velocity. + +### Phase 3 (6–8s) — Recoil, Anchor Pose & Resolution +- **Objective:** Settle into an anchor freeze-pose, absorbing recoil and displaying exertion. +- **Safe Prompt Verbs:** `skids to a firm halt kicking up dry dust`, `holds the defensive parry lock as orange sparks scatter`, `chest heaves with controlled breaths, fierce glare locked on opponent`. +- **Environmental Aftermath:** Cloaks settle, kicked-up gravel rolls to a stop, rising smoke clears. + +--- + +## 3. Physics-Safe Action Vocabulary vs. Deformation Traps + +| Combat Archetype | ❌ High-Risk Triggers (Causes Morphing) | ✅ Physics-Safe Vocabulary (Clean 100% Render) | +| :--- | :--- | :--- | +| **Swords / Blades** | `stabs sword through enemy chest, blood splatters` | `delivers a decisive diagonal downward slash, blade clashing against raised iron shield in an explosive burst of orange sparks` | +| **Spears / Polearms** | `twirls spear rapidly spinning 10 times in air` | `thrusts the heavy spear forward in an explosive straight line, then retracts immediately into a solid defensive guard` | +| **Archery / Snipers** | `rapidly shoots 10 arrows in 2 seconds` | `smoothly pulls bowstring taut to jawline, exhales, and looses a single heavy war arrow that streaks through smoke` | +| **Dodges & Evasions** | `does a backflip somersault in midair` | `ducks low beneath the sweeping blade, sidestepping swiftly to screen-left with defensive guard raised` | +| **Cavalry / Horseback** | `horse leaps directly over camera lens` | `gallops hard diagonally across the frame from mid-ground to foreground, hooves churning up wet mud` | +| **Unarmed Melee** | `grapples and rolls on the floor wrestling` | `drives a heavy iron-gauntleted punch forward, deflecting the incoming blow with a solid forearm block` | + +--- + +## 4. Master Battle Sequence Templates + +### Template 1: Melee Duel (Clashing Steel) +```text +[0-3s] Medium shot: The commander lowers his combat stance, drawing his bronze blade in a deliberate arc as hot torch embers drift past. +[3-6s] He explodes forward in a decisive diagonal slash; his blade collides violently with his opponent's raised iron buckler, discharging a brilliant shower of orange sparks. The camera rapidly dollies forward to accentuate the impact. +[6-8s] Both warriors lock blades in a rigid contest of physical will, muscles straining, breath pluming in the freezing mountain air. +Audio: Resonant clatter of striking metal, sizzle of flying sparks, heavy guttural war grunt. +Negative: subtitles, captions, watermark, text overlay, extra limbs, distorted hands. +``` + +### Template 2: Precision Archery Sequence +```text +[0-3s] Medium close-up: The archer stands resolute upon the wind-swept battlements, drawing the heavy horn bowstring back to her jawline with frozen focus amidst heavy snowfall. +[3-6s] She looses the arrow; the bowstring snaps forward with a sharp vibration, and the iron bodkin arrow streaks diagonally across the snowy sky. The camera smoothly pans alongside the arrow's flight path. +[6-8s] She lowers her bow into a ready stance, eyes tracking the distant impact beyond the palisade, her fur-lined cloak whipping violently in the gale. +Audio: Crisp snap of bowstring vibration, whistling air rush of speeding arrow, distant heavy thud into wood. +Negative: subtitles, captions, watermark, text overlay, extra fingers. +``` + +### Template 3: Armored Cavalry Charge +```text +[0-3s] Wide shot: The armored cavalry vanguard holds formation momentarily at the crest of the grassy hill, war steeds stamping restless hooves into rising morning mist. +[3-6s] The riders surge downhill simultaneously in a thunderous charge, iron lances leveled horizontally, moving diagonally from upper-left to lower-right. The camera tracks smoothly alongside the galloping horses. +[6-8s] Mud and clods of earth erupt violently beneath pounding hooves, silk battle banners fluttering furiously overhead as the charge reaches full momentum. +Audio: Massive rhythmic thunder of hundreds of galloping hooves, clanking bronze armor plates, distant war horn call. +Negative: subtitles, captions, watermark, text overlay, distorted legs. +``` + +### Template 4: Fortress Gate Siege & Shield Wall +```text +[0-3s] Low-angle shot: Soldiers brace their heavy bronze tower shields together into an unbroken wall, locking shoulders against the reinforced timber frame. +[3-6s] A volley of flaming arrows rains down from the dark sky, striking the shield wall in explosive bursts of sparks and splintering wood. The camera remains locked in a low-angle heroic perspective. +[6-8s] The soldiers hold their ground without flinching, smoke curling off the charred bronze shield faces as the commander raises his sword to signal the counter-assault. +Audio: Thundering impact of flaming arrows on metal and timber, hissing fire extinguished on wet wood, resolute soldier battle cry. +Negative: subtitles, captions, watermark, text overlay, blurry faces. +``` diff --git a/skills/fk-camera-guide.md b/skills/fk-camera-guide.md index 839211ed3..85031fb29 100644 --- a/skills/fk-camera-guide.md +++ b/skills/fk-camera-guide.md @@ -343,8 +343,46 @@ Negative: subtitles, watermark, text overlay, blurry faces. --- +## Cinema Lens Profiles & Optical Emulation + +Lenses define the soul and optical texture of the image. Rather than using generic words like "cinematic", specify the exact lens package and optical characteristics: + +| Lens Package | Prompt Keywords | Visual Signature | Ideal Genre | +| :--- | :--- | :--- | :--- | +| **Anamorphic 2.39:1** | `shot on 35mm anamorphic lens, oval bokeh, horizontal blue streak lens flares` | Ultra-widescreen field of view, elliptical bokeh, horizontal cobalt streaks. | Sci-fi, blockbuster action, panoramic battlefields. | +| **Cooke Panchro / "Cooke Look"** | `Cooke S4/i prime lens, warm organic skin tones, painterly roll-off bokeh` | Flattering organic skin warmth, painterly focus roll-off, vintage character. | Psychological drama, character close-ups, intimate dialogue. | +| **Arri Master Prime** | `Arri Master Prime lens, ultra-sharp edge-to-edge clarity, neutral high contrast` | Clinical optical resolution, zero aberration, authentic theatrical realism. | Epic warfare, detailed armor, ancient architectural majesty. | +| **Vintage Leica Summilux** | `Leica Summilux-C vintage glass, creamy soft highlights, subtle micro-contrast` | Creamy highlight bloom, delicate micro-contrast, intimate nostalgic glow. | Atmospheric night exteriors, period flashbacks, candlelight. | + +--- + +## Hollywood Color Grading & Film Stock Matrix + +Color palette establishes the emotional tone of the sequence before physical action unfolds: + +| Color Grade / Stock | Prompt Keywords | Emotional Atmosphere | Benchmark Context | +| :--- | :--- | :--- | :--- | +| **Bleach Bypass (Silver Retention)** | `bleach bypass color grade, high contrast, desaturated muted tones, gritty silver sheen` | Harsh, uncompromising, tragic, militaristic grit. | Blood-soaked combat, ruined citadels in post-siege aftermath. | +| **Teal & Orange** | `teal and orange color grade, rich amber skin tones against deep cyan shadows` | Vibrant, high kinetic energy, modern blockbuster punch. | High-speed pursuits, night ambushes with blazing torches. | +| **Kodachrome 64 Vintage** | `Kodachrome 64 aesthetic, deep saturated reds and golds, warm nostalgic film grain` | Historical reverence, nostalgic warmth, timeless prestige. | Childhood retrospectives, coronation banquets, imperial glory. | +| **Chiaroscuro Night** | `chiaroscuro lighting, deep crushing black shadows, single directional candlelight source` | Paranoia, perilous conspiracy, claustrophobic power struggle. | Palace palace coup meetings, late-night war councils. | + +--- + +## The 180-Degree Rule in AI Direction (Spatial Continuity) + +In consecutive dialogue shots between two opposing characters or armies: +- **Core Principle:** An imaginary line of action connects the two subjects. The camera **must remain strictly on one side** of this axis across consecutive cuts. +- **Eyeline Vector Matching:** + - **Character A (Close-up):** `looking screen-right towards opponent`. + - **Character B (Close-up):** `looking screen-left towards opponent`. + - *If both characters are prompted looking screen-right, the audience perceives them gazing in the same direction rather than making direct eye contact.* + +--- + ## Quality Checklist + Before submitting any video prompt, verify: - [ ] Prompt is 100–150 words, 3–6 sentences diff --git a/skills/fk-character-bible.md b/skills/fk-character-bible.md new file mode 100644 index 000000000..6507a1283 --- /dev/null +++ b/skills/fk-character-bible.md @@ -0,0 +1,124 @@ +# Character Bible & Visual Consistency — AI Film Production + +Standards and technical workflows for maintaining biometric fidelity, wardrobe coherence, signature accessories, and environmental continuity across multi-chapter AI films in Google Flow and Veo 3. + +--- + +## 1. Core Consistency Invariants + +In multi-chapter AI filmmaking (5 to 20+ episodes), the most destructive failure modes are: +1. **Facial Drift:** Subtle generational changes in jawline, eye color, facial hair, or perceived age across chapters. +2. **Wardrobe Glitching:** A character wearing battle armor spontaneously switching into court robes, or cape colors morphing between cuts. +3. **Vanishing Identifiers:** Signature scars, tattoos, family heirlooms, or eye patches disappearing between consecutive scenes. + +### The Golden Production Rule: +> **"Appearance in Reference, Action in Prompt"** +> * Detailed physical appearance (facial architecture, hairstyle, bone structure, clothing fabric, color palette) **MUST** be locked into the reference image and Entity description. +> * Scene prompts **MUST NEVER** re-describe facial anatomy. Prompts must specify **ACTION, TEMPORAL KINETICS, AND IMMEDIATE EMOTION ONLY**. + +--- + +## 2. Character Visual Anchor Sheet + +Before scripting an episode, every recurring character requires an immutable Visual Anchor Sheet saved at `.omc/research/_character_bible.md`: + +### Specification Template: +```markdown +### [ENTITY_KEY] Character Display Name (Role-Based Alias) +* **Entity Name:** Commander_Steel (Never use real public figures — Rule 15) +* **Biometric Invariants:** + - Perceived Age & Build: Male, 38 years old, athletic battle-hardened build, 6'1" stature. + - Facial Structure: Sharp square jawline, high weathered cheekbones, piercing cold amber eyes. + - Signature Identifier: Thin 3cm diagonal pale battle scar running across the left cheekbone. + - Hair & Facial Hair: Jet-black hair tightly bound in a high topknot with an antique bronze hair pin; clean-trimmed stubble along the jawline. +* **Palette Signature (Hex Codes):** + - Primary: Deep crimson blood (`#801818` / Crimson blood). + - Secondary: Charcoal carbon (`#1A1A1D` / Matte black). + - Metal: Antique unpolished bronze (`#8C6239` / Weathered bronze). +* **Signature Prop / Weapon:** + - Double-edged bronze broadsword with an engraved dragon guard and grey stingray-skin wrapped hilt. +``` + +--- + +## 3. Wardrobe State Matrix (Costume Progression by Story Arc) + +Characters cannot remain in pristine identical garments through battles, captivity, or coronation. However, wardrobe transitions must be managed through strict **Discrete States**: + +| State | State Identifier | Costume & Physical Condition | Narrative Context | Associated Entity Reference | +| :--- | :--- | :--- | :--- | :--- | +| **STATE 01** | `Normal / Court` | Raw silk ceremonial robe in indigo blue, jade hair pin, pristine posture. | Imperial audience, civilian life, covert meetings. | `Commander_Steel_Court` | +| **STATE 02** | `Battle / Armor` | Black iron scale armor, bronze dragon pauldrons, heavy crimson battle cloak. | Field command, vanguard assault, night patrol. | `Commander_Steel_Armor` | +| **STATE 03** | `Wounded / Battle-worn` | Shattered shoulder plate, scorched cloak, blood-stained linen band wrapped on forehead. | Post-siege breakout, desperate retreat, duel aftermath. | `Commander_Steel_Wounded` | +| **STATE 04** | `Coronation / Triumph` | Golden embroidered imperial vestments, ceremonial dragon crown, dignified triumph. | Victory parade, enthronement, climactic resolution. | `Commander_Steel_Triumph` | + +### Production Rules for Wardrobe Changes: +- When a character undergoes a major visual transformation, **create a distinct Entity Reference** (e.g., `Commander_Steel_Armor` vs. `Commander_Steel_Wounded`). +- Generate and verify dedicated reference images for each state (`POST /api/requests/batch` with `GENERATE_CHARACTER_IMAGE`). +- Bind the exact matching entity name into the scene's `character_names` array in `POST /api/scenes`. + +--- + +## 4. Rule 15 Compliance: Real-People Bypass + +Modern generative video models (Google Flow, Veo 3, Imagen 3) enforce strict automated safety filters that reject generation requests containing names of real public figures, historical leaders, or politicians. + +### Safe Execution Protocol: +1. **Role-Based Aliases:** + - ❌ **Reject:** `Napoleon_Bonaparte`, `George_Washington`, `Tran_Hung_Dao`. + - ✅ **Approve:** `Supreme_Commander_Grand_Marshal`, `Continental_General`, `Supreme_Field_Marshal`. +2. **Pure Anatomical Descriptions (Zero Named Identity):** + - Prompt description: *"A seasoned 13th-century military general with piercing eyes, dignified weathered facial features, high cheekbones, traditional topknot hair tied with antique bronze pin, wearing iron scale armor."* +3. **Dialogue & Narrator Isolation:** + - Formal titles and narrative lore may appear in `narrator_text` (handled via Edge-TTS audio), but **real names must NEVER enter image or video prompts**. + +--- + +## 5. Environmental & World Consistency + +Consistency applies equally to sets, citadels, terrain, and lighting: + +1. **Entity Type = `location`:** Always generate reference images in **HORIZONTAL (16:9)** orientation. +2. **Unified Lighting Signature:** + - Lock the illumination source across the scene chain (e.g., *"lit strictly by flickering orange pitch torches and distant embers, deep chiaroscuro shadows"*). +3. **Dual Entity Ingestion in Google Flow:** + - When posting scenes, include both the character and location in `character_names`: + ```json + { + "character_names": ["Commander_Steel_Armor", "Thang_Long_Grand_Palace"] + } + ``` + - Flow maps both reference media IDs into `imageInputs`, anchoring the character's facial likeness simultaneously with architectural consistency. + +--- + +## 6. Per-Project Series Manifest Engine (`scripts/series_manifest.py`) + +When managing multi-chapter epics (e.g., 5 to 20+ episodes), re-creating entities or re-generating reference images causes catastrophic visual drift. FlowKit provides an automated **Per-Project Series Manifest Engine**: + +- **Location:** Stored strictly per-project inside `output//series_manifest.json`. +- **Automatic Generation:** Automatically synthesized and synchronized by FlowKit API whenever `GET /api/projects/{pid}/output-dir` or `GET /api/projects/{pid}/manifest` is accessed. + +### Workflow: +1. **Auto-Generate & Sync from Active Project:** + ```bash + # Synchronize entities, media_ids, and episodes into output//series_manifest.json + python scripts/series_manifest.py sync --project-id + ``` + +2. **Inspect Series Manifest Overview:** + ```bash + python scripts/series_manifest.py show --project-dir output/ + ``` + +3. **Bootstrap New Episodes with Zero Ref Drift:** + ```bash + # Create Chapter 6, reusing existing character & location UUIDs + python scripts/series_manifest.py bootstrap \ + --project-dir output/ \ + --episode 6 \ + --title "Chương VI: Huyết Nguyệt" + ``` + *(This automatically links all pre-existing character and location `media_id`s into the new project, completely skipping reference image generation and preserving 100% biometric consistency across seasons).* + + diff --git a/skills/fk-cinematic-transitions.md b/skills/fk-cinematic-transitions.md new file mode 100644 index 000000000..b4778ef50 --- /dev/null +++ b/skills/fk-cinematic-transitions.md @@ -0,0 +1,156 @@ +# Cinematic Transitions & Chapter Bumpers — AI Film Direction + +Comprehensive technical guide and automated recipes for Hollywood-grade transitions, chapter interstitial bumpers, and multi-layer continuity in Google Flow and Veo 3. + +--- + +## 1. Principles of AI Cinematic Transitions + +In generative AI filmmaking, the most glaring indicators of amateur production are: +- **Abrupt Hard Cuts:** Jarring jumps between unrelated camera motions without visual or kinetic preparation. +- **Overused Cross-Dissolves:** Monotonous 50/50 opacity blends that muddy the image and dilute visual impact. +- **Truncated Chapter Transitions:** Abrupt jumps between story arcs without breathing room for the audience to absorb narrative progression. + +This skill establishes **four tiers of cinematic continuity** combining Veo 3 directorial prompt engineering, multi-layer audio lead-ins, and precision FFmpeg post-processing. + +--- + +## 2. Chapter Interstitial Bumpers (Golden Serif & Sub-Bass Drones) + +When compiling episodic scenes or multi-chapter narratives into a master film, every chapter transition requires a **3.2s – 4.0s** interstitial bumper. + +### Visual Architecture: +1. **Background:** Deep obsidian black `#08080A` or subtle volumetric smoke texture. +2. **Typography Hierarchy:** + - **Line 1 (Chapter Title):** Elegant Serif (e.g., Trajan Pro / Times New Roman Bold), royal antique gold `#E6C280` or amber `#D4AF37`. + - **Line 2 (Location / Temporal Anchor):** Subdued smoke grey `#8E95A5`, clean geometric spacing. +3. **Ken Burns Motion Dynamics:** Ultra-slow linear zoom from `1.0x` to `1.04x` over 3.5s (`zoompan` filter), giving static typography dimensional depth. +4. **Dip-to-Black Envelope:** 0.8s fade-in from pure black -> 1.9s hold -> 0.8s fade-out to pure black. +5. **Sub-Bass Drone Acoustic Design:** + - 40Hz – 60Hz Brown noise resonance (rumble felt in the chest). + - Deep cinematic boom, resonant temple bell chime, or distant war horn to establish solemn gravity. + +### Automated Python + FFmpeg Bumper Generation: +```python +from PIL import Image, ImageDraw, ImageFont + +# Generate 1920x1080 or 1280x720 canvas +img = Image.new("RGB", (1280, 720), (8, 8, 11)) +draw = ImageDraw.Draw(img) + +# Center divider line in antique gold +draw.line([(440, 395), (840, 395)], fill=(180, 145, 75), width=2) +img.save("bumper_canvas.png") +``` + +Render into animated bumper with sub-bass audio: +```bash +ffmpeg -y -loop 1 -i bumper_canvas.png \ + -f lavfi -i "anoisesrc=c=brown:r=48000:a=0.3,lowpass=f=75,volume=0.6" \ + -vf "zoompan=z='min(zoom+0.0003,1.04)':d=88:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':s=1280x720,fade=t=in:st=0:d=0.8,fade=t=out:st=2.7:d=0.8" \ + -af "afade=t=in:st=0:d=0.8,afade=t=out:st=2.7:d=0.8" \ + -t 3.5 -c:v libx264 -pix_fmt yuv420p -c:a aac -b:a 192k bumper.mp4 +``` + +--- + +## 3. In-Camera AI Transitions (Directing the Lens) + +Rather than forcing transitions in the edit, instruct the generative model to execute transitions directly inside the lens: + +### A. Whip Pan / Swish Pan +* **Purpose:** Dynamic leap across time or vast geographical distance during high-tension sequences. +* **Scene N (Outgoing):** + ```text + ...In the final second, the camera executes a violent whip pan to the right, dissolving the entire background into motion blur. + ``` +* **Scene N+1 (Incoming):** + ```text + The scene begins with a high-speed whip pan entering from screen-left, quickly stabilizing onto [Subject] standing in combat stance. + ``` + +### B. Frame Obscurity / Object Wipe +* **Purpose:** Concealing the edit point behind a foreground physical obstruction. +* **Scene N (Outgoing):** + ```text + A heavy armored warrior in a black cloak marches directly past the camera from right to left, his dark cloak completely blacking out the entire lens in the final second. + ``` +* **Scene N+1 (Incoming):** + ```text + The shot opens from behind a thick wooden palace pillar moving out of frame to the left, revealing [New Scene]. + ``` + +### C. Focus Pull / Defocus Transition +* **Purpose:** Shifting between reality, flashback, memory, or intense internal dilemma. +* **Scene N (Outgoing):** + ```text + The camera slowly racks focus away from the protagonist's sorrowful expression, dissolving the frame into soft, circular golden bokeh. + ``` +* **Scene N+1 (Incoming):** + ```text + Beginning in complete soft bokeh blur, the lens smoothly pulls focus inward to reveal the sharp, trembling flame of a bronze oil lamp. + ``` + +--- + +## 4. Visual Match Cuts + +Match cuts establish thematic, psychological, or kinetic parallels between two distinct shots: + +### A. Graphic Match (Shape & Composition) +Aligning subjects with identical geometry and screen placement across the cut point: + +| Outgoing Shot (Scene N) | Incoming Shot (Scene N+1) | Cinematic Thematic Meaning | +| :--- | :--- | :--- | +| Blood-red full moon centered in a stormy night sky (EWS). | Circular bronze war gong struck by an iron mallet in the grand hall (CU). | Omen of impending dynasty collapse manifesting into war. | +| Single tear falling from an empress's cheek (ECU). | Single raindrop hitting the tranquil surface of the river (MS). | Personal sorrow swallowed by the vast flow of history. | + +### B. Match Cut on Action (Momentum & Kinetic Trajectory) +* **Core Rule:** Match direction, speed, and trajectory of the action across the cut. Always cut at **peak velocity (mid-motion)**, never after movement has settled. +* **Scene N (Outgoing):** General slashes his bronze blade diagonally downward from top-right to bottom-left (`camera whip pans following the sword strike`). +* **Scene N+1 (Incoming):** An enemy battle flag is sliced diagonally in two along the exact matching trajectory (`camera continues the rapid diagonal movement before settling`). + +--- + +## 5. Audio Transitions: J-Cuts, L-Cuts & Sound Bridges + +Over 50% of cinematic immersion is acoustic. Audio bridges eliminate perceived visual abruptness: + +### A. J-Cut (Audio Lead-in) +* **Technique:** The audio of Scene N+1 (dialogue, war cries, gallop of steeds, or ringing church bell) enters **1.0s – 1.5s** before the visual cut occurs. +* **Psychological Impact:** Prepares the viewer's subconscious, creating momentum into the incoming scene. + +### B. L-Cut (Audio Hangover) +* **Technique:** The dying reverberation, heavy exhale, or final sentence of Scene N continues for 1.0s into Scene N+1. +* **Psychological Impact:** Sustains emotional resonance and dramatic gravity across scene changes. + +### C. Sound Bridge (Acoustic Continuity) +* Sustaining a unifying atmospheric tone (torrential rain, howling wind, or a thematic musical motif) seamlessly across contrasting camera angles. + +--- + +## 6. Post-Production FFmpeg Recipes + +### 1. Head Trim to Eliminate AI Generator Glitches: +AI video models (including Veo 3) often suffer from a micro-freeze or flicker on frame 0. Standardize every clip: +```bash +ffmpeg -ss 1.0 -t 7.0 -i raw_scene.mp4 -c:v libx264 -crf 18 -c:a aac -b:a 192k normalized_scene.mp4 +``` + +### 2. Dip-to-Black Sequence Concatenation: +```bash +# Fade out scene tail +ffmpeg -i scene_A.mp4 -vf "fade=t=out:st=6.2:d=0.8" -af "afade=t=out:st=6.2:d=0.8" -c:v libx264 -c:a aac scene_A_faded.mp4 + +# Fade in scene head +ffmpeg -i scene_B.mp4 -vf "fade=t=in:st=0:d=0.8" -af "afade=t=in:st=0:d=0.8" -c:v libx264 -c:a aac scene_B_faded.mp4 +``` + +### 3. Master Multi-Chapter Compilation: +Use the battle-tested script: +```bash +python scripts/build_master_film.py \ + --project-dir output/ \ + --chapters 1 2 3 4 5 \ + --output output//_CINEMATIC_MASTER.mp4 +``` diff --git a/skills/fk-concat-fit-narrator.md b/skills/fk-concat-fit-narrator.md index 2d4ad9fc8..55d7f0e14 100644 --- a/skills/fk-concat-fit-narrator.md +++ b/skills/fk-concat-fit-narrator.md @@ -308,6 +308,50 @@ Per-scene breakdown: Total saved: XXs ``` +## Step 9: Multi-Chapter Cinematic Master Film Assembly (`--master`) + +When producing an episodic or multi-chapter film (e.g., Chapters 1 through 5), this stage compiles all independent chapter masters into a seamless **Cinematic Master Film**: + +```bash +# Execute master compilation across all chapters +python scripts/build_master_film.py \ + --project-dir output/ \ + --chapters 1 2 3 4 5 \ + --output output//_CINEMATIC_MASTER.mp4 +``` + +### Standard 4-Step Technical Workflow: + +1. **Chapter Interstitial Bumpers (3.5s duration):** + - Renders 1280x720 / 3840x2160 title plates featuring an obsidian background `#08080A`, antique gold dividing line `#B4914B`, and dignified Serif typography (`timesbd.ttf`). + - Ken Burns motion dynamics: micro-zoom from 1.0x to 1.04x over 3.5s (`zoompan=z='min(zoom+0.0003,1.04)':d=88:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)'`). + - Integrated acoustic tone: 40–60Hz Brown noise sub-bass drone creating a solemn, cinematic atmosphere. + +2. **Dip-to-Black Transitions:** + - Outgoing chapter tail: 0.8s fade-out to black (`fade=t=out:st=:d=0.8` and `afade=t=out:st=:d=0.8`). + - Incoming chapter head: 0.8s fade-in from black (`fade=t=in:st=0:d=0.8` and `afade=t=in:st=0:d=0.8`). + - Interstitial bumper inserted between chapters as an acoustic and visual bridge. + +3. **Cinematic Multi-Layer Audio Balance:** + - **TTS Voice Narration:** `volume=1.40` (+2.9 dB boost for presence and intelligibility). + - **Veo 3 Ambient / Foley:** `volume=0.25` (-12 dB ducking so background noise never interferes with spoken dialogue). + - **Bumper Drone / Chapter Stinger:** `volume=0.50` (Resonant and deep without causing distortion). + +4. **Automated Subtitle & Hardsub Generation (`scripts/generate_subtitles.py`):** + - Automatically computes timeline timestamps from scene durations and narrator text. + - Generates standard `.srt` (for YouTube CC / VLC) and `.vtt` (for web players). + - Burns hardsubs directly into frames with custom styling presets: + ```bash + python scripts/generate_subtitles.py \ + --project-dir output/ \ + --burn-subtitles \ + --input-video output//_CINEMATIC_MASTER.mp4 \ + --style cinematic_gold + ``` + - **Styles:** `cinematic_gold` (Antique Gold text `#E6C280` with dark shadow), `clean_white` (Crisp White `#FFFFFF`), `cyber_amber` (Amber Gold), `emerald_hud` (Sci-Fi HUD Green). + +--- + ## Common Issues | Issue | Cause | Fix | @@ -318,3 +362,6 @@ Per-scene breakdown: | Scene order wrong | Not sorted by display_order | Sort scenes before processing | | TTS file not found | Wrong path or naming mismatch | Check both TTS path patterns | | Abrupt video cut | No fade-out at trim point | Add optional `-af "afade=t=out:st={CUT_DUR-0.3}:d=0.3"` | +| Bumper audio missing | Video concat without audio stream | Always include an audio stream with bumpers (drone or silent evaluation stream) | + + diff --git a/skills/fk-doctor.md b/skills/fk-doctor.md index 56ebbff14..a2fc34b8a 100644 --- a/skills/fk-doctor.md +++ b/skills/fk-doctor.md @@ -163,6 +163,13 @@ Three behaviours on this path routinely look like bugs and are not: - **A poll can say "Media not found." and the job still finishes.** The project listing is what decides; the poll is a hint. Never treat the complaint as fatal. +- **CRITICAL: Polling timeout must NOT trigger entity re-upload.** + `processor.py:_handle_failure` had a bug where matching `"not found"` triggered `_recover_entity_not_found`, + which falsely re-uploaded the start image and overwrote the genuine generated scene image media ID. + The guard in `processor.py` (line 485) is: + `if "not found" in str(error_msg).lower() and "polling timeout" not in str(error_msg).lower():` + If a scene's `image_media_id` was accidentally overwritten by this bug, check `/api/requests` history + or restore the original generated image media ID from the initial GENERATE_IMAGE completed payload. - **A media id arrives before the clip is fetchable.** The media record serves the poster image first and grows the `/video/` url in later, so a scene sits PENDING for a while after its id exists. Downloading on the id alone saves a diff --git a/skills/fk-gen-narrator.md b/skills/fk-gen-narrator.md index 8272d0866..c71f7a606 100644 --- a/skills/fk-gen-narrator.md +++ b/skills/fk-gen-narrator.md @@ -188,16 +188,31 @@ The `ref_text` is the **exact transcript** of what's spoken in `ref_audio`. - If template was created via `/fk-gen-tts-template`: `ref_text` = the standard base transcript used during creation (stored in `templates.json`) - If template is a user-provided WAV: transcribe it first using whisper, then use that transcript as `ref_text` for all scenes -### Provider (optional) +### Edge-TTS Neural Voices (Zero-Cost, High-Fidelity Narration) -Usage: `/fk-gen-narrator [--provider ] [--force] [--language vi] [--speed 1.1]` +The pipeline natively supports Microsoft Edge TTS for broadcast-grade neural voice synthesis: -Add `"provider": ""` to the `/api/tts/generate` payload to route TTS -through a provider job (`assistant`) instead of the local OmniVoice engine — -the worker's provider must support audio (`generate_audio` capability). Omit -it for local TTS. `flow` cannot do audio and is rejected with 400. +| Neural Voice Model | Voice Profile & Timbre | Optimal Genre | Recommended Rate | +|:---|:---|:---|:---| +| `vi-VN-NamMinhNeural` | Male, resonant baritone, authoritative Northern dialect | History, military, documentary, epic action | `+0%` or `-2%` (Solemn) | +| `vi-VN-HoaiMyNeural` | Female, crystalline clarity, nuanced emotional delivery | Poetic drama, introspective narrative, tragedy | `+0%` or `+3%` | + +**Automated Python Edge-TTS Generation:** +```python +import edge_tts, asyncio + +async def generate_scene_edge_tts(text: str, out_wav: str, voice: str = "vi-VN-NamMinhNeural", rate: str = "+0%"): + communicate = edge_tts.Communicate(text, voice=voice, rate=rate) + await communicate.save(out_wav) +``` + +**Cinematic Punctuation & Pacing Controls:** +- Em Dash (`—`): Enforces a 0.4s – 0.5s dramatic acoustic pause before revealing crucial plot words. +- Ellipsis (`...`): Injects an atmospheric 0.6s trailing fade for lingering contemplation. +- Comma (`,`): Structurally segments complex thoughts into 4–6 word cadences, preventing rushed phonemes. ### Key rules: + - `ref_audio` = the voice template WAV file (voice timbre source) - `ref_text` = exact transcript of `ref_audio` (phoneme alignment) - Both MUST be provided together — never just `ref_audio` alone diff --git a/skills/fk-review-video.md b/skills/fk-review-video.md index 20cc6e1ea..75a440882 100644 --- a/skills/fk-review-video.md +++ b/skills/fk-review-video.md @@ -249,20 +249,35 @@ HIGH errors → note `usable_segments` before the error timestamp. Trim or regen MINOR errors → acceptable for most use cases. Polish optional. -### Prevention Patterns - -| Issue | Fix | -|-------|-----| -| Character drift | Simpler prompts, add "steady camera, minimal movement" | -| Breed swap | Use high color contrast between similar characters | -| Character count | ONE dominant character, others in background | -| Reverse motion | Regen video (luck-based, different seed) | -| Brand logos | Add "no brand logos, no text" to prompt | -| Camera drift | Add "static camera" or "locked-off shot" to video_prompt | -| Human hands | Add "paws, claws, hooves" (or correct anatomy) to prompt | +### Automatic Prompt Healing (Self-Correction Loop for Scores < 7.5) + +In compliance with **Critical Rule 16**, any scene scoring below 7.5 undergoes automated diagnostic healing and regeneration (capped at 2 cycles): + +1. **Extract Error Vectors from the `errors` Array:** + - If error contains `Camera Drift`: Append `locked-off static camera, subtle smooth tracking` to the camera sentence. + - If error contains `Character Drift`: Append `strictly preserves identical facial bone structure and eye color from reference`. + - If error contains `Object/Anatomy Morph`: Append `natural realistic anatomy, five distinct fingers, rigid solid weapon hilt`. + - If error contains `Reverse Motion / Jerk`: Append `continuous linear motion, fluid steady trajectory without backward hitch`. + +2. **Update Scene via PATCH (Rule 13):** + ```bash + curl -X PATCH http://127.0.0.1:8100/api/scenes/ \ + -H "Content-Type: application/json" \ + -d '{"video_prompt": ""}' + ``` + +3. **Dispatch REGENERATE_VIDEO Request:** + ```bash + curl -X POST http://127.0.0.1:8100/api/requests \ + -H "Content-Type: application/json" \ + -d '{"type": "REGENERATE_VIDEO", "scene_id": "", "project_id": "", "video_id": "", "orientation": "${ORI}"}' + ``` + +--- ## Cost Note + Each scene review = 1 Claude Vision API call with N frames. - Light mode (32 frames/scene): ~$0.01–0.03 per scene - Deep mode (64 frames/scene): ~2x light mode cost diff --git a/skills/fk-scriptwriter.md b/skills/fk-scriptwriter.md new file mode 100644 index 000000000..24e18f693 --- /dev/null +++ b/skills/fk-scriptwriter.md @@ -0,0 +1,550 @@ +# The Ultimate AI Screenplay Bible — Google Flow & Veo 3 + +Usage: `/fk-scriptwriter "" [--episode N] [--scenes 8|12] [--lang vi|en] [--orientation HORIZONTAL|VERTICAL] [--fast]` + +- **Default:** Runs the **Interactive 5-Step Director Workflow** (Section A), pausing for approval at Steps 1, 3, and 5. +- `--fast`: Bypasses user review gates to directly generate technical production scripts (still strictly enforces Section N Quality Gates). + +--- + +## 0. Technical Truths of FlowKit (Must Never Violate) + +| Technical Reality | Direct Screenplay Consequence | +| :--- | :--- | +| `POST /api/scenes` only accepts: `video_id, display_order, prompt, image_prompt, video_prompt, transition_prompt, character_names, parent_scene_id, chain_type, source`. Extra fields are **silently ignored**. | Sending `narrator_text` in the POST payload will be **lost**. You must call `PATCH /api/scenes/{sid}` with `{"narrator_text": "..."}` immediately after scene creation. | +| The server automatically injects the material `scene_prefix` (e.g., `realistic`) to the beginning of `prompt`. | Do NOT manually prepend material style prefixes into `prompt` to avoid duplicate prompt contamination. | +| `character_names` must **strictly match** project entity names (characters, locations, visual assets). | This is how reference images are routed into Google Flow `imageInputs`. Mismatched names = missing refs = facial drift and identity loss. | +| `chain_type: CONTINUATION` uses the subsequent scene image as `endImage`. On the modern Flow API, endImage triggers an immediate fatal error: `UNSUPPORTED_ON_BATCH_API`. | **Default every scene to `ROOT`.** Only use chained transitions when `FLOW_ALLOW_DEGRADED=1` is confirmed or when using compatible providers. | +| Veo 3 video clips are 8.0s; post-production applies `-ss 1` head trim → **7.0s** usable footage remaining. | All narrator mathematics (Section J) are calibrated against a 7.0s effective window. | +| Scenes are mutable via `PATCH`. | Refine prompts via `PATCH /api/scenes/{sid}`. **Never delete and recreate** (preserves generated media). | + +--- + +## A. Interactive 5-Step Director Workflow + +### Step 1 — Pitch Logline (Pause for Approval) +- If the subject is based on real historical events or public figures: execute `/fk-research` first (Rule 14). +- Present **2–3 creative angles**, each including: 1-sentence logline, genre preset (Section L), narrative tone, and the opening 3-second visual hook. + +### Step 2 — Cast & World Lock +- Enumerate project entities: `character` (vertical 9:16 portrait), `location` (horizontal 16:9 landscape), and `visual_asset`. +- Lock **Lighting Signature**, **Color Palette**, and **Dialogue Language** (e.g., Vietnamese or English). +- If the project already exists: query `GET /api/projects/{pid}` to obtain exact entity names. + +### Step 3 — Beat Sheet: 8–12 Beats (Pause for Approval) +One line per scene: scene archetype (Section D) · shot scale · characters present · dialogue presence · targeted emotional shift (Section I2). + +### Step 4 — Technical Production Script +Author exhaustive specifications per scene: `prompt`, `video_prompt`, `narrator_text`, `character_names`, `music_cue`, `wardrobe_state`. + +### Step 5 — Self-Audit & Pipeline Ingestion (Pause for Approval) +1. Run the **20-Point Quality Gate** (Section N) — output full verification scorecard; resolve any failing items. +2. Save screenplay: `.omc/research/_ep_script.json`. +3. Inquire: *"Dispatch into FlowKit pipeline immediately?"* → upon confirmation, execute Section O. + +--- + +## B. Series Bible & Multi-Episode Arc Architecture + +Before scripting Episode 1, compile a minimal Series Bible (saved at `.omc/research/_bible.md`): + +- **Series Logline** (1 sentence) · **Core Theme** · **World Rules** (e.g., "Solar temperature increases 1°C every 3 days"). +- **Series Clock**: Universal countdown anchor. Every episode must advance this ticking clock. +- **Visual Leitmotif**: A recurring visual motif that evolves across episodes (e.g., the sun grows progressively crimson). + +### 4-Act Structure for a 10–12 Episode Series +| Act | Episodes | Narrative Function | Emotional Temperature | +| :--- | :--- | :--- | :--- | +| **Act 1 — Inciting Arc** | 1–3 | Introduce protagonists, stakes, allies, opposing force | Curiosity → Rising dread | +| **Act 2 — Escalation Arc** | 4–7 | Resource competition, betrayals, pyrrhic victories | Sustained high tension | +| **Act 3 — Darkest Night** | 8–9 | Core citadel under siege, catastrophic personal loss | Existential despair | +| **Act 4 — Climax & Resolution** | 10+ | Final confrontation, ultimate sacrifice, transformed world | Catharsis & resonance | + +**Episode Transition Rule:** Scene 0 of Episode N+1 must directly address or escalate the cliffhanger of Episode N within the first 3 seconds. + +--- + +## C. The 10 Core Screenplay Commandments + +1. **Action-Only Prompts:** Never describe facial anatomy, hair color, or body build in scene prompts. Reference images govern identity; prompts describe action only (Wardrobe state is the sole exception — Section F). +2. **3-Beat Structure in 8 Seconds:** Mandate `0-3s`, `3-6s`, `6-8s` temporal breakdown in every `video_prompt`. +3. **Narrator Mathematics:** Narrator audio must comfortably conclude within 7.0s (Section J). +4. **Show ≠ Tell:** Narration must reveal unseen context, motives, or stakes. Never redundantly narrate what is already visible on screen. +5. **Maximum 2 Named Characters per Scene:** Crowds remain blurred in the background. +6. **Camera Movement as Standalone Sentence:** Camera direction must be separated from character action sentences. +7. **No Consecutive Scale Repetition:** Never place two identical shot sizes back-to-back (Section G). +8. **Physiological Emotion:** Describe observable physiological symptoms rather than abstract adjectives (Section I). +9. **Lighting Signature Consistency:** Maintain unified lighting within identical temporal and spatial sequences. +10. **Unresolved Cliffhanger:** Every episode must end on an unanswered question or suspended threat. + +--- + +## D. 10 Professional Cinematic Scene Archetypes + +A genuine film is not a slideshow of walking figures with continuous narration. Every scene must adopt one of the following 10 archetypes, and each episode must blend **at least 5–6 distinct archetypes**: + +### 1. Establishing Shot +- **Function:** Establishes geography, scale, time of day, and environmental scale. Zero or tiny character presence. +- **Framing:** Extreme Wide Shot (EWS) / Aerial / Bird's Eye. +- **Dialogue:** None. Narration + environmental audio only. +- **video_prompt Formula:** + ```text + 0-3s: Aerial establishing shot of the mountain pass at dawn, morning fog clinging to jagged limestone peaks. 3-6s: The camera slowly descends toward an ancient stone fortress, golden sunrise light glinting off slate watchtowers. 6-8s: The camera settles on the heavy timber gates slightly ajar. Smooth crane-down movement. Lighting: soft golden dawn, volumetric morning mist. Audio: distant mountain winds, faint raven calls. Negative: subtitles, watermark, text overlay. + ``` + +### 2. Dialogue Scene — Two-Shot +- **Function:** Two characters exchange vital plot information, make decisions, or enter conflict. **The backbone of cinematic storytelling.** +- **Framing:** Medium Two-Shot → Over-the-Shoulder → Reaction Close-up. +- **Dialogue:** Spoken naturally by characters inside the clip (`Character says: "..." (no subtitles)`). +- **video_prompt Formula:** + ```text + 0-3s: Medium two-shot inside dim military tent. General Tien and Doctor Thuy sit across a rough wooden table. Tien leans forward and speaks in a low urgent tone. Tien says: "We have thirty days. No more." (no subtitles) 3-6s: Over-the-shoulder from behind Tien, camera focuses on Thuy. She listens intently, brow furrowing, then gives a slow resolute nod. Thuy says: "I will secure the medical supplies." (no subtitles) 6-8s: Close-up of Tien's face — a flicker of relief, then hardening resolve. Static locked-off shot with subtle rack focus. Lighting: warm candlelight through tent canvas, deep shadows. Audio: quiet room ambience, howling wind outside tent. Negative: subtitles, watermark, text overlay. + ``` + +### 3. Dialogue Scene — Reaction Focus +- **Function:** One character speaks off-screen or from behind, while the camera fixates on the listener's internal shift. +- **Framing:** Medium → Slow push-in to Close-up on the listener. +- **video_prompt Formula:** + ```text + 0-3s: Medium shot of Doctor Thuy speaking firmly across the table, gesturing slightly. Thuy says: "The reserves will only last two weeks." (no subtitles) 3-6s: Slow push-in to close-up of General Tien listening. His jaw tightens, eyes narrowing as he absorbs the gravity of the crisis. 6-8s: Tien looks down at the battle map, takes a slow breath, then looks back up with cold determination. Lighting: warm diffused lamp light. Audio: quiet room tone, faint distant rain. Negative: subtitles, watermark, text overlay. + ``` + +### 4. Action Beat +- **Function:** Physical labor, mechanical repairs, tactical operations, or combat maneuvers. +- **Framing:** Medium Tracking / Kinetic Dynamic. +- **video_prompt Formula:** + ```text + 0-3s: Medium tracking shot as General Tien hauls an iron reinforcement beam, sparks drifting from a brazier against the stone wall. 3-6s: He braces his shoulder against the timber barricade and hammers a heavy iron locking peg into place with a mallet. 6-8s: Tien steps back, wipes sweat from his brow, and inspects the fortified gate with a firm nod. Lateral tracking shot following the movement. Lighting: chiaroscuro — warm orange forge glow against dark stone shadows. Audio: harsh metallic clanging of hammer on iron, crackling fire. Negative: subtitles, watermark, text overlay. + ``` + +### 5. Pure Reaction Shot +- **Function:** Intense close-up on a character processing shocking news, discovery, or danger. No dialogue — pure micro-expression. +- **Framing:** Close-up / Extreme Close-up. +- **video_prompt Formula:** + ```text + 0-3s: Close-up of General Tien's face illuminated by the crimson glow of a warning signal. His pupils dilate, lips parting slightly. 3-6s: Slow push-in to extreme close-up. A bead of sweat rolls down his temple. He swallows hard. 6-8s: His eyes narrow into hardened resolve, jaw setting firmly. He exhales through his nose. Static shot with subtle handheld micro-movement. Lighting: pulsing red warning glow on one side, deep shadow on the other. Audio: low electronic drone, controlled heavy breathing. Negative: subtitles, watermark, text overlay. + ``` + +### 6. Insert / Detail Shot +- **Function:** Macro shot on a crucial thematic prop: maps, hourglass, broken seal, thermometer, dagger. +- **Framing:** Macro / Extreme Close-up. +- **video_prompt Formula:** + ```text + 0-3s: Extreme close-up of an ancient bronze sundial, shadows stretching across carved zodiac markers. 3-6s: Camera slowly racks focus to reveal a royal seal stamped in red wax on parchment behind the sundial. 6-8s: A hand enters the frame and draws an ink line across the parchment with a bamboo brush. Smooth rack focus. Lighting: harsh afternoon sun through slatted blinds. Audio: ticking of a clock, distant courtyard birds. Negative: subtitles, watermark, text overlay. + ``` + +### 7. Montage Beat (Compressed Time) +- **Function:** Rapid progression of preparation, construction, marching, or tactical training. +- **Framing:** Fast cutting or multi-action pacing within a single clip. +- **video_prompt Formula:** + ```text + 0-2s: Overhead shot of hands stacking bamboo arrows into wooden quivers. 2-4s: Medium shot of Tien tightening leather straps on an armored saddle. 4-6s: Close-up of fresh water pouring into clay jars. 6-8s: Wide shot of the fortified camp, organized and prepared as evening torches ignite. Fast montage rhythm. Lighting: warm amber dusk. Audio: rhythmic sounds of sharpening blades, pouring water, marching boots. Negative: subtitles, watermark, text overlay. + ``` + +### 8. Stalking / Surveillance Shot +- **Function:** Generating covert suspense, feelings of being hunted, or espionage. +- **Framing:** Long Telephoto compressed through foreground obstruction (branches, lattice, pillars). +- **video_prompt Formula:** + ```text + 0-3s: Long telephoto shot through carved wooden palace lattice — Lord Kha exits a pavilion, adjusting his silk collar. The lattice partially obscures the frame. 3-6s: Rack focus from the wooden screen to Kha's face. He pauses, glances sideways, and smiles coldly. 6-8s: Kha steps into a waiting carriage. The camera remains static behind the screen as the carriage pulls away. Locked-off telephoto through obstruction. Lighting: midday contrast, deep shadows beneath eaves. Audio: distant palace chatter, carriage wheels grinding on gravel. Negative: subtitles, watermark, text overlay. + ``` + +### 9. Atmospheric Transition / Bridge Shot +- **Function:** Establishing time passage, twilight into darkness, weather changes. Provides narrative breathing room. +- **Framing:** Wide / Time-lapse style. +- **video_prompt Formula:** + ```text + 0-3s: Wide static shot of the citadel exterior at dusk. The last rays of golden sunlight turn stone parapets amber. 3-6s: Shadows lengthen rapidly across the courtyard as the sun slips below the mountain crest. Citadel watch fires ignite one by one. 6-8s: Night falls — a single beacon fire casts warm light across the stone gate. Static wide shot, natural time progression. Lighting: golden hour transitioning to deep twilight. Audio: evening crickets, distant guard horn call. Negative: subtitles, watermark, text overlay. + ``` + +### 10. Silent Moment (The Breathing Room) +- **Function:** Total cinematic pause. No dialogue, no narrator. Pure image, breathing, and acoustic realism. +- **Framing:** Medium or Wide, locked-off static. +- **video_prompt Formula:** + ```text + 0-3s: Medium shot of General Tien sitting alone on a stone bench in the quiet courtyard. A single shaft of moonlight cuts across his shoulders. 3-6s: He stares at the ground. His chest rises and falls with a long, slow breath. Cold mist drifts across the flagstones. 6-8s: He lifts his gaze slowly toward the distant horizon. Locked-off static shot, zero camera movement. Lighting: single volumetric moonlight beam in darkness. Audio: near-silence — only his breathing and the distant rustle of pine needles. Negative: subtitles, watermark, text overlay. + ``` + +--- + +## E. Multi-Language & Native Dialogue Directing + +### The Core Invariant: Narration Leads, Dialogue Punctuates +In high-end cinema, dialogue and narration must never collide: +``` +[1] NARRATOR TTS: Sets macroscopic context, stakes, and countdown (plays during 0-3s or before). +[2] AMBIENT AUDIO (Veo 3 Native): Continuous environmental bed (wind, rain, crackling fire). +[3] CHARACTER DIALOGUE (Veo 3 Native): Brief, sharp, localized speech embedded inside the clip. +``` + +### Prompt Dialogue Syntax +```text +[Character Name] says: "[Dialogue Line]" (no subtitles) +``` +Examples: +- English: `Tien says: "Thirty days. No more." (no subtitles) — low urgent voice` +- Vietnamese: `Tiến nói: "Ba mươi ngày. Không hơn." (không phụ đề) — giọng trầm, dứt khoát` + +### Dialogue Rules: +1. **Length Cap:** Maximum **10–12 words per character per 8s clip** (Rule 12). +2. **Speaker Limit:** Maximum 2 speaking characters per scene. +3. **Delivery Direction:** Append vocal tone immediately following the quote: `— whispered urgently` or `— deep commanding baritone`. +4. **Mandatory Suffix:** Always include `(no subtitles)` or `(không phụ đề)` to prevent AI video generators from burning deformed text overlays onto the video frames. +5. **No Redundancy:** If the narrator says "They met to discuss the siege", the character must NOT say "We must discuss the siege". Dialogue expresses immediate emotional reaction and commitments. + +--- + +## F. Wardrobe & Temporal Decay Dynamics + +Reference images lock **facial identity**; clothing must be directed in prompts as **functional layers** tied to physical action: + +- ✅ **Correct:** `General Tien, wearing a heavy soot-stained leather breastplate, lowers his iron visor.` +- ❌ **Incorrect:** `General Tien, a handsome Vietnamese general with sharp cheekbones and black hair.` + +### Temporal Costume Progression: +| Story Stage | Wardrobe State Description | +| :--- | :--- | +| **Opening / Prologue** | `clean ceremonial robes, neat topknot, pristine fabric` | +| **Onset of Struggle** | `sleeves rolled up, light dust on shoulders, untied sash` | +| **Middle / Prolonged War** | `sweat-stained tunic, scuffed leather armor, soot on collar` | +| **Darkest Night / Climax** | `torn cloak, blood-stained linen bandage on forearm, ash-streaked face` | + +--- + +## G. Scale Alternation & Cinematic Rhythm + +Never use the same shot scale in consecutive scenes. Standard 8-Scene Rhythm: + +| Scene | Archetype | Shot Framing | Kinetic Velocity | Dialogue? | +| :---: | :--- | :--- | :--- | :---: | +| 0 | Hook / Reaction | Close-up | Rapid / Urgent | Optional | +| 1 | Establishing | Extreme Wide (EWS) | Majestic / Slow | None | +| 2 | Action Beat | Medium Tracking | Kinetic / Driving | Short command | +| 3 | **Dialogue Two-Shot** | Two-Shot → OTS | Moderate / Intimate | **Mandatory** | +| 4 | Insert / Detail | Macro | Static / Tense | None | +| 5 | **Dialogue / Reaction** | Close-up → Push-in | Deep / Emotional | **Mandatory** | +| 6 | Surveillance / Threat | Telephoto through Obstruction | Simmering Tension | None | +| 7 | Cliffhanger | Wide → Slow Push-in | Accelerating Dread | Climactic line | + +**The Dialogue Invariant:** Every 8-scene episode must contain **at least 2 dialogue scenes**. A video without dialogue is an automated slideshow, not cinema. + +--- + +## H. Director of Photography (DP) Lexicon + +### Camera Movements: +- `slow push-in` — Deepens internal psychological tension or realization. +- `slow pull-back` — Evokes isolation, smallness against the environment. +- `low-angle tracking` — Imparts authority, heroic determination. +- `lateral tracking` — Accelerates urgency, pursuit, race against time. +- `overhead bird-eye` — Establishes tactical layout, vulnerability. +- `rack focus from A to B` — Shifts viewer focus between foreground threat and background reaction. +- `over-the-shoulder (OTS)` — Intimate conversational framing. +- `locked-off static` — Somber gravity, quiet contemplation. +- `Dutch angle` — Disorientation, psychological unbalance. +- `subtle handheld` — Gritty documentary realism, combat tension. + +### Lighting Signatures: +- `hard chiaroscuro, deep shadows` — Danger, conspiracy, moral ambiguity. +- `volumetric light beams through dust` — Fortress interiors, catacombs, temples. +- `warm golden-hour rim light` — Hope, honor, farewell. +- `flickering torchlight against wet stone` — Dungeon, night fortress defense. +- `harsh midday sun with heat shimmer` — Desolation, heat crisis, arid wasteland. +- `cold overcast diffused daylight` — Bleak realism, sorrow, military readiness. + +### Optical Focal Lengths: +- `35mm natural perspective` — Grounded documentary realism. +- `85mm portrait, shallow depth of field` — Emotional character isolation. +- `telephoto lens compression` — Espionage, compressed crowds, claustrophobia. +- `wide 24mm` — Vast architectural scale or overwhelming landscape. + +--- + +## I. Micro-Expression Physicality + +AI models fail on abstract adjectives like "he looks sad". Direct precise physiological symptoms: + +| Emotion | Avoid Abstract Words | Direct Physical Symptoms | +| :--- | :--- | :--- | +| **Terror** | `he is terrified` | `rapid shallow breathing, eyes darting left and right, hand gripping table edge until knuckles whiten` | +| **Resolve** | `she looks determined` | `jaw tightening firmly, gaze narrowing to a fixed point, slow decisive nod` | +| **Shock** | `he is shocked` | `sudden complete stillness, lips parting without a sound, breath held mid-inhale` | +| **Exhaustion** | `he is exhausted` | `shoulders sagging forward, spine slumping, leaning heavily against the stone wall, slow heavy blink` | +| **Suppressed Grief** | `she is sad` | `eyes glistening without tears falling, swallowing hard twice, looking away toward the window` | +| **Suspicion** | `he is suspicious` | `head tilting 15 degrees, eyes narrowing, weight shifting to back foot in a half-step retreat` | +| **Arrogance** | `he is arrogant` | `chin raised exposing throat, slow measured stride, thin smirk curling one corner of mouth` | +| **Relief** | `she is relieved` | `long slow exhale through parted lips, shoulders dropping two inches, eyes closing for three beats` | + +--- + +## I2. The 8-Second Micro-Emotional Arc (A → B Progression) + +Every scene **MUST** exhibit an internal emotional transformation. A character begins at State A and arrives at State B: + +``` +Beat 1 (0-3s): STATE A — Initial baseline emotion +Beat 2 (3-6s): THE CATALYST — Visual, acoustic, or physical shift that fractures the baseline +Beat 3 (6-8s): STATE B — New, irreversible emotional resolution +``` + +### 15 Extended Physiological Expression States: +1. **Calm → Terror:** Eyes gazing calmly → Pupils dilate widely, lips part trembling → Face goes pale, steps backward. +2. **Skepticism → Bitter Realization:** Brows slightly furrowed → Pupils freeze, jaw muscle twitches → Slow shake of head, glistening eyes. +3. **Despair → Desperate Resolve:** Head lowered in defeat → Slowly lifts chin through disheveled hair → Jaw sets, fists clench white, eyes blaze. +4. **Confidence → Sudden Collapse:** Smug half-smile → Smile vanishes instantly, brow contorts → Stares blankly downward, hands tremble. +5. **Fear → Rising Courage:** Body shaking, darting eyes → Closes eyes, takes one deep breath → Opens eyes locked on the enemy, stands tall. +6. **Rage → Cold Cruelty:** Veins bulging on neck, panting → Breath abruptly slows, facial muscles relax into blankness → Eyes turn icy, cold smirk forms. +7. **Physical Pain → Iron Will:** Grimacing from wound, biting lower lip → Sharp hiss through teeth, sweating profusely → Forces eyes open, stance solidifies. +8. **Vigilance → Moving Relief:** Hand clenched on sword hilt, scanning shadows → Grip slowly relaxes, shoulders drop → Soft exhale, gaze softens warmly. +9. **Pride → Humiliated Rage:** Chin high, disdainful stare → Lowers head, ears flushing red → Clenches fists until veins stand out. +10. **Remorse → Redemption Resolve:** Staring down at trembling hands in self-blame → Looks up toward the horizon → Expression turns steely, gives a decisive nod. +11. **Confusion → Sudden Epiphany:** Eyes scanning documents frantically → Pupils freeze, light sparks in eyes → Gentle smile forms as puzzle clicks. +12. **Isolation → Found Solidarity:** Vacant stare in the crowd → Catches comrade's loyal gaze → Subtle nod, warmth returns to weathered face. +13. **Agony → Manic Defiance:** Tears streaming down, head in hands → Broken laughter escapes lips → Eyes widen with wild defiance. +14. **Melancholy → Peaceful Acceptance:** Heavy weary eyes, downturned mouth → Closes eyes into the passing breeze → Gentle half-smile, total tranquility. +15. **Casual Watch → Maximum Alertness:** Scanning darkness lazily → Ear twitches slightly, pupils snap toward shadows → Lowers center of gravity silently. + +--- + +## I3. 8 Cinematic Action Archetypes + +### 1. Melee Duel / Clashing Blades +- **AI Safety Rule:** Avoid impaling weapons through bodies. Describe weapon trajectory and explosive spark impacts on shields/guards. +- **video_prompt:** + ```text + 0-3s: Two warriors lower their combat stances, bronze swords raised to shoulder height, eyes locked across drifting ash. 3-6s: The left warrior lunges forward in a powerful diagonal slash; his blade collides violently with his opponent's iron shield, discharging brilliant orange sparks. Camera tracks the kinetic slash. 6-8s: Both warriors lock blades in a rigid contest of brute strength, muscles straining, hot breath steaming in the cold night air. Audio: Clashing steel, sizzling sparks, heavy war grunts. Negative: subtitles, watermark, text overlay. + ``` + +### 2. High-Speed Pursuit +- **AI Safety Rule:** Never run directly into the camera lens. Track diagonally or laterally. +- **video_prompt:** + ```text + 0-3s: A courier gallops at full sprint along a muddy forest road, black cloak fluttering in the storm. 3-6s: Three mounted pursuers surge into frame behind him, arrows whistling past and striking the earth. The camera tracks laterally alongside the galloping steeds. 6-8s: The courier jerks the reins, veering sharply through a narrow rocky ravine, mud spraying across the lower frame. Audio: Thundering rhythmic hooves, whistling arrows, panicked horse whinny. Negative: subtitles, watermark, text overlay. + ``` + +### 3. Dodge & Counter-Strike +- **AI Safety Rule:** Duck or sidestep; avoid 360-degree midair flips. +- **video_prompt:** + ```text + 0-3s: The general stands in a balanced guard stance, watching an enemy spear thrust incoming. 3-6s: As the spear tip nears, he ducks low to the left, pivoting his wrist to strike the spear shaft upward with his broadsword hilt. The camera pushes in on the deflection. 6-8s: The spear deflects wide; the general straightens into an imposing counter stance. Audio: Whistling spear air rush, dull timber crack, clatter of weapon. Negative: subtitles, watermark, text overlay. + ``` + +### 4. Precision Archery +- **AI Safety Rule:** Structure as pull -> release shockwave -> trajectory pan. +- **video_prompt:** + ```text + 0-3s: The archer stands steady upon the battlement, drawing the heavy recurve bowstring back to her jawline in the rain. 3-6s: She releases; the bowstring snaps forward and the iron arrow streaks diagonally through the mist. The camera pans rapidly with the arrow trajectory. 6-8s: The arrow strikes the enemy signal banner in the distance, tearing it down; the archer lowers her bow with a calm exhale. Audio: Crisp bowstring snap, piercing arrow whistle, distant timber crash. Negative: subtitles, watermark, text overlay. + ``` + +### 5. Stealth Ambush +- **AI Safety Rule:** Emerge from natural shadow/cover; avoid teleportation artifacts. +- **video_prompt:** + ```text + 0-3s: A patrol unit carrying torches marches cautiously through a silent canyon pass, firelight dancing on rock walls. 3-6s: From dark tree branches above, cloaked scouts drop down silently, blades drawn to block the path. Low-angle camera looking up dramatically. 6-8s: A dropped torch hisses into a puddle and extinguishes in smoke; the scouts form an unbroken perimeter in the moonlight. Audio: Rustling leaves, taut rope snap, hissing fire extinguishing, unison steel unsheathing. Negative: subtitles, watermark, text overlay. + ``` + +### 6. Breaching / Gate Breakout +- **AI Safety Rule:** Direct kinetic impact against timber/iron; use dust and debris shockwaves. +- **video_prompt:** + ```text + 0-3s: The lead warrior locks his heavy bronze shield against his shoulder, driving all momentum forward. 3-6s: He smashes into the reinforced timber palace doors, splintering wood and sending dust billowing across the frame. Subtle camera shake on impact. 6-8s: The doors burst open, morning sunlight flooding inward to silhouette the warrior raising his sword to lead the charge. Audio: War cry, splintering timber crash, iron impact boom. Negative: subtitles, watermark, text overlay. + ``` + +### 7. Desperate Shield Wall Stand +- **AI Safety Rule:** Anchor firm poses; express resilience under pressure. +- **video_prompt:** + ```text + 0-3s: Shield-bearers drop to one knee, interlocking large bronze shields into a solid barricade before incoming fire arrows. 3-6s: A barrage of flaming arrows thuds heavily into the shields, smoking under the impact, but the wall holds firm. Low-angle heroic perspective. 6-8s: Smoke curls off the scorched shields; the commander raps his sword pommel three times against bronze to rally the ranks. Audio: Raining arrow impacts on metal, crackling flames, three crisp steel strikes. Negative: subtitles, watermark, text overlay. + ``` + +### 8. Tense Standoff / Eye-to-Eye +- **AI Safety Rule:** Minimal physical body movement; concentrate energy into eyes, breathing, and 180-degree arc camera orbit. +- **video_prompt:** + ```text + 0-3s: Medium two-shot of two rival commanders facing each other three paces apart on an ancient wooden bridge, wind whipping their robes. 3-6s: The camera executes a slow 180-degree arc shot around them. Neither moves; their eyes burn with locked hatred as one hand rests upon his sword hilt. 6-8s: Close-up of a bead of sweat rolling down the jawline; a thumb subtly clicks the sword guard upward from the scabbard. Audio: Creaking wooden bridge, distant wind chime, dry throat swallow, metallic click. Negative: subtitles, watermark, text overlay. + ``` + +--- + +## I4. The Suspense & Tension Toolkit (6 Master Techniques) + +True suspense is generated through **information withholding** and **impending dread**, not cheap jump scares: + +### 1. The Ticking Clock +- **Principle:** Audience watches a physical deadline expire (candle melting toward gunpowder, sun sinking below the horizon). +- `video_prompt`: Macro close-up of a red candle melting onto a war table, hot wax pooling toward the edge of an envelope dusted with sulfur. Camera slowly dollies forward. +- `narrator_text`: Thirty seconds remain. If unopened, the cipher will consume itself in flames. +- `Audio`: Rhythmic dripping of wax like a clock pendulum, shallow choked breathing. + +### 2. The Blind Spot / Negative Space +- **Principle:** Character framed on the extreme third, leaving an expansive, pitch-black void behind them. +- `video_prompt`: Close-up of general cleaning his sword by candlelight on screen-left. The right two-thirds is a pitch-black corridor behind him. A faint shadow drifts in the deep darkness. +- `narrator_text`: In the shadows of the imperial court, the deadliest blade always strikes from behind. +- `Audio`: Cloth wiping across cold steel, faint padding footsteps on distant floorboards. + +### 3. The Delayed Reveal +- **Principle:** Character witnesses a horrific sight first, face contorting, while concealing the source from the viewer until the 6th second. +- `video_prompt`: 0-3s: Close-up of a sentry peering through a wooden shutter, eyes widening in sheer disbelief, jaw trembling. 3-6s: Camera slowly tracks over the sentry's shoulder. 6-8s: The river below is revealed, covered with thousands of silent enemy warships emerging from the mist. +- `narrator_text`: When the shutter opened, all hope for a peaceful night dissolved into the mist. +- `Audio`: Creaking shutter hinge, pounding heartbeat, then thundering roar of a thousand oars churning water. + +### 4. Sonic Isolation / The Sensory Cutout +- **Principle:** Abruptly eliminate all musical score, isolating a single surreal sound to heighten visceral tension. +- `video_prompt`: Close-up in slow motion of the archer taking aim amidst a chaotic battlefield. His focus is absolute; a single raindrop strikes his eyelid, causing a micro-blink. +- `narrator_text`: Amidst ten thousand clashing blades, time freezes before the arrow of destiny. +- `Audio`: Total muting of battle noise; only a slow 40 BPM heartbeat and deep breath intake. + +### 5. The Deceptive Calm +- **Principle:** Unnerving stillness that contrasts with imminent annihilation. +- `video_prompt`: Mirror-flat morning lake surface; a water lily sways gently in the breeze. Suddenly, concentric ripples erupt across the surface, vibrating with increasing violence from underground tremors. +- `narrator_text`: The lake remains terrifyingly still... Herald of the catastrophe gathering beneath the earth. +- `Audio`: Solitary bird chirp abruptly silenced by deep subterranean rumble, water sloshing. + +### 6. Time Dilation on Edge +- **Principle:** Deconstruct a 1-second real-world crisis into a full 8-second cinematic struggle. +- `video_prompt`: 0-3s: Bloodied hand of a guardsman reaches out in desperation toward a falling battle standard. 3-6s: Fingers brush against the silk banner by millimeters; macro camera captures fabric sliding across knuckles. 6-8s: He strains forward another half-inch, gripping the wooden pole right before it hits the ground. +- `narrator_text`: A single fraction of an inch decided the fate of the entire army. +- `Audio`: Slow-motion fluttering silk, teeth grinding in agony, decisive timber snap as hand grips wood. + +--- + +## J. Narrator Mathematics (The 7.0s Usable Window) + +Veo 3 produces an 8.0s clip. Post-production trims the first 1.0s (`-ss 1`) to eliminate model initialization freezes. Usable footage = **7.0 seconds**. + +### Exact Word Count Constraints (Hard Maximum): +| Language | Max Words | Target Duration | Speed Rate | Structural Rules | +| :--- | :---: | :---: | :---: | :--- | +| **Vietnamese** | **18–22** | ~6.0s – 6.5s | 1.1x | Tonal diacritics slow TTS. 2 punchy clauses separated by `—`. | +| **English** | **20–24** | ~6.0s – 6.5s | 1.0x | Active verbs, zero filler adjectives. | +| **Scenes with Dialogue** | **12–16** | ~4.0s – 4.5s | 1.1x | Narration must finish BEFORE characters begin speaking. | + +**The Golden Rule:** A narrator must NEVER narrate what is already obvious on screen. Narration reveals *lore, motivation, consequences, and the ticking clock*. + +--- + +## K. Anti-Artifact Playbook + +| AI Vulnerability | Problematic Prompting | Physics-Safe Prompting | +| :--- | :--- | :--- | +| **Finger Dexterity** | Typing passcodes, interlinking fingers | Pressing flat palm, shifting lever, turning wheel, wearing gauntlets | +| **Text & Numbers** | Close-ups of readable screens or paper | Graphical symbols: glowing runes, flashing red signal, wax seal | +| **180° Head Turn** | Character turning from back to front | Split into 2 separate scenes; cut directly to front close-up | +| **Feet Slipping** | Floating walk cycle without contact | Specify surface traction: `boots striking wet concrete firmly` | +| **Mid-Clip Costume Change** | Character taking off coat or backpack | Garments must be fully worn from Frame 0 | +| **Body Merging** | Intimate grappling or tight hugs | Maintain distance: `standing an arm's length apart` | +| **Physical Impossibility** | Superhuman leaps, car crashes | Shoot the aftermath: dust billowing, camera shaking, debris settling | +| **Action Overload** | 5 actions crammed into 8s | Strictly 1 primary kinetic action per temporal beat | + +--- + +## L. Genre Presets + +| Genre | Color Palette Signature | Characteristic Keywords | Signature Hook | +| :--- | :--- | :--- | :--- | +| **Post-Apocalypse / Survival** | Burnt amber, dust grey | rust, corrugated iron, sandstorm, gas mask | Thermometer spikes past fatal threshold | +| **Revenge / Modern Noir** | Charcoal black, cold glass reflections | penthouse window, tailored suit, rain slick | Old scar throbs with memory | +| **Historical War / Epic** | Muted bronze, crimson, ash | iron scale armor, war drums, banner, torches | Ominous battle horn echoes in fog | +| **Cyberpunk / Sci-Fi** | Deep cyan, neon magenta | airlock steam, zero-g debris, biometric HUD | Pressure seal breach alarm | +| **Dark Fantasy** | Midnight violet, torch orange | ancient runes, misty bog, iron talismans | Relic emits sudden shockwave | + +--- + +## L2. Safety Filter Ladder (Real-People Bypass) + +If a prompt trips safety moderation, descend this ladder systematically: +1. **Camera Angle Shift:** Reposition camera behind the character or in a 3/4 profile. +2. **Remove Names from Prompt:** Retain entity in `character_names`, but remove specific aliases from the `video_prompt` text (use "the commander"). +3. **Drop Reference Dependency:** Remove `character_names` for that single scene, relying on prompt physical descriptors. +4. **Keyword Sanitation:** Substitute flagged terms: `confidential/classified` → `parchment/scroll`; `weapon/rifle` → `iron gear`; `blood/kill` → `confrontation`. Never include minors. + +--- + +## M. Audio & Musical Score Architecture + +### Audio Tags in `video_prompt`: +- `Audio:` Background acoustic bed (wind howling, rain on canvas, engine idle). +- `SFX:` Discrete synchronized impacts (steel clashing, bolt locking, glass shattering). +- `Dialogue:` Native speech formatted as `Character says: "..." (no subtitles)`. +- **Mandatory Negative Tag:** `Negative: subtitles, captions, watermark, text overlay.` + +### `music_cue` (Stored in screenplay JSON metadata, never sent to generation API): +- **Hook:** `low analog drone, ticking pulse, 60 BPM` +- **Escalation:** `industrial percussion, driving bass, 90 BPM` +- **Dialogue:** `sparse piano over warm ambient pad, breathing room` +- **Dread / Threat:** `dissonant low strings, sub-bass swells` +- **Cliffhanger:** `crescendo to a massive hit, then abrupt absolute silence` + +--- + +## N. Quality Gate — 20 Production Checkpoints + +Every scene script must pass this 20-point audit before generation: + +| # | Checkpoint | Pass Criteria | +| :-: | :--- | :--- | +| 1 | Action-Only Prompt | Zero descriptions of face/hair/body in prompts | +| 2 | Wardrobe Progression | Costume changes justified and recorded in `wardrobe_state` | +| 3 | 3-Beat Pacing | Every `video_prompt` contains `0-3s`, `3-6s`, `6-8s` | +| 4 | Prompt Word Count | 100–150 words per prompt, containing lighting + audio tags | +| 5 | Narrator Word Count | 18–22 words (12–16 words for scenes with dialogue) | +| 6 | Show ≠ Tell | Narration does not redundantly describe on-screen actions | +| 7 | Character Limit | Maximum 2 named characters per scene | +| 8 | Entity Integrity | `character_names` strictly matches project database entities | +| 9 | Scale Alternation | No two consecutive scenes share the same framing scale | +| 10 | Standalone Camera | Camera motion written as a dedicated separate sentence | +| 11 | Physiological Emotion | Emotions described via physiological cues, not abstract adjectives | +| 12 | Anti-Artifact Rules | Free of finger micro-actions, text, 180° turns, mid-clip costume swaps | +| 13 | Lighting Consistency | Unified lighting signature across same-location scenes | +| 14 | Safety Compliance | Role-based aliases only; zero public figure names or flagged terms | +| 15 | 3-Second Hook | Scene 0 presents immediate visual conflict in the opening frame | +| 16 | Cliffhanger | Final scene leaves a suspended, unanswered narrative threat | +| 17 | Fact-Check Verification | Historical/factual data verified via research notes | +| 18 | Chain Type Standard | Defaulted to `ROOT` | +| 19 | Dialogue Presence | Minimum 2 dialogue scenes per 8-scene episode | +| 20 | Subtitle Suppression | All dialogue includes `(no subtitles)` suffix | + +--- + +## O. Production Output & Pipeline Execution + +### O.1 Screenplay JSON Schema +Save at `.omc/research/_ep_script.json`: +```json +{ + "series": "Hong Nhat Thang Long", + "episode": 2, + "title": "Race Against Time", + "orientation": "HORIZONTAL", + "lighting_signature": "volumetric light through dust (indoor); harsh midday sun (outdoor)", + "scenes": [ + { + "display_order": 0, + "scene_type": "reaction_hook", + "beat": "hook", + "framing": "close-up", + "chain_type": "ROOT", + "character_names": ["Commander_Tien"], + "has_dialogue": false, + "wardrobe_state": "sleeves rolled up, light dust on shoulders", + "prompt": "Close-up inside dim warehouse. Commander Tien stares at a pulsing red warning display, face half-lit by crimson glow. 35mm lens, shallow depth of field.", + "video_prompt": "0-3s: Close-up of Commander Tien's face illuminated by pulsing red warning light. His eyes widen, lips parting slightly. 3-6s: Slow push-in to extreme close-up. Sweat on his brow catches the red light. He swallows hard. 6-8s: His jaw sets firmly, eyes narrowing with resolve. He exhales through his nose. Static shot with subtle handheld shake. Lighting: pulsing red on one side, deep shadow on the other. Audio: low electronic alarm pulse, controlled breathing. Negative: subtitles, watermark, text overlay.", + "narrator_text": "The solar radiation warning flashes across the forecast terminal. The countdown stands at exactly thirty days.", + "music_cue": "low analog drone, ticking pulse, 60 BPM" + } + ] +} +``` + +### O.2 Pipeline Ingestion Protocol +1. Verify daemon: `curl -s http://127.0.0.1:8100/health` → `{"extension_connected": true}`. +2. Create video entry: `POST /api/videos` with `project_id`, `title`, `orientation`. +3. Create scenes: `POST /api/scenes` (only approved schema fields). +4. Patch narration: `PATCH /api/scenes/{sid}` with `{"narrator_text": "..."}`. +5. Batch generation execution: + - Reference images: `POST /api/requests/batch` with `GENERATE_CHARACTER_IMAGE`. + - Scene start images: `POST /api/requests/batch` with `GENERATE_IMAGE`. + - Veo 3 video clips: `POST /api/requests/batch` with `GENERATE_VIDEO`. + - AI Vision review: `POST /api/videos/{vid}/review?mode=light`. + - TTS narration: `POST /api/tts/generate` (Edge-TTS or OmniVoice). + - Final concatenation & audio mastering: `/fk-concat-fit-narrator`. diff --git a/skills/fk-sound-design.md b/skills/fk-sound-design.md new file mode 100644 index 000000000..1152f7a26 --- /dev/null +++ b/skills/fk-sound-design.md @@ -0,0 +1,105 @@ +# Sound Design & Audio Mastering — AI Cinematic Soundscapes + +Industry standards for multi-layer sound design, automated dynamic ducking, sub-bass rumble synthesis, and EBU R128 loudness mastering for Google Veo 3, Edge-TTS, and AI cinematic productions. + +--- + +## 1. Principles of AI Sound Design + +> *"Sound is 50 percent of the movie-going experience, and in AI cinema, sound represents 70 percent of perceived reality."* — George Lucas + +When generative AI imagery occasionally exhibits synthetic artifacts, a **rich, multi-layered, and physically grounded soundscape** anchors the viewer's subconscious, convincing the brain of physical reality. + +--- + +## 2. The 4-Layer Audio Architecture + +Every professional AI cinematic scene must be constructed from four independent acoustic strata: + +``` +LAYER 1: NARRATOR / DIALOGUE ────► Center (Mid/Mono), Crisp clarity, High presence (+2.5dB to +3.5dB) +LAYER 2: VEO 3 FOLEY & SFX ──────► Discrete impacts, Footsteps, Clashing steel, Bowstring release +LAYER 3: AMBIENCE & ROOM TONE ──► Wind howling, Falling rain, Campfire crackle, Night cicadas +LAYER 4: SCORE & SUB-BASS DRONE ─► Orchestral themes (Suno AI), War drums, 40-60Hz tactile rumble +``` + +### Acoustic Balance Matrix: + +| Audio Stratum | Generation Source | Role in Scene | Standard Level (Gain Factor) | +|:---|:---|:---|:---| +| **Layer 1: Voice (Dialogue & Narration)** | Edge-TTS (`NamMinhNeural` / `HoaiMyNeural`) | Story progression, emotional anchoring | `1.30 – 1.50` (+2.5dB to +3.5dB) | +| **Layer 2: Foley & SFX (Physical Action)** | Veo 3 Native Audio / SFX Library | Physical weight, combat impact | `0.60 – 0.80` (When dialogue absent) | +| **Layer 3: Ambience (World Acoustic)** | Veo 3 Background Audio / Field Recordings | Environmental scale & space | `0.20 – 0.30` (Auto-ducked during dialogue) | +| **Layer 4: Score & Sub-Bass Drone** | Suno AI (`/fk-gen-music`) & Brown noise | Emotional pulse & visceral tension | `0.35 – 0.50` (Score), `0.60` (Bumper drone) | + +--- + +## 3. Automated Audio Ducking Invariant + +The most common defect in amateur AI video compiles is **background audio or music drowning out spoken dialogue**. + +### FFmpeg Sidechain Ducking Formula: +When dialogue or voice narration is active, ambient sound and background music must automatically duck by **-12dB to -15dB**: + +```bash +# Mix Voice (input 1) with Ambient (input 0) applying cinema balance: +ffmpeg -y -i scene_video.mp4 -i scene_tts.wav \ + -filter_complex "[0:a]volume=0.25[bg];[1:a]volume=1.40[fg];[bg][fg]amix=inputs=2:duration=first:dropout_transition=2[aout]" \ + -map 0:v -map "[aout]" -c:v copy -c:a aac -b:a 192k output_mixed.mp4 +``` + +--- + +## 4. Sub-Bass Drone Synthesis (Suspense & Chapter Bumpers) + +Frequencies between **40Hz and 60Hz** bypass the auditory ear canal and vibrate directly in the chest cavity, creating visceral tension: + +1. **Dramatic Triggers:** + - Pre-ambush stillness, ticking clocks, impending royal betrayals. + - Chapter interstitial bumpers (creating solemn, ancient reverence). +2. **FFmpeg Procedural Sub-Bass Rumble Generation:** + ```bash + # Synthesize 3.5s of Brown Noise filtered at 48Hz for cinematic bumper transition: + ffmpeg -f lavfi -i "anoisesrc=c=brown:r=48000:a=0.3,lowpass=f=75,volume=0.6" -t 3.5 -c:a aac drone.m4a + ``` + +--- + +## 5. Broadcast & YouTube Mastering (EBU R128 Loudness) + +Before final distribution on YouTube (Shorts or Long-form) or streaming platforms, the master audio must comply with international broadcast loudness standards: +- **Integrated Loudness Target:** `-14.0 LUFS` (±1 LUFS) for YouTube (prevents YouTube's automated loudness penalty compressor from squashing dynamics). +- **True Peak Ceiling:** `-1.0 dBTP` (prevents digital clipping and inter-sample distortion on mobile DACs). +- **Loudness Range (LRA):** `7.0 to 10.0 LU` (maintains cinematic dynamic range between whispers and explosions). + +### Mastering Command via FFmpeg: +```bash +ffmpeg -i input_master.mp4 \ + -af "loudnorm=I=-14:LRA=7:TP=-1.0" \ + -c:v copy -c:a aac -b:a 256k final_master_mastered.mp4 +``` + +--- + +## 6. Procedural Foley & SFX Layering (`scripts/sfx_layering.py`) + +When scene actions feature intense physical beats (blade combat, heavy strikes, detonations, underground tremors), FlowKit's automated sound design engine scans the `prompt` or `video_prompt` to synthesize and layer synchronized sound effects: + +### Supported SFX Categories & Triggers: +- **`metal_clash`** (Keywords: `knife`, `blade`, `sword`, `dao`, `kiếm`, `chém`, `steel`): Metallic blade impact with high-frequency shimmer. +- **`heavy_impact`** (Keywords: `strike`, `slam`, `punch`, `đấm`, `va chạm`, `ngã gục`): Low-end punch with 65Hz transient thud. +- **`explosion_blast`** (Keywords: `explosion`, `blast`, `nổ`, `bomb`, `shockwave`, `lựu đạn`): Deep detonation rumble with brown noise decay. +- **`underground_drone`** (Keywords: `tầng hầm`, `b3`, `cống ngầm`, `underground`, `tunnel`): 45Hz subterranean room tone. +- **`alarm_siren`** (Keywords: `báo động`, `siren`, `alarm`, `klaxon`, `còi báo`): Modulated tactical warning siren. +- **`heartbeat_tension`** (Keywords: `tim đập`, `tension`, `gasping`, `thở dốc`, `hồi hộp`): 60 BPM physiological heartbeat pulse. + +### Automated Layering Command: +```bash +python scripts/sfx_layering.py \ + --input-video path/to/scene.mp4 \ + --prompt "0-3s: Tactical knife blade clash. 3-6s: Heavy strike against concrete." \ + --output path/to/scene_with_sfx.mp4 \ + --volume 0.6 +``` +*(Studio sample overrides can be added to `assets/sfx//` for custom studio WAV assets).* + From 4152c2a2c09f4301ad9dfba995ea47ecaf8d2311 Mon Sep 17 00:00:00 2001 From: TIENLV Date: Tue, 6 Oct 2026 19:41:59 +0700 Subject: [PATCH 60/68] test(setup): update test_setup.py to include antigravity generator target --- tests/unit/test_setup.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_setup.py b/tests/unit/test_setup.py index 3e35a13ad..62c839f52 100644 --- a/tests/unit/test_setup.py +++ b/tests/unit/test_setup.py @@ -35,6 +35,7 @@ def sandbox(setup_mod, monkeypatch, tmp_path): monkeypatch.setattr( setup_mod, "LEGACY_GEMINI_COMMANDS_DIR", tmp_path / ".gemini" / "commands" / "fk") monkeypatch.setattr(setup_mod, "LEGACY_GEMINI_MD", tmp_path / "GEMINI.md") + monkeypatch.setattr(setup_mod, "ANTIGRAVITY_SKILLS_DIR", tmp_path / ".agents" / "skills") (tmp_path / "skills").mkdir() (tmp_path / "skills" / "fk-demo.md").write_text("# fk-demo — A demo skill\n", encoding="utf-8") return tmp_path @@ -46,10 +47,17 @@ def sandbox(setup_mod, monkeypatch, tmp_path): class TestRetiredGeminiTarget: def test_gemini_is_not_a_generator_any_more(self, setup_mod): assert "gemini" not in setup_mod.TOOLS - assert set(setup_mod.TOOLS) == {"claude", "codex"} + assert set(setup_mod.TOOLS) == {"claude", "codex", "antigravity"} assert not hasattr(setup_mod, "generate_gemini") assert not hasattr(setup_mod, "generate_gemini_md") + def test_antigravity_generator_creates_skills(self, setup_mod, sandbox): + skills = setup_mod.discover_skills() + count = setup_mod.generate_antigravity(skills) + assert count > 0 + assert (sandbox / ".agents" / "skills" / "fk-demo" / "SKILL.md").exists() + + def test_a_stale_state_file_naming_gemini_does_not_crash_sync( self, setup_mod, sandbox, capsys ): From 6801f5a5304e41ff40566945008ba845447111a8 Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen Date: Sat, 24 Oct 2026 14:20:08 +0700 Subject: [PATCH 61/68] feat(image): add Nano Banana 2.1 (BELUGA), retire NARWHAL from the NANO_BANANA_2 nickname Banana 2 (NARWHAL) answers [5] NOT_FOUND on ogiZ0b in every project since early October 2026. BELUGA (the UI's beluga_display) is its successor and generates normally on the batch path. - IMAGE_MODELS accepts BELUGA and BELUGA_THINKING_{LOW,MED,HIGH}. - NANO_BANANA_2_1 -> BELUGA; NANO_BANANA_2 now lands on BELUGA too. NARWHAL still passes through when named explicitly. - Default image model is unchanged (NANO_BANANA_PRO / GEM_PIX_2). Verified live on 2026-10-24: BELUGA 200, NANO_BANANA_2 via the new mapping 200, NARWHAL [5]. BELUGA_THINKING_* not exercised live. Co-Authored-By: Claude Opus 5.5 (1M context) --- agent/models.json | 3 ++- agent/services/flow_batch.py | 13 +++++++++++-- skills/fk-change-model.md | 20 ++++++++++++++------ tests/unit/test_flow_batch.py | 7 ++++++- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/agent/models.json b/agent/models.json index 67b9c1e4a..91b609aaf 100644 --- a/agent/models.json +++ b/agent/models.json @@ -55,7 +55,8 @@ }, "image_models": { "NANO_BANANA_PRO": "GEM_PIX_2", - "NANO_BANANA_2": "NARWHAL", + "NANO_BANANA_2_1": "BELUGA", + "NANO_BANANA_2": "BELUGA", "NANO_BANANA_2_LITE": "HARBOR_SEAL" }, "default_image_model": "NANO_BANANA_PRO", diff --git a/agent/services/flow_batch.py b/agent/services/flow_batch.py index 1262966d0..852478ec3 100644 --- a/agent/services/flow_batch.py +++ b/agent/services/flow_batch.py @@ -59,13 +59,22 @@ #: ids are accepted by ``resolve_image_model`` instead of being silently #: replaced by the default, so callers can opt into a newly exposed model #: before Flow Kit itself ships another release. -IMAGE_MODELS = {"GEM_PIX_2", "NARWHAL", "HARBOR_SEAL"} +#: +#: BELUGA is Nano Banana 2.1 (the UI's `beluga_display`); the THINKING +#: variants are values 37-39 of the same enum in the Flow bundle. Banana 2 +#: (`NARWHAL`) has answered `[5]` NOT_FOUND in every project since early +#: October 2026, so the NANO_BANANA_2 nickname now lands on its successor. +IMAGE_MODELS = { + "GEM_PIX_2", "NARWHAL", "HARBOR_SEAL", + "BELUGA", "BELUGA_THINKING_LOW", "BELUGA_THINKING_MED", "BELUGA_THINKING_HIGH", +} IMAGE_MODEL = "GEM_PIX_2" #: Friendly aliases. Exact Flow wire ids work too. IMAGE_MODEL_BY_NICKNAME = { "NANO_BANANA_PRO": "GEM_PIX_2", - "NANO_BANANA_2": "NARWHAL", + "NANO_BANANA_2_1": "BELUGA", + "NANO_BANANA_2": "BELUGA", "NANO_BANANA_2_LITE": "HARBOR_SEAL", "NANO_BANANA_LITE": "HARBOR_SEAL", } diff --git a/skills/fk-change-model.md b/skills/fk-change-model.md index 5cba5f6ba..d0a777ef5 100644 --- a/skills/fk-change-model.md +++ b/skills/fk-change-model.md @@ -29,9 +29,11 @@ So changing a Landscape vs Portrait key has **no effect** on the batch path — only the quality tier survives the fold. `r2v` and `start_end` keys are moot there too: both are unported. -Image models are unaffected: `GEM_PIX_2` (Nano Banana Pro) and `NARWHAL` -(Banana 2) are both accepted, and `default_image_model` in `models.json` picks -which nickname is used. +Image models are unaffected: `GEM_PIX_2` (Nano Banana Pro), `BELUGA` +(Nano Banana 2.1, plus `BELUGA_THINKING_LOW/MED/HIGH`) and `HARBOR_SEAL` +(2 Lite) are accepted, and `default_image_model` in `models.json` picks which +nickname is used. `NARWHAL` (Banana 2) answers `[5]` NOT_FOUND since October +2026; the `NANO_BANANA_2` nickname now maps to `BELUGA`. ## Step 1: Show Current Models @@ -57,7 +59,9 @@ Display in a readable table: | Key | Model | |-----|-------| | NANO_BANANA_PRO | `GEM_PIX_2` | -| NANO_BANANA_2 | `NARWHAL` | +| NANO_BANANA_2_1 | `BELUGA` | +| NANO_BANANA_2 | `BELUGA` (was `NARWHAL`, retired) | +| NANO_BANANA_2_LITE | `HARBOR_SEAL` | ### Upscale Models @@ -82,7 +86,8 @@ After user picks, apply the matching preset from the Quick Switch Presets sectio **For image model:** Use `AskUserQuestion` with options: - label: "GEM_PIX_2 (Recommended)", description: "Gemini Pix 2 · current default" -- label: "NARWHAL", description: "Alternative image model" +- label: "BELUGA", description: "Nano Banana 2.1" +- label: "HARBOR_SEAL", description: "Nano Banana 2 Lite" ## Step 3: Change a Model (Manual) @@ -231,7 +236,10 @@ curl -s -X PATCH http://127.0.0.1:8100/api/models \ | Key | Description | |-----|-------------| | `GEM_PIX_2` | Gemini Pix 2 (current default) | -| `NARWHAL` | Narwhal model | +| `BELUGA` | Nano Banana 2.1 | +| `BELUGA_THINKING_LOW` / `_MED` / `_HIGH` | Nano Banana 2.1 with thinking | +| `HARBOR_SEAL` | Nano Banana 2 Lite | +| `NARWHAL` | Nano Banana 2 — retired, answers `[5]` NOT_FOUND | ### Upscale | Key | Description | diff --git a/tests/unit/test_flow_batch.py b/tests/unit/test_flow_batch.py index 98d72fd4c..fb48f08ee 100644 --- a/tests/unit/test_flow_batch.py +++ b/tests/unit/test_flow_batch.py @@ -330,11 +330,16 @@ def test_an_unknown_aspect_name_raises_rather_than_defaulting(self): def test_nicknames_resolve_to_wire_names(self): assert fb.resolve_image_model("NANO_BANANA_PRO") == "GEM_PIX_2" - assert fb.resolve_image_model("NANO_BANANA_2") == "NARWHAL" + assert fb.resolve_image_model("NANO_BANANA_2_1") == "BELUGA" assert fb.resolve_image_model("NANO_BANANA_2_LITE") == "HARBOR_SEAL" + def test_nano_banana_2_lands_on_its_successor_not_the_retired_narwhal(self): + assert fb.resolve_image_model("NANO_BANANA_2") == "BELUGA" + def test_wire_names_and_future_model_ids_pass_through(self): assert fb.resolve_image_model("NARWHAL") == "NARWHAL" + assert fb.resolve_image_model("BELUGA") == "BELUGA" + assert fb.resolve_image_model("beluga_thinking_high") == "BELUGA_THINKING_HIGH" assert fb.resolve_image_model("harbor_seal") == "HARBOR_SEAL" assert fb.resolve_image_model("FUTURE_BANANA_3") == "FUTURE_BANANA_3" From 7ddb07911cc2731ed9ec0a99e63a104ec979add5 Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen Date: Sat, 24 Oct 2026 14:22:35 +0700 Subject: [PATCH 62/68] feat(muse2api): send entity reference images with scene images The provider dropped every reference image on the assumption that the gateway took none. It does: /v1/images/generations accepts `image` as a data URL or a list of them, and the browser driver attaches them to the muse.ai chat. Scenes rendered through muse2api therefore lost their characters. - Muse2APIClient.generate_image takes `images` and sends them as `image`, capped at MAX_IMAGE_REFS (4). - The provider dedupes the job's refs, keeps the first four (logging the rest) and inlines them as data URLs. - An unreadable or unreachable ref now fails the job instead of rendering the scene without its character; httpx errors on input fetch are caught like OSError/ValueError (this also covers a video's start frame). - README and /fk-provider describe the new behaviour and the billing note for gateways with wallets enabled. Co-Authored-By: Claude Opus 5.5 (1M context) --- README.md | 11 ++++-- agent/sdk/services/muse2api_provider.py | 31 ++++++++++++----- agent/services/muse2api_client.py | 15 ++++++-- skills/fk-provider.md | 3 +- tests/unit/test_muse2api_provider.py | 46 +++++++++++++++++++++++-- 5 files changed, 88 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 1fdec7d4a..e795b8c7e 100644 --- a/README.md +++ b/README.md @@ -405,9 +405,14 @@ gateway may run on another host), and downloads every result into so `/fk-refresh-urls` is never needed for it. Supports image and i2v; no edit, upscale or TTS, and no end frame or r2v unless -`MUSE2API_ALLOW_DEGRADED=1`. Entity reference images are not sent (muse.ai takes -none), so character consistency across scenes is weaker than on Flow. -Troubleshooting lives in `/fk-provider` and `/fk-doctor`. +`MUSE2API_ALLOW_DEGRADED=1`. Entity reference images are sent with each scene +image (up to four, inline as data URLs; extra refs are dropped and logged), and +a ref that cannot be read fails the job rather than rendering the scene without +its character. + +If the gateway runs with billing enabled, every call is charged to the wallet of +the key in `MUSE2API_KEY`. Use the admin key or a key marked `unlimited` for +Flow Kit. Troubleshooting lives in `/fk-provider` and `/fk-doctor`. ### Post-production (provider-neutral) diff --git a/agent/sdk/services/muse2api_provider.py b/agent/sdk/services/muse2api_provider.py index 3cad78b0b..d58b9503c 100644 --- a/agent/sdk/services/muse2api_provider.py +++ b/agent/sdk/services/muse2api_provider.py @@ -16,8 +16,8 @@ What muse.ai can and cannot do shapes the capabilities: -* image — text-to-image. Reference images are not an input the - gateway accepts, so entity refs are dropped (logged). +* image — text-to-image, with up to four entity refs sent inline as + data URLs (extra refs are dropped, logged). * video (i2v) — first frame + prompt. * chained video — no end-frame input: fails unless MUSE2API_ALLOW_DEGRADED=1, which drops the end frame and renders plain i2v. @@ -34,6 +34,8 @@ from pathlib import Path from urllib.parse import unquote, urlparse +import httpx + from agent import config from agent.sdk.services.assistant_provider import _image_result, _video_result from agent.sdk.services.provider_base import ( @@ -44,7 +46,12 @@ ProviderCapabilities, ProviderJob, ) -from agent.services.muse2api_client import Muse2APIClient, Muse2APIError, to_data_url +from agent.services.muse2api_client import ( + MAX_IMAGE_REFS, + Muse2APIClient, + Muse2APIError, + to_data_url, +) from agent.utils.paths import file_url_to_path logger = logging.getLogger(__name__) @@ -113,8 +120,8 @@ async def run(self, job: ProviderJob) -> dict: except Muse2APIError as e: logger.error("muse2api: job %s (%s) failed: %s", job.job_id[:12], job.kind, e) return {"error": str(e)} - except (OSError, ValueError) as e: - # Unreadable input image, full disk, bad base64 … + except (OSError, ValueError, httpx.HTTPError) as e: + # Unreadable or unreachable input image, full disk, bad base64 … logger.error("muse2api: job %s (%s) failed: %s", job.job_id[:12], job.kind, e) return {"error": f"muse2api: {e}"} return {"error": f"muse2api provider does not support job kind '{job.kind}'"} @@ -124,11 +131,17 @@ async def _run_image(self, job: ProviderJob) -> dict: composition = (job.extra or {}).get("composition") if composition: prompt = f"{prompt}\n\nComposition: {composition}" - if job.reference_urls: - logger.info("muse2api: job %s — %d reference image(s) dropped, the " - "gateway takes no image refs", job.job_id[:12], len(job.reference_urls)) + refs = list(dict.fromkeys(job.reference_urls or [])) + if len(refs) > MAX_IMAGE_REFS: + logger.warning("muse2api: job %s — %d reference images, the gateway takes " + "%d; dropping the rest", job.job_id[:12], len(refs), MAX_IMAGE_REFS) + refs = refs[:MAX_IMAGE_REFS] + # An unreadable ref fails the job (OSError/ValueError in run()) rather + # than quietly rendering a scene without its character. + images = [await to_data_url(ref) for ref in refs] data = await self.client.generate_image( - prompt, model=config.MUSE2API_IMAGE_MODEL, size=_ASPECT.get(job.orientation)) + prompt, model=config.MUSE2API_IMAGE_MODEL, size=_ASPECT.get(job.orientation), + images=images or None) url = await self._save(job.job_id, data, _image_ext(data)) mid = str(uuid.uuid4()) logger.info("muse2api: image %s ready (media_id=%s)", job.job_id[:12], mid[:8]) diff --git a/agent/services/muse2api_client.py b/agent/services/muse2api_client.py index 6beeafea6..89d896ecb 100644 --- a/agent/services/muse2api_client.py +++ b/agent/services/muse2api_client.py @@ -3,7 +3,7 @@ muse2api exposes the muse.ai web app as an OpenAI-compatible API. Flow Kit only needs the media half of it: - POST /v1/images/generations prompt -> image(s) (synchronous) + POST /v1/images/generations prompt (+ up to 4 refs) -> image (synchronous) POST /v1/videos prompt (+first frame) -> task GET /v1/videos/{task_id} task status; result.url when succeeded GET /v1/media/{name} download generated media (public) @@ -38,6 +38,8 @@ logger = logging.getLogger(__name__) TERMINAL_OK = "succeeded" +#: The gateway's ``image`` field on /v1/images/generations takes up to four refs. +MAX_IMAGE_REFS = 4 TERMINAL_FAILED = ("failed", "cancelled") @@ -142,11 +144,18 @@ async def readyz(self) -> dict: # ── Images ── - async def generate_image(self, prompt: str, *, model: str, size: str | None) -> bytes: - """Generate one image and return its bytes (b64_json: no second download).""" + async def generate_image(self, prompt: str, *, model: str, size: str | None, + images: list[str] | None = None) -> bytes: + """Generate one image and return its bytes (b64_json: no second download). + + ``images`` are reference images as data URLs; the gateway attaches + them to the muse.ai chat and takes at most :data:`MAX_IMAGE_REFS`. + """ body = {"prompt": prompt, "model": model, "n": 1, "response_format": "b64_json"} if size: body["size"] = size + if images: + body["image"] = images[:MAX_IMAGE_REFS] data = await self._request("POST", "/v1/images/generations", json=body, timeout=self.timeout_s) items = data.get("data") or [] diff --git a/skills/fk-provider.md b/skills/fk-provider.md index c51e54044..9b6c4f917 100644 --- a/skills/fk-provider.md +++ b/skills/fk-provider.md @@ -52,7 +52,8 @@ audio — it is rejected with 400.) - `assistant`: image, edit_image, i2v, r2v, **audio (TTS)**. No upscale. - `muse2api`: image, i2v. No edit_image, upscale or audio. No end frame and no r2v unless `MUSE2API_ALLOW_DEGRADED=1` (then both render as plain i2v). - Entity reference images are not sent — muse.ai takes none. + Entity reference images are sent with scene images (up to four; an + unreadable ref fails the job). Asking a provider for a kind it doesn't support returns 400 with a message naming the right backend to use instead. diff --git a/tests/unit/test_muse2api_provider.py b/tests/unit/test_muse2api_provider.py index 2c179c4a8..17b58065f 100644 --- a/tests/unit/test_muse2api_provider.py +++ b/tests/unit/test_muse2api_provider.py @@ -88,9 +88,9 @@ def start_image(tmp_path): return "file://" + str(p) -async def test_image_is_saved_locally_with_minted_uuid(provider, gateway): +async def test_image_is_saved_locally_with_minted_uuid(provider, gateway, start_image): job = ProviderJob(job_id="img1", kind=KIND_IMAGE, prompt="a fox", - orientation="HORIZONTAL", reference_urls=("file:///x.png",), + orientation="HORIZONTAL", reference_urls=(start_image,), extra={"composition": "wide establishing shot"}) result = await provider.run(job) @@ -106,6 +106,48 @@ async def test_image_is_saved_locally_with_minted_uuid(provider, gateway): assert body["model"] == "muse-image" assert body["response_format"] == "b64_json" assert "wide establishing shot" in body["prompt"] + assert body["image"] == ["data:image/png;base64," + base64.b64encode(PNG).decode()] + + +async def test_image_without_refs_sends_no_image_field(provider, gateway): + job = ProviderJob(job_id="img2", kind=KIND_IMAGE, prompt="a fox", orientation="VERTICAL") + assert parse_result(await provider.run(job), "GENERATE_IMAGE").success + assert "image" not in gateway.calls[0][2] + + +async def test_image_refs_are_deduped_and_capped_at_four(provider, gateway, tmp_path): + refs = [] + for i in range(6): + p = tmp_path / f"ref{i}.png" + p.write_bytes(PNG + bytes([i])) + refs.append("file://" + str(p)) + job = ProviderJob(job_id="img3", kind=KIND_IMAGE, prompt="a fox", + orientation="VERTICAL", reference_urls=(refs[0], refs[0], *refs[1:])) + assert parse_result(await provider.run(job), "GENERATE_IMAGE").success + + sent = gateway.calls[0][2]["image"] + assert len(sent) == 4 + assert sent == ["data:image/png;base64," + base64.b64encode(PNG + bytes([i])).decode() + for i in range(4)] + + +async def test_unreadable_ref_fails_the_job_instead_of_dropping_the_character(provider, gateway): + job = ProviderJob(job_id="img4", kind=KIND_IMAGE, prompt="a fox", + orientation="VERTICAL", reference_urls=("file:///no/such/ref.png",)) + result = await provider.run(job) + assert "error" in result and "ref.png" in result["error"] + assert gateway.calls == [] + + +async def test_unreachable_http_ref_fails_the_job(provider, gateway, monkeypatch): + async def boom(ref, **_): + raise httpx.ConnectError("no route", request=httpx.Request("GET", ref)) + monkeypatch.setattr(mp, "to_data_url", boom) + job = ProviderJob(job_id="img5", kind=KIND_IMAGE, prompt="a fox", + orientation="VERTICAL", reference_urls=("https://cdn.test/ref.png",)) + result = await provider.run(job) + assert result["error"].startswith("muse2api: ") + assert gateway.calls == [] async def test_video_sends_first_frame_inline_and_polls(provider, gateway, start_image): From 0c6c041613e5d2f8920d13dae8c1f3fe6a7cc8b4 Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen Date: Sun, 25 Oct 2026 00:25:34 +0700 Subject: [PATCH 63/68] fix(flow): keep the unusual-activity hold across restarts, bound hijack retries Issue #67 reports accounts whose manual Flow UI generation was blocked after FlowKit testing; retrying into the block is a suspected cause. - The generation hold after PUBLIC_ERROR_UNUSUAL_ACTIVITY is written to flow_generation_hold.json and restored on start, so a restart no longer lifts it. FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S defaults to 3600 (was 120). A shorter hold never replaces a longer one or its reason. - [HIJACK] extension_hijack_detected was requeued forever without counting; it now fails once retry_count reaches 3. - Any "unusual_activity" spelling is terminal; a bare code no longer falls into the 10x reCAPTCHA retry loop. - POST /api/flow/clear-hijack clears the file too; /api/flow/status reports the hold's reason. Takes the persistent-hold and bounded-retry ideas of #68 onto the current batch transport. Co-Authored-By: Claude Opus 5.5 (1M context) --- .gitignore | 2 + agent/api/flow.py | 14 ++--- agent/config.py | 6 +- agent/services/flow_client.py | 75 +++++++++++++++++++----- agent/worker/processor.py | 31 ++++++---- skills/fk-doctor.md | 3 +- tests/conftest.py | 8 +++ tests/unit/test_flow_global_throttle.py | 78 +++++++++++++++++++++++++ tests/unit/test_processor.py | 33 +++++++++++ 9 files changed, 215 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 8f770c988..4a856497c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ __pycache__/ *.db-shm *.db-wal *.db-journal +flow_generation_hold.json +flow_generation_hold.tmp .env output/ youtube/channels/ diff --git a/agent/api/flow.py b/agent/api/flow.py index 7ed3602ca..18f9859be 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -201,19 +201,15 @@ async def extension_status(): @router.post("/clear-hijack") async def clear_hijack_cooldown(): - """Reset the generation cooldown triggered by extension_hijack_detected. + """Lift the generation hold (hijack or unusual-activity) by hand, including + the copy on disk. - Call this after deploying the bypass fix to immediately resume generation - without waiting for the cooldown to expire. + Only do this once the account generates normally in the Flow UI again: + submitting into an active unusual-activity block may prolong it. """ - import time as _time - client = get_flow_client() - old_until = client._generation_unusual_until - client._generation_unusual_until = 0.0 - was_active = old_until > 0.0 and old_until > _time.monotonic() return { "cleared": True, - "was_active": was_active, + "was_active": get_flow_client().clear_generation_hold(), } diff --git a/agent/config.py b/agent/config.py index 42aa2c459..574c208c5 100644 --- a/agent/config.py +++ b/agent/config.py @@ -41,9 +41,13 @@ FLOW_GENERATION_MAX_CONCURRENT = max( 1, int(os.environ.get("FLOW_GENERATION_MAX_CONCURRENT", "1")) ) +# After Google answers PUBLIC_ERROR_UNUSUAL_ACTIVITY, no generation is submitted +# for this long. The hold is written to FLOW_GENERATION_HOLD_PATH so a restart +# does not lift it (#67): retrying into the block may be what prolongs it. FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S = max( - 0.0, float(os.environ.get("FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S", "120")) + 0.0, float(os.environ.get("FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S", "3600")) ) +FLOW_GENERATION_HOLD_PATH = BASE_DIR / "flow_generation_hold.json" FLOW_SESSION_PROJECT_IDLE_S = max( 300.0, float(os.environ.get("FLOW_SESSION_PROJECT_IDLE_S", "7200")) ) diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index e16e11abe..874a2f57d 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -29,7 +29,7 @@ FLOW_PROJECT_ID, FLOW_ALLOW_DEGRADED, DEFAULT_PAYGATE_TIER, FLOW_GENERATION_MIN_INTERVAL_S, FLOW_GENERATION_MAX_CONCURRENT, - FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, + FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, FLOW_GENERATION_HOLD_PATH, ) from agent import config as _config from agent.services import flow_batch as fb @@ -72,6 +72,8 @@ def __init__(self): self._generation_unusual_until = 0.0 self._generation_last_unusual_at: Optional[float] = None self._generation_last_unusual_rpc: Optional[str] = None + self._generation_hold_reason: Optional[str] = None + self._load_generation_hold() # WS stats self._ws_connect_count = 0 self._ws_disconnect_count = 0 @@ -204,12 +206,66 @@ def set_flow_key(self, key: str): def connected(self) -> bool: return bool(self._extensions) + def _set_generation_hold(self, seconds: float, reason: str, rpcid: str) -> None: + """Stop generation submits for ``seconds`` and record it on disk, so a + restart keeps the hold. A longer hold already in place is kept, with + its reason.""" + until = time.monotonic() + seconds + if until <= self._generation_unusual_until: + return + self._generation_unusual_until = until + self._generation_last_unusual_at = time.time() + self._generation_last_unusual_rpc = rpcid + self._generation_hold_reason = reason + tmp = FLOW_GENERATION_HOLD_PATH.with_suffix(".tmp") + try: + tmp.write_text(json.dumps({ + "until": time.time() + seconds, + "reason": reason, + "rpc": rpcid, + "at": self._generation_last_unusual_at, + })) + tmp.replace(FLOW_GENERATION_HOLD_PATH) + except OSError as exc: + logger.warning("Could not persist the generation hold: %s", exc) + + def _load_generation_hold(self) -> None: + try: + hold = json.loads(FLOW_GENERATION_HOLD_PATH.read_text()) + remaining = float(hold["until"]) - time.time() + except FileNotFoundError: + return + except (OSError, ValueError, KeyError, TypeError) as exc: + logger.warning("Ignoring unreadable generation hold %s: %s", + FLOW_GENERATION_HOLD_PATH, exc) + return + if remaining <= 0: + return + self._generation_unusual_until = time.monotonic() + remaining + self._generation_last_unusual_at = hold.get("at") + self._generation_last_unusual_rpc = hold.get("rpc") + self._generation_hold_reason = hold.get("reason") + logger.warning("Generation hold restored from disk (%s): %.0fs left", + self._generation_hold_reason, remaining) + + def clear_generation_hold(self) -> bool: + """Lift the hold by hand. Returns whether one was active.""" + was_active = self._generation_unusual_until > time.monotonic() + self._generation_unusual_until = 0.0 + self._generation_hold_reason = None + try: + FLOW_GENERATION_HOLD_PATH.unlink(missing_ok=True) + except OSError as exc: + logger.warning("Could not remove the generation hold file: %s", exc) + return was_active + @property def generation_guard_status(self) -> dict: remaining = max(0.0, self._generation_unusual_until - time.monotonic()) return { "cooldown_active": remaining > 0, "cooldown_remaining_s": round(remaining, 3), + "cooldown_reason": self._generation_hold_reason if remaining > 0 else None, "last_unusual_activity_at": self._generation_last_unusual_at, "last_unusual_activity_rpc": self._generation_last_unusual_rpc, } @@ -567,13 +623,9 @@ async def batch_rpc(self, rpcid: str, freq: str, # x2a trap: the token was poisoned with action # "extension_hijack_detected". This is a system-level trap, # NOT an account issue — don't apply the long cooldown. - # Short pause lets the bypass re-initialise on next tab. - self._generation_unusual_until = max( - self._generation_unusual_until, - time.monotonic() + 30.0, - ) - self._generation_last_unusual_at = time.time() - self._generation_last_unusual_rpc = rpcid + # Short pause lets the bypass re-initialise on next tab; the + # worker gives up on the request after a few of these. + self._set_generation_hold(30.0, "extension_hijack_detected", rpcid) logger.error( "[HIJACK] extension_hijack_detected — captcha bypass may " "have failed; pausing generation submits for 30s" @@ -584,12 +636,9 @@ async def batch_rpc(self, rpcid: str, freq: str, else: result["error"] = "[HIJACK] extension_hijack_detected" elif is_unusual: - self._generation_unusual_until = max( - self._generation_unusual_until, - time.monotonic() + FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, + self._set_generation_hold( + FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, "unusual_activity", rpcid, ) - self._generation_last_unusual_at = time.time() - self._generation_last_unusual_rpc = rpcid logger.warning( "Google unusual-activity block detected; pausing generation submits for %.0fs", FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, diff --git a/agent/worker/processor.py b/agent/worker/processor.py index 1acf65ba6..336f60542 100644 --- a/agent/worker/processor.py +++ b/agent/worker/processor.py @@ -20,6 +20,11 @@ logger = logging.getLogger(__name__) +# A failed captcha bypass gives up once the request's retry_count reaches this, +# instead of retrying forever (#67). The count is shared with other retries, +# which only makes it stop sooner. +HIJACK_MAX_RETRIES = 3 + _API_CALL_TYPES = {"GENERATE_IMAGE", "REGENERATE_IMAGE", "EDIT_IMAGE", "GENERATE_VIDEO", "REGENERATE_VIDEO", "GENERATE_VIDEO_REFS", "UPSCALE_VIDEO", "GENERATE_CHARACTER_IMAGE", "REGENERATE_CHARACTER_IMAGE", @@ -492,16 +497,20 @@ async def _handle_failure(rid: str, req: dict, result: dict, retry_after: dict = error_lower = str(error_msg).lower() # [HIJACK] extension_hijack_detected — the captcha bypass failed and the - # token was poisoned by x2a. This is a system-level trap, NOT an account - # issue. Don't burn retry count — the bypass may succeed on the next - # attempt once the tab re-initializes. + # token was poisoned by x2a. The bypass may succeed once the tab + # re-initializes, but each retry is another submit Google can see, so + # give up after HIJACK_MAX_RETRIES (#67). if "[hijack]" in error_lower or "extension_hijack" in error_lower: - await crud.update_request(rid, status="PENDING", error_message=str(error_msg)) - logger.error( - "Request %s [HIJACK] captcha bypass failed — will retry without " - "counting (system error, not account error): %s", - rid[:8], error_msg, - ) + retry = req.get("retry_count", 0) + 1 + if retry < HIJACK_MAX_RETRIES: + await crud.update_request(rid, status="PENDING", retry_count=retry, error_message=str(error_msg)) + logger.error("Request %s [HIJACK] captcha bypass failed (retry %d/%d): %s", + rid[:8], retry, HIJACK_MAX_RETRIES, error_msg) + else: + await crud.update_request(rid, status="FAILED", error_message=str(error_msg)) + await _mark_scene_failed(req) + logger.error("Request %s FAILED after %d [HIJACK] attempts: %s", + rid[:8], retry, error_msg) return # PUBLIC_ERROR_UNUSUAL_ACTIVITY is a Google anti-abuse/session trust block, @@ -509,7 +518,7 @@ async def _handle_failure(rid: str, req: dict, result: dict, retry_after: dict = # loop only creates more generation submits while Google is asking us to # slow down, so stop this request and require an explicit resubmit after # the session/network has recovered. - if "public_error_unusual_activity" in error_lower or "unusual activity" in error_lower: + if "unusual_activity" in error_lower or "unusual activity" in error_lower: await crud.update_request(rid, status="FAILED", error_message=str(error_msg)) await _mark_scene_failed(req) logger.error("Request %s FAILED (Google unusual-activity block; manual recovery required): %s", @@ -531,7 +540,7 @@ async def _handle_failure(rid: str, req: dict, result: dict, retry_after: dict = return # reCAPTCHA errors: retry up to 10 times — deferred dict in main loop handles delay - if "captcha" in error_lower or "recaptcha" in error_lower or "unusual_activity" in error_lower: + if "captcha" in error_lower or "recaptcha" in error_lower: retry = req.get("retry_count", 0) + 1 if retry < 10: await crud.update_request(rid, status="PENDING", retry_count=retry, error_message=str(error_msg)) diff --git a/skills/fk-doctor.md b/skills/fk-doctor.md index a2fc34b8a..8de0f611d 100644 --- a/skills/fk-doctor.md +++ b/skills/fk-doctor.md @@ -150,7 +150,8 @@ Detection lives in `agent/worker/_parsing.py:_is_error`. A result is treated as | `NO_INJECTION_RESULT` | `chrome.scripting.executeScript` resolved with no frame result (`background.js:540`), so the envelope never ran — the Flow tab went away or was still booting at the moment of the call. Most likely on the first captcha-bearing RPC after an agent restart | Retried with backoff, counts against `MAX_RETRIES` | Usually transient — retry first. Rule out the lookalikes before digging: a failed mint reports `CAPTCHA_FAILED`, an oversized payload is not it (`MAX_RPC_TEXT` is 32 MB), and a structured-clone failure surfaces as 500, not 502. If it repeats, pin the Flow tab and reload the extension | | `NO_FLOW_PROJECT` | A low-level caller reached batchexecute without a project id | **Terminal — not retried** | Use `POST /api/projects` to create a real Flow project, or call a public `/api/flow/*` endpoint without `project_id` so the session-project lease resolves one automatically | | `UNSUPPORTED_ON_BATCH_API` | A capability whose payload was never captured off the new UI, all on the Veo path: **video upscale**, **Veo r2v**, **Veo start+end-frame chaining**. Every Omni mode is ported, so this never names Omni any more | **Terminal — not retried** | For chaining and r2v, `FLOW_ALLOW_DEGRADED=1` falls back to plain i2v off the start frame. Upscale has no fallback. Real fix: capture the payload — `docs/CAPTURE.md` | -| `PUBLIC_ERROR_UNUSUAL_ACTIVITY` | Google rejected the generation as unusual activity / reCAPTCHA risk evaluation | **Do not auto-retry** — repeated submits can prolong the block | Pause generation submits, keep the browser/session/network stable, and retry manually only after the trust signal has had time to recover | +| `PUBLIC_ERROR_UNUSUAL_ACTIVITY` | Google rejected the generation as unusual activity / reCAPTCHA risk evaluation | **Do not auto-retry** — repeated submits can prolong the block | FlowKit holds all generation submits for `FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S` (default 3600s); the hold is saved to `flow_generation_hold.json` and survives a restart — see `GET /api/flow/status` → `generation_throttle`. Keep the browser/session/network stable. Lift it early (`POST /api/flow/clear-hijack`) only once manual generation in the Flow UI works again | +| `[HIJACK] extension_hijack_detected` | The page's reCAPTCHA wrapper marked the token as coming from an extension; the bypass did not capture the pristine `execute` | Retried after a 30s hold, **at most 3 attempts**, then `FAILED` | Reload the Flow tab and resubmit once. If it keeps failing, stop and check that manual generation in the Flow UI still works before trying again | | `no ogiZ0b envelope in response` | The RPC answered but not with the payload we came for — usually a signed-out page returning an HTML redirect | Retried with backoff | Re-sign in on the Flow tab | | `Polling timeout after Ns: Media not found.` | The job never produced media inside the budget | Terminal after `MAX_RETRIES` | The quoted complaint is a **diagnostic, not the cause** — finished jobs report it too. Check the Flow UI: if the clip is there, raise `VIDEO_POLL_TIMEOUT` | diff --git a/tests/conftest.py b/tests/conftest.py index 90e1b9956..922b894eb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -164,3 +164,11 @@ async def test_db(tmp_path, monkeypatch): yield tmp_path / "test.db" await schema.close_db() schema._db_connection = None + + +@pytest.fixture(autouse=True) +def _generation_hold_path(tmp_path, monkeypatch): + """Keep FlowClient's persisted generation hold out of the real agent dir.""" + path = tmp_path / "flow_generation_hold.json" + monkeypatch.setattr("agent.services.flow_client.FLOW_GENERATION_HOLD_PATH", path) + return path diff --git a/tests/unit/test_flow_global_throttle.py b/tests/unit/test_flow_global_throttle.py index 9fed7740a..b34986526 100644 --- a/tests/unit/test_flow_global_throttle.py +++ b/tests/unit/test_flow_global_throttle.py @@ -74,3 +74,81 @@ async def fake_send(method, params, timeout=300): result = await client.batch_rpc("meta", "x") assert result["status"] == 200 assert calls == 1 + + +async def _unusual(client, monkeypatch): + async def fake_send(method, params, timeout=300): + return {"status": 200, "data": "PUBLIC_ERROR_UNUSUAL_ACTIVITY"} + + monkeypatch.setattr(client, "_send", fake_send) + await client.batch_rpc("a", "x", captcha_action=fb.CAPTCHA_IMAGE) + + +@pytest.mark.asyncio +async def test_unusual_activity_hold_survives_a_restart(monkeypatch, _generation_hold_path): + monkeypatch.setattr(fc, "FLOW_GENERATION_MIN_INTERVAL_S", 0.0) + monkeypatch.setattr(fc, "FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S", 3600.0) + await _unusual(fc.FlowClient(), monkeypatch) + assert _generation_hold_path.exists() + + restarted = fc.FlowClient() + calls = 0 + + async def fake_send(method, params, timeout=300): + nonlocal calls + calls += 1 + return {"status": 200, "data": "ok"} + + monkeypatch.setattr(restarted, "_send", fake_send) + result = await restarted.batch_rpc("b", "y", captcha_action=fb.CAPTCHA_VIDEO) + assert result["status"] == 429 and calls == 0 + status = restarted.generation_guard_status + assert status["cooldown_reason"] == "unusual_activity" + assert 3590 < status["cooldown_remaining_s"] <= 3600 + + +def test_expired_or_unreadable_hold_is_ignored(_generation_hold_path): + _generation_hold_path.write_text('{"until": 1, "reason": "unusual_activity"}') + assert fc.FlowClient().generation_guard_status["cooldown_active"] is False + _generation_hold_path.write_text("not json") + assert fc.FlowClient().generation_guard_status["cooldown_active"] is False + + +@pytest.mark.asyncio +async def test_clear_lifts_the_hold_and_its_file(monkeypatch, _generation_hold_path): + monkeypatch.setattr(fc, "FLOW_GENERATION_MIN_INTERVAL_S", 0.0) + client = fc.FlowClient() + await _unusual(client, monkeypatch) + assert client.clear_generation_hold() is True + assert not _generation_hold_path.exists() + assert fc.FlowClient().generation_guard_status["cooldown_active"] is False + assert client.clear_generation_hold() is False + + +@pytest.mark.asyncio +async def test_hijack_sets_a_short_hold(monkeypatch, _generation_hold_path): + monkeypatch.setattr(fc, "FLOW_GENERATION_MIN_INTERVAL_S", 0.0) + client = fc.FlowClient() + + async def fake_send(method, params, timeout=300): + return {"status": 200, "error": "extension_hijack_detected"} + + monkeypatch.setattr(client, "_send", fake_send) + result = await client.batch_rpc("a", "x", captcha_action=fb.CAPTCHA_IMAGE) + assert result["error"].startswith("[HIJACK]") + status = client.generation_guard_status + assert status["cooldown_reason"] == "extension_hijack_detected" + assert 0 < status["cooldown_remaining_s"] <= 30 + + +@pytest.mark.asyncio +async def test_a_shorter_hold_keeps_the_longer_one_and_its_reason(monkeypatch, _generation_hold_path): + monkeypatch.setattr(fc, "FLOW_GENERATION_MIN_INTERVAL_S", 0.0) + monkeypatch.setattr(fc, "FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S", 3600.0) + client = fc.FlowClient() + await _unusual(client, monkeypatch) + client._set_generation_hold(30.0, "extension_hijack_detected", "b") + status = client.generation_guard_status + assert status["cooldown_reason"] == "unusual_activity" + assert status["cooldown_remaining_s"] > 3590 + assert fc.FlowClient().generation_guard_status["cooldown_reason"] == "unusual_activity" diff --git a/tests/unit/test_processor.py b/tests/unit/test_processor.py index c615912c3..682aaa490 100644 --- a/tests/unit/test_processor.py +++ b/tests/unit/test_processor.py @@ -7,6 +7,7 @@ _is_already_completed, _mark_scene_failed, _handle_failure, + HIJACK_MAX_RETRIES, ) from agent.config import MAX_RETRIES @@ -202,6 +203,38 @@ async def test_unusual_activity_is_not_retried_as_captcha(self): assert "retry_count" not in call_kwargs[1] mock_crud.update_scene.assert_awaited_once_with("scene-001", vertical_video_status="FAILED") + @pytest.mark.asyncio + async def test_bare_unusual_activity_code_is_not_retried(self): + req = make_req(retry_count=0) + with patch("agent.worker.processor.crud") as mock_crud: + mock_crud.update_request = AsyncMock() + mock_crud.update_scene = AsyncMock() + await _handle_failure(req["id"], req, {"error": "UNUSUAL_ACTIVITY"}) + assert mock_crud.update_request.call_args[1]["status"] == "FAILED" + assert "retry_count" not in mock_crud.update_request.call_args[1] + + @pytest.mark.asyncio + async def test_hijack_is_retried_and_counted(self): + req = make_req(retry_count=0) + with patch("agent.worker.processor.crud") as mock_crud: + mock_crud.update_request = AsyncMock() + mock_crud.update_scene = AsyncMock() + await _handle_failure(req["id"], req, {"error": "[HIJACK] extension_hijack_detected"}) + kwargs = mock_crud.update_request.call_args[1] + assert kwargs["status"] == "PENDING" and kwargs["retry_count"] == 1 + mock_crud.update_scene.assert_not_awaited() + + @pytest.mark.asyncio + async def test_hijack_fails_after_the_limit(self): + req = make_req(req_type="GENERATE_IMAGE", scene_id="scene-001", + retry_count=HIJACK_MAX_RETRIES - 1) + with patch("agent.worker.processor.crud") as mock_crud: + mock_crud.update_request = AsyncMock() + mock_crud.update_scene = AsyncMock() + await _handle_failure(req["id"], req, {"error": "[HIJACK] extension_hijack_detected"}) + assert mock_crud.update_request.call_args[1]["status"] == "FAILED" + mock_crud.update_scene.assert_awaited_once_with("scene-001", vertical_image_status="FAILED") + @pytest.mark.asyncio async def test_extracts_error_message_from_nested_data(self): """Error message extraction from data.error.message should work.""" From 2bd2024641f58c3e21927465183f928377c6f459 Mon Sep 17 00:00:00 2001 From: Hoang Tuan Nguyen Date: Sun, 25 Oct 2026 18:17:16 +0700 Subject: [PATCH 64/68] docs: account-safety hold and BELUGA image model in README and IMAGE_API Co-Authored-By: Claude Opus 5.5 (1M context) --- README.md | 30 ++++++++++++++++++++++++++---- docs/IMAGE_API.md | 7 +++++-- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e795b8c7e..77d56ab34 100644 --- a/README.md +++ b/README.md @@ -273,6 +273,8 @@ extension are not needed for muse2api requests. Full setup: |---------|---------|--------------| | `FLOW_PROJECT_ID` | — | The Flow project every RPC is scoped to. Required. | | `FLOW_ALLOW_DEGRADED` | `0` | `1` lets scene chaining and r2v fall back to plain i2v instead of failing. | +| `FLOW_GENERATION_MAX_CONCURRENT` / `FLOW_GENERATION_MIN_INTERVAL_S` | `1` / `3` | Every CAPTCHA-bearing Flow generation submit is serialised and spaced by at least this many seconds. | +| `FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S` | `3600` | After Google answers `PUBLIC_ERROR_UNUSUAL_ACTIVITY`, no generation is submitted for this long. The hold is saved to `flow_generation_hold.json` and survives a restart; see [Account safety](#account-safety). | | `DEFAULT_PAYGATE_TIER` | `PAYGATE_TIER_TWO` | Carried for the DB and dashboard; no longer selects a model. | | `MEDIA_PROVIDER` | `flow` | `flow` (Google Flow via extension) or `assistant` (route all generation to the AI assistant). | | `ASSISTANT_PROVIDER_TIMEOUT_S` | `1800` | How long a request waits for a worker to complete its provider job before failing. | @@ -447,9 +449,12 @@ fallback only runs when the extension is connected. ### Image API -The migrated image path supports Nano Banana Pro, Nano Banana 2 and Nano Banana -2 Lite, all five current aspect ratios, 1-4 outputs, true base-image editing and -native 2K image export. Exact future Flow image model wire ids pass through +The migrated image path supports Nano Banana Pro (`GEM_PIX_2`, the default), +Nano Banana 2.1 (`BELUGA`, plus `BELUGA_THINKING_LOW/MED/HIGH`) and Nano Banana 2 +Lite (`HARBOR_SEAL`), all five current aspect ratios, 1-4 outputs, true +base-image editing and native 2K image export. Nano Banana 2 (`NARWHAL`) answers +`[5] NOT_FOUND` since October 2026, so the `NANO_BANANA_2` nickname now maps to +`BELUGA`; switch with `/fk-change-model`. Exact future Flow image model wire ids pass through without being silently replaced by the default model. See [`docs/IMAGE_API.md`](docs/IMAGE_API.md). @@ -915,12 +920,29 @@ drawtext` shows whether yours has it. - **Reference blocking** — scene image gen refuses if any referenced entity is missing `media_id` - **Skip completed** — won't re-generate already-completed assets - **Cascade clear** — regenerating image auto-resets downstream video + upscale -- **Retry** — failed requests retry up to 5 times +- **Retry** — failed requests retry up to 5 times, except the account-safety cases below - **UUID enforcement** — extracts UUID from fifeUrl if response doesn't provide it directly - **Voice context** — auto-appends character `voice_description` to video prompts - **No background music** — auto-appends "no background music, keep sound effects" to all video prompts - **Dual video response schema** — Lite/Fast/Ultra models return `operations[]` and stream URLs; Low Priority models (`veo_3_1_*_low_priority`, `*_ultra_relaxed`) return `workflows + media` with the MP4 inline as base64. The SDK auto-detects, validates the `ftyp` magic, and saves the binary to `output/_workflow_videos/{media_id}.mp4`. The scene's `_video_url` is then a `file://` path which `curl` and `ffmpeg` handle natively. `_video_media_id` always stores the real Flow media UUID, so upscale works for both schemas. +### Account safety + +Some users reported Google accounts whose manual Flow UI generation was refused +after FlowKit testing ([#67](https://github.com/crisng95/flowkit/issues/67)). +Submitting more generations into a Google anti-abuse block may prolong it, so +FlowKit stops instead of retrying: + +- **`PUBLIC_ERROR_UNUSUAL_ACTIVITY`** (any spelling) fails the request at once + and holds every further generation submit for `FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S` + (1 hour by default). The hold is written to `flow_generation_hold.json`, so + restarting the agent does not lift it. Media reads and polling keep working. +- **`[HIJACK] extension_hijack_detected`** (the reCAPTCHA bypass failed) pauses + submits for 30s and is retried at most 3 times, then the request fails. +- `GET /api/flow/status` → `generation_throttle` shows whether a hold is active, + its reason and the seconds left. `POST /api/flow/clear-hijack` lifts it by + hand — only do that once manual generation in the Flow UI works again. + ### Default Model & Tier Compatibility The default for `PAYGATE_TIER_TWO` `frame_2_video` and `start_end_frame_2_video` is `veo_3_1_i2v_lite_low_priority` — the TRUE 0-credit Low Priority that works on every service tier including `SERVICE_TIER_ADVANCED`. diff --git a/docs/IMAGE_API.md b/docs/IMAGE_API.md index 64130dde6..89ad47591 100644 --- a/docs/IMAGE_API.md +++ b/docs/IMAGE_API.md @@ -22,9 +22,12 @@ capabilities currently wired by Flow Kit. Current Flow UI model ids observed on the migrated frontend: -- `GEM_PIX_2` — Nano Banana Pro -- `NARWHAL` — Nano Banana 2 +- `GEM_PIX_2` — Nano Banana Pro (default) +- `BELUGA` — Nano Banana 2.1; `BELUGA_THINKING_LOW` / `_MED` / `_HIGH` are its + thinking variants (accepted, not yet exercised live) - `HARBOR_SEAL` — Nano Banana 2 Lite +- `NARWHAL` — Nano Banana 2, retired: answers `[5] NOT_FOUND` since October + 2026. The `NANO_BANANA_2` nickname maps to `BELUGA` instead. Friendly aliases from `models.json` continue to work. Flow Kit also passes a syntactically valid future wire model id through unchanged instead of silently From ac33f0f7dd446ced674c0ecf932d02df2d1af368 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Tue, 27 Oct 2026 13:21:48 +0200 Subject: [PATCH 65/68] fix(sync): restore optional native Flow UI routing after upstream merge --- agent/api/flow.py | 12 ++ agent/config.py | 10 ++ agent/services/flow_client.py | 45 ++++++- docs/FORK_SYNC.md | 16 +++ tests/unit/test_fork_browser_backend.py | 152 ++++++++++++++++++++++++ 5 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 tests/unit/test_fork_browser_backend.py diff --git a/agent/api/flow.py b/agent/api/flow.py index f3810b1f6..88bf5fb92 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -12,6 +12,7 @@ FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, ) from agent.services.flow_client import get_flow_client +from agent import config as _config from agent.services.flow_project_session import current_session_project, ensure_session_project from agent.services.omni_flash import ( check_omni_flash_status, @@ -617,6 +618,17 @@ async def _upload_image_bytes( result.get("error", result.get("data")), ) media_id = result.get("_mediaId") + if media_id and _config.FLOW_BROWSER_BACKEND == "playwright_ui": + # Fresh API media need a cache or a picker refresh in the native UI. + from agent.services.flow_ui_generation import ( + cache_uploaded_media_bytes, + mark_uploaded_media_for_ui_refresh, + ) + cached = cache_uploaded_media_bytes( + media_id, image_bytes, mime_type=mime_type, file_name=file_name, + ) + if cached is None: + mark_uploaded_media_for_ui_refresh(resolved_project_id, media_id) return { "media_id": media_id, "project_id": resolved_project_id, diff --git a/agent/config.py b/agent/config.py index 4496a4577..074b65b1f 100644 --- a/agent/config.py +++ b/agent/config.py @@ -27,6 +27,16 @@ # lease instead of pinning all work into one forever-growing project. FLOW_PROJECT_ID = os.environ.get("FLOW_PROJECT_ID", "") +# The stock upstream transport is the Chrome extension bridge. The fork can +# opt into its local Flow CDP + native Playwright UI generator explicitly. +# Never silently select CDP: it requires a separately owned, authenticated +# local Chrome profile and is not available on standard upstream installs. +FLOW_BROWSER_BACKEND = os.environ.get( + "FLOW_BROWSER_BACKEND", "extension" +).strip().lower() +if FLOW_BROWSER_BACKEND not in {"extension", "playwright_ui"}: + raise ValueError("FLOW_BROWSER_BACKEND must be extension or playwright_ui") + # Ad-hoc direct /api/flow calls without a project share a short-lived project. # The lease survives browser tab parking and agent restarts, but rotates after # this much generation/upload inactivity. diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index 42c0a7979..4bcd82225 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -560,6 +560,39 @@ async def _send(self, method: str, params: dict, timeout: float = 300) -> dict: # None of that can be replayed from here, so the agent builds the envelope # and the extension runs it inside a signed-in flow.google.com tab. + async def _dispatch_browser_rpc( + self, rpcid: str, freq: str, params: dict, *, + captcha_action: str | None, match: str | None, + custom_path: str | None, timeout: float, + ) -> dict: + """Use the standard extension or an explicitly enabled local UI backend. + + In local UI mode, supported generation RPCs submit via the real Flow + composer. Other RPCs go through its signed-in Chrome CDP session. + Custom StreamChat paths remain on the extension bridge. + """ + if _config.FLOW_BROWSER_BACKEND == "extension" or custom_path: + return await self._send("batch_rpc", params, timeout=timeout) + + if rpcid in { + fb.RPC_GEN_IMAGE, fb.RPC_GEN_VIDEO, fb.RPC_GEN_VIDEO_TEXT, + fb.RPC_GEN_VIDEO_FIRST_LAST, fb.RPC_GEN_VIDEO_REFERENCES, + }: + from agent.services.flow_playwright_generation import run_flow_playwright_generation + return await run_flow_playwright_generation( + rpcid, freq, + project_id=self._batch_active_project or FLOW_PROJECT_ID or None, + timeout=timeout, + ) + + from agent.services.browser_session import run_flow_batch_rpc + return await run_flow_batch_rpc( + rpcid, freq, + captcha_action=captcha_action, match=match, + project_id=self._batch_active_project or FLOW_PROJECT_ID or None, + timeout=timeout, + ) + async def batch_rpc(self, rpcid: str, freq: str, captcha_action: str | None = None, match: str | None = None, @@ -581,7 +614,11 @@ async def batch_rpc(self, rpcid: str, freq: str, is_generation = captcha_action in {fb.CAPTCHA_IMAGE, fb.CAPTCHA_VIDEO} if not is_generation: - return await self._send("batch_rpc", params, timeout=timeout) + return await self._dispatch_browser_rpc( + rpcid, freq, params, + captcha_action=captcha_action, match=match, + custom_path=custom_path, timeout=timeout, + ) now = time.monotonic() if now < self._generation_unusual_until: @@ -614,7 +651,11 @@ async def batch_rpc(self, rpcid: str, freq: str, await asyncio.sleep(delay) self._generation_last_submit_at = time.monotonic() - result = await self._send("batch_rpc", params, timeout=timeout) + result = await self._dispatch_browser_rpc( + rpcid, freq, params, + captcha_action=captcha_action, match=match, + custom_path=custom_path, timeout=timeout, + ) blob = f"{result.get('error', '')} {result.get('data', '')}" is_hijack = "extension_hijack" in blob.lower() is_unusual = ( diff --git a/docs/FORK_SYNC.md b/docs/FORK_SYNC.md index 30ed6f2a6..9f6e71f96 100644 --- a/docs/FORK_SYNC.md +++ b/docs/FORK_SYNC.md @@ -32,3 +32,19 @@ sync candidate by running `git pull` inside a dirty production checkout. repository integration. - Optional YouTube tests require `googleapiclient` and may be omitted in a limited test environment; document skipped dependencies explicitly. + +## Fork-specific local UI backend + +Upstream's browser-extension transport remains the default. Dedicated local +FlowKit Chrome setups can explicitly set `FLOW_BROWSER_BACKEND=playwright_ui` +to restore the fork's Playwright native-composer generation and direct CDP +metadata/media calls. Fresh API uploads also regain their native picker cache +and refresh recovery. A signed-in Chrome profile, the optional Playwright +dependency, and a dedicated Flow CDP endpoint (typically +`FLOW_CHROME_CDP=http://127.0.0.1:9224`) are required. + +Do not enable this option for a generic extension-based upstream install or +point it at an unrelated Chrome profile. The default +`FLOW_BROWSER_BACKEND=extension` preserves upstream routing. Custom +StreamChat RPCs use the extension bridge in both modes. Test local-browser +compatibility in a controlled session before production rollout. diff --git a/tests/unit/test_fork_browser_backend.py b/tests/unit/test_fork_browser_backend.py new file mode 100644 index 000000000..ed013bb07 --- /dev/null +++ b/tests/unit/test_fork_browser_backend.py @@ -0,0 +1,152 @@ +"""Check preservation of fork native-UI routing after upstream merges.""" + +import time +from unittest.mock import AsyncMock, MagicMock, patch + +import pytest + +from agent import config +from agent.api import flow as flow_api +from agent.services import flow_batch as fb +from agent.services.flow_client import FlowClient + + +@pytest.mark.asyncio +async def test_default_extension_backend_uses_upstream_transport(monkeypatch): + monkeypatch.setattr(config, "FLOW_BROWSER_BACKEND", "extension") + client = FlowClient() + client._send = AsyncMock(return_value={"status": 200, "data": "batch-result"}) + + result = await client.batch_rpc(fb.RPC_GEN_IMAGE, "mock-freq", fb.CAPTCHA_IMAGE) + + assert result["status"] == 200 + client._send.assert_awaited_once() + assert client._send.await_args.args[0] == "batch_rpc" + + +@pytest.mark.asyncio +async def test_opt_in_ui_generation_uses_native_playwright(monkeypatch): + monkeypatch.setattr(config, "FLOW_BROWSER_BACKEND", "playwright_ui") + client = FlowClient() + client._batch_active_project = "project-1" + client._send = AsyncMock(side_effect=AssertionError("extension must not submit UI generation")) + with patch( + "agent.services.flow_playwright_generation.run_flow_playwright_generation", + new_callable=AsyncMock, + ) as run_ui: + run_ui.return_value = {"status": 200, "data": "real-ui-result"} + result = await client.batch_rpc(fb.RPC_GEN_VIDEO, "mock-freq", fb.CAPTCHA_VIDEO) + + assert result["data"] == "real-ui-result" + run_ui.assert_awaited_once_with( + fb.RPC_GEN_VIDEO, "mock-freq", project_id="project-1", timeout=300, + ) + client._send.assert_not_awaited() + + +@pytest.mark.asyncio +async def test_opt_in_ui_non_generation_uses_signed_cdp(monkeypatch): + monkeypatch.setattr(config, "FLOW_BROWSER_BACKEND", "playwright_ui") + client = FlowClient() + client._batch_active_project = "project-1" + client._send = AsyncMock(side_effect=AssertionError("metadata must go through CDP")) + with patch( + "agent.services.browser_session.run_flow_batch_rpc", new_callable=AsyncMock + ) as cdp: + cdp.return_value = {"status": 200, "data": "cdp-result"} + result = await client.batch_rpc(fb.RPC_MEDIA, "freq", match="video") + + assert result["data"] == "cdp-result" + cdp.assert_awaited_once_with( + fb.RPC_MEDIA, "freq", captcha_action=None, match="video", + project_id="project-1", timeout=300, + ) + + +@pytest.mark.asyncio +async def test_ui_backend_upscale_uses_cdp_not_composer(monkeypatch): + monkeypatch.setattr(config, "FLOW_BROWSER_BACKEND", "playwright_ui") + client = FlowClient() + with ( + patch("agent.services.browser_session.run_flow_batch_rpc", + new_callable=AsyncMock) as cdp, + patch("agent.services.flow_playwright_generation.run_flow_playwright_generation", + new_callable=AsyncMock) as ui, + ): + cdp.return_value = {"status": 200} + result = await client.batch_rpc(fb.RPC_UPSCALE, "freq", fb.CAPTCHA_VIDEO) + assert result["status"] == 200 + cdp.assert_awaited_once() + ui.assert_not_awaited() + + +@pytest.mark.asyncio +async def test_ui_backend_custom_streamchat_uses_extension_bridge(monkeypatch): + monkeypatch.setattr(config, "FLOW_BROWSER_BACKEND", "playwright_ui") + client = FlowClient() + client._send = AsyncMock(return_value={"status": 200}) + with patch("agent.services.browser_session.run_flow_batch_rpc", + new_callable=AsyncMock) as cdp: + result = await client.batch_rpc( + "StreamChat", "freq", custom_path="/custom-path", + ) + assert result["status"] == 200 + client._send.assert_awaited_once() + cdp.assert_not_awaited() + + +@pytest.mark.asyncio +async def test_ui_backend_respects_existing_account_hold(monkeypatch): + monkeypatch.setattr(config, "FLOW_BROWSER_BACKEND", "playwright_ui") + client = FlowClient() + client._generation_unusual_until = time.monotonic() + 3600 + with patch("agent.services.flow_playwright_generation.run_flow_playwright_generation", + new_callable=AsyncMock) as ui: + result = await client.batch_rpc(fb.RPC_GEN_IMAGE, "freq", fb.CAPTCHA_IMAGE) + assert result["status"] == 429 + ui.assert_not_awaited() + + +@pytest.mark.asyncio +async def test_ui_upload_restores_fresh_picker_cache(monkeypatch): + monkeypatch.setattr(config, "FLOW_BROWSER_BACKEND", "playwright_ui") + client = MagicMock() + client.upload_image = AsyncMock(return_value={ + "status": 200, "_mediaId": "media-1", "data": {"media": {"name": "media-1"}}, + }) + with ( + patch.object(flow_api, "_resolve_direct_project", new_callable=AsyncMock, + return_value="project-1"), + patch("agent.services.flow_ui_generation.cache_uploaded_media_bytes", + return_value=None) as cache, + patch("agent.services.flow_ui_generation.mark_uploaded_media_for_ui_refresh") as refresh, + ): + result = await flow_api._upload_image_bytes( + client, b"image-bytes", project_id="project-1", + mime_type="image/png", file_name="reference.png", + ) + assert result["media_id"] == "media-1" + cache.assert_called_once_with( + "media-1", b"image-bytes", + mime_type="image/png", file_name="reference.png", + ) + refresh.assert_called_once_with("project-1", "media-1") + + +@pytest.mark.asyncio +async def test_extension_upload_does_not_touch_local_browser_cache(monkeypatch): + monkeypatch.setattr(config, "FLOW_BROWSER_BACKEND", "extension") + client = MagicMock() + client.upload_image = AsyncMock(return_value={ + "status": 200, "_mediaId": "media-1", "data": {}, + }) + with ( + patch.object(flow_api, "_resolve_direct_project", new_callable=AsyncMock, + return_value="project-1"), + patch("agent.services.flow_ui_generation.cache_uploaded_media_bytes") as cache, + ): + await flow_api._upload_image_bytes( + client, b"image-bytes", project_id="project-1", + mime_type="image/png", file_name="reference.png", + ) + cache.assert_not_called() From 9ad18c3720a03ded7e6867c0c17477a1ccae3368 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Tue, 27 Oct 2026 13:26:00 +0200 Subject: [PATCH 66/68] fix(sync): restore lost Flow browser and model API imports --- agent/api/flow.py | 4 ++ tests/unit/test_fork_api_imports.py | 60 +++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 tests/unit/test_fork_api_imports.py diff --git a/agent/api/flow.py b/agent/api/flow.py index 88bf5fb92..bb67daa4c 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -12,6 +12,10 @@ FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, ) from agent.services.flow_client import get_flow_client +from agent.services.browser_session import ( + ensure_flow_session, inspect_flow_session, inspect_google_account, +) +from agent.services.image_capabilities import image_capabilities from agent import config as _config from agent.services.flow_project_session import current_session_project, ensure_session_project from agent.services.omni_flash import ( diff --git a/tests/unit/test_fork_api_imports.py b/tests/unit/test_fork_api_imports.py new file mode 100644 index 000000000..36039632f --- /dev/null +++ b/tests/unit/test_fork_api_imports.py @@ -0,0 +1,60 @@ +"""Exercise routes whose module-level imports were lost during upstream merge.""" + +from unittest.mock import AsyncMock, MagicMock, patch + +import pytest + +from agent.api import flow + + +@pytest.mark.asyncio +async def test_browser_status_checks_real_session_inspector(): + client = MagicMock(connected=True, _flow_key=None) + client.generation_guard_status = {"cooldown_reason": None} + with ( + patch.object(flow, "get_flow_client", return_value=client), + patch.object(flow, "inspect_flow_session", new_callable=AsyncMock) as inspect, + ): + inspect.return_value = { + "signedIn": True, "flowTabPresent": True, + "atTokenPresent": True, "url": "https://flow.google.com/", + } + result = await flow.extension_status() + assert result["authenticated"] is True + assert result["transport"] == "batch" + inspect.assert_awaited_once_with() + + +@pytest.mark.asyncio +async def test_ensure_session_calls_local_flow_browser_recovery(): + client = MagicMock(connected=True) + with ( + patch.object(flow, "get_flow_client", return_value=client), + patch.object(flow, "ensure_flow_session", new_callable=AsyncMock) as recover, + ): + recover.return_value = {"signedIn": True, "state": "AUTHENTICATED"} + result = await flow.ensure_session() + assert result["authenticated"] is True + recover.assert_awaited_once_with() + + +@pytest.mark.asyncio +async def test_account_route_calls_local_inspector(): + client = MagicMock(connected=True) + with ( + patch.object(flow, "get_flow_client", return_value=client), + patch.object(flow, "inspect_google_account", new_callable=AsyncMock) as inspect, + ): + inspect.return_value = {"account": "test-account"} + result = await flow.get_account() + assert result == {"account": "test-account"} + inspect.assert_awaited_once_with() + + +@pytest.mark.asyncio +async def test_capabilities_route_uses_dynamic_model_inspector(): + with patch.object(flow, "image_capabilities", new_callable=AsyncMock) as inspect: + inspect.return_value = {"models": ["BELUGA"]} + result = await flow.get_image_capabilities(refresh=True) + assert result["models"] == ["BELUGA"] + inspect.assert_awaited_once_with(refresh=True) From 1b8556e06ea545135947dbca03fbbaf46b0bbf73 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Wed, 28 Oct 2026 18:02:47 +0200 Subject: [PATCH 67/68] ci: avoid unbounded apt setup on GitHub runners --- .github/workflows/tests.yml | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ed84785d8..0e8aaf3c3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,7 +15,9 @@ concurrency: jobs: unit: - runs-on: ubuntu-latest + # Pin to a stable runner while ubuntu-latest transitions to Ubuntu 26.04. + # Tooling (including ffmpeg/fonts) differs during the rollout. + runs-on: ubuntu-24.04 # The suite takes ~7s. A ceiling this generous only ever trips on a hang, # which this suite has had before: an aiosqlite connection left open keeps a # non-daemon worker thread alive and the interpreter never exits. @@ -38,14 +40,25 @@ jobs: requirements.txt requirements-dev.txt - - name: Install ffmpeg - # fonts-dejavu-core is not optional. The drawtext call in - # video_reviewer.py passes no fontfile=, so it asks fontconfig for a - # default family; with --no-install-recommends the runner can end up - # with an ffmpeg that has drawtext and no font for it to use. + - name: Ensure ffmpeg and fonts + # Hosted Ubuntu images can already include both. Unconditional apt + # update has hung until the 10-minute job timeout (Python 3.13 CI), + # preventing the test suite from running at all. Only install what is + # missing and bound apt network operations so the failure is visible. run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends ffmpeg fonts-dejavu-core + if command -v ffmpeg >/dev/null && \ + command -v fc-match >/dev/null && \ + fc-match "DejaVu Sans" | grep -qi "DejaVu"; then + echo "ffmpeg and DejaVu font are already available" + else + timeout 90s sudo apt-get update \ + -o Acquire::Retries=1 \ + -o Acquire::http::Timeout=15 \ + -o Acquire::https::Timeout=15 + timeout 90s sudo env DEBIAN_FRONTEND=noninteractive apt-get install \ + -y --no-install-recommends ffmpeg fonts-dejavu-core + fi + command -v ffmpeg - name: Report whether drawtext renders # This used to fail the build, because naming an absent filter aborted From 64adb1d7ad42c0db626536044844257b925c6385 Mon Sep 17 00:00:00 2001 From: Bl0ck <36800583+Bl0ck154@users.noreply.github.com> Date: Wed, 28 Oct 2026 18:31:50 +0200 Subject: [PATCH 68/68] refactor(flow): unify Omni and video export polling --- agent/api/flow.py | 9 +- agent/api/upscale_status.py | 37 ++++-- agent/services/flow_client.py | 15 +++ agent/services/flow_poll.py | 175 +++++++++++++++++++++++++++ agent/services/omni_flash.py | 101 ++-------------- agent/services/upscale_polling.py | 167 ------------------------- docs/VIDEO_EXPORTS.md | 19 ++- tests/unit/test_flow_poll.py | 88 ++++++++++++++ tests/unit/test_omni_flash.py | 28 +++-- tests/unit/test_shared_export_api.py | 143 ++++++++++++++++++++++ 10 files changed, 491 insertions(+), 291 deletions(-) create mode 100644 agent/services/flow_poll.py delete mode 100644 agent/services/upscale_polling.py create mode 100644 tests/unit/test_flow_poll.py create mode 100644 tests/unit/test_shared_export_api.py diff --git a/agent/api/flow.py b/agent/api/flow.py index bb67daa4c..483877496 100644 --- a/agent/api/flow.py +++ b/agent/api/flow.py @@ -12,6 +12,7 @@ FLOW_UNUSUAL_ACTIVITY_COOLDOWN_S, ) from agent.services.flow_client import get_flow_client +from agent.services.flow_poll import check_workflow_status from agent.services.browser_session import ( ensure_flow_session, inspect_flow_session, inspect_google_account, ) @@ -139,6 +140,7 @@ class CheckStatusRequest(BaseModel): workflows: Optional[list[dict]] = None project_id: str = "" include_encoded_video: bool = False + mode: Literal["omni", "export"] = "omni" class CheckOmniStatusRequest(BaseModel): @@ -449,11 +451,16 @@ async def check_status(body: CheckStatusRequest): if body.workflows: try: - return await check_omni_flash_status( + result = await check_workflow_status( body.workflows, + mode="media_redirect" if body.mode == "export" else "batch_media", include_encoded_video=body.include_encoded_video, project_id=body.project_id, + client=client, ) + if body.mode == "export": + result["download_ready"] = result["status"] == "COMPLETED" + return result except ValueError as exc: raise HTTPException(400, str(exc)) from exc except RuntimeError as exc: diff --git a/agent/api/upscale_status.py b/agent/api/upscale_status.py index 6f9c0f9f7..ceb273706 100644 --- a/agent/api/upscale_status.py +++ b/agent/api/upscale_status.py @@ -6,7 +6,8 @@ from pydantic import BaseModel from agent.services.flow_client import get_flow_client -from agent.services.upscale_polling import annotate_upscale_polling, check_upscale_status +from agent.services.flow_poll import annotate_polling, check_workflow_status +from agent.services.flow_project_session import ensure_session_project router = APIRouter(prefix="/flow", tags=["flow"]) @@ -41,34 +42,48 @@ async def export_video(body: ExportVideoRequest): if body.quality == "1080p" else "VIDEO_RESOLUTION_4K" ) + # An export is scoped to a real Flow project. A direct caller may omit + # project_id, in which case allocate/reuse the leased session project. + project_id = str(body.project_id or "").strip() + if not project_id: + try: + session = await ensure_session_project(client) + project_id = str(session.get("project_id") or "") + except Exception as exc: + raise HTTPException(502, f"Could not create Flow session project: {exc}") from exc + if not project_id: + raise HTTPException(502, "Flow session project did not return an id") + result = await client.upscale_video( media_id=body.media_id, scene_id=body.scene_id, aspect_ratio=body.aspect_ratio, resolution=resolution, - project_id=body.project_id, + project_id=project_id, ) if result.get("error") or ( isinstance(result.get("status"), int) and result["status"] >= 400 ): - raise HTTPException( - result.get("status", 502), - result.get("error", result.get("data")), - ) + status = result.get("status") + http_status = status if isinstance(status, int) and 400 <= status <= 599 else 502 + raise HTTPException(http_status, result.get("error", result.get("data"))) - annotated = annotate_upscale_polling(result) + annotated = annotate_polling(result, mode="media_redirect", project_id=project_id) data = annotated.get("data", annotated) if isinstance(data, dict): data["export"] = { "quality": body.quality, "resolution": resolution, "native_flow_export": True, - "next": "/api/flow/check-export-status", + "next": "/api/flow/check-status", + "check_status_mode": "export", } return data -@router.post("/check-export-status") +# Backward-compatible aliases retained for existing fork clients. +# New callers use /api/flow/check-status with mode=export. +@router.post("/check-export-status", deprecated=True) @router.post("/check-upscale-status", include_in_schema=False) async def check_export_status(body: CheckExportStatusRequest): """Return a signed downloadable URL when the native Flow export is ready.""" @@ -76,7 +91,9 @@ async def check_export_status(body: CheckExportStatusRequest): if not client.connected: raise HTTPException(503, "Extension not connected") try: - result = await check_upscale_status(body.workflows) + result = await check_workflow_status( + body.workflows, mode="media_redirect", client=client, + ) except ValueError as exc: raise HTTPException(400, str(exc)) from exc diff --git a/agent/services/flow_client.py b/agent/services/flow_client.py index 4bcd82225..730f55c56 100644 --- a/agent/services/flow_client.py +++ b/agent/services/flow_client.py @@ -1216,6 +1216,21 @@ async def get_media(self, media_id: str) -> dict: data["image"] = {"fifeUrl": urls.image} return {"status": 200, "data": data} + async def resolve_media_url(self, media_id: str) -> dict: + """Resolve a signed Flow video URL without buffering video bytes.""" + result = await self.get_media(media_id) + data = result.get("data") if isinstance(result.get("data"), dict) else {} + video = data.get("video") if isinstance(data, dict) else None + candidate = video.get("fifeUrl") if isinstance(video, dict) else None + return { + "status": result.get("status", 200), + "data": { + "url": candidate, + "contentType": "video/mp4" if candidate else None, + }, + "error": result.get("error"), + } + async def upload_image(self, image_base64: str, mime_type: str = "image/jpeg", project_id: str = "", file_name: str = "image.jpg") -> dict: """Upload an image into the project so it can be used as a reference.""" diff --git a/agent/services/flow_poll.py b/agent/services/flow_poll.py new file mode 100644 index 000000000..fb00faf2e --- /dev/null +++ b/agent/services/flow_poll.py @@ -0,0 +1,175 @@ +"""Shared polling helpers for Flow workflow-backed video jobs. + +Workflow-producing surfaces (Omni and native video export) return the same +logical pair: a workflow name plus a primary media id. This module owns the +normalization, response annotation and one-pass polling so each feature does +not grow its own copy of transport/status handling. +""" +from __future__ import annotations + +from agent.services.flow_client import get_flow_client + +_ALLOWED_MEDIA_URL_PREFIX = "https://flow-content.google/video/" +_POLL_MODES = {"batch_media", "media_redirect"} + + +def normalize_workflow(workflow: dict) -> dict | None: + """Normalize a raw Flow workflow or a FlowKit polling descriptor.""" + if not isinstance(workflow, dict): + return None + name = workflow.get("name") + primary_media_id = workflow.get("primary_media_id") + if not primary_media_id: + metadata = workflow.get("metadata") + if isinstance(metadata, dict): + primary_media_id = metadata.get("primaryMediaId") + if not isinstance(name, str) or not name: + return None + if not isinstance(primary_media_id, str) or not primary_media_id: + return None + item = {"name": name, "primary_media_id": primary_media_id} + project_id = workflow.get("project_id") or workflow.get("projectId") + if isinstance(project_id, str) and project_id: + item["project_id"] = project_id + return item + + +def extract_workflows(result: dict) -> list[dict]: + """Extract normalized workflow descriptors from a submit response.""" + if not isinstance(result, dict): + return [] + data = result.get("data") if isinstance(result.get("data"), dict) else result + workflows = data.get("workflows", []) if isinstance(data, dict) else [] + return [item for workflow in workflows if (item := normalize_workflow(workflow))] + + +def annotate_polling(result: dict, *, mode: str, project_id: str = "") -> dict: + """Attach the descriptor callers can pass back to ``/flow/check-status``.""" + if mode not in _POLL_MODES: + raise ValueError(f"Unknown Flow polling mode: {mode}") + workflows = extract_workflows(result) + if not workflows: + return result + if project_id: + for workflow in workflows: + workflow["project_id"] = project_id + data = result.get("data") if isinstance(result.get("data"), dict) else result + if isinstance(data, dict): + descriptor = {"mode": mode, "workflows": workflows} + if project_id: + descriptor["project_id"] = project_id + data["flowkitPolling"] = descriptor + return result + + +def _normalize_workflows(workflows: list[dict]) -> list[dict]: + return [item for workflow in (workflows or []) if (item := normalize_workflow(workflow))] + + +def _parse_media_redirect(response: dict) -> tuple[str | None, str | None, str | None]: + if not isinstance(response, dict): + return None, None, "Flow media redirect returned an invalid response" + status = response.get("status") + data = response.get("data") if isinstance(response.get("data"), dict) else {} + candidate = data.get("url") + content_type = data.get("contentType") + if ( + isinstance(status, int) + and status < 400 + and isinstance(candidate, str) + and candidate.startswith(_ALLOWED_MEDIA_URL_PREFIX) + ): + return candidate, content_type if isinstance(content_type, str) else None, None + error = response.get("error") + if not error and isinstance(status, int) and status >= 400: + error = f"API_{status}" + return None, content_type if isinstance(content_type, str) else None, str(error or "media redirect not ready") + + +async def _check_media_ready( + workflows: list[dict], + *, + client, + include_encoded_video: bool, + project_id: str, +) -> dict: + resolved_project_id = project_id or next( + (item.get("project_id", "") for item in workflows if item.get("project_id")), "" + ) + items = [] + for workflow in workflows: + media_id = workflow["primary_media_id"] + response = await client.resolve_media_url(media_id) + url, content_type, diagnostic = _parse_media_redirect(response) + item_project = workflow.get("project_id") or resolved_project_id + if url: + media = { + "media_id": media_id, + "url": url, + "encoded_video_available": False, + "resolved_via": "as29s", + } + if content_type: + media["content_type"] = content_type + if include_encoded_video: + media["encoded_video"] = None + item = { + "name": workflow["name"], + "primary_media_id": media_id, + "done": True, + "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL", + "error": None, + "media": media, + } + else: + item = { + "name": workflow["name"], + "primary_media_id": media_id, + "done": False, + "status": "PENDING", + "error": None, + } + if diagnostic: + item["probe"] = {"diagnostic": diagnostic} + if isinstance(response, dict) and isinstance(response.get("status"), int): + item["probe"]["http_status"] = response["status"] + if item_project: + item["project_id"] = item_project + items.append(item) + + all_done = bool(items) and all(item["done"] for item in items) + result = { + "done": all_done, + "status": "COMPLETED" if all_done else "PENDING", + "workflows": items, + } + if resolved_project_id: + result["project_id"] = resolved_project_id + return result + + +async def check_workflow_status( + workflows: list[dict], + *, + mode: str, + include_encoded_video: bool = False, + project_id: str = "", + client=None, +) -> dict: + """Perform one non-blocking poll pass for a workflow-backed Flow job.""" + if mode not in _POLL_MODES: + raise ValueError(f"Unknown Flow polling mode: {mode}") + normalized = _normalize_workflows(workflows) + if not normalized: + raise ValueError( + "Flow polling requires workflow descriptors with name and primary_media_id " + "(or raw Flow metadata.primaryMediaId)" + ) + + client = client or get_flow_client() + return await _check_media_ready( + normalized, + client=client, + include_encoded_video=include_encoded_video, + project_id=project_id, + ) diff --git a/agent/services/omni_flash.py b/agent/services/omni_flash.py index 9f686a939..a05201962 100644 --- a/agent/services/omni_flash.py +++ b/agent/services/omni_flash.py @@ -24,6 +24,7 @@ from agent.services import flow_batch as fb from agent.services.flow_client import get_flow_client +from agent.services.flow_poll import check_workflow_status, extract_workflows _MODELS_FILE = Path(__file__).parent.parent / "models.json" @@ -135,39 +136,9 @@ def _validate_frame_inputs( raise ValueError("Omni Flash First+Last requires a non-empty end_image_media_id") -def _normalize_workflow(workflow: dict) -> dict | None: - """Normalize a raw Flow workflow or FlowKit polling descriptor.""" - if not isinstance(workflow, dict): - return None - name = workflow.get("name") - primary_media_id = workflow.get("primary_media_id") - if not primary_media_id: - metadata = workflow.get("metadata") - if isinstance(metadata, dict): - primary_media_id = metadata.get("primaryMediaId") - if not isinstance(name, str) or not name: - return None - if not isinstance(primary_media_id, str) or not primary_media_id: - return None - item = {"name": name, "primary_media_id": primary_media_id} - project_id = workflow.get("project_id") or workflow.get("projectId") - if isinstance(project_id, str) and project_id: - item["project_id"] = project_id - return item - - def extract_omni_workflows(result: dict) -> list[dict]: - """Extract ``name`` + ``primaryMediaId`` pairs from an Omni submit.""" - if not isinstance(result, dict): - return [] - data = result.get("data") if isinstance(result.get("data"), dict) else result - workflows = data.get("workflows", []) if isinstance(data, dict) else [] - normalized = [] - for workflow in workflows: - item = _normalize_workflow(workflow) - if item: - normalized.append(item) - return normalized + """Backward-compatible alias for shared Flow workflow extraction.""" + return extract_workflows(result) async def generate_omni_flash_text_video( @@ -366,66 +337,16 @@ async def generate_omni_flash_video( batch_model = f"abra_r2v_{duration_s}s" + ("_360p" if resolution == "360p" else "") return _batch_operation_result(operation, pid, batch_model, duration_s, resolution) -async def _check_omni_batch_media( - workflows: list[dict], - include_encoded_video: bool = False, - project_id: str = "", -) -> dict: - normalized = [item for workflow in (workflows or []) if (item := _normalize_workflow(workflow))] - if not normalized: - raise ValueError("Omni polling requires workflow descriptors with name and primary_media_id") - resolved_project_id = project_id or next( - (item.get("project_id", "") for item in normalized if item.get("project_id")), "") - client = get_flow_client() - items = [] - for workflow in normalized: - media_id = workflow["primary_media_id"] - response = await client.get_media(media_id) - data = response.get("data") if isinstance(response, dict) else None - video = data.get("video") if isinstance(data, dict) else None - url = video.get("fifeUrl") if isinstance(video, dict) else None - if isinstance(url, str) and url.startswith("https://flow-content.google/video/"): - media = { - "media_id": media_id, - "url": url, - "encoded_video_available": False, - "resolved_via": "as29s", - } - if include_encoded_video: - media["encoded_video"] = None - items.append({ - "name": workflow["name"], - "primary_media_id": media_id, - "project_id": workflow.get("project_id") or resolved_project_id, - "done": True, - "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL", - "error": None, - "media": media, - }) - else: - items.append({ - "name": workflow["name"], - "primary_media_id": media_id, - "project_id": workflow.get("project_id") or resolved_project_id, - "done": False, - "status": "PENDING", - "error": None, - }) - all_done = bool(items) and all(item["done"] for item in items) - return { - "project_id": resolved_project_id or None, - "done": all_done, - "status": "COMPLETED" if all_done else "PENDING", - "workflows": items, - } - - - - async def check_omni_flash_status( workflows: list[dict], include_encoded_video: bool = False, project_id: str = "", ) -> dict: - """Perform one non-blocking poll pass for Omni workflow-backed jobs.""" - return await _check_omni_batch_media(workflows, include_encoded_video, project_id) + """Poll Omni workflows through the shared Flow media resolver.""" + return await check_workflow_status( + workflows, + mode="batch_media", + include_encoded_video=include_encoded_video, + project_id=project_id, + client=get_flow_client(), + ) diff --git a/agent/services/upscale_polling.py b/agent/services/upscale_polling.py deleted file mode 100644 index cf4b5ab41..000000000 --- a/agent/services/upscale_polling.py +++ /dev/null @@ -1,167 +0,0 @@ -"""Headless polling for Flow video upscales. - -Google Flow's upsampler returns workflow descriptors whose logical -``primaryMediaId`` may not appear in ``flow.projectInitialData``. The browser UI -can still resolve completed media through ``media.getMediaUrlRedirect``. - -This module exposes a small active poller that treats a successful authenticated -media redirect as the completion signal, avoiding the legacy -``batchCheckAsyncVideoGenerationStatus`` and ``/v1/media/{id}`` paths. -""" - -from __future__ import annotations - -from agent.services.flow_client import get_flow_client - -_ALLOWED_MEDIA_URL_PREFIX = "https://flow-content.google/" - - -def _normalize_workflow(workflow: dict) -> dict | None: - if not isinstance(workflow, dict): - return None - name = workflow.get("name") - primary_media_id = workflow.get("primary_media_id") - if not primary_media_id: - metadata = workflow.get("metadata") - if isinstance(metadata, dict): - primary_media_id = metadata.get("primaryMediaId") - if not isinstance(name, str) or not name: - return None - if not isinstance(primary_media_id, str) or not primary_media_id: - return None - return {"name": name, "primary_media_id": primary_media_id} - - -def extract_upscale_workflows(result: dict) -> list[dict]: - if not isinstance(result, dict): - return [] - data = result.get("data") if isinstance(result.get("data"), dict) else result - workflows = data.get("workflows", []) if isinstance(data, dict) else [] - normalized = [] - for workflow in workflows: - item = _normalize_workflow(workflow) - if item: - normalized.append(item) - return normalized - - -def annotate_upscale_polling(result: dict) -> dict: - workflows = extract_upscale_workflows(result) - if not workflows: - return result - data = result.get("data") if isinstance(result.get("data"), dict) else result - if isinstance(data, dict): - data["flowkitPolling"] = { - "mode": "media_redirect", - "workflows": workflows, - } - return result - - -async def _fetch_media_url(client, media_id: str) -> dict: - """Use the current signed-in Flow media lookup (as29s) only.""" - result = await client.get_media(media_id) - data = result.get("data") if isinstance(result.get("data"), dict) else {} - video = data.get("video") if isinstance(data, dict) else None - candidate = video.get("fifeUrl") if isinstance(video, dict) else None - return { - "status": result.get("status", 200), - "data": { - "url": candidate, - "contentType": "video/mp4" if candidate else None, - }, - "error": result.get("error"), - } - - -def _parse_media_redirect(response: dict) -> tuple[str | None, str | None, str | None]: - if not isinstance(response, dict): - return None, None, "Flow media redirect returned an invalid response" - status = response.get("status") - data = response.get("data") if isinstance(response.get("data"), dict) else {} - candidate = data.get("url") - content_type = data.get("contentType") - if ( - isinstance(status, int) - and status < 400 - and isinstance(candidate, str) - and candidate.startswith(_ALLOWED_MEDIA_URL_PREFIX) - ): - return candidate, content_type if isinstance(content_type, str) else None, None - error = response.get("error") - if not error and isinstance(status, int) and status >= 400: - error = f"API_{status}" - if not error: - error = "media redirect not ready" - return None, content_type if isinstance(content_type, str) else None, str(error) - - -async def check_upscale_status( - workflows: list[dict], - include_encoded_video: bool = False, -) -> dict: - """Poll native Flow Full HD/4K export workflows without buffering the MP4.""" - normalized = [] - for workflow in workflows or []: - item = _normalize_workflow(workflow) - if item: - normalized.append(item) - if not normalized: - raise ValueError( - "Export polling requires workflow descriptors with name and " - "primary_media_id (or raw Flow metadata.primaryMediaId)" - ) - - client = get_flow_client() - items = [] - for workflow in normalized: - media_id = workflow["primary_media_id"] - response = await _fetch_media_url(client, media_id) - url, content_type, diagnostic = _parse_media_redirect(response) - if url: - media = { - "media_id": media_id, - "url": url, - "encoded_video_available": False, - "resolved_via": "as29s", - } - if content_type: - media["content_type"] = content_type - if include_encoded_video: - media["encoded_video"] = None - items.append({ - "name": workflow["name"], - "primary_media_id": media_id, - "done": True, - "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL", - "error": None, - "media": media, - }) - continue - - probe = {} - if isinstance(response, dict): - if isinstance(response.get("status"), int): - probe["http_status"] = response["status"] - data = response.get("data") - if isinstance(data, dict) and isinstance(data.get("url"), str): - probe["resolved_url"] = data["url"] - if diagnostic: - probe["diagnostic"] = diagnostic - item = { - "name": workflow["name"], - "primary_media_id": media_id, - "done": False, - "status": "PENDING", - "error": None, - } - if probe: - item["probe"] = probe - items.append(item) - - all_done = bool(items) and all(item["done"] for item in items) - return { - "done": all_done, - "status": "COMPLETED" if all_done else "PENDING", - "workflows": items, - } diff --git a/docs/VIDEO_EXPORTS.md b/docs/VIDEO_EXPORTS.md index de056793e..a413cef37 100644 --- a/docs/VIDEO_EXPORTS.md +++ b/docs/VIDEO_EXPORTS.md @@ -25,12 +25,14 @@ curl -sS -X POST http://127.0.0.1:8100/api/flow/export-video \ `quality` defaults to `1080p`. `4k` remains an explicit API option, but it is plan-gated by Google Flow; the currently verified account exposes 4K as disabled while 1080p is available. +If `project_id` is omitted, FlowKit uses its leased session project. + The response contains `flowkitPolling.workflows`. Poll those descriptors: ```bash -curl -sS -X POST http://127.0.0.1:8100/api/flow/check-export-status \ +curl -sS -X POST http://127.0.0.1:8100/api/flow/check-status \ -H 'Content-Type: application/json' \ - -d '{"workflows": }' + -d '{"mode":"export","workflows": }' ``` When `download_ready` becomes `true`, use @@ -39,12 +41,7 @@ When `download_ready` becomes `true`, use ## Compatibility -The older endpoints remain supported: - -- `POST /api/flow/upscale-video` -- `POST /api/flow/check-upscale-status` - -They are aliases/low-level surfaces for the same Google Flow capability. New -integrations should use `export-video` and `check-export-status`, because those -names describe the user-visible operation: selecting the downloadable output -quality. +For compatibility, older clients can still call `check-export-status` and +`check-upscale-status`. Both aliases now delegate to the same shared Flow +poller as `check-status`; they are deprecated for new integrations. +`POST /api/flow/upscale-video` remains the low-level submission API. diff --git a/tests/unit/test_flow_poll.py b/tests/unit/test_flow_poll.py new file mode 100644 index 000000000..bee92e7d2 --- /dev/null +++ b/tests/unit/test_flow_poll.py @@ -0,0 +1,88 @@ +from unittest.mock import AsyncMock, MagicMock, patch + +import pytest + +import agent.services.flow_poll as polling +from agent.services.flow_client import FlowClient +from agent.services.flow_poll import annotate_polling, check_workflow_status + +MEDIA = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" + + +def test_annotate_export_polling_uses_workflow_primary_media_id(): + result = { + "status": 200, + "data": { + "workflows": [ + {"name": "wf-1", "metadata": {"primaryMediaId": MEDIA + "_upsampled"}} + ] + }, + } + annotated = annotate_polling(result, mode="media_redirect") + assert annotated["data"]["flowkitPolling"] == { + "mode": "media_redirect", + "workflows": [ + {"name": "wf-1", "primary_media_id": MEDIA + "_upsampled"} + ], + } + + +@pytest.mark.asyncio +async def test_batch_poll_resolves_completed_media_through_public_resolver(): + client = MagicMock() + client.resolve_media_url = AsyncMock(return_value={ + "status": 200, + "data": { + "url": "https://flow-content.google/video/out?Signature=test", + "contentType": "video/mp4", + }, + }) + with patch("agent.services.flow_poll.get_flow_client", return_value=client): + result = await check_workflow_status( + [{"name": "wf-1", "primary_media_id": MEDIA + "_upsampled"}], + mode="media_redirect", + ) + + assert result["done"] is True + assert result["status"] == "COMPLETED" + assert result["workflows"][0]["media"]["resolved_via"] == "as29s" + client.resolve_media_url.assert_awaited_once_with(MEDIA + "_upsampled") + + +@pytest.mark.asyncio +async def test_batch_poll_stays_pending_until_video_url_exists(): + client = MagicMock() + client.resolve_media_url = AsyncMock(return_value={ + "status": 404, + "error": "not ready", + "data": {}, + }) + with patch("agent.services.flow_poll.get_flow_client", return_value=client): + result = await check_workflow_status( + [{"name": "wf-1", "primary_media_id": MEDIA + "_upsampled"}], + mode="media_redirect", + ) + + assert result["done"] is False + assert result["status"] == "PENDING" + assert result["workflows"][0]["status"] == "PENDING" + + +def test_unknown_poll_mode_is_rejected(): + with pytest.raises(ValueError, match="Unknown Flow polling mode"): + annotate_polling({"data": {"workflows": []}}, mode="mystery") + + +@pytest.mark.asyncio +async def test_flow_client_media_resolver_uses_get_media_on_batch(): + client = FlowClient() + client.get_media = AsyncMock(return_value={ + "status": 200, + "data": {"video": {"fifeUrl": "https://flow-content.google/video/media-1?sig=x"}}, + }) + + result = await client.resolve_media_url("media-1") + + assert result["data"]["url"].startswith("https://flow-content.google/video/") + assert result["data"]["contentType"] == "video/mp4" + client.get_media.assert_awaited_once_with("media-1") diff --git a/tests/unit/test_omni_flash.py b/tests/unit/test_omni_flash.py index 7bcb137e3..fcb69642d 100644 --- a/tests/unit/test_omni_flash.py +++ b/tests/unit/test_omni_flash.py @@ -190,15 +190,12 @@ async def test_first_last_rejects_missing_end_before_submit(): @pytest.mark.asyncio -async def test_batch_omni_poll_uses_as29s_media(monkeypatch): +async def test_batch_omni_poll_uses_as29s_media(): client = MagicMock() - client.get_media = AsyncMock(return_value={ + client.resolve_media_url = AsyncMock(return_value={ "status": 200, - "data": { - "video": { - "fifeUrl": "https://flow-content.google/video/media-1?Signature=test" - } - }, + "data": {"url": "https://flow-content.google/video/media-1?Signature=test", + "contentType": "video/mp4"}, }) with patch("agent.services.omni_flash.get_flow_client", return_value=client): @@ -213,7 +210,7 @@ async def test_batch_omni_poll_uses_as29s_media(monkeypatch): assert result["done"] is True assert result["status"] == "COMPLETED" assert result["workflows"][0]["media"]["resolved_via"] == "as29s" - client.get_media.assert_awaited_once_with("media-1") + client.resolve_media_url.assert_awaited_once_with("media-1") @pytest.mark.asyncio @@ -221,8 +218,11 @@ async def test_batch_poll_hands_back_the_signed_url_and_buffers_nothing(): """The poller must return Flow's signed url, never the bytes: buffering a finished clip through the agent is what the as29s lookup exists to avoid.""" client = MagicMock() - client.get_media = AsyncMock(return_value={"status": 200, "data": {"video": { - "fifeUrl": "https://flow-content.google/video/media-1?Signature=test"}}}) + client.resolve_media_url = AsyncMock(return_value={ + "status": 200, + "data": {"url": "https://flow-content.google/video/media-1?Signature=test", + "contentType": "video/mp4"}, + }) with patch("agent.services.omni_flash.get_flow_client", return_value=client): result = await check_omni_flash_status( @@ -241,8 +241,12 @@ async def test_batch_poll_treats_a_media_record_without_video_as_pending(): """A media id exists before its clip does — the record serves the poster image first. Reading that as done is what saves a still instead of a video.""" client = MagicMock() - client.get_media = AsyncMock(return_value={"status": 200, "data": {"image": { - "fifeUrl": "https://flow-content.google/image/media-1?Signature=test"}}}) + client.resolve_media_url = AsyncMock(return_value={ + "status": 200, "data": { + "url": "https://flow-content.google/image/media-1?Signature=test", + "contentType": "image/jpeg", + }, + }) with patch("agent.services.omni_flash.get_flow_client", return_value=client): result = await check_omni_flash_status( diff --git a/tests/unit/test_shared_export_api.py b/tests/unit/test_shared_export_api.py new file mode 100644 index 000000000..fd4666bc2 --- /dev/null +++ b/tests/unit/test_shared_export_api.py @@ -0,0 +1,143 @@ +"""Fork export endpoints share the current upstream PR #40 poller.""" + +from unittest.mock import AsyncMock, MagicMock, patch + +import pytest +from fastapi import HTTPException + +from agent.api import flow, upscale_status +from agent.services.flow_poll import check_workflow_status + + +@pytest.mark.asyncio +async def test_export_allocates_session_project_for_projectless_calls(): + client = MagicMock(connected=True) + client.upscale_video = AsyncMock(return_value={ + "status": 200, "data": { + "workflows": [{"name": "upscaled-media", "primary_media_id": "upscaled-media"}], + }, + }) + with ( + patch.object(upscale_status, "get_flow_client", return_value=client), + patch.object(upscale_status, "ensure_session_project", + new_callable=AsyncMock) as lease, + ): + lease.return_value = {"project_id": "project-123"} + result = await upscale_status.export_video( + upscale_status.ExportVideoRequest(media_id="video") + ) + + lease.assert_awaited_once_with(client) + client.upscale_video.assert_awaited_once_with( + media_id="video", scene_id="export", + aspect_ratio="VIDEO_ASPECT_RATIO_LANDSCAPE", + resolution="VIDEO_RESOLUTION_1080P", + project_id="project-123", + ) + assert result["flowkitPolling"]["mode"] == "media_redirect" + assert result["flowkitPolling"]["project_id"] == "project-123" + assert result["export"]["next"] == "/api/flow/check-status" + assert result["export"]["check_status_mode"] == "export" + + +@pytest.mark.asyncio +async def test_export_with_explicit_project_avoids_session_allocation(): + client = MagicMock(connected=True) + client.upscale_video = AsyncMock(return_value={"status": 200, "data": {"workflows": []}}) + with ( + patch.object(upscale_status, "get_flow_client", return_value=client), + patch.object(upscale_status, "ensure_session_project", + new_callable=AsyncMock) as lease, + ): + await upscale_status.export_video( + upscale_status.ExportVideoRequest(media_id="video", project_id="existing-project") + ) + lease.assert_not_awaited() + assert client.upscale_video.await_args.kwargs["project_id"] == "existing-project" + + +@pytest.mark.asyncio +async def test_export_project_lease_failure_is_a_clean_http_error(): + client = MagicMock(connected=True) + with ( + patch.object(upscale_status, "get_flow_client", return_value=client), + patch.object(upscale_status, "ensure_session_project", + new_callable=AsyncMock, side_effect=RuntimeError("cannot create")), + ): + with pytest.raises(HTTPException) as error: + await upscale_status.export_video( + upscale_status.ExportVideoRequest(media_id="video") + ) + assert error.value.status_code == 502 + + +@pytest.mark.asyncio +async def test_shared_check_status_export_sets_download_ready(): + client = MagicMock(connected=True) + client.resolve_media_url = AsyncMock(return_value={ + "status": 200, + "data": {"url": "https://flow-content.google/video/export.mp4?sig=x", + "contentType": "video/mp4"}, + }) + with patch.object(flow, "get_flow_client", return_value=client): + result = await flow.check_status(flow.CheckStatusRequest( + mode="export", project_id="project-123", + workflows=[{"name": "workflow-1", "primary_media_id": "video-upscaled"}], + )) + assert result["download_ready"] is True + assert result["workflows"][0]["media"]["resolved_via"] == "as29s" + client.resolve_media_url.assert_awaited_once_with("video-upscaled") + + +@pytest.mark.asyncio +async def test_legacy_export_status_alias_still_uses_shared_poll(): + client = MagicMock(connected=True) + client.resolve_media_url = AsyncMock(return_value={ + "status": 404, "error": "not ready", + }) + with patch.object(upscale_status, "get_flow_client", return_value=client): + result = await upscale_status.check_export_status( + upscale_status.CheckExportStatusRequest( + workflows=[{"name": "workflow-1", "primary_media_id": "video-upscaled"}], + ) + ) + assert result["download_ready"] is False + assert result["workflows"][0]["status"] == "PENDING" + + +@pytest.mark.asyncio +async def test_shared_poller_rejects_image_url_as_finished_video(): + client = MagicMock() + client.resolve_media_url = AsyncMock(return_value={ + "status": 200, + "data": {"url": "https://flow-content.google/image/not-video.jpg?sig=x", + "contentType": "image/jpeg"}, + }) + result = await check_workflow_status( + [{"name": "wf", "primary_media_id": "video-upscaled"}], + mode="media_redirect", client=client, + ) + assert result["done"] is False + assert result["status"] == "PENDING" + + +@pytest.mark.asyncio +async def test_export_provider_error_preserves_http_status(): + client = MagicMock(connected=True) + client.upscale_video = AsyncMock(return_value={"status": 403, "error": "plan restricted"}) + with patch.object(upscale_status, "get_flow_client", return_value=client): + with pytest.raises(HTTPException) as error: + await upscale_status.export_video( + upscale_status.ExportVideoRequest(media_id="video", project_id="project-123") + ) + assert error.value.status_code == 403 + + +@pytest.mark.asyncio +async def test_export_requires_browser_connection(): + with patch.object(upscale_status, "get_flow_client", return_value=MagicMock(connected=False)): + with pytest.raises(HTTPException) as error: + await upscale_status.export_video( + upscale_status.ExportVideoRequest(media_id="video") + ) + assert error.value.status_code == 503