diff --git a/app/api/lmstudio/route.ts b/app/api/lmstudio/route.ts new file mode 100644 index 0000000..3f81a73 --- /dev/null +++ b/app/api/lmstudio/route.ts @@ -0,0 +1,259 @@ +// Proxy for LM Studio API — avoids CORS issues by routing through Next.js server +// Includes agentic tool loop: streams LM Studio responses, executes tool calls +// server-side, feeds results back, and continues until the model is done. +import { NextRequest } from "next/server"; +import { TOOL_DEFINITIONS, executeTool } from "./tools"; + +const MAX_TOOL_ROUNDS = 5; + +// GET /api/lmstudio?url=&path=&apiKey= +// Proxies GET requests (e.g. /v1/models) +export async function GET(req: NextRequest) { + const { searchParams } = req.nextUrl; + const baseUrl = searchParams.get("url"); + const path = searchParams.get("path") || "/v1/models"; + const apiKey = searchParams.get("apiKey"); + + if (!baseUrl) { + return Response.json({ error: "Missing url parameter" }, { status: 400 }); + } + + const target = `${baseUrl.replace(/\/$/, "")}${path}`; + const headers: Record = {}; + if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`; + + try { + const res = await fetch(target, { headers }); + const data = await res.json(); + return Response.json(data, { status: res.status }); + } catch (err) { + return Response.json( + { error: (err as Error).message || "Failed to reach LM Studio" }, + { status: 502 } + ); + } +} + +// ── SSE stream helpers ─────────────────────────────────────────────────────── + +interface ToolCallAccum { + id: string; + name: string; + args: string; +} + +interface StreamResult { + finishReason: string | null; + toolCalls: ToolCallAccum[]; +} + +// Consume an SSE stream from LM Studio, forwarding chunks to the client writer +// and collecting any tool calls. +async function consumeStream( + upstream: Response, + writer: WritableStreamDefaultWriter, + encoder: TextEncoder +): Promise { + const reader = upstream.body!.getReader(); + const decoder = new TextDecoder(); + let buffer = ""; + const toolCalls = new Map(); + let finishReason: string | null = null; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + buffer += decoder.decode(value, { stream: true }); + const lines = buffer.split("\n"); + buffer = lines.pop() || ""; + + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed.startsWith("data: ")) continue; + const data = trimmed.slice(6); + if (data === "[DONE]") continue; + + try { + const chunk = JSON.parse(data); + const choice = chunk.choices?.[0]; + if (!choice) continue; + const delta = choice.delta; + + // Collect tool calls + if (delta?.tool_calls) { + for (const tc of delta.tool_calls) { + const idx = tc.index ?? 0; + if (!toolCalls.has(idx)) { + toolCalls.set(idx, { id: "", name: "", args: "" }); + } + const entry = toolCalls.get(idx)!; + if (tc.id) entry.id = tc.id; + if (tc.function?.name) entry.name += tc.function.name; + if (tc.function?.arguments) entry.args += tc.function.arguments; + } + } + + if (choice.finish_reason) { + finishReason = choice.finish_reason; + } + } catch { + // skip malformed + } + + // Forward all SSE lines to the client as-is + await writer.write(encoder.encode(trimmed + "\n\n")); + } + } + + return { finishReason, toolCalls: Array.from(toolCalls.values()) }; +} + +// POST /api/lmstudio — proxies chat completions with SSE streaming + tool loop +export async function POST(req: NextRequest) { + const body = await req.json(); + const { _proxyUrl, _proxyApiKey, _enableTools, ...rest } = body; + + if (!_proxyUrl) { + return Response.json({ error: "Missing _proxyUrl in body" }, { status: 400 }); + } + + const target = `${(_proxyUrl as string).replace(/\/$/, "")}/v1/chat/completions`; + const headers: Record = { "Content-Type": "application/json" }; + if (_proxyApiKey) headers["Authorization"] = `Bearer ${_proxyApiKey}`; + + // Inject tool definitions if enabled + if (_enableTools && !rest.tools) { + rest.tools = TOOL_DEFINITIONS; + rest.tool_choice = "auto"; + } + + const encoder = new TextEncoder(); + + const stream = new ReadableStream({ + async start(controller) { + const writer = { + write: async (chunk: Uint8Array) => controller.enqueue(chunk), + } as WritableStreamDefaultWriter; + + let messages = [...(rest.messages || [])]; + let round = 0; + + try { + while (round < MAX_TOOL_ROUNDS) { + round++; + const upstream = await fetch(target, { + method: "POST", + headers, + body: JSON.stringify({ ...rest, messages }), + }); + + if (!upstream.ok) { + const errText = await upstream.text().catch(() => `HTTP ${upstream.status}`); + controller.enqueue( + encoder.encode(`data: ${JSON.stringify({ error: errText })}\n\n`) + ); + break; + } + + if (!upstream.body) { + controller.enqueue( + encoder.encode(`data: ${JSON.stringify({ error: "No response body" })}\n\n`) + ); + break; + } + + const { finishReason, toolCalls } = await consumeStream( + upstream, + writer, + encoder + ); + + // If the model didn't request tool calls, we're done + if (finishReason !== "tool_calls" || toolCalls.length === 0) { + break; + } + + // Build the assistant message with tool_calls for the conversation + const assistantMsg: Record = { + role: "assistant", + content: null, + tool_calls: toolCalls.map((tc, i) => ({ + id: tc.id || `call_${i}`, + type: "function", + function: { name: tc.name, arguments: tc.args }, + })), + }; + messages.push(assistantMsg); + + // Execute each tool call and add results + for (const tc of toolCalls) { + // Notify client that we're executing a tool + const toolStatusEvent = { + choices: [ + { + delta: { + tool_execution: { + name: tc.name, + args: tc.args, + status: "running", + call_id: tc.id, + }, + }, + }, + ], + }; + controller.enqueue( + encoder.encode(`data: ${JSON.stringify(toolStatusEvent)}\n\n`) + ); + + const result = await executeTool(tc.name, tc.args); + + // Notify client of tool result + const toolResultEvent = { + choices: [ + { + delta: { + tool_execution: { + name: tc.name, + status: "done", + call_id: tc.id, + result, + }, + }, + }, + ], + }; + controller.enqueue( + encoder.encode(`data: ${JSON.stringify(toolResultEvent)}\n\n`) + ); + + messages.push({ + role: "tool", + tool_call_id: tc.id || `call_${toolCalls.indexOf(tc)}`, + content: result, + }); + } + + // Continue the loop — next iteration sends updated messages back to LM Studio + } + } catch (err) { + const errMsg = (err as Error).message || "Unknown error"; + controller.enqueue( + encoder.encode(`data: ${JSON.stringify({ error: errMsg })}\n\n`) + ); + } + + controller.enqueue(encoder.encode("data: [DONE]\n\n")); + controller.close(); + }, + }); + + return new Response(stream, { + headers: { + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache", + Connection: "keep-alive", + }, + }); +} diff --git a/app/api/lmstudio/tools.ts b/app/api/lmstudio/tools.ts new file mode 100644 index 0000000..23d0ff0 --- /dev/null +++ b/app/api/lmstudio/tools.ts @@ -0,0 +1,208 @@ +// Server-side implementations of LM Studio's built-in tools +// Mirrors the danielsig/duckduckgo and danielsig/visit-website plugins + +// ── Tool definitions (OpenAI function calling format) ──────────────────────── + +export const TOOL_DEFINITIONS = [ + { + type: "function" as const, + function: { + name: "Web_Search", + description: + "Search for web pages on DuckDuckGo using a query string and return a list of URLs.", + parameters: { + type: "object", + properties: { + query: { type: "string", description: "The search query for finding web pages" }, + pageSize: { + type: "number", + description: "Number of web results per page (1-10, default 5)", + }, + }, + required: ["query"], + }, + }, + }, + { + type: "function" as const, + function: { + name: "Image_Search", + description: + "Search for images on DuckDuckGo using a query string and return a list of image URLs.", + parameters: { + type: "object", + properties: { + query: { type: "string", description: "The search query for finding images" }, + pageSize: { + type: "number", + description: "Number of image results per page (1-10, default 5)", + }, + }, + required: ["query"], + }, + }, + }, + { + type: "function" as const, + function: { + name: "Visit_Website", + description: + "Visit a website and return its title, headings, links, and text content.", + parameters: { + type: "object", + properties: { + url: { type: "string", description: "The URL of the website to visit" }, + contentLimit: { + type: "number", + description: "Maximum text content length (default 2000)", + }, + }, + required: ["url"], + }, + }, + }, +]; + +// ── Spoof headers to avoid bot detection ───────────────────────────────────── + +function spoofHeaders(referer?: string): Record { + const h: Record = { + "User-Agent": + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", + "Accept-Language": "en-US,en;q=0.9", + }; + if (referer) h["Referer"] = referer; + return h; +} + +// ── Tool implementations ───────────────────────────────────────────────────── + +async function webSearch(args: { query: string; pageSize?: number }): Promise { + const pageSize = Math.min(Math.max(args.pageSize || 5, 1), 10); + const url = new URL("https://duckduckgo.com/html/"); + url.searchParams.append("q", args.query); + + const res = await fetch(url.toString(), { method: "GET", headers: spoofHeaders() }); + if (!res.ok) return `Error: Failed to fetch search results: ${res.statusText}`; + + const html = await res.text(); + const links: [string, string][] = []; + const regex = /\shref="[^"]*(https?[^?&"]+)[^>]*>([^<]*)/gm; + let match; + while (links.length < pageSize && (match = regex.exec(html))) { + const label = match[2].replace(/\s+/g, " ").trim(); + const href = decodeURIComponent(match[1]); + if (!links.some(([, u]) => u === href)) links.push([label, href]); + } + + if (links.length === 0) return "No web pages found for the query."; + return JSON.stringify({ links, count: links.length }); +} + +async function imageSearch(args: { query: string; pageSize?: number }): Promise { + const pageSize = Math.min(Math.max(args.pageSize || 5, 1), 10); + const url = new URL("https://duckduckgo.com/"); + url.searchParams.append("q", args.query); + url.searchParams.append("iax", "images"); + url.searchParams.append("ia", "images"); + + const res = await fetch(url.toString(), { method: "GET", headers: spoofHeaders() }); + if (!res.ok) return `Error: Failed to fetch image results: ${res.statusText}`; + + const html = await res.text(); + // Extract vqd token for image API + const vqdMatch = html.match(/vqd=['"]([^'"]+)['"]/); + if (!vqdMatch) return "Error: Could not extract search token for images."; + + const imgUrl = new URL("https://duckduckgo.com/i.js"); + imgUrl.searchParams.append("q", args.query); + imgUrl.searchParams.append("vqd", vqdMatch[1]); + imgUrl.searchParams.append("o", "json"); + + const imgRes = await fetch(imgUrl.toString(), { + headers: spoofHeaders("https://duckduckgo.com/"), + }); + if (!imgRes.ok) return "Error: Failed to fetch image results."; + + const data = await imgRes.json(); + const images = (data.results || []).slice(0, pageSize).map((r: { title: string; image: string }) => ({ + title: r.title, + url: r.image, + })); + + if (images.length === 0) return "No images found for the query."; + return JSON.stringify({ images, count: images.length }); +} + +async function visitWebsite(args: { url: string; contentLimit?: number }): Promise { + const contentLimit = args.contentLimit || 2000; + + const res = await fetch(args.url, { method: "GET", headers: spoofHeaders() }); + if (!res.ok) return `Error: Failed to visit website: ${res.statusText}`; + + const html = await res.text(); + + // Extract title + const title = html.match(/]*>([^<]*)<\/title>/i)?.[1]?.trim() || ""; + + // Extract headings + const headings: string[] = []; + const hRegex = /]*>([^<]*)<\/h[1-3]>/gi; + let hMatch; + while (headings.length < 10 && (hMatch = hRegex.exec(html))) { + const text = hMatch[1].trim(); + if (text) headings.push(text); + } + + // Extract text content (strip tags, collapse whitespace) + const bodyMatch = html.match(/]*>([\s\S]*)<\/body>/i); + let textContent = bodyMatch?.[1] || html; + textContent = textContent + .replace(//gi, "") + .replace(//gi, "") + .replace(/<[^>]+>/g, " ") + .replace(/\s+/g, " ") + .trim() + .slice(0, contentLimit); + + // Extract links + const links: [string, string][] = []; + const linkRegex = /]*href="([^"]+)"[^>]*>([^<]*)<\/a>/gi; + let lMatch; + while (links.length < 20 && (lMatch = linkRegex.exec(html))) { + const href = lMatch[1]; + const label = lMatch[2].trim(); + if (href.startsWith("http") && label) links.push([label, href]); + } + + return JSON.stringify({ title, headings, textContent, links: links.slice(0, 20) }); +} + +// ── Execute a tool call by name ────────────────────────────────────────────── + +export async function executeTool( + name: string, + argsJson: string +): Promise { + let args: Record; + try { + args = JSON.parse(argsJson); + } catch { + return `Error: Invalid JSON arguments: ${argsJson}`; + } + + switch (name) { + case "Web_Search": + case "Web Search": + return webSearch(args as { query: string; pageSize?: number }); + case "Image_Search": + case "Image Search": + return imageSearch(args as { query: string; pageSize?: number }); + case "Visit_Website": + case "Visit Website": + return visitWebsite(args as { url: string; contentLimit?: number }); + default: + return `Error: Unknown tool "${name}"`; + } +} diff --git a/app/page.tsx b/app/page.tsx index 6006d1b..98608f8 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -6,6 +6,7 @@ import { useState, useRef, useEffect, useCallback } from "react"; import { useWebSocket, type WebSocketMessage } from "@/lib/useWebSocket"; import { getToolDisplay } from "@/lib/toolDisplay"; import { DEMO_HISTORY, createDemoHandler, type DemoCallbacks } from "@/lib/demoMode"; +import { fetchLmStudioModels, createLmStudioHandler, type LmStudioConfig, type LmStudioCallbacks, type LmStudioModel } from "@/lib/lmStudio"; // ── Types ──────────────────────────────────────────────────────────────────── @@ -106,6 +107,14 @@ interface WSHello { type WSIncomingMessage = WSResponse | WSEvent | WSHello; +type BackendMode = "openclaw" | "lmstudio" | "demo"; + +interface ConnectionConfig { + mode: BackendMode; + url: string; + token?: string; + model?: string; +} function getTextFromContent(content: ContentPart[] | string | null): string { if (!content) return ""; @@ -596,17 +605,49 @@ function MessageRow({ message, isStreaming }: { message: Message; isStreaming: b const isUser = message.role === "user"; + // Build interleaved thinking + tool_call parts from content array (preserves chronological order) + // Filter out thinking parts that are empty/whitespace-only (can happen from tag residue) + const interleavedParts = Array.isArray(message.content) + ? (message.content as ContentPart[]).filter((p) => + (p.type === "thinking" && p.text?.trim()) || p.type === "tool_call" || p.type === "toolCall" + ) + : []; + const hasThinkingParts = interleavedParts.some((p) => p.type === "thinking"); + return (
- {message.reasoning && ( -
- - - {thinkingPreview(message.reasoning)} - -

{message.reasoning}

-
+ {hasThinkingParts ? ( + // Render interleaved thinking pills and tool call pills in content order + interleavedParts.map((part, i) => + part.type === "thinking" && part.text ? ( +
+ + + {thinkingPreview(part.text)} + +

{part.text}

+
+ ) : (part.type === "tool_call" || part.type === "toolCall") ? ( + + ) : null + ) + ) : ( + // Fallback: legacy rendering for OpenClaw/demo messages using message.reasoning + <> + {message.reasoning && ( +
+ + + {thinkingPreview(message.reasoning)} + +

{message.reasoning}

+
+ )} + {toolCalls.map((tc, i) => ( + + ))} + )} {isUser ? ( <> @@ -790,7 +831,7 @@ function CommandSheet({ <> {/* Backdrop */}
{/* Handle */}
@@ -1109,14 +1150,21 @@ function SetupDialog({ connectionError, isDemoMode, }: { - onConnect: (url: string, token?: string) => void; + onConnect: (config: ConnectionConfig) => void; visible: boolean; connectionState?: "connecting" | "connected" | "disconnected" | "error"; connectionError?: string | null; isDemoMode?: boolean; }) { + const [mode, setMode] = useState<"openclaw" | "lmstudio">("openclaw"); const [url, setUrl] = useState("ws://127.0.0.1:18789"); const [token, setToken] = useState(""); + const [lmsUrl, setLmsUrl] = useState("http://127.0.0.1:1234"); + const [lmsApiKey, setLmsApiKey] = useState(""); + const [lmsModel, setLmsModel] = useState(""); + const [lmsModels, setLmsModels] = useState([]); + const [lmsModelLoading, setLmsModelLoading] = useState(false); + const [lmsModelError, setLmsModelError] = useState(""); const [error, setError] = useState(""); const [phase, setPhase] = useState<"idle" | "entering" | "open" | "closing" | "closed">("idle"); const inputRef = useRef(null); @@ -1125,11 +1173,20 @@ function SetupDialog({ useEffect(() => { if (visible && (phase === "closed" || phase === "idle")) { // Pre-fill from localStorage if available + const savedMode = window.localStorage.getItem("mobileclaw-mode") as "openclaw" | "lmstudio" | null; + if (savedMode === "openclaw" || savedMode === "lmstudio") setMode(savedMode); const savedUrl = window.localStorage.getItem("openclaw-url"); const savedToken = window.localStorage.getItem("openclaw-token"); if (savedUrl) setUrl(savedUrl); if (savedToken) setToken(savedToken); + const savedLmsUrl = window.localStorage.getItem("lmstudio-url"); + const savedLmsApiKey = window.localStorage.getItem("lmstudio-apikey"); + const savedLmsModel = window.localStorage.getItem("lmstudio-model"); + if (savedLmsUrl) setLmsUrl(savedLmsUrl); + if (savedLmsApiKey) setLmsApiKey(savedLmsApiKey); + if (savedLmsModel) setLmsModel(savedLmsModel); setError(""); + setLmsModelError(""); requestAnimationFrame(() => { setPhase("entering"); requestAnimationFrame(() => setPhase("open")); @@ -1148,23 +1205,72 @@ function SetupDialog({ } }, [phase]); + // Fetch LM Studio models when URL changes and mode is lmstudio + const fetchModels = useCallback(async (baseUrl: string, apiKey?: string) => { + const trimmed = baseUrl.trim(); + if (!trimmed) return; + setLmsModelLoading(true); + setLmsModelError(""); + try { + const models = await fetchLmStudioModels(trimmed, apiKey || undefined); + setLmsModels(models); + // Auto-select first model if none selected + if (models.length > 0 && !lmsModel) { + setLmsModel(models[0].id); + } + } catch (err) { + setLmsModelError((err as Error).message || "Cannot reach server"); + setLmsModels([]); + } finally { + setLmsModelLoading(false); + } + }, [lmsModel]); + const handleSubmit = () => { - const trimmed = url.trim(); - // Allow empty URL for mock mode - if (trimmed) { + if (mode === "openclaw") { + const trimmed = url.trim(); + // Allow empty URL for mock mode + if (trimmed) { + try { + new URL(trimmed); + } catch { + setError("Please enter a valid URL or leave empty for demo mode"); + return; + } + } + setError(""); + setPhase("closing"); + setTimeout(() => { + setPhase("closed"); + if (!trimmed) { + onConnect({ mode: "demo", url: "" }); + } else { + onConnect({ mode: "openclaw", url: trimmed, token: token.trim() || undefined }); + } + }, 500); + } else { + const trimmed = lmsUrl.trim(); + if (!trimmed) { + setError("Please enter the LM Studio server URL"); + return; + } try { new URL(trimmed); } catch { - setError("Please enter a valid URL or leave empty for mock mode"); + setError("Please enter a valid URL"); return; } + if (!lmsModel) { + setError("Please select a model"); + return; + } + setError(""); + setPhase("closing"); + setTimeout(() => { + setPhase("closed"); + onConnect({ mode: "lmstudio", url: trimmed, token: lmsApiKey.trim() || undefined, model: lmsModel }); + }, 500); } - setError(""); - setPhase("closing"); - setTimeout(() => { - setPhase("closed"); - onConnect(trimmed, token.trim() || undefined); - }, 500); }; if (phase === "closed" || (!visible && phase === "idle")) return null; @@ -1210,57 +1316,174 @@ function SetupDialog({ boxShadow: isClosing ? "0 0 20px oklch(0.55 0 0 / 0.15)" : "none", }} > - - - + {mode === "lmstudio" ? ( + + + + ) : ( + + + + )}

Connect to MobileClaw

-

- {isDemoMode - ? "Demo environment — no server needed. Carry on." - : "Enter server URL (https:// or http://) or leave empty for mock mode."} +

+ Choose a backend and configure your connection.

- {/* URL input */} -
- - { setUrl(e.target.value); setError(""); }} - onKeyDown={(e) => { if (e.key === "Enter") handleSubmit(); }} - placeholder={isDemoMode ? "Not needed in demo mode" : "ws://127.0.0.1:18789"} - disabled={isConnecting || isDemoMode} - className={`w-full rounded-xl border bg-background px-4 py-2.5 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50 ${error || connectionError ? "border-destructive" : "border-border"}`} - /> - {error &&

{error}

} - {connectionError &&

{connectionError}

} + {/* Mode selector — segmented control */} +
+ +
- {/* Token input */} -
- - setToken(e.target.value)} - onKeyDown={(e) => { if (e.key === "Enter") handleSubmit(); }} - placeholder={isDemoMode ? "Not needed in demo mode" : "Enter gateway auth token"} - disabled={isConnecting || isDemoMode} - className="w-full rounded-xl border border-border bg-background px-4 py-2.5 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50" - /> -
+ {mode === "openclaw" ? ( + <> + {/* URL input */} +
+ + { setUrl(e.target.value); setError(""); }} + onKeyDown={(e) => { if (e.key === "Enter") handleSubmit(); }} + placeholder="ws://127.0.0.1:18789" + disabled={isConnecting} + className={`w-full rounded-xl border bg-background px-4 py-2.5 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50 ${error || connectionError ? "border-destructive" : "border-border"}`} + /> +
+ + {/* Token input — hidden when URL is empty (demo mode) */} + {url.trim() && ( +
+ + setToken(e.target.value)} + onKeyDown={(e) => { if (e.key === "Enter") handleSubmit(); }} + placeholder="Enter gateway auth token" + disabled={isConnecting} + className="w-full rounded-xl border border-border bg-background px-4 py-2.5 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50" + /> +
+ )} + + ) : ( + <> + {/* LM Studio URL */} +
+ +
+ { setLmsUrl(e.target.value); setError(""); setLmsModelError(""); }} + onKeyDown={(e) => { if (e.key === "Enter") handleSubmit(); }} + placeholder="http://127.0.0.1:1234" + disabled={isConnecting} + className={`flex-1 rounded-xl border bg-background px-4 py-2.5 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50 ${error || connectionError || lmsModelError ? "border-destructive" : "border-border"}`} + /> + +
+ {lmsModelError &&

{lmsModelError}

} +
+ + {/* API Key (optional) */} +
+ + setLmsApiKey(e.target.value)} + onKeyDown={(e) => { if (e.key === "Enter") handleSubmit(); }} + placeholder="lm-studio or leave empty" + disabled={isConnecting} + className="w-full rounded-xl border border-border bg-background px-4 py-2.5 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50" + /> +
- {/* Connect / Close button */} + {/* Model selector */} +
+ + {lmsModels.length > 0 ? ( + + ) : ( + { setLmsModel(e.target.value); setError(""); }} + onKeyDown={(e) => { if (e.key === "Enter") handleSubmit(); }} + placeholder="Click Fetch or type model name" + disabled={isConnecting} + className={`w-full rounded-xl border bg-background px-4 py-2.5 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50 ${error ? "border-destructive" : "border-border"}`} + /> + )} +
+ + )} + + {error &&

{error}

} + {connectionError &&

{connectionError}

} + + {/* Connect button */} - {!isDemoMode && ( + {mode === "openclaw" && (

- Leave empty to use mock mode without a server + Leave empty to use demo mode without a server

)}
@@ -1329,6 +1550,11 @@ export default function Home() { const [isDemoMode, setIsDemoMode] = useState(false); const demoHandlerRef = useRef | null>(null); + // Backend mode: openclaw (WebSocket), lmstudio (HTTP+SSE), or demo + const [backendMode, setBackendMode] = useState("openclaw"); + const lmStudioConfigRef = useRef(null); + const lmStudioHandlerRef = useRef | null>(null); + // Track active run for streaming const activeRunIdRef = useRef(null); const sendWSMessageRef = useRef<((message: WebSocketMessage) => boolean) | null>(null); @@ -1754,6 +1980,7 @@ export default function Home() { const params = new URLSearchParams(window.location.search); if (params.has("demo")) { setIsDemoMode(true); + setBackendMode("demo"); setMessages(DEMO_HISTORY); setCurrentModel("demo/openclaw-preview"); setShowSetup(false); @@ -1832,6 +2059,101 @@ export default function Home() { demoHandlerRef.current = createDemoHandler(callbacks); }, [isDemoMode]); + // LM Studio mode: create handler with callbacks + useEffect(() => { + if (backendMode !== "lmstudio" || !lmStudioConfigRef.current) { + lmStudioHandlerRef.current = null; + return; + } + const config = lmStudioConfigRef.current; + const callbacks: LmStudioCallbacks = { + onStreamStart: (runId) => { + setIsStreaming(true); + setStreamingId(runId); + setMessages((prev) => [ + ...prev, + { role: "assistant", content: [], id: runId, timestamp: Date.now() }, + ]); + }, + onThinking: (runId, text, segment) => { + setMessages((prev) => { + const idx = prev.findIndex((m) => m.id === runId); + if (idx < 0) return prev; + const target = prev[idx]; + const parts = Array.isArray(target.content) ? [...target.content] : []; + // Find the thinking part for this segment + let segIdx = 0; + const thinkPartIdx = parts.findIndex((p) => { + if (p.type === "thinking") { + if (segIdx === segment) return true; + segIdx++; + } + return false; + }); + if (thinkPartIdx >= 0) { + parts[thinkPartIdx] = { ...parts[thinkPartIdx], text }; + } else { + // Always push at end — onTextDelta will move text part to end on next update + parts.push({ type: "thinking", text }); + } + return [...prev.slice(0, idx), { ...target, content: parts }, ...prev.slice(idx + 1)]; + }); + }, + onTextDelta: (runId, _delta, fullText) => { + setMessages((prev) => { + const idx = prev.findIndex((m) => m.id === runId); + if (idx < 0) return prev; + const target = prev[idx]; + // Preserve existing non-text parts (tool_call, thinking), update only the text part + const existingParts = Array.isArray(target.content) ? target.content.filter((p: ContentPart) => p.type !== "text") : []; + return [ + ...prev.slice(0, idx), + { ...target, content: [...existingParts, { type: "text", text: fullText }] }, + ...prev.slice(idx + 1), + ]; + }); + }, + onToolStart: (runId, name, args) => { + setMessages((prev) => { + const idx = prev.findIndex((m) => m.id === runId); + if (idx < 0) return prev; + const target = prev[idx]; + const parts = Array.isArray(target.content) ? target.content : []; + return [ + ...prev.slice(0, idx), + { ...target, content: [...parts, { type: "tool_call", name, arguments: args, status: "running" as const }] }, + ...prev.slice(idx + 1), + ]; + }); + }, + onToolEnd: (runId, name, result, isError) => { + setMessages((prev) => { + const idx = prev.findIndex((m) => m.id === runId); + if (idx < 0) return prev; + const target = prev[idx]; + if (!Array.isArray(target.content)) return prev; + const updated = target.content.map((p: ContentPart) => + p.type === "tool_call" && p.name === name && p.status === "running" + ? { ...p, status: (isError ? "error" : "success") as "error" | "success", result: result || undefined, resultError: isError } + : p + ); + return [...prev.slice(0, idx), { ...target, content: updated }, ...prev.slice(idx + 1)]; + }); + }, + onStreamEnd: (runId) => { + setIsStreaming(false); + setStreamingId(null); + }, + onError: (runId, error) => { + setConnectionError(error); + }, + }; + // Use currentModel so the handler is recreated when the model changes + const activeConfig = { ...config, model: currentModel || config.model }; + lmStudioConfigRef.current = activeConfig; + lmStudioHandlerRef.current = createLmStudioHandler(activeConfig, callbacks); + }, [backendMode, currentModel]); + // Track scroll position — continuous CSS var for animations, React state only for pointer-events phase const handleScroll = useCallback(() => { if (scrollRafId.current != null) return; @@ -1888,14 +2210,24 @@ export default function Home() { refreshStartRef.current = Date.now(); // Hold at a small offset to show spinner — bounce back happens when history arrives setPullTransform(40, true); - // Re-fetch history + // LM Studio and demo modes have no server-side history — just bounce back + if (backendMode === "lmstudio" || backendMode === "demo") { + setTimeout(() => { + requestAnimationFrame(() => { + setPullTransform(0, true); + setRefreshing(false); + }); + }, 300); + return; + } + // Re-fetch history (OpenClaw) sendWSMessageRef.current?.({ type: "req", id: `history-${Date.now()}`, method: "chat.history", params: { sessionKey: sessionKeyRef.current }, } as unknown as WebSocketMessage); - }, [setPullTransform]); + }, [setPullTransform, backendMode]); // Pull-up-to-refresh touch handlers — direct DOM transforms, no React re-renders @@ -1986,54 +2318,100 @@ export default function Home() { useEffect(() => { // Skip auto-connect in demo mode (check URL params directly to avoid race with state) if (isDemoMode) return; - if (typeof window !== "undefined" && new URLSearchParams(window.location.search).has("demo")) return; - const saved = window.localStorage.getItem("openclaw-url"); - const savedToken = window.localStorage.getItem("openclaw-token"); - if (savedToken) gatewayTokenRef.current = savedToken; - // Only auto-connect if there's actually a saved URL - if (saved) { - setOpenclawUrl(saved); - let wsUrl = saved; - if (!saved.startsWith("ws://") && !saved.startsWith("wss://")) { - wsUrl = saved.replace(/^http:\/\//, "ws://").replace(/^https:\/\//, "wss://"); + const savedMode = window.localStorage.getItem("mobileclaw-mode") as BackendMode | null; + + if (savedMode === "lmstudio") { + const savedUrl = window.localStorage.getItem("lmstudio-url"); + const savedApiKey = window.localStorage.getItem("lmstudio-apikey"); + const savedModel = window.localStorage.getItem("lmstudio-model"); + if (savedUrl && savedModel) { + setBackendMode("lmstudio"); + const config: LmStudioConfig = { baseUrl: savedUrl, apiKey: savedApiKey || undefined, model: savedModel }; + lmStudioConfigRef.current = config; + setCurrentModel(savedModel); + setOpenclawUrl(savedUrl); + } else { + setShowSetup(true); } - connect(wsUrl); } else { - // No saved config — show setup dialog - setShowSetup(true); + const saved = window.localStorage.getItem("openclaw-url"); + const savedToken = window.localStorage.getItem("openclaw-token"); + if (savedToken) gatewayTokenRef.current = savedToken; + if (saved) { + setBackendMode("openclaw"); + setOpenclawUrl(saved); + let wsUrl = saved; + if (!saved.startsWith("ws://") && !saved.startsWith("wss://")) { + wsUrl = saved.replace(/^http:\/\//, "ws://").replace(/^https:\/\//, "wss://"); + } + connect(wsUrl); + } else { + setShowSetup(true); + } } }, [connect, isDemoMode]); - const handleConnect = useCallback((url: string, token?: string) => { - window.localStorage.setItem("openclaw-url", url); - if (token) window.localStorage.setItem("openclaw-token", token); - gatewayTokenRef.current = token ?? null; - setOpenclawUrl(url); + const handleConnect = useCallback((config: ConnectionConfig) => { setConnectionError(null); - if (!url) { - // Empty URL — enter demo mode + setMessages([]); + + if (config.mode === "demo") { + window.localStorage.setItem("mobileclaw-mode", "demo"); + window.localStorage.removeItem("openclaw-url"); + setBackendMode("demo"); setIsDemoMode(true); setMessages(DEMO_HISTORY); setCurrentModel("demo/openclaw-preview"); return; } - // If URL starts with ws:// or wss://, use it directly - // Otherwise, convert http:// to ws:// and https:// to wss:// - let wsUrl = url; - if (!url.startsWith("ws://") && !url.startsWith("wss://")) { - wsUrl = url.replace(/^http:\/\//, "ws://").replace(/^https:\/\//, "wss://"); + + if (config.mode === "lmstudio") { + window.localStorage.setItem("mobileclaw-mode", "lmstudio"); + window.localStorage.setItem("lmstudio-url", config.url); + if (config.token) window.localStorage.setItem("lmstudio-apikey", config.token); + else window.localStorage.removeItem("lmstudio-apikey"); + if (config.model) window.localStorage.setItem("lmstudio-model", config.model); + setBackendMode("lmstudio"); + setIsDemoMode(false); + const lmsConfig: LmStudioConfig = { baseUrl: config.url, apiKey: config.token, model: config.model! }; + lmStudioConfigRef.current = lmsConfig; + setCurrentModel(config.model || null); + setOpenclawUrl(config.url); + // Disconnect any existing WebSocket + disconnect(); + return; + } + + // OpenClaw mode + window.localStorage.setItem("mobileclaw-mode", "openclaw"); + window.localStorage.setItem("openclaw-url", config.url); + if (config.token) window.localStorage.setItem("openclaw-token", config.token); + gatewayTokenRef.current = config.token ?? null; + setBackendMode("openclaw"); + setIsDemoMode(false); + lmStudioConfigRef.current = null; + lmStudioHandlerRef.current = null; + setOpenclawUrl(config.url); + let wsUrl = config.url; + if (!config.url.startsWith("ws://") && !config.url.startsWith("wss://")) { + wsUrl = config.url.replace(/^http:\/\//, "ws://").replace(/^https:\/\//, "wss://"); } connect(wsUrl); - }, [connect]); + }, [connect, disconnect]); const handleDisconnect = useCallback(() => { disconnect(); + lmStudioHandlerRef.current?.stop(); + lmStudioHandlerRef.current = null; + lmStudioConfigRef.current = null; window.localStorage.removeItem("openclaw-url"); + window.localStorage.removeItem("mobileclaw-mode"); setOpenclawUrl(null); setMessages([]); setIsStreaming(false); setStreamingId(null); setConnectionError(null); + setBackendMode("openclaw"); }, [disconnect]); // Auto-scroll: on non-streaming message changes (history load, new user message), scroll to bottom @@ -2099,11 +2477,25 @@ export default function Home() { setMessages((prev) => [...prev, userMsg]); // Demo mode — route through local handler - if (isDemoMode) { + if (isDemoMode || backendMode === "demo") { demoHandlerRef.current?.sendMessage(text); return; } + // LM Studio mode — route through HTTP+SSE handler + if (backendMode === "lmstudio") { + // Send the full conversation history (including the new user message) to LM Studio + setMessages((prev) => { + // Use a microtask to send after state is updated + Promise.resolve().then(() => { + lmStudioHandlerRef.current?.sendMessage(prev); + }); + return prev; + }); + return; + } + + // OpenClaw mode — WebSocket if (!isConnected) return; // Generate idempotency key for this run @@ -2124,7 +2516,7 @@ export default function Home() { sendWSMessageRef.current?.(requestMsg as unknown as WebSocketMessage); setIsStreaming(true); - }, [isConnected, isDemoMode]); + }, [isConnected, isDemoMode, backendMode]); const handleCommandSelect = useCallback((command: string) => { setPendingCommand(command); @@ -2139,9 +2531,9 @@ export default function Home() {
{/* Setup dialog */} { + onConnect={(config) => { setShowSetup(false); - handleConnect(url, token); + handleConnect(config); }} visible={showSetup} connectionState={connectionState} @@ -2181,11 +2573,16 @@ export default function Home() { )}
- {isDemoMode ? ( + {isDemoMode || backendMode === "demo" ? ( <> Demo + ) : backendMode === "lmstudio" ? ( + <> + + LM Studio + ) : ( <> &path=` — proxies model listing +- **POST** `/api/lmstudio` — proxies chat completions with SSE streaming + +Updated `lib/lmStudio.ts` to route all requests through `/api/lmstudio` instead of hitting LM Studio directly. + +### 3. Thinking block parsing (`` tags) + +Qwen3 and similar models output reasoning inside `...` tags in the content stream (rather than using the `reasoning_content` field). Added a streaming parser in `lib/lmStudio.ts` that: + +- Detects `` and `` tags across chunk boundaries +- Routes thinking content to `onThinking` callback (renders in collapsible reasoning UI) +- Routes regular content to `onTextDelta` callback +- Handles partial tag matches at chunk boundaries via `partialTagSuffix()` helper + +### 4. Model switching fix + +The `useEffect` that creates the LM Studio handler only depended on `[backendMode]`. Changing the model in settings updated the config ref but didn't recreate the handler. Fixed by adding `currentModel` to the dependency array. + +### 5. Server-side tool execution (`app/api/lmstudio/tools.ts`) + +LM Studio's built-in chat UI has DuckDuckGo and web browsing tools (via `danielsig/duckduckgo` and `danielsig/visit-website` plugins). These don't execute when using the API directly. Implemented server-side equivalents: + +**Tool definitions** (injected into the `tools` array of chat completion requests): +- `Web_Search` — DuckDuckGo web search, returns ranked links +- `Image_Search` — DuckDuckGo image search +- `Visit_Website` — fetches a URL, extracts title/headings/links/text + +**Agentic loop** in the proxy route: +1. Sends request to LM Studio with tool definitions +2. Streams response to client (text, thinking, tool call deltas) +3. If `finish_reason: "tool_calls"`, executes tools server-side +4. Sends custom `tool_execution` SSE events so client shows tool pills +5. Feeds tool results back to LM Studio as `role: "tool"` messages +6. Loops (up to 5 rounds) until model produces a final text response + +### 6. Tool pill UI fixes + +- Moved tool pills to render **above** text content in assistant messages (was below) +- Fixed duplicate spinning pills: removed `onToolStart` from `delta.tool_calls` handler — now only server-side `tool_execution` events drive tool pill creation/finalization +- Tool pills now show tool name and arguments (server sends `args` in the running event) + +### 7. Production deployment via Tailscale + +- Built production bundle (`pnpm run build`) +- Started production server on port 3100 (`PORT=3100 pnpm run start`) +- Configured Tailscale serve to proxy HTTPS :3000 to localhost:3100 +- Accessible at `https://krzysztofs-mac-studio.tail657ea.ts.net:3000/` + +### 8. Split thinking blocks around tool calls + +When a Qwen model thinks, uses a tool, then thinks again, both thinking segments were rendered as a single merged thinking pill. Fixed by modeling thinking as content parts interleaved with tool calls: + +**`lib/lmStudio.ts`** — segment tracking: +- Added `thinkingSegment` counter alongside `fullThinking` +- On `tool_execution` with `status === "running"`: reset `fullThinking = ""` and increment `thinkingSegment++` +- Updated `onThinking` callback signature to `(runId, text, segment)` so the UI can track which segment to update + +**`app/page.tsx`** — LM Studio `onThinking` callback: +- Instead of setting `message.reasoning`, manages `{ type: "thinking", text }` content parts in the content array, indexed by segment number +- New segments always push to the end of the array (not before text parts — that was causing ordering bugs where all thinking clustered before tool calls) + +**`app/page.tsx`** — message renderer: +- Checks for `thinking` content parts in the content array +- If found, renders them interleaved with `tool_call` parts in array order (each thinking segment gets its own collapsible pill) +- Filters out empty/whitespace-only thinking parts (residue from `` tag boundaries) +- Falls back to `message.reasoning` for OpenClaw/demo messages (backward compat) + +**Bug fix during implementation**: The initial version inserted new thinking parts *before the text part* in the content array. But whitespace between `` and `` tags leaked as text deltas, placing a text part before tool_calls — so new thinking segments ended up before tool_calls too, breaking the interleaved order. + +## Files changed + +| File | Change | +|------|--------| +| `app/api/lmstudio/route.ts` | New — CORS proxy + agentic tool loop | +| `app/api/lmstudio/tools.ts` | New — tool definitions + server-side implementations | +| `lib/lmStudio.ts` | Proxy routing, `` parser, tool_execution event handling | +| `app/page.tsx` | Tool pills above text, model switch effect dependency | + +## Architecture + +``` +Browser (MobileClaw UI) + | + |-- GET /api/lmstudio?url=...&path=/v1/models (model list) + |-- POST /api/lmstudio (chat + tools) + | +Next.js API Route (proxy + tool executor) + | + |-- GET LM Studio /v1/models + |-- POST LM Studio /v1/chat/completions (streaming) + | | + | |-- if finish_reason: "tool_calls" + | | |-- execute Web_Search / Image_Search / Visit_Website + | | |-- send tool_execution SSE events to client + | | |-- feed results back to LM Studio + | | |-- loop until text response + | | + | |-- stream text/thinking/tool deltas to client + | +LM Studio (localhost:1234) +``` diff --git a/lib/lmStudio.ts b/lib/lmStudio.ts new file mode 100644 index 0000000..a2e2d29 --- /dev/null +++ b/lib/lmStudio.ts @@ -0,0 +1,398 @@ +// LM Studio API client — OpenAI-compatible HTTP + SSE streaming +// Supports text, reasoning/thinking, and tool call streaming + +// ── Types ──────────────────────────────────────────────────────────────────── + +export interface LmStudioConfig { + baseUrl: string; + apiKey?: string; + model: string; +} + +export interface LmStudioModel { + id: string; + object: string; + owned_by: string; +} + +interface ContentPart { + type: string; + text?: string; + name?: string; + arguments?: string; + status?: "running" | "success" | "error"; + result?: string; + resultError?: boolean; +} + +interface Message { + role: string; + content: ContentPart[] | string | null; + timestamp?: number; + id?: string; + reasoning?: string; + toolName?: string; + toolArgs?: string; + isError?: boolean; + stopReason?: string; + isContext?: boolean; +} + +// OpenAI chat completion message format +interface OpenAIMessage { + role: "system" | "user" | "assistant" | "tool"; + content: string | null; + tool_calls?: { id: string; type: "function"; function: { name: string; arguments: string } }[]; + tool_call_id?: string; +} + +// ── Model fetching ─────────────────────────────────────────────────────────── + +export async function fetchLmStudioModels( + baseUrl: string, + apiKey?: string +): Promise { + const params = new URLSearchParams({ url: baseUrl.replace(/\/$/, ""), path: "/v1/models" }); + if (apiKey) params.set("apiKey", apiKey); + + const res = await fetch(`/api/lmstudio?${params}`); + if (!res.ok) throw new Error(`Failed to fetch models: ${res.status}`); + const data = await res.json(); + return data.data || []; +} + +// ── Message conversion ─────────────────────────────────────────────────────── + +function getTextFromContent(content: ContentPart[] | string | null): string { + if (!content) return ""; + if (typeof content === "string") return content; + return content + .filter((p) => p.type === "text" && p.text) + .map((p) => p.text!) + .join(""); +} + +function getToolCallsFromContent(content: ContentPart[] | string | null): ContentPart[] { + if (!content || typeof content === "string") return []; + return content.filter((p) => p.type === "tool_call" && p.name); +} + +export function toOpenAIMessages(messages: Message[]): OpenAIMessage[] { + const result: OpenAIMessage[] = []; + + for (const msg of messages) { + if (msg.role === "system" || msg.stopReason === "injected") { + const text = getTextFromContent(msg.content); + if (text) result.push({ role: "system", content: text }); + continue; + } + + if (msg.role === "user") { + const text = getTextFromContent(msg.content); + if (text) result.push({ role: "user", content: text }); + continue; + } + + if (msg.role === "assistant") { + const text = getTextFromContent(msg.content); + const toolCalls = getToolCallsFromContent(msg.content); + + const openaiMsg: OpenAIMessage = { + role: "assistant", + content: text || null, + }; + + if (toolCalls.length > 0) { + openaiMsg.tool_calls = toolCalls.map((tc, i) => ({ + id: `call_${i}`, + type: "function" as const, + function: { + name: tc.name!, + arguments: tc.arguments || "{}", + }, + })); + } + + result.push(openaiMsg); + continue; + } + + // Skip tool result messages — LM Studio doesn't execute tools + if (msg.role === "tool" || msg.role === "toolResult" || msg.role === "tool_result") { + continue; + } + } + + return result; +} + +// ── Streaming callbacks ────────────────────────────────────────────────────── + +export interface LmStudioCallbacks { + onStreamStart: (runId: string) => void; + onThinking: (runId: string, text: string, segment: number) => void; + onTextDelta: (runId: string, delta: string, fullText: string) => void; + onToolStart: (runId: string, name: string, args: string) => void; + onToolEnd: (runId: string, name: string, result: string, isError: boolean) => void; + onStreamEnd: (runId: string) => void; + onError: (runId: string, error: string) => void; +} + +// Check if the end of `text` is a partial prefix of `tag` (e.g. "") +// Returns the length of the partial match, or 0 if none. +function partialTagSuffix(text: string, tag: string): number { + const maxLen = Math.min(text.length, tag.length - 1); + for (let len = maxLen; len >= 1; len--) { + if (text.endsWith(tag.slice(0, len))) return len; + } + return 0; +} + +// ── SSE streaming handler ──────────────────────────────────────────────────── + +export function createLmStudioHandler( + config: LmStudioConfig, + callbacks: LmStudioCallbacks +) { + let abortController: AbortController | null = null; + + async function sendMessage(messages: Message[]) { + abortController?.abort(); + abortController = new AbortController(); + + const runId = `lms-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`; + callbacks.onStreamStart(runId); + + const openaiMessages = toOpenAIMessages(messages); + const url = "/api/lmstudio"; + + const body: Record = { + _proxyUrl: config.baseUrl.replace(/\/$/, ""), + _proxyApiKey: config.apiKey || undefined, + _enableTools: true, + model: config.model, + messages: openaiMessages, + stream: true, + }; + + try { + const res = await fetch(url, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(body), + signal: abortController.signal, + }); + + if (!res.ok) { + const errText = await res.text().catch(() => `HTTP ${res.status}`); + callbacks.onError(runId, errText); + callbacks.onStreamEnd(runId); + return; + } + + if (!res.body) { + callbacks.onError(runId, "No response body"); + callbacks.onStreamEnd(runId); + return; + } + + const reader = res.body.getReader(); + const decoder = new TextDecoder(); + let buffer = ""; + let fullText = ""; + let fullThinking = ""; + let thinkingSegment = 0; + // Track ... tag parsing state + // Some models (e.g. GLM) start responding in thinking mode without + // an explicit tag — detect from model name + const modelLower = config.model.toLowerCase(); + const implicitThinking = modelLower.includes("glm"); + let insideThinkTag = implicitThinking; + let tagBuffer = ""; // accumulates partial tag matches + + // Accumulate tool calls by index + const toolCalls = new Map(); + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + buffer += decoder.decode(value, { stream: true }); + const lines = buffer.split("\n"); + buffer = lines.pop() || ""; + + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed.startsWith("data: ")) continue; + const data = trimmed.slice(6); + if (data === "[DONE]") { + // Finalize any tool calls that haven't been ended yet + for (const tc of Array.from(toolCalls.values())) { + if (tc.started) { + callbacks.onToolEnd(runId, tc.name, tc.args, false); + } + } + callbacks.onStreamEnd(runId); + return; + } + + try { + const chunk = JSON.parse(data); + const choice = chunk.choices?.[0]; + if (!choice) continue; + const delta = choice.delta; + if (!delta) continue; + + // Text content — parse ... tags from stream + if (delta.content) { + const raw = delta.content as string; + // Feed into tag buffer for cross-chunk tag parsing + let pending = tagBuffer + raw; + tagBuffer = ""; + + while (pending.length > 0) { + if (insideThinkTag) { + const closeIdx = pending.indexOf(""); + if (closeIdx === -1) { + // Check for a partial at the end + const partialClose = partialTagSuffix(pending, ""); + if (partialClose > 0) { + const safe = pending.slice(0, pending.length - partialClose); + tagBuffer = pending.slice(pending.length - partialClose); + if (safe) { fullThinking += safe; callbacks.onThinking(runId, fullThinking, thinkingSegment); } + } else { + fullThinking += pending; + callbacks.onThinking(runId, fullThinking, thinkingSegment); + } + pending = ""; + } else { + const thinkContent = pending.slice(0, closeIdx); + if (thinkContent) { fullThinking += thinkContent; callbacks.onThinking(runId, fullThinking, thinkingSegment); } + insideThinkTag = false; + pending = pending.slice(closeIdx + "".length); + } + } else { + const openIdx = pending.indexOf(""); + const closeIdx = pending.indexOf(""); + + // found before — model was implicitly in thinking mode + // (e.g. GLM outputs thinking without prefix) + if (closeIdx !== -1 && (openIdx === -1 || closeIdx < openIdx)) { + const before = pending.slice(0, closeIdx); + // Retroactively move any already-emitted text to thinking + if (fullText || before) { + fullThinking += fullText + before; + if (fullText) { + fullText = ""; + callbacks.onTextDelta(runId, "", ""); + } + callbacks.onThinking(runId, fullThinking, thinkingSegment); + } + pending = pending.slice(closeIdx + "".length); + } else if (openIdx === -1) { + // No think tags — check for partial tags at the end + const partialOpen = partialTagSuffix(pending, ""); + const partialClose = partialTagSuffix(pending, ""); + const partial = Math.max(partialOpen, partialClose); + if (partial > 0) { + const safe = pending.slice(0, pending.length - partial); + tagBuffer = pending.slice(pending.length - partial); + if (safe) { fullText += safe; callbacks.onTextDelta(runId, safe, fullText); } + } else { + fullText += pending; + callbacks.onTextDelta(runId, pending, fullText); + } + pending = ""; + } else { + const before = pending.slice(0, openIdx); + if (before) { fullText += before; callbacks.onTextDelta(runId, before, fullText); } + insideThinkTag = true; + pending = pending.slice(openIdx + "".length); + } + } + } + } + + // Reasoning/thinking content (LM Studio reasoning_content field) + if (delta.reasoning_content) { + fullThinking += delta.reasoning_content; + callbacks.onThinking(runId, fullThinking, thinkingSegment); + } + + // Tool calls — accumulate across multiple chunks (don't fire + // onToolStart here; server-side tool_execution events handle the UI) + if (delta.tool_calls) { + for (const tc of delta.tool_calls) { + const idx = tc.index ?? 0; + if (!toolCalls.has(idx)) { + toolCalls.set(idx, { id: "", name: "", args: "", started: false }); + } + const entry = toolCalls.get(idx)!; + if (tc.id) entry.id = tc.id; + if (tc.function?.name) entry.name += tc.function.name; + if (tc.function?.arguments) entry.args += tc.function.arguments; + } + } + + // Server-side tool execution events (from agentic proxy) + if (delta.tool_execution) { + const te = delta.tool_execution; + console.log("[lmStudio] tool_execution event:", te.status, te.name, te.call_id); + if (te.status === "running") { + // Reset thinking accumulator so post-tool thinking becomes a new segment + fullThinking = ""; + thinkingSegment++; + callbacks.onToolStart(runId, te.name, te.args || ""); + } else if (te.status === "done") { + console.log("[lmStudio] calling onToolEnd for", te.name); + callbacks.onToolEnd(runId, te.name, te.result || "", false); + // Models that start in implicit thinking mode will also start + // thinking in the next agentic round after tool execution + if (implicitThinking) { + insideThinkTag = true; + } + } + } + + // Finish reason — finalize tool calls (for client-only tool display) + if (choice.finish_reason === "tool_calls") { + // Don't finalize here — the server will execute tools and continue. + // Clear tracked tool calls so they don't get double-finalized. + toolCalls.clear(); + } else if (choice.finish_reason) { + for (const tc of Array.from(toolCalls.values())) { + if (tc.started) { + callbacks.onToolEnd(runId, tc.name, tc.args, false); + } + } + } + } catch { + // Skip malformed JSON chunks + } + } + } + + // Stream ended without [DONE] — finalize + for (const tc of Array.from(toolCalls.values())) { + if (tc.started) { + callbacks.onToolEnd(runId, tc.name, tc.args, false); + } + } + callbacks.onStreamEnd(runId); + } catch (err) { + if ((err as Error).name === "AbortError") { + callbacks.onStreamEnd(runId); + return; + } + callbacks.onError(runId, (err as Error).message || "Unknown error"); + callbacks.onStreamEnd(runId); + } + } + + function stop() { + abortController?.abort(); + abortController = null; + } + + return { sendMessage, stop }; +} diff --git a/lib/useWebSocket.ts b/lib/useWebSocket.ts index 3c74b23..c443136 100644 --- a/lib/useWebSocket.ts +++ b/lib/useWebSocket.ts @@ -40,6 +40,11 @@ export function useWebSocket(options: UseWebSocketOptions = {}) { const connectInternal = useCallback((url: string) => { if (wsRef.current) { + // Prevent old socket from triggering reconnect logic or updating state + wsRef.current.onclose = null; + wsRef.current.onerror = null; + wsRef.current.onmessage = null; + wsRef.current.onopen = null; wsRef.current.close(); } @@ -82,11 +87,15 @@ export function useWebSocket(options: UseWebSocketOptions = {}) { }; ws.onmessage = (event) => { + if (typeof event.data !== "string") { + console.warn("[WS] Received non-text message:", event.data); + return; + } try { const data = JSON.parse(event.data) as WebSocketMessage; optionsRef.current.onMessage?.(data); } catch (err) { - console.error("Failed to parse WebSocket message:", err); + console.error("Failed to parse WebSocket message:", err, "Raw data:", event.data); } }; } catch (err) { diff --git a/next-env.d.ts b/next-env.d.ts index 9edff1c..c4b7818 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/types/routes.d.ts"; +import "./.next/dev/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/tsconfig.tsbuildinfo b/tsconfig.tsbuildinfo new file mode 100644 index 0000000..7278e4a --- /dev/null +++ b/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"fileNames":["./node_modules/typescript/lib/lib.es5.d.ts","./node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/typescript/lib/lib.es2021.d.ts","./node_modules/typescript/lib/lib.es2022.d.ts","./node_modules/typescript/lib/lib.es2023.d.ts","./node_modules/typescript/lib/lib.es2024.d.ts","./node_modules/typescript/lib/lib.esnext.d.ts","./node_modules/typescript/lib/lib.dom.d.ts","./node_modules/typescript/lib/lib.dom.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/typescript/lib/lib.es2016.intl.d.ts","./node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2017.date.d.ts","./node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/typescript/lib/lib.es2021.promise.d.ts","./node_modules/typescript/lib/lib.es2021.string.d.ts","./node_modules/typescript/lib/lib.es2021.weakref.d.ts","./node_modules/typescript/lib/lib.es2021.intl.d.ts","./node_modules/typescript/lib/lib.es2022.array.d.ts","./node_modules/typescript/lib/lib.es2022.error.d.ts","./node_modules/typescript/lib/lib.es2022.intl.d.ts","./node_modules/typescript/lib/lib.es2022.object.d.ts","./node_modules/typescript/lib/lib.es2022.string.d.ts","./node_modules/typescript/lib/lib.es2022.regexp.d.ts","./node_modules/typescript/lib/lib.es2023.array.d.ts","./node_modules/typescript/lib/lib.es2023.collection.d.ts","./node_modules/typescript/lib/lib.es2023.intl.d.ts","./node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2024.collection.d.ts","./node_modules/typescript/lib/lib.es2024.object.d.ts","./node_modules/typescript/lib/lib.es2024.promise.d.ts","./node_modules/typescript/lib/lib.es2024.regexp.d.ts","./node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2024.string.d.ts","./node_modules/typescript/lib/lib.esnext.array.d.ts","./node_modules/typescript/lib/lib.esnext.collection.d.ts","./node_modules/typescript/lib/lib.esnext.intl.d.ts","./node_modules/typescript/lib/lib.esnext.disposable.d.ts","./node_modules/typescript/lib/lib.esnext.promise.d.ts","./node_modules/typescript/lib/lib.esnext.decorators.d.ts","./node_modules/typescript/lib/lib.esnext.iterator.d.ts","./node_modules/typescript/lib/lib.esnext.float16.d.ts","./node_modules/typescript/lib/lib.esnext.error.d.ts","./node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts","./node_modules/typescript/lib/lib.decorators.d.ts","./node_modules/typescript/lib/lib.decorators.legacy.d.ts","./node_modules/@types/react/global.d.ts","./node_modules/csstype/index.d.ts","./node_modules/@types/react/index.d.ts","./node_modules/next/dist/styled-jsx/types/css.d.ts","./node_modules/next/dist/styled-jsx/types/macro.d.ts","./node_modules/next/dist/styled-jsx/types/style.d.ts","./node_modules/next/dist/styled-jsx/types/global.d.ts","./node_modules/next/dist/styled-jsx/types/index.d.ts","./node_modules/next/dist/server/get-page-files.d.ts","./node_modules/@types/node/compatibility/disposable.d.ts","./node_modules/@types/node/compatibility/indexable.d.ts","./node_modules/@types/node/compatibility/iterators.d.ts","./node_modules/@types/node/compatibility/index.d.ts","./node_modules/@types/node/globals.typedarray.d.ts","./node_modules/@types/node/buffer.buffer.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/web-globals/abortcontroller.d.ts","./node_modules/@types/node/web-globals/domexception.d.ts","./node_modules/@types/node/web-globals/events.d.ts","./node_modules/undici-types/header.d.ts","./node_modules/undici-types/readable.d.ts","./node_modules/undici-types/file.d.ts","./node_modules/undici-types/fetch.d.ts","./node_modules/undici-types/formdata.d.ts","./node_modules/undici-types/connector.d.ts","./node_modules/undici-types/client.d.ts","./node_modules/undici-types/errors.d.ts","./node_modules/undici-types/dispatcher.d.ts","./node_modules/undici-types/global-dispatcher.d.ts","./node_modules/undici-types/global-origin.d.ts","./node_modules/undici-types/pool-stats.d.ts","./node_modules/undici-types/pool.d.ts","./node_modules/undici-types/handlers.d.ts","./node_modules/undici-types/balanced-pool.d.ts","./node_modules/undici-types/agent.d.ts","./node_modules/undici-types/mock-interceptor.d.ts","./node_modules/undici-types/mock-agent.d.ts","./node_modules/undici-types/mock-client.d.ts","./node_modules/undici-types/mock-pool.d.ts","./node_modules/undici-types/mock-errors.d.ts","./node_modules/undici-types/proxy-agent.d.ts","./node_modules/undici-types/env-http-proxy-agent.d.ts","./node_modules/undici-types/retry-handler.d.ts","./node_modules/undici-types/retry-agent.d.ts","./node_modules/undici-types/api.d.ts","./node_modules/undici-types/interceptors.d.ts","./node_modules/undici-types/util.d.ts","./node_modules/undici-types/cookies.d.ts","./node_modules/undici-types/patch.d.ts","./node_modules/undici-types/websocket.d.ts","./node_modules/undici-types/eventsource.d.ts","./node_modules/undici-types/filereader.d.ts","./node_modules/undici-types/diagnostics-channel.d.ts","./node_modules/undici-types/content-type.d.ts","./node_modules/undici-types/cache.d.ts","./node_modules/undici-types/index.d.ts","./node_modules/@types/node/web-globals/fetch.d.ts","./node_modules/@types/node/web-globals/navigator.d.ts","./node_modules/@types/node/web-globals/storage.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/inspector.generated.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/readline/promises.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/sea.d.ts","./node_modules/@types/node/sqlite.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/stream/consumers.d.ts","./node_modules/@types/node/stream/web.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/test.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/index.d.ts","./node_modules/@types/react/canary.d.ts","./node_modules/@types/react/experimental.d.ts","./node_modules/@types/react-dom/index.d.ts","./node_modules/@types/react-dom/canary.d.ts","./node_modules/@types/react-dom/experimental.d.ts","./node_modules/next/dist/lib/fallback.d.ts","./node_modules/next/dist/compiled/webpack/webpack.d.ts","./node_modules/next/dist/shared/lib/modern-browserslist-target.d.ts","./node_modules/next/dist/shared/lib/entry-constants.d.ts","./node_modules/next/dist/shared/lib/constants.d.ts","./node_modules/next/dist/server/config.d.ts","./node_modules/next/dist/lib/load-custom-routes.d.ts","./node_modules/next/dist/shared/lib/image-config.d.ts","./node_modules/next/dist/build/webpack/plugins/subresource-integrity-plugin.d.ts","./node_modules/next/dist/server/body-streams.d.ts","./node_modules/next/dist/server/lib/cache-control.d.ts","./node_modules/next/dist/lib/setup-exception-listeners.d.ts","./node_modules/next/dist/lib/worker.d.ts","./node_modules/next/dist/lib/constants.d.ts","./node_modules/next/dist/lib/bundler.d.ts","./node_modules/next/dist/client/components/app-router-headers.d.ts","./node_modules/next/dist/client/components/router-reducer/router-reducer-types.d.ts","./node_modules/next/dist/client/flight-data-helpers.d.ts","./node_modules/next/dist/client/components/segment-cache/cache-key.d.ts","./node_modules/next/dist/client/components/router-reducer/fetch-server-response.d.ts","./node_modules/next/dist/shared/lib/app-router-types.d.ts","./node_modules/next/dist/build/static-paths/types.d.ts","./node_modules/next/dist/build/rendering-mode.d.ts","./node_modules/next/dist/server/lib/router-utils/build-prefetch-segment-data-route.d.ts","./node_modules/next/dist/server/require-hook.d.ts","./node_modules/next/dist/server/lib/experimental/ppr.d.ts","./node_modules/next/dist/lib/page-types.d.ts","./node_modules/next/dist/build/segment-config/app/app-segment-config.d.ts","./node_modules/next/dist/build/segment-config/pages/pages-segment-config.d.ts","./node_modules/next/dist/build/analysis/get-page-static-info.d.ts","./node_modules/next/dist/build/webpack/loaders/get-module-build-info.d.ts","./node_modules/next/dist/build/webpack/plugins/middleware-plugin.d.ts","./node_modules/next/dist/server/node-polyfill-crypto.d.ts","./node_modules/next/dist/server/node-environment-baseline.d.ts","./node_modules/next/dist/server/node-environment-extensions/error-inspect.d.ts","./node_modules/next/dist/server/node-environment-extensions/console-file.d.ts","./node_modules/next/dist/server/node-environment-extensions/console-exit.d.ts","./node_modules/next/dist/server/node-environment-extensions/console-dim.external.d.ts","./node_modules/next/dist/server/node-environment-extensions/unhandled-rejection.d.ts","./node_modules/next/dist/server/node-environment-extensions/random.d.ts","./node_modules/next/dist/server/node-environment-extensions/date.d.ts","./node_modules/next/dist/server/node-environment-extensions/web-crypto.d.ts","./node_modules/next/dist/server/node-environment-extensions/node-crypto.d.ts","./node_modules/next/dist/server/node-environment.d.ts","./node_modules/next/dist/build/page-extensions-type.d.ts","./node_modules/next/dist/server/route-kind.d.ts","./node_modules/next/dist/server/route-definitions/route-definition.d.ts","./node_modules/next/dist/server/route-definitions/app-page-route-definition.d.ts","./node_modules/next/dist/server/lib/cache-handlers/types.d.ts","./node_modules/next/dist/server/response-cache/types.d.ts","./node_modules/next/dist/server/resume-data-cache/cache-store.d.ts","./node_modules/next/dist/server/resume-data-cache/resume-data-cache.d.ts","./node_modules/next/dist/server/render-result.d.ts","./node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.d.ts","./node_modules/next/dist/server/instrumentation/types.d.ts","./node_modules/next/dist/lib/coalesced-function.d.ts","./node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.d.ts","./node_modules/next/dist/server/lib/router-utils/types.d.ts","./node_modules/next/dist/trace/types.d.ts","./node_modules/next/dist/trace/trace.d.ts","./node_modules/next/dist/trace/shared.d.ts","./node_modules/next/dist/trace/index.d.ts","./node_modules/next/dist/build/load-jsconfig.d.ts","./node_modules/@next/env/dist/index.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/use-cache-tracker-utils.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/telemetry-plugin.d.ts","./node_modules/next/dist/telemetry/storage.d.ts","./node_modules/next/dist/build/build-context.d.ts","./node_modules/next/dist/shared/lib/bloom-filter.d.ts","./node_modules/next/dist/build/webpack-config.d.ts","./node_modules/next/dist/build/swc/generated-native.d.ts","./node_modules/next/dist/build/swc/types.d.ts","./node_modules/next/dist/server/dev/parse-version-info.d.ts","./node_modules/next/dist/next-devtools/shared/types.d.ts","./node_modules/next/dist/server/dev/dev-indicator-server-state.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/cache-indicator.d.ts","./node_modules/next/dist/server/lib/parse-stack.d.ts","./node_modules/next/dist/next-devtools/server/shared.d.ts","./node_modules/next/dist/next-devtools/shared/stack-frame.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/utils/get-error-by-type.d.ts","./node_modules/@types/react/jsx-runtime.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/container/runtime-error/render-error.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/shared.d.ts","./node_modules/next/dist/server/dev/debug-channel.d.ts","./node_modules/next/dist/server/dev/hot-reloader-types.d.ts","./node_modules/next/dist/server/lib/i18n-provider.d.ts","./node_modules/next/dist/server/web/next-url.d.ts","./node_modules/next/dist/compiled/@edge-runtime/cookies/index.d.ts","./node_modules/next/dist/server/web/spec-extension/cookies.d.ts","./node_modules/next/dist/server/web/spec-extension/request.d.ts","./node_modules/next/dist/server/after/builtin-request-context.d.ts","./node_modules/next/dist/server/web/spec-extension/fetch-event.d.ts","./node_modules/next/dist/server/web/spec-extension/response.d.ts","./node_modules/next/dist/build/segment-config/middleware/middleware-config.d.ts","./node_modules/next/dist/server/web/types.d.ts","./node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-url.d.ts","./node_modules/next/dist/server/base-http/node.d.ts","./node_modules/next/dist/build/webpack/plugins/next-font-manifest-plugin.d.ts","./node_modules/next/dist/server/route-definitions/locale-route-definition.d.ts","./node_modules/next/dist/server/route-definitions/pages-route-definition.d.ts","./node_modules/next/dist/shared/lib/mitt.d.ts","./node_modules/next/dist/client/with-router.d.ts","./node_modules/next/dist/client/router.d.ts","./node_modules/next/dist/client/route-loader.d.ts","./node_modules/next/dist/client/page-loader.d.ts","./node_modules/next/dist/shared/lib/router/router.d.ts","./node_modules/next/dist/shared/lib/router-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/image-config-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/app-router-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/pages/module.compiled.d.ts","./node_modules/next/dist/build/templates/pages.d.ts","./node_modules/next/dist/server/route-modules/pages/module.d.ts","./node_modules/next/dist/shared/lib/deep-readonly.d.ts","./node_modules/next/dist/next-devtools/userspace/pages/pages-dev-overlay-setup.d.ts","./node_modules/next/dist/server/render.d.ts","./node_modules/next/dist/server/response-cache/index.d.ts","./node_modules/next/dist/server/route-definitions/pages-api-route-definition.d.ts","./node_modules/next/dist/server/route-matches/pages-api-route-match.d.ts","./node_modules/next/dist/server/route-matchers/route-matcher.d.ts","./node_modules/next/dist/server/route-matcher-providers/route-matcher-provider.d.ts","./node_modules/next/dist/server/route-matcher-managers/route-matcher-manager.d.ts","./node_modules/next/dist/server/normalizers/normalizer.d.ts","./node_modules/next/dist/server/normalizers/locale-route-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/pathname-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/suffix.d.ts","./node_modules/next/dist/server/normalizers/request/rsc.d.ts","./node_modules/next/dist/server/normalizers/request/prefetch-rsc.d.ts","./node_modules/next/dist/server/normalizers/request/next-data.d.ts","./node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.d.ts","./node_modules/next/dist/server/base-server.d.ts","./node_modules/next/dist/server/lib/async-callback-set.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-regex.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-matcher.d.ts","./node_modules/sharp/lib/index.d.ts","./node_modules/next/dist/server/image-optimizer.d.ts","./node_modules/next/dist/server/next-server.d.ts","./node_modules/next/dist/server/lib/types.d.ts","./node_modules/next/dist/server/lib/lru-cache.d.ts","./node_modules/next/dist/server/lib/dev-bundler-service.d.ts","./node_modules/next/dist/server/use-cache/cache-life.d.ts","./node_modules/next/dist/server/dev/static-paths-worker.d.ts","./node_modules/next/dist/server/dev/next-dev-server.d.ts","./node_modules/next/dist/server/next.d.ts","./node_modules/next/dist/server/lib/render-server.d.ts","./node_modules/next/dist/server/lib/router-server.d.ts","./node_modules/next/dist/shared/lib/router/utils/path-match.d.ts","./node_modules/next/dist/server/lib/router-utils/filesystem.d.ts","./node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.d.ts","./node_modules/next/dist/server/lib/router-utils/router-server-context.d.ts","./node_modules/next/dist/server/route-modules/route-module.d.ts","./node_modules/next/dist/server/load-components.d.ts","./node_modules/next/dist/server/web/adapter.d.ts","./node_modules/next/dist/server/app-render/types.d.ts","./node_modules/next/dist/build/webpack/loaders/metadata/types.d.ts","./node_modules/next/dist/build/webpack/loaders/next-app-loader/index.d.ts","./node_modules/next/dist/server/lib/app-dir-module.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.d.ts","./node_modules/next/dist/server/async-storage/draft-mode-provider.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/headers.d.ts","./node_modules/next/dist/server/app-render/cache-signal.d.ts","./node_modules/next/dist/server/app-render/dynamic-rendering.d.ts","./node_modules/next/dist/server/request/fallback-params.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage-instance.d.ts","./node_modules/next/dist/server/lib/lazy-result.d.ts","./node_modules/next/dist/server/lib/implicit-tags.d.ts","./node_modules/next/dist/server/app-render/staged-rendering.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage.external.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-relative-url.d.ts","./node_modules/next/dist/server/app-render/app-render.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/client/components/error-boundary.d.ts","./node_modules/next/dist/client/components/layout-router.d.ts","./node_modules/next/dist/client/components/render-from-template-context.d.ts","./node_modules/next/dist/server/app-render/action-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/action-async-storage.external.d.ts","./node_modules/next/dist/client/components/client-page.d.ts","./node_modules/next/dist/client/components/client-segment.d.ts","./node_modules/next/dist/server/request/search-params.d.ts","./node_modules/next/dist/client/components/hooks-server-context.d.ts","./node_modules/next/dist/client/components/http-access-fallback/error-boundary.d.ts","./node_modules/next/dist/lib/metadata/types/alternative-urls-types.d.ts","./node_modules/next/dist/lib/metadata/types/extra-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-types.d.ts","./node_modules/next/dist/lib/metadata/types/manifest-types.d.ts","./node_modules/next/dist/lib/metadata/types/opengraph-types.d.ts","./node_modules/next/dist/lib/metadata/types/twitter-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-interface.d.ts","./node_modules/next/dist/lib/metadata/types/resolvers.d.ts","./node_modules/next/dist/lib/metadata/types/icons.d.ts","./node_modules/next/dist/lib/metadata/resolve-metadata.d.ts","./node_modules/next/dist/lib/metadata/metadata.d.ts","./node_modules/next/dist/lib/framework/boundary-components.d.ts","./node_modules/next/dist/server/app-render/rsc/preloads.d.ts","./node_modules/next/dist/server/app-render/rsc/postpone.d.ts","./node_modules/next/dist/server/app-render/rsc/taint.d.ts","./node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.d.ts","./node_modules/next/dist/server/app-render/collect-segment-data.d.ts","./node_modules/next/dist/next-devtools/userspace/app/segment-explorer-node.d.ts","./node_modules/next/dist/server/app-render/entry-base.d.ts","./node_modules/next/dist/build/templates/app-page.d.ts","./node_modules/@types/react/jsx-dev-runtime.d.ts","./node_modules/@types/react/compiler-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.d.ts","./node_modules/@types/react-dom/client.d.ts","./node_modules/@types/react-dom/static.d.ts","./node_modules/@types/react-dom/server.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.compiled.d.ts","./node_modules/next/dist/server/route-definitions/app-route-route-definition.d.ts","./node_modules/next/dist/server/async-storage/work-store.d.ts","./node_modules/next/dist/server/web/http.d.ts","./node_modules/next/dist/server/route-modules/app-route/shared-modules.d.ts","./node_modules/next/dist/client/components/redirect-status-code.d.ts","./node_modules/next/dist/client/components/redirect-error.d.ts","./node_modules/next/dist/build/templates/app-route.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.compiled.d.ts","./node_modules/next/dist/build/segment-config/app/app-segments.d.ts","./node_modules/next/dist/build/utils.d.ts","./node_modules/next/dist/build/turborepo-access-trace/types.d.ts","./node_modules/next/dist/build/turborepo-access-trace/result.d.ts","./node_modules/next/dist/build/turborepo-access-trace/helpers.d.ts","./node_modules/next/dist/build/turborepo-access-trace/index.d.ts","./node_modules/next/dist/export/routes/types.d.ts","./node_modules/next/dist/export/types.d.ts","./node_modules/next/dist/export/worker.d.ts","./node_modules/next/dist/build/worker.d.ts","./node_modules/next/dist/build/index.d.ts","./node_modules/next/dist/server/lib/incremental-cache/index.d.ts","./node_modules/next/dist/server/after/after.d.ts","./node_modules/next/dist/server/after/after-context.d.ts","./node_modules/next/dist/server/app-render/work-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/work-async-storage.external.d.ts","./node_modules/next/dist/server/request/params.d.ts","./node_modules/next/dist/server/route-matches/route-match.d.ts","./node_modules/next/dist/server/request-meta.d.ts","./node_modules/next/dist/cli/next-test.d.ts","./node_modules/next/dist/server/config-shared.d.ts","./node_modules/next/dist/server/base-http/index.d.ts","./node_modules/next/dist/server/api-utils/index.d.ts","./node_modules/next/dist/build/adapter/build-complete.d.ts","./node_modules/next/dist/types.d.ts","./node_modules/next/dist/shared/lib/html-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/utils.d.ts","./node_modules/next/dist/pages/_app.d.ts","./node_modules/next/app.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-cache.d.ts","./node_modules/next/dist/server/web/spec-extension/revalidate.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-no-store.d.ts","./node_modules/next/dist/server/use-cache/cache-tag.d.ts","./node_modules/next/cache.d.ts","./node_modules/next/dist/pages/_document.d.ts","./node_modules/next/document.d.ts","./node_modules/next/dist/shared/lib/dynamic.d.ts","./node_modules/next/dynamic.d.ts","./node_modules/next/dist/pages/_error.d.ts","./node_modules/next/error.d.ts","./node_modules/next/dist/shared/lib/head.d.ts","./node_modules/next/head.d.ts","./node_modules/next/dist/server/request/cookies.d.ts","./node_modules/next/dist/server/request/headers.d.ts","./node_modules/next/dist/server/request/draft-mode.d.ts","./node_modules/next/headers.d.ts","./node_modules/next/dist/shared/lib/get-img-props.d.ts","./node_modules/next/dist/client/image-component.d.ts","./node_modules/next/dist/shared/lib/image-external.d.ts","./node_modules/next/image.d.ts","./node_modules/next/dist/client/link.d.ts","./node_modules/next/link.d.ts","./node_modules/next/dist/client/components/readonly-url-search-params.d.ts","./node_modules/next/dist/client/components/unrecognized-action-error.d.ts","./node_modules/next/dist/client/components/redirect.d.ts","./node_modules/next/dist/client/components/not-found.d.ts","./node_modules/next/dist/client/components/forbidden.d.ts","./node_modules/next/dist/client/components/unauthorized.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.server.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.d.ts","./node_modules/next/dist/client/components/navigation.react-server.d.ts","./node_modules/next/dist/client/components/navigation.d.ts","./node_modules/next/navigation.d.ts","./node_modules/next/router.d.ts","./node_modules/next/dist/client/script.d.ts","./node_modules/next/script.d.ts","./node_modules/next/dist/server/web/spec-extension/user-agent.d.ts","./node_modules/next/dist/compiled/@edge-runtime/primitives/url.d.ts","./node_modules/next/dist/server/web/spec-extension/image-response.d.ts","./node_modules/next/dist/compiled/@vercel/og/satori/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/emoji/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/types.d.ts","./node_modules/next/dist/server/after/index.d.ts","./node_modules/next/dist/server/request/connection.d.ts","./node_modules/next/server.d.ts","./node_modules/next/types/global.d.ts","./node_modules/next/types/compiled.d.ts","./node_modules/next/types.d.ts","./node_modules/next/index.d.ts","./node_modules/next/image-types/global.d.ts","./.next/types/routes.d.ts","./next-env.d.ts","./lib/demoMode.ts","./lib/lmStudio.ts","./lib/toolDisplay.ts","./lib/useWebSocket.ts","./node_modules/clsx/clsx.d.mts","./node_modules/tailwind-merge/dist/types.d.ts","./lib/utils.ts","./node_modules/@locator/shared/dist/types.d.ts","./node_modules/@locator/shared/dist/sharedOptionsStore.d.ts","./node_modules/@locator/shared/dist/index.d.ts","./node_modules/@treelocator/runtime/dist/consts.d.ts","./node_modules/@treelocator/runtime/dist/adapters/jsx/runtimeStore.d.ts","./node_modules/@treelocator/runtime/dist/index.d.ts","./app/LocatorProvider.tsx","./node_modules/next/dist/compiled/@next/font/dist/types.d.ts","./node_modules/next/dist/compiled/@next/font/dist/google/index.d.ts","./node_modules/next/font/google/index.d.ts","./node_modules/@vercel/analytics/dist/next/index.d.mts","./app/layout.tsx","./app/page.tsx","./.next/types/validator.ts","./node_modules/@types/d3-array/index.d.ts","./node_modules/@types/d3-color/index.d.ts","./node_modules/@types/d3-ease/index.d.ts","./node_modules/@types/d3-interpolate/index.d.ts","./node_modules/@types/d3-path/index.d.ts","./node_modules/@types/d3-time/index.d.ts","./node_modules/@types/d3-scale/index.d.ts","./node_modules/@types/d3-shape/index.d.ts","./node_modules/@types/d3-timer/index.d.ts","./node_modules/@types/estree/index.d.ts","./node_modules/@types/json-schema/index.d.ts","./node_modules/@types/eslint/use-at-your-own-risk.d.ts","./node_modules/@types/eslint/index.d.ts","./node_modules/@types/eslint-scope/index.d.ts"],"fileIdsList":[[97,145,162,163],[97,145,162,163,281,503,506,526,527],[85,97,145,162,163,281,520],[85,97,145,162,163,281,504,521,524,525],[85,97,145,162,163,281,508,509,510,511],[97,145,162,163,281],[85,97,145,162,163,281],[97,145,162,163,281,512,513],[97,145,162,163,504,505,506],[97,145,162,163,515,516],[97,145,162,163,517,518,519],[97,145,162,163,530],[97,145,162,163,534],[97,145,162,163,533],[97,145,162,163,538,541],[97,145,162,163,538,539,540],[97,145,162,163,541],[97,142,143,145,162,163],[97,144,145,162,163],[145,162,163],[97,145,150,162,163,180],[97,145,146,151,156,162,163,165,177,188],[97,145,146,147,156,162,163,165],[92,93,94,97,145,162,163],[97,145,148,162,163,189],[97,145,149,150,157,162,163,166],[97,145,150,162,163,177,185],[97,145,151,153,156,162,163,165],[97,144,145,152,162,163],[97,145,153,154,162,163],[97,145,155,156,162,163],[97,144,145,156,162,163],[97,145,156,157,158,162,163,177,188],[97,145,156,157,158,162,163,172,177,180],[97,138,145,153,156,159,162,163,165,177,188],[97,145,156,157,159,160,162,163,165,177,185,188],[97,145,159,161,162,163,177,185,188],[95,96,97,98,99,100,101,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194],[97,145,156,162,163],[97,145,162,163,164,188],[97,145,153,156,162,163,165,177],[97,145,162,163,166],[97,145,162,163,167],[97,144,145,162,163,168],[97,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194],[97,145,162,163,170],[97,145,162,163,171],[97,145,156,162,163,172,173],[97,145,162,163,172,174,189,191],[97,145,157,162,163],[97,145,156,162,163,177,178,180],[97,145,162,163,179,180],[97,145,162,163,177,178],[97,145,162,163,180],[97,145,162,163,181],[97,142,145,162,163,177,182],[97,145,156,162,163,183,184],[97,145,162,163,183,184],[97,145,150,162,163,165,177,185],[97,145,162,163,186],[97,145,162,163,165,187],[97,145,159,162,163,171,188],[97,145,150,162,163,189],[97,145,162,163,177,190],[97,145,162,163,164,191],[97,145,162,163,192],[97,138,145,162,163],[97,138,145,156,158,162,163,168,177,180,188,190,191,193],[97,145,162,163,177,194],[85,89,97,145,162,163,196,197,198,200,450,497],[85,97,145,162,163],[85,89,97,145,162,163,196,197,198,199,411,450,497],[85,89,97,145,162,163,196,197,199,200,450,497],[85,97,145,162,163,200,411,412],[85,97,145,162,163,200,411],[85,89,97,145,162,163,197,198,199,200,450,497],[85,89,97,145,162,163,196,198,199,200,450,497],[83,84,97,145,162,163],[97,145,162,163,453],[97,145,162,163,455,456,457,458],[97,145,162,163,205,207,211,223,232,436,446],[97,145,162,163,207,227,228,229,231,446],[97,145,162,163,207,262,264,266,267,270,446,448],[97,145,162,163,207,211,213,214,215,216,222,223,224,435,446,448],[97,145,162,163,446],[97,145,162,163,221,222,228,416,425,442],[97,145,162,163,207],[97,145,162,163,201,221,442],[97,145,162,163,272],[97,145,162,163,271,446],[97,145,159,162,163,406,416,502],[97,145,159,162,163,374,386,425,441],[97,145,159,162,163,317],[97,145,162,163,429],[97,145,162,163,428,429,430],[97,145,162,163,428],[91,97,145,159,162,163,201,207,211,214,222,225,226,228,232,244,245,272,347,426,436,446,450],[97,145,162,163,205,207,230,262,263,268,269,446,502],[97,145,162,163,230,502],[97,145,162,163,205,245,361,446,502],[97,145,162,163,502],[97,145,162,163,207,230,231,502],[97,145,162,163,265,502],[97,145,162,163,225,427,434],[97,145,162,163,171,281,442],[97,145,162,163,281,442],[85,97,145,162,163,378],[97,145,162,163,314,315,442,478,479,486],[97,145,162,163,422,478,480,481,482,483,485],[97,145,162,163,421],[97,145,162,163,421,422],[97,145,162,163,216,217,218,219,221],[97,145,162,163,220,221],[97,145,162,163,484],[97,145,162,163,221],[85,97,145,162,163,208,472],[85,97,145,162,163,188],[85,97,145,162,163,230,305],[85,97,145,162,163,230],[97,145,162,163,303,307],[85,97,145,162,163,304,452],[97,145,162,163,522],[85,89,97,145,159,162,163,195,196,197,198,199,200,450,495,496],[97,145,159,162,163],[97,145,159,162,163,211,252,322,337,358,360,431,432,446,447],[97,145,162,163,244,433],[97,145,162,163,450],[97,145,162,163,206],[85,97,145,162,163,363,376,385,395,397,441],[97,145,162,163,171,363,376,394,395,396,441,501],[97,145,162,163,388,389,390,391,392,393],[97,145,162,163,390],[97,145,162,163,394],[97,145,162,163,279,280,281,283],[85,97,145,162,163,273,274,275,276,282],[97,145,162,163,279,282],[97,145,162,163,277],[97,145,162,163,278],[85,97,145,162,163,281,304,452],[85,97,145,162,163,281,451,452],[85,97,145,162,163,281,452],[97,145,162,163,337,438],[97,145,162,163,438],[97,145,159,162,163,447,452],[97,145,162,163,382],[97,144,145,162,163,381],[97,145,162,163,221,253,254,320,323,360,369,372,374,375,415,441,444,447],[97,145,162,163,221,254,403],[97,145,162,163,374,441],[85,97,145,162,163,374,379,380,382,383,384,385,386,387,398,399,400,401,402,404,405,441,442,502],[97,145,162,163,368],[97,145,159,162,163,171,208,252,254,255,276,299,320,337,347,358,359,415,437,446,447,448,450,502],[97,145,162,163,441],[97,144,145,162,163,228,320,347,371,437,439,440,447],[97,145,162,163,374],[97,144,145,162,163,252,289,323,364,365,366,367,368,369,370,372,373,441,442],[97,145,159,162,163,289,290,364,447,448],[97,145,162,163,228,337,347,360,437,441,447],[97,145,159,162,163,446,448],[97,145,159,162,163,177,444,447,448],[97,145,159,162,163,171,188,201,211,222,230,253,254,255,257,286,291,296,299,320,322,323,325,328,330,333,334,335,336,358,360,436,437,442,444,446,447,448],[97,145,159,162,163,177],[97,145,162,163,207,208,209,226,444,445,450,452,502],[97,145,162,163,205,446],[97,145,162,163,285],[97,145,159,162,163,177,188,247,270,272,273,274,275,276,283,284,502],[97,145,162,163,171,188,201,222,247,262,295,296,297,298,323,328,337,343,346,348,358,360,437,442,444],[97,145,162,163,222,225,226,244,347,437,446],[97,145,159,162,163,188,208,211,323,341,444,446],[97,145,162,163,362],[97,145,159,162,163,276,284,285,344,345,355],[97,145,162,163,444,446],[97,145,162,163,369,371],[97,145,162,163,320,323,436,452],[97,145,159,162,163,171,258,262,298,328,343,346,350,444],[97,145,159,162,163,225,244,262,351],[97,145,162,163,207,257,353,436,446],[97,145,159,162,163,188,276,446],[97,145,159,162,163,230,256,257,258,267,285,352,354,436,446],[91,97,145,162,163,254,320,357,450,452],[97,145,159,162,163,171,188,211,225,232,244,253,255,291,295,296,297,298,299,323,325,337,338,340,342,358,360,436,437,442,443,444,452],[97,145,159,162,163,177,225,343,349,355,444],[97,145,162,163,235,236,237,238,239,240,241,242,243],[97,145,162,163,286,329],[97,145,162,163,331],[97,145,162,163,329],[97,145,162,163,331,332],[97,145,159,162,163,211,214,216,252,447],[97,145,159,162,163,171,206,208,253,254,299,319,320,321,358,444,448,450,452],[97,145,159,162,163,171,188,210,216,321,323,369,437,443,447],[97,145,162,163,364],[97,145,162,163,365],[97,145,162,163,221,222,415],[97,145,162,163,366],[97,145,162,163,246,250],[97,145,159,162,163,211,246,253],[97,145,162,163,249,250],[97,145,162,163,251],[97,145,162,163,246,247],[97,145,162,163,246,300],[97,145,162,163,246],[97,145,162,163,286,327,443],[97,145,162,163,326],[97,145,162,163,247,442,443],[97,145,162,163,324,443],[97,145,162,163,247,442],[97,145,162,163,415],[97,145,162,163,211,221,223,248,253,320,323,357,360,363,369,376,377,407,410,414,436,444,447],[97,145,162,163,308,311,312,313,314,315],[85,97,145,162,163,198,200,281,408,409],[85,97,145,162,163,198,200,281,408,409,413],[97,145,162,163,424],[97,145,162,163,228,290,320,357,360,374,382,386,417,418,419,420,422,423,426,436,441,446],[97,145,162,163,314],[97,145,162,163,319],[97,145,159,162,163,253,301,316,318,322,357,444,450,452],[97,145,162,163,308,309,310,311,312,313,314,315,451],[91,97,145,159,162,163,171,188,246,247,255,299,320,323,355,356,358,436,437,446,447,450],[97,145,162,163,290,292,295,437],[97,145,159,162,163,286,446],[97,145,162,163,289,374],[97,145,162,163,288],[97,145,162,163,290,291],[97,145,162,163,287,289,446],[97,145,159,162,163,210,290,292,293,294,446,447],[85,97,145,162,163,217,221,442],[85,97,145,162,163,220],[97,145,162,163,203,204],[85,97,145,162,163,208],[85,97,145,162,163,442],[85,91,97,145,162,163,299,320,450,452],[97,145,162,163,208,472,473],[85,97,145,162,163,307],[85,97,145,162,163,171,188,206,269,302,304,306,452],[97,145,162,163,230,442,447],[97,145,162,163,339,442],[85,97,145,157,159,162,163,171,205,206,264,307,450,451],[85,97,145,162,163,196,197,198,199,200,450,497],[85,86,87,88,89,97,145,162,163],[97,145,150,162,163],[97,145,162,163,259,260,261],[97,145,162,163,259],[85,89,97,145,159,161,162,163,171,195,196,197,198,199,200,201,206,255,350,394,448,449,452,497],[97,145,162,163,460],[97,145,162,163,462],[97,145,162,163,464],[97,145,162,163,523],[97,145,162,163,466],[97,145,162,163,468,469,470],[97,145,162,163,474],[90,97,145,162,163,454,459,461,463,465,467,471,475,477,488,489,491,500,501,502,503],[97,145,162,163,476],[97,145,162,163,487],[97,145,162,163,304],[97,145,162,163,490],[97,144,145,162,163,290,292,293,295,492,493,494,497,498,499],[97,145,162,163,195],[97,145,162,163,177,195],[97,110,114,145,162,163,188],[97,110,145,162,163,177,188],[97,105,145,162,163],[97,107,110,145,162,163,185,188],[97,145,162,163,165,185],[97,105,145,162,163,195],[97,107,110,145,162,163,165,188],[97,102,103,106,109,145,156,162,163,177,188],[97,110,117,145,162,163],[97,102,108,145,162,163],[97,110,131,132,145,162,163],[97,106,110,145,162,163,180,188,195],[97,131,145,162,163,195],[97,104,105,145,162,163,195],[97,110,145,162,163],[97,104,105,106,107,108,109,110,111,112,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,132,133,134,135,136,137,145,162,163],[97,110,125,145,162,163],[97,110,117,118,145,162,163],[97,108,110,118,119,145,162,163],[97,109,145,162,163],[97,102,105,110,145,162,163],[97,110,114,118,119,145,162,163],[97,114,145,162,163],[97,108,110,113,145,162,163,188],[97,102,107,110,117,145,162,163],[97,145,162,163,177],[97,105,110,131,145,162,163,193,195]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"2ab096661c711e4a81cc464fa1e6feb929a54f5340b46b0a07ac6bbf857471f0","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"60037901da1a425516449b9a20073aa03386cce92f7a1fd902d7602be3a7c2e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22adec94ef7047a6c9d1af3cb96be87a335908bf9ef386ae9fd50eeb37f44c47","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"73f78680d4c08509933daf80947902f6ff41b6230f94dd002ae372620adb0f60","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5239f5c01bcfa9cd32f37c496cf19c61d69d37e48be9de612b541aac915805b","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"7e29f41b158de217f94cb9676bf9cbd0cd9b5a46e1985141ed36e075c52bf6ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"f123246a7b6c04d80b9b57fadfc6c90959ec6d5c0d4c8e620e06e2811ae3a052","impliedFormat":1},{"version":"acd8fd5090ac73902278889c38336ff3f48af6ba03aa665eb34a75e7ba1dccc4","impliedFormat":1},{"version":"d6258883868fb2680d2ca96bc8b1352cab69874581493e6d52680c5ffecdb6cc","impliedFormat":1},{"version":"1b61d259de5350f8b1e5db06290d31eaebebc6baafd5f79d314b5af9256d7153","impliedFormat":1},{"version":"f258e3960f324a956fc76a3d3d9e964fff2244ff5859dcc6ce5951e5413ca826","impliedFormat":1},{"version":"643f7232d07bf75e15bd8f658f664d6183a0efaca5eb84b48201c7671a266979","impliedFormat":1},{"version":"21da358700a3893281ce0c517a7a30cbd46be020d9f0c3f2834d0a8ad1f5fc75","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"bb45cd435da536500f1d9692a9b49d0c570b763ccbf00473248b777f5c1f353b","impliedFormat":1},{"version":"6b4e081d55ac24fc8a4631d5dd77fe249fa25900abd7d046abb87d90e3b45645","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"83e63d6ccf8ec004a3bb6d58b9bb0104f60e002754b1e968024b320730cc5311","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"d2bc7425ef40526650d6db7e072c1ff4a51101c3ac2cc4b666623b19496a6e27","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"f27524f4bef4b6519c604bdb23bf4465bddcccbf3f003abb901acbd0d7404d99","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"6b039f55681caaf111d5eb84d292b9bee9e0131d0db1ad0871eef0964f533c73","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c959a391a75be9789b43c8468f71e3fa06488b4d691d5729dde1416dcd38225b","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"0dba70b3fb0dcd713fda33c2df64fa6751fff6460e536971cee917260fb17882","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"9f663c2f91127ef7024e8ca4b3b4383ff2770e5f826696005de382282794b127","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"2beff543f6e9a9701df88daeee3cdd70a34b4a1c11cb4c734472195a5cb2af54","impliedFormat":1},{"version":"bfffea552cca245df227337223c7554b35df629ba1d4e09edee4521ce7f24827","impliedFormat":1},{"version":"be1cc4d94ea60cbe567bc29ed479d42587bf1e6cba490f123d329976b0fe4ee5","impliedFormat":1},{"version":"42bc0e1a903408137c3df2b06dfd7e402cdab5bbfa5fcfb871b22ebfdb30bd0b","impliedFormat":1},{"version":"9894dafe342b976d251aac58e616ac6df8db91fb9d98934ff9dd103e9e82578f","impliedFormat":1},{"version":"413df52d4ea14472c2fa5bee62f7a40abd1eb49be0b9722ee01ee4e52e63beb2","impliedFormat":1},{"version":"db6d2d9daad8a6d83f281af12ce4355a20b9a3e71b82b9f57cddcca0a8964a96","impliedFormat":1},{"version":"446a50749b24d14deac6f8843e057a6355dd6437d1fac4f9e5ce4a5071f34bff","impliedFormat":1},{"version":"182e9fcbe08ac7c012e0a6e2b5798b4352470be29a64fdc114d23c2bab7d5106","impliedFormat":1},{"version":"14109b34dc927e3b872c0f954a8d2536c245e38062bc47e8f97ba27f922fc9bd","impliedFormat":1},{"version":"1214c8bb321e2376f9dfc174a97b06c6e7bef05a61a1c50f094617d99fc4c9dd","impliedFormat":1},{"version":"96ffa70b486207241c0fcedb5d9553684f7fa6746bc2b04c519e7ebf41a51205","impliedFormat":1},{"version":"5c24c66b3ba29ce9f2a79c719967e6e944131352a117a0bc43fa5b346b5562b3","impliedFormat":1},{"version":"a86f82d646a739041d6702101afa82dcb935c416dd93cbca7fd754fd0282ce1f","impliedFormat":1},{"version":"ad0d1d75d129b1c80f911be438d6b61bfa8703930a8ff2be2f0e1f8a91841c64","impliedFormat":1},{"version":"ce75b1aebb33d510ff28af960a9221410a3eaf7f18fc5f21f9404075fba77256","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"496bbf339f3838c41f164238543e9fe5f1f10659cb30b68903851618464b98ba","impliedFormat":1},{"version":"099f915371bf0f8fd812d48a088531397f9edaf2ebfefe422cbe774c274a1621","impliedFormat":1},{"version":"78a2869ad0cbf3f9045dda08c0d4562b7e1b2bfe07b19e0db072f5c3c56e9584","impliedFormat":1},{"version":"f0a1bd6ad77f98dd7ed0d3207fcbcb5dd109ba144799cf41b8ea4dacb4e3e009","impliedFormat":1},{"version":"197efda3bbcdd3f1bc5379cd0534f1ab740f3be957efb17b320da8e7dcb2743b","impliedFormat":1},{"version":"0c05e9842ec4f8b7bfebfd3ca61604bb8c914ba8da9b5337c4f25da427a005f2","impliedFormat":1},{"version":"faed7a5153215dbd6ebe76dfdcc0af0cfe760f7362bed43284be544308b114cf","impliedFormat":1},{"version":"612f05ebdd6c4c3bab261d327082ad0c876332263b23cb29ea37ef5921086a2e","impliedFormat":1},{"version":"42277254e219cd5b047373e39d48248cd228d84b200b08e4d4d0949d6a48ef86","impliedFormat":1},{"version":"b06d68a692d3c1dd12bed02eaa3b4c06cfc2a3e9560b0cecd2014bba480c4e8e","impliedFormat":1},{"version":"9e2739b32f741859263fdba0244c194ca8e96da49b430377930b8f721d77c000","impliedFormat":1},{"version":"fb1d8e814a3eeb5101ca13515e0548e112bd1ff3fb358ece535b93e94adf5a3a","impliedFormat":1},{"version":"ffa495b17a5ef1d0399586b590bd281056cee6ce3583e34f39926f8dcc6ecdb5","impliedFormat":1},{"version":"f8d5ff8eafd37499f2b6a98659dd9b45a321de186b8db6b6142faed0fea3de77","impliedFormat":1},{"version":"c86fe861cf1b4c46a0fb7d74dffe596cf679a2e5e8b1456881313170f092e3fa","impliedFormat":1},{"version":"c685d9f68c70fe11ce527287526585a06ea13920bb6c18482ca84945a4e433a7","impliedFormat":1},{"version":"540cc83ab772a2c6bc509fe1354f314825b5dba3669efdfbe4693ecd3048e34f","impliedFormat":1},{"version":"121b0696021ab885c570bbeb331be8ad82c6efe2f3b93a6e63874901bebc13e3","impliedFormat":1},{"version":"4e01846df98d478a2a626ec3641524964b38acaac13945c2db198bf9f3df22ee","impliedFormat":1},{"version":"678d6d4c43e5728bf66e92fc2269da9fa709cb60510fed988a27161473c3853f","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"aa14cee20aa0db79f8df101fc027d929aec10feb5b8a8da3b9af3895d05b7ba2","impliedFormat":1},{"version":"493c700ac3bd317177b2eb913805c87fe60d4e8af4fb39c41f04ba81fae7e170","impliedFormat":1},{"version":"aeb554d876c6b8c818da2e118d8b11e1e559adbe6bf606cc9a611c1b6c09f670","impliedFormat":1},{"version":"acf5a2ac47b59ca07afa9abbd2b31d001bf7448b041927befae2ea5b1951d9f9","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"d71291eff1e19d8762a908ba947e891af44749f3a2cbc5bd2ec4b72f72ea795f","impliedFormat":1},{"version":"c0480e03db4b816dff2682b347c95f2177699525c54e7e6f6aa8ded890b76be7","impliedFormat":1},{"version":"892258709c8fc69cc1711d3554503f35101381df7e33eec344356bdc443ba07b","impliedFormat":1},{"version":"b620391fe8060cf9bedc176a4d01366e6574d7a71e0ac0ab344a4e76576fcbb8","impliedFormat":1},{"version":"3e7efde639c6a6c3edb9847b3f61e308bf7a69685b92f665048c45132f51c218","impliedFormat":1},{"version":"df45ca1176e6ac211eae7ddf51336dc075c5314bc5c253651bae639defd5eec5","impliedFormat":1},{"version":"106c6025f1d99fd468fd8bf6e5bda724e11e5905a4076c5d29790b6c3745e50c","impliedFormat":1},{"version":"ee8df1cb8d0faaca4013a1b442e99130769ce06f438d18d510fed95890067563","impliedFormat":1},{"version":"bfb7f8475428637bee12bdd31bd9968c1c8a1cc2c3e426c959e2f3a307f8936f","impliedFormat":1},{"version":"6f491d0108927478d3247bbbc489c78c2da7ef552fd5277f1ab6819986fdf0b1","impliedFormat":1},{"version":"0d8f2b8781c721170b87a6b662b3cb038fd1a721165ecca390352c818d425872","impliedFormat":1},{"version":"15a234e5031b19c48a69ccc1607522d6e4b50f57d308ecb7fe863d44cd9f9eb3","impliedFormat":1},{"version":"380647d8f3b7f852cca6d154a376dbf8ac620a2f12b936594504a8a852e71d2f","impliedFormat":1},{"version":"148679c6d0f449210a96e7d2e562d589e56fcde87f843a92808b3ff103f1a774","impliedFormat":1},{"version":"6459054aabb306821a043e02b89d54da508e3a6966601a41e71c166e4ea1474f","impliedFormat":1},{"version":"2f9c89cbb29d362290531b48880a4024f258c6033aaeb7e59fbc62db26819650","impliedFormat":1},{"version":"bb37588926aba35c9283fe8d46ebf4e79ffe976343105f5c6d45f282793352b2","impliedFormat":1},{"version":"05c97cddbaf99978f83d96de2d8af86aded9332592f08ce4a284d72d0952c391","impliedFormat":1},{"version":"72179f9dd22a86deaad4cc3490eb0fe69ee084d503b686985965654013f1391b","impliedFormat":1},{"version":"2e6114a7dd6feeef85b2c80120fdbfb59a5529c0dcc5bfa8447b6996c97a69f5","impliedFormat":1},{"version":"7b6ff760c8a240b40dab6e4419b989f06a5b782f4710d2967e67c695ef3e93c4","impliedFormat":1},{"version":"c8f004e6036aa1c764ad4ec543cf89a5c1893a9535c80ef3f2b653e370de45e6","impliedFormat":1},{"version":"dd80b1e600d00f5c6a6ba23f455b84a7db121219e68f89f10552c54ba46e4dc9","impliedFormat":1},{"version":"b064c36f35de7387d71c599bfcf28875849a1dbc733e82bd26cae3d1cd060521","impliedFormat":1},{"version":"05c7280d72f3ed26f346cbe7cbbbb002fb7f15739197cbbee6ab3fd1a6cb9347","impliedFormat":1},{"version":"8de9fe97fa9e00ec00666fa77ab6e91b35d25af8ca75dabcb01e14ad3299b150","impliedFormat":1},{"version":"803cd2aaf1921c218916c2c7ee3fce653e852d767177eb51047ff15b5b253893","impliedFormat":1},{"version":"dba114fb6a32b355a9cfc26ca2276834d72fe0e94cd2c3494005547025015369","impliedFormat":1},{"version":"7ab12b2f1249187223d11a589f5789c75177a0b597b9eb7f8e2e42d045393347","impliedFormat":1},{"version":"b4d871fb9b74fb5f9d4a4d54f5e01254282b2250bb0e8152bbd51aac2e67d9f7","impliedFormat":1},{"version":"93436bd74c66baba229bfefe1314d122c01f0d4c1d9e35081a0c4f0470ac1a6c","impliedFormat":1},{"version":"f974e4a06953682a2c15d5bd5114c0284d5abf8bc0fe4da25cb9159427b70072","impliedFormat":1},{"version":"50256e9c31318487f3752b7ac12ff365c8949953e04568009c8705db802776fb","impliedFormat":1},{"version":"7d73b24e7bf31dfb8a931ca6c4245f6bb0814dfae17e4b60c9e194a631fe5f7b","impliedFormat":1},{"version":"d130c5f73768de51402351d5dc7d1b36eaec980ca697846e53156e4ea9911476","impliedFormat":1},{"version":"413586add0cfe7369b64979d4ec2ed56c3f771c0667fbde1bf1f10063ede0b08","impliedFormat":1},{"version":"06472528e998d152375ad3bd8ebcb69ff4694fd8d2effaf60a9d9f25a37a097a","impliedFormat":1},{"version":"50b5bc34ce6b12eccb76214b51aadfa56572aa6cc79c2b9455cdbb3d6c76af1d","impliedFormat":1},{"version":"b7e16ef7f646a50991119b205794ebfd3a4d8f8e0f314981ebbe991639023d0e","impliedFormat":1},{"version":"42c169fb8c2d42f4f668c624a9a11e719d5d07dacbebb63cbcf7ef365b0a75b3","impliedFormat":1},{"version":"a401617604fa1f6ce437b81689563dfdc377069e4c58465dbd8d16069aede0a5","impliedFormat":1},{"version":"6e9082e91370de5040e415cd9f24e595b490382e8c7402c4e938a8ce4bccc99f","impliedFormat":1},{"version":"8695dec09ad439b0ceef3776ea68a232e381135b516878f0901ed2ea114fd0fe","impliedFormat":1},{"version":"5ab8a9b437a9b2d1d3729def9694ba15525fd4028307e803fafc09aa30a8486a","impliedFormat":1},{"version":"d682336018141807fb602709e2d95a192828fcb8d5ba06dda3833a8ea98f69e3","impliedFormat":1},{"version":"6124e973eab8c52cabf3c07575204efc1784aca6b0a30c79eb85fe240a857efa","impliedFormat":1},{"version":"0d891735a21edc75df51f3eb995e18149e119d1ce22fd40db2b260c5960b914e","impliedFormat":1},{"version":"3b414b99a73171e1c4b7b7714e26b87d6c5cb03d200352da5342ab4088a54c85","impliedFormat":1},{"version":"4fbd3116e00ed3a6410499924b6403cc9367fdca303e34838129b328058ede40","impliedFormat":1},{"version":"b01bd582a6e41457bc56e6f0f9de4cb17f33f5f3843a7cf8210ac9c18472fb0f","impliedFormat":1},{"version":"0a437ae178f999b46b6153d79095b60c42c996bc0458c04955f1c996dc68b971","impliedFormat":1},{"version":"74b2a5e5197bd0f2e0077a1ea7c07455bbea67b87b0869d9786d55104006784f","impliedFormat":1},{"version":"4a7baeb6325920044f66c0f8e5e6f1f52e06e6d87588d837bdf44feb6f35c664","impliedFormat":1},{"version":"12d218a49dbe5655b911e6cc3c13b2c655e4c783471c3b0432137769c79e1b3c","impliedFormat":1},{"version":"7274fbffbd7c9589d8d0ffba68157237afd5cecff1e99881ea3399127e60572f","impliedFormat":1},{"version":"6b0fc04121360f752d196ba35b6567192f422d04a97b2840d7d85f8b79921c92","impliedFormat":1},{"version":"1a82deef4c1d39f6882f28d275cad4c01f907b9b39be9cbc472fcf2cf051e05b","impliedFormat":1},{"version":"c5426dbfc1cf90532f66965a7aa8c1136a78d4d0f96d8180ecbfc11d7722f1a5","impliedFormat":1},{"version":"65a15fc47900787c0bd18b603afb98d33ede930bed1798fc984d5ebb78b26cf9","impliedFormat":1},{"version":"9d202701f6e0744adb6314d03d2eb8fc994798fc83d91b691b75b07626a69801","impliedFormat":1},{"version":"de9d2df7663e64e3a91bf495f315a7577e23ba088f2949d5ce9ec96f44fba37d","impliedFormat":1},{"version":"c7af78a2ea7cb1cd009cfb5bdb48cd0b03dad3b54f6da7aab615c2e9e9d570c5","impliedFormat":1},{"version":"1ee45496b5f8bdee6f7abc233355898e5bf9bd51255db65f5ff7ede617ca0027","impliedFormat":1},{"version":"42189cd810c0bf1247da0742d5744bb7c1486de6fd62269d5c25833b7ec38732","affectsGlobalScope":true,"impliedFormat":1},{"version":"3fbdd025f9d4d820414417eeb4107ffa0078d454a033b506e22d3a23bc3d9c41","affectsGlobalScope":true,"impliedFormat":1},{"version":"a8f8e6ab2fa07b45251f403548b78eaf2022f3c2254df3dc186cb2671fe4996d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa6c12a7c0f6b84d512f200690bfc74819e99efae69e4c95c4cd30f6884c526e","impliedFormat":1},{"version":"f1c32f9ce9c497da4dc215c3bc84b722ea02497d35f9134db3bb40a8d918b92b","impliedFormat":1},{"version":"b73c319af2cc3ef8f6421308a250f328836531ea3761823b4cabbd133047aefa","affectsGlobalScope":true,"impliedFormat":1},{"version":"e433b0337b8106909e7953015e8fa3f2d30797cea27141d1c5b135365bb975a6","impliedFormat":1},{"version":"40436e992021afc07b61da5f488e9671729a3c5b5e6665b99b1fb43a39081ee3","impliedFormat":1},{"version":"ddff7fc6edbdc5163a09e22bf8df7bef75f75369ebd7ecea95ba55c4386e2441","impliedFormat":1},{"version":"3a788c7fb7b1b1153d69a4d1d9e1d0dfbcf1127e703bdb02b6d12698e683d1fb","impliedFormat":1},{"version":"2e4f37ffe8862b14d8e24ae8763daaa8340c0df0b859d9a9733def0eee7562d9","impliedFormat":1},{"version":"d38530db0601215d6d767f280e3a3c54b2a83b709e8d9001acb6f61c67e965fc","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"4805f6161c2c8cefb8d3b8bd96a080c0fe8dbc9315f6ad2e53238f9a79e528a6","impliedFormat":1},{"version":"b83cb14474fa60c5f3ec660146b97d122f0735627f80d82dd03e8caa39b4388c","impliedFormat":1},{"version":"9c82171d836c47486074e4ca8e059735bf97b205e70b196535b5efd40cbe1bc5","impliedFormat":1},{"version":"f374cb24e93e7798c4d9e83ff872fa52d2cdb36306392b840a6ddf46cb925cb6","impliedFormat":1},{"version":"42b81043b00ff27c6bd955aea0f6e741545f2265978bf364b614702b72a027ab","impliedFormat":1},{"version":"162e071992b34bc36ca257d629547f93cb43728d6fe073ad18a237e4f7c52d7d","impliedFormat":1},{"version":"b73cbf0a72c8800cf8f96a9acfe94f3ad32ca71342a8908b8ae484d61113f647","impliedFormat":1},{"version":"bae6dd176832f6423966647382c0d7ba9e63f8c167522f09a982f086cd4e8b23","impliedFormat":1},{"version":"20865ac316b8893c1a0cc383ccfc1801443fbcc2a7255be166cf90d03fac88c9","impliedFormat":1},{"version":"c9958eb32126a3843deedda8c22fb97024aa5d6dd588b90af2d7f2bfac540f23","impliedFormat":1},{"version":"461d0ad8ae5f2ff981778af912ba71b37a8426a33301daa00f21c6ccb27f8156","impliedFormat":1},{"version":"e927c2c13c4eaf0a7f17e6022eee8519eb29ef42c4c13a31e81a611ab8c95577","impliedFormat":1},{"version":"fcafff163ca5e66d3b87126e756e1b6dfa8c526aa9cd2a2b0a9da837d81bbd72","impliedFormat":1},{"version":"70246ad95ad8a22bdfe806cb5d383a26c0c6e58e7207ab9c431f1cb175aca657","impliedFormat":1},{"version":"f00f3aa5d64ff46e600648b55a79dcd1333458f7a10da2ed594d9f0a44b76d0b","impliedFormat":1},{"version":"772d8d5eb158b6c92412c03228bd9902ccb1457d7a705b8129814a5d1a6308fc","impliedFormat":1},{"version":"45490817629431853543adcb91c0673c25af52a456479588b6486daba34f68bb","impliedFormat":1},{"version":"802e797bcab5663b2c9f63f51bdf67eff7c41bc64c0fd65e6da3e7941359e2f7","impliedFormat":1},{"version":"8b4327413e5af38cd8cb97c59f48c3c866015d5d642f28518e3a891c469f240e","impliedFormat":1},{"version":"d76bd0317e0958a220262a40d24f43fd5db2ff6e0ef0b2e14d2acdf7f88a78af","impliedFormat":1},{"version":"4b20fcf10a5413680e39f5666464859fc56b1003e7dfe2405ced82371ebd49b6","impliedFormat":1},{"version":"c06ef3b2569b1c1ad99fcd7fe5fba8d466e2619da5375dfa940a94e0feea899b","impliedFormat":1},{"version":"f7d628893c9fa52ba3ab01bcb5e79191636c4331ee5667ecc6373cbccff8ae12","impliedFormat":1},{"version":"1d879125d1ec570bf04bc1f362fdbe0cb538315c7ac4bcfcdf0c1e9670846aa6","impliedFormat":1},{"version":"8c50ee1fcb97de2860d9ebd76561614ab6d365ac8390ef4a02bb4e76929705d1","impliedFormat":1},{"version":"cff125b5bbb8b819d7835c6b78809416d08da8b00e66611bfe368e0964be7b83","impliedFormat":1},{"version":"d663134457d8d669ae0df34eabd57028bddc04fc444c4bc04bc5215afc91e1f4","impliedFormat":1},{"version":"985153f0deb9b4391110331a2f0c114019dbea90cba5ca68a4107700796e0d75","impliedFormat":1},{"version":"382654d5da3eda8ea18f931d380ab6b099daa4913ae5b64265e6960338572914","impliedFormat":1},{"version":"43e96a3d5d1411ab40ba2f61d6a3192e58177bcf3b133a80ad2a16591611726d","impliedFormat":1},{"version":"58659b06d33fa430bee1105b75cf876c0a35b2567207487c8578aec51ca2d977","impliedFormat":1},{"version":"d8cdd9477b9c5d1a8fbf2fa58e2eb6723969e7201b3549f998e0d2661dfec9d8","impliedFormat":1},{"version":"cfa846a7b7847a1d973605fbb8c91f47f3a0f0643c18ac05c47077ebc72e71c7","impliedFormat":1},{"version":"20e1c8beced348a9bf7864dd2b3ca7efa9ea6675dde8ecae6109b1a3f7248cd2","impliedFormat":1},{"version":"6c800b281b9e89e69165fd11536195488de3ff53004e55905e6c0059a2d8591e","impliedFormat":1},{"version":"7d4254b4c6c67a29d5e7f65e67d72540480ac2cfb041ca484847f5ae70480b62","impliedFormat":1},{"version":"19c3d6db2020cee6f9d8d79e13c15e546e05b6db2020a3ee63789ec74a9990b3","impliedFormat":1},{"version":"41eeb453ccb75c5b2c3abef97adbbd741bd7e9112a2510e12f03f646dc9ad13d","impliedFormat":1},{"version":"0285dbbb2fdb8c5e9b50b92570c4c039b1eea2da4cfb5a04e77c1ca8b1949771","impliedFormat":1},{"version":"301cf1d98bce8b1666184888c7aaacd6c9dfed9185510f4317ed623596e38d2c","impliedFormat":1},{"version":"6c66d5cf284a56109703f941c92b9a22f2472c14645f80a2dbb8e4ef2128d67c","impliedFormat":1},{"version":"a3e7d932dc9c09daa99141a8e4800fc6c58c625af0d4bbb017773dc36da75426","impliedFormat":1},{"version":"0b888a0aa10655cadc0dc3b66cd79a99d79ff376aaacc9b628a3c497646fddab","impliedFormat":1},{"version":"a57b1802794433adec9ff3fed12aa79d671faed86c49b09e02e1ac41b4f1d33a","impliedFormat":1},{"version":"ad10d4f0517599cdeca7755b930f148804e3e0e5b5a3847adce0f1f71bbccd74","impliedFormat":1},{"version":"1042064ece5bb47d6aba91648fbe0635c17c600ebdf567588b4ca715602f0a9d","impliedFormat":1},{"version":"c49469a5349b3cc1965710b5b0f98ed6c028686aa8450bcb3796728873eb923e","impliedFormat":1},{"version":"4a889f2c763edb4d55cb624257272ac10d04a1cad2ed2948b10ed4a7fda2a428","impliedFormat":1},{"version":"7bb79aa2fead87d9d56294ef71e056487e848d7b550c9a367523ee5416c44cfa","impliedFormat":1},{"version":"d88ea80a6447d7391f52352ec97e56b52ebec934a4a4af6e2464cfd8b39c3ba8","impliedFormat":1},{"version":"d3c8b73132efa48e9399d63e8946a57ed4a7176e2f26d2f144bb14c89fcdefc1","impliedFormat":1},{"version":"96171c03c2e7f314d66d38acd581f9667439845865b7f85da8df598ff9617476","impliedFormat":1},{"version":"27ff4196654e6373c9af16b6165120e2dd2169f9ad6abb5c935af5abd8c7938c","impliedFormat":1},{"version":"8c030e515014c10a2b98f9f48408e3ba18023dfd3f56e3312c6c2f3ae1f55a16","impliedFormat":1},{"version":"d193c8a86144b3a87b22bc1f5534b9c3e0f5a187873ec337c289a183973a58fe","impliedFormat":1},{"version":"d2aa1580a899bcec04c29b1c37f2a60f62e2f03acb731534d4e210307c982da8","impliedFormat":1},{"version":"58d70c38037fc0f949243388ff7ae20cf43321107152f14a9d36ca79311e0ada","impliedFormat":1},{"version":"f56bdc6884648806d34bc66d31cdb787c4718d04105ce2cd88535db214631f82","impliedFormat":1},{"version":"68ab1530f0ddf7475425917b0e04068afdc1aee2db033bed9aa9b60a914c512e","impliedFormat":1},{"version":"01479d9d5a5dda16d529b91811375187f61a06e74be294a35ecce77e0b9e8d6c","impliedFormat":1},{"version":"49f95e989b4632c6c2a578cc0078ee19a5831832d79cc59abecf5160ea71abad","impliedFormat":1},{"version":"9666533332f26e8995e4d6fe472bdeec9f15d405693723e6497bf94120c566c8","impliedFormat":1},{"version":"ce0df82a9ae6f914ba08409d4d883983cc08e6d59eb2df02d8e4d68309e7848b","impliedFormat":1},{"version":"796273b2edc72e78a04e86d7c58ae94d370ab93a0ddf40b1aa85a37a1c29ecd7","impliedFormat":1},{"version":"5df15a69187d737d6d8d066e189ae4f97e41f4d53712a46b2710ff9f8563ec9f","impliedFormat":1},{"version":"1a4dc28334a926d90ba6a2d811ba0ff6c22775fcc13679521f034c124269fd40","impliedFormat":1},{"version":"f05315ff85714f0b87cc0b54bcd3dde2716e5a6b99aedcc19cad02bf2403e08c","impliedFormat":1},{"version":"8a8c64dafaba11c806efa56f5c69f611276471bef80a1db1f71316ec4168acef","impliedFormat":1},{"version":"43ba4f2fa8c698f5c304d21a3ef596741e8e85a810b7c1f9b692653791d8d97a","impliedFormat":1},{"version":"5fad3b31fc17a5bc58095118a8b160f5260964787c52e7eb51e3d4fcf5d4a6f0","impliedFormat":1},{"version":"72105519d0390262cf0abe84cf41c926ade0ff475d35eb21307b2f94de985778","impliedFormat":1},{"version":"d0a4cac61fa080f2be5ebb68b82726be835689b35994ba0e22e3ed4d2bc45e3b","impliedFormat":1},{"version":"c857e0aae3f5f444abd791ec81206020fbcc1223e187316677e026d1c1d6fe08","impliedFormat":1},{"version":"ccf6dd45b708fb74ba9ed0f2478d4eb9195c9dfef0ff83a6092fa3cf2ff53b4f","impliedFormat":1},{"version":"2d7db1d73456e8c5075387d4240c29a2a900847f9c1bff106a2e490da8fbd457","impliedFormat":1},{"version":"2b15c805f48e4e970f8ec0b1915f22d13ca6212375e8987663e2ef5f0205e832","impliedFormat":1},{"version":"205a31b31beb7be73b8df18fcc43109cbc31f398950190a0967afc7a12cb478c","impliedFormat":1},{"version":"8fca3039857709484e5893c05c1f9126ab7451fa6c29e19bb8c2411a2e937345","impliedFormat":1},{"version":"35069c2c417bd7443ae7c7cafd1de02f665bf015479fec998985ffbbf500628c","impliedFormat":1},{"version":"dba6c7006e14a98ec82999c6f89fbbbfd1c642f41db148535f3b77b8018829b8","impliedFormat":1},{"version":"7f897b285f22a57a5c4dc14a27da2747c01084a542b4d90d33897216dceeea2e","impliedFormat":1},{"version":"7e0b7f91c5ab6e33f511efc640d36e6f933510b11be24f98836a20a2dc914c2d","impliedFormat":1},{"version":"045b752f44bf9bbdcaffd882424ab0e15cb8d11fa94e1448942e338c8ef19fba","impliedFormat":1},{"version":"2894c56cad581928bb37607810af011764a2f511f575d28c9f4af0f2ef02d1ab","impliedFormat":1},{"version":"0a72186f94215d020cb386f7dca81d7495ab6c17066eb07d0f44a5bf33c1b21a","impliedFormat":1},{"version":"d96b39301d0ded3f1a27b47759676a33a02f6f5049bfcbde81e533fd10f50dcb","impliedFormat":1},{"version":"2ded4f930d6abfaa0625cf55e58f565b7cbd4ab5b574dd2cb19f0a83a2f0be8b","impliedFormat":1},{"version":"0aedb02516baf3e66b2c1db9fef50666d6ed257edac0f866ea32f1aa05aa474f","impliedFormat":1},{"version":"ca0f4d9068d652bad47e326cf6ba424ac71ab866e44b24ddb6c2bd82d129586a","affectsGlobalScope":true,"impliedFormat":1},{"version":"04d36005fcbeac741ac50c421181f4e0316d57d148d37cc321a8ea285472462b","impliedFormat":1},{"version":"56ccb49443bfb72e5952f7012f0de1a8679f9f75fc93a5c1ac0bafb28725fc5f","impliedFormat":1},{"version":"20fa37b636fdcc1746ea0738f733d0aed17890d1cd7cb1b2f37010222c23f13e","impliedFormat":1},{"version":"d90b9f1520366d713a73bd30c5a9eb0040d0fb6076aff370796bc776fd705943","impliedFormat":1},{"version":"bc03c3c352f689e38c0ddd50c39b1e65d59273991bfc8858a9e3c0ebb79c023b","impliedFormat":1},{"version":"19df3488557c2fc9b4d8f0bac0fd20fb59aa19dec67c81f93813951a81a867f8","affectsGlobalScope":true,"impliedFormat":1},{"version":"b25350193e103ae90423c5418ddb0ad1168dc9c393c9295ef34980b990030617","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef86adb77316505c6b471da1d9b8c9e428867c2566270e8894d4d773a1c4dc2","impliedFormat":1},{"version":"1b239954e46191b95913d20771cf4283f63c3ebac79d7e30736a8d40b094fdaf","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"2652448ac55a2010a1f71dd141f828b682298d39728f9871e1cdf8696ef443fd","impliedFormat":1},{"version":"02c4fc9e6bb27545fa021f6056e88ff5fdf10d9d9f1467f1d10536c6e749ac50","impliedFormat":1},{"version":"120599fd965257b1f4d0ff794bc696162832d9d8467224f4665f713a3119078b","impliedFormat":1},{"version":"5433f33b0a20300cca35d2f229a7fc20b0e8477c44be2affeb21cb464af60c76","impliedFormat":1},{"version":"db036c56f79186da50af66511d37d9fe77fa6793381927292d17f81f787bb195","impliedFormat":1},{"version":"bd4131091b773973ca5d2326c60b789ab1f5e02d8843b3587effe6e1ea7c9d86","impliedFormat":1},{"version":"c7f6485931085bf010fbaf46880a9b9ec1a285ad9dc8c695a9e936f5a48f34b4","impliedFormat":1},{"version":"14f6b927888a1112d662877a5966b05ac1bf7ed25d6c84386db4c23c95a5363b","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"b5189fd031ef3232ec66817df5a8e7b23b079fdf3cd29a0c100eff1e98b2ce8e","impliedFormat":1},{"version":"00d3b80428c646edbd62379ea531606ee94eed51c4759cbab5a454e92b379690","impliedFormat":1},{"version":"49c346823ba6d4b12278c12c977fb3a31c06b9ca719015978cb145eb86da1c61","impliedFormat":1},{"version":"bfac6e50eaa7e73bb66b7e052c38fdc8ccfc8dbde2777648642af33cf349f7f1","impliedFormat":1},{"version":"92f7c1a4da7fbfd67a2228d1687d5c2e1faa0ba865a94d3550a3941d7527a45d","impliedFormat":1},{"version":"f53b120213a9289d9a26f5af90c4c686dd71d91487a0aa5451a38366c70dc64b","impliedFormat":1},{"version":"83fe880c090afe485a5c02262c0b7cdd76a299a50c48d9bde02be8e908fb4ae6","impliedFormat":1},{"version":"946a709579b7868a92a70ad70906444f32803fa6e6ce3739b6594c17691837ce","impliedFormat":1},{"version":"57d67b72e06059adc5e9454de26bbfe567d412b962a501d263c75c2db430f40e","impliedFormat":1},{"version":"6511e4503cf74c469c60aafd6589e4d14d5eb0a25f9bf043dcbecdf65f261972","impliedFormat":1},{"version":"5b955caba32e3dc3c3e293e00c104e255f0868848796e5bd5763f990c36d2798","impliedFormat":1},{"version":"8c70ddc0c22d85e56011d49fddfaae3405eb53d47b59327b9dd589e82df672e7","impliedFormat":1},{"version":"a67b87d0281c97dfc1197ef28dfe397fc2c865ccd41f7e32b53f647184cc7307","impliedFormat":1},{"version":"771ffb773f1ddd562492a6b9aaca648192ac3f056f0e1d997678ff97dbb6bf9b","impliedFormat":1},{"version":"232f70c0cf2b432f3a6e56a8dc3417103eb162292a9fd376d51a3a9ea5fbbf6f","impliedFormat":1},{"version":"4162ae9d4c1b8a7ab7f9ef287d98e9000b57062db1eb1ae735c4814845c2cb5d","impliedFormat":1},{"version":"a0ba218ac1baa3da0d5d9c1ec1a7c2f8676c284e6f5b920d6d049b13fa267377","impliedFormat":1},{"version":"8a0e762ceb20c7e72504feef83d709468a70af4abccb304f32d6b9bac1129b2c","impliedFormat":1},{"version":"d0af5b1b8d6262ef94fee7f8a39d12db1e21762a048ae33d4a5941a5b9fc2e1d","impliedFormat":1},{"version":"9252d498a77517aab5d8d4b5eb9d71e4b225bbc7123df9713e08181de63180f6","impliedFormat":1},{"version":"54d320df89710586fddb799b1b4f5b3364773a510dc5d507f3fbf52d8a734ae4","impliedFormat":1},{"version":"35e6379c3f7cb27b111ad4c1aa69538fd8e788ab737b8ff7596a1b40e96f4f90","impliedFormat":1},{"version":"1fffe726740f9787f15b532e1dc870af3cd964dbe29e191e76121aa3dd8693f2","impliedFormat":1},{"version":"371bf6127c1d427836de95197155132501cb6b69ef8709176ce6e0b85d059264","impliedFormat":1},{"version":"2bafd700e617d3693d568e972d02b92224b514781f542f70d497a8fdf92d52a2","affectsGlobalScope":true,"impliedFormat":1},{"version":"5542d8a7ea13168cb573be0d1ba0d29460d59430fb12bb7bf4674efd5604e14c","impliedFormat":1},{"version":"af48e58339188d5737b608d41411a9c054685413d8ae88b8c1d0d9bfabdf6e7e","impliedFormat":1},{"version":"616775f16134fa9d01fc677ad3f76e68c051a056c22ab552c64cc281a9686790","impliedFormat":1},{"version":"65c24a8baa2cca1de069a0ba9fba82a173690f52d7e2d0f1f7542d59d5eb4db0","impliedFormat":1},{"version":"f9fe6af238339a0e5f7563acee3178f51db37f32a2e7c09f85273098cee7ec49","impliedFormat":1},{"version":"1de8c302fd35220d8f29dea378a4ae45199dc8ff83ca9923aca1400f2b28848a","impliedFormat":1},{"version":"77e71242e71ebf8528c5802993697878f0533db8f2299b4d36aa015bae08a79c","impliedFormat":1},{"version":"98a787be42bd92f8c2a37d7df5f13e5992da0d967fab794adbb7ee18370f9849","impliedFormat":1},{"version":"332248ee37cca52903572e66c11bef755ccc6e235835e63d3c3e60ddda3e9b93","impliedFormat":1},{"version":"94e8cc88ae2ef3d920bb3bdc369f48436db123aa2dc07f683309ad8c9968a1e1","impliedFormat":1},{"version":"4545c1a1ceca170d5d83452dd7c4994644c35cf676a671412601689d9a62da35","impliedFormat":1},{"version":"320f4091e33548b554d2214ce5fc31c96631b513dffa806e2e3a60766c8c49d9","impliedFormat":1},{"version":"a2d648d333cf67b9aeac5d81a1a379d563a8ffa91ddd61c6179f68de724260ff","impliedFormat":1},{"version":"d90d5f524de38889d1e1dbc2aeef00060d779f8688c02766ddb9ca195e4a713d","impliedFormat":1},{"version":"a3f41ed1b4f2fc3049394b945a68ae4fdefd49fa1739c32f149d32c0545d67f5","impliedFormat":1},{"version":"b0309e1eda99a9e76f87c18992d9c3689b0938266242835dd4611f2b69efe456","impliedFormat":1},{"version":"47699512e6d8bebf7be488182427189f999affe3addc1c87c882d36b7f2d0b0e","impliedFormat":1},{"version":"6ceb10ca57943be87ff9debe978f4ab73593c0c85ee802c051a93fc96aaf7a20","impliedFormat":1},{"version":"1de3ffe0cc28a9fe2ac761ece075826836b5a02f340b412510a59ba1d41a505a","impliedFormat":1},{"version":"e46d6cc08d243d8d0d83986f609d830991f00450fb234f5b2f861648c42dc0d8","impliedFormat":1},{"version":"1c0a98de1323051010ce5b958ad47bc1c007f7921973123c999300e2b7b0ecc0","impliedFormat":1},{"version":"ff863d17c6c659440f7c5c536e4db7762d8c2565547b2608f36b798a743606ca","impliedFormat":1},{"version":"5412ad0043cd60d1f1406fc12cb4fb987e9a734decbdd4db6f6acf71791e36fe","impliedFormat":1},{"version":"ad036a85efcd9e5b4f7dd5c1a7362c8478f9a3b6c3554654ca24a29aa850a9c5","impliedFormat":1},{"version":"fedebeae32c5cdd1a85b4e0504a01996e4a8adf3dfa72876920d3dd6e42978e7","impliedFormat":1},{"version":"b6c1f64158da02580f55e8a2728eda6805f79419aed46a930f43e68ad66a38fc","impliedFormat":1},{"version":"cdf21eee8007e339b1b9945abf4a7b44930b1d695cc528459e68a3adc39a622e","impliedFormat":1},{"version":"9f9bb6755a8ce32d656ffa4763a8144aa4f274d6b69b59d7c32811031467216e","impliedFormat":1},{"version":"bc9ee0192f056b3d5527bcd78dc3f9e527a9ba2bdc0a2c296fbc9027147df4b2","impliedFormat":1},{"version":"330896c1a2b9693edd617be24fbf9e5895d6e18c7955d6c08f028f272b37314d","impliedFormat":1},{"version":"1d9c0a9a6df4e8f29dc84c25c5aa0bb1da5456ebede7a03e03df08bb8b27bae6","impliedFormat":1},{"version":"84380af21da938a567c65ef95aefb5354f676368ee1a1cbb4cae81604a4c7d17","impliedFormat":1},{"version":"1af3e1f2a5d1332e136f8b0b95c0e6c0a02aaabd5092b36b64f3042a03debf28","impliedFormat":1},{"version":"30d8da250766efa99490fc02801047c2c6d72dd0da1bba6581c7e80d1d8842a4","impliedFormat":1},{"version":"03566202f5553bd2d9de22dfab0c61aa163cabb64f0223c08431fb3fc8f70280","impliedFormat":1},{"version":"4c0a1233155afb94bd4d7518c75c84f98567cd5f13fc215d258de196cdb40d91","impliedFormat":1},{"version":"f9ceb394e029da0392ebd49564002b01fb4517cef0d14b238f2a8e7362a833e1","impliedFormat":1},{"version":"1de80059b8078ea5749941c9f863aa970b4735bdbb003be4925c853a8b6b4450","impliedFormat":1},{"version":"1d079c37fa53e3c21ed3fa214a27507bda9991f2a41458705b19ed8c2b61173d","impliedFormat":1},{"version":"5bf5c7a44e779790d1eb54c234b668b15e34affa95e78eada73e5757f61ed76a","impliedFormat":1},{"version":"5835a6e0d7cd2738e56b671af0e561e7c1b4fb77751383672f4b009f4e161d70","impliedFormat":1},{"version":"5c634644d45a1b6bc7b05e71e05e52ec04f3d73d9ac85d5927f647a5f965181a","impliedFormat":1},{"version":"4b7f74b772140395e7af67c4841be1ab867c11b3b82a51b1aeb692822b76c872","impliedFormat":1},{"version":"27be6622e2922a1b412eb057faa854831b95db9db5035c3f6d4b677b902ab3b7","impliedFormat":1},{"version":"a68d4b3182e8d776cdede7ac9630c209a7bfbb59191f99a52479151816ef9f9e","impliedFormat":99},{"version":"39644b343e4e3d748344af8182111e3bbc594930fff0170256567e13bbdbebb0","impliedFormat":99},{"version":"ed7fd5160b47b0de3b1571c5c5578e8e7e3314e33ae0b8ea85a895774ee64749","impliedFormat":99},{"version":"63a7595a5015e65262557f883463f934904959da563b4f788306f699411e9bac","impliedFormat":1},{"version":"4ba137d6553965703b6b55fd2000b4e07ba365f8caeb0359162ad7247f9707a6","impliedFormat":1},{"version":"6de125ea94866c736c6d58d68eb15272cf7d1020a5b459fea1c660027eca9a90","affectsGlobalScope":true,"impliedFormat":1},{"version":"8fac4a15690b27612d8474fb2fc7cc00388df52d169791b78d1a3645d60b4c8b","affectsGlobalScope":true,"impliedFormat":1},{"version":"064ac1c2ac4b2867c2ceaa74bbdce0cb6a4c16e7c31a6497097159c18f74aa7c","impliedFormat":1},{"version":"3dc14e1ab45e497e5d5e4295271d54ff689aeae00b4277979fdd10fa563540ae","impliedFormat":1},{"version":"d3b315763d91265d6b0e7e7fa93cfdb8a80ce7cdd2d9f55ba0f37a22db00bdb8","impliedFormat":1},{"version":"b789bf89eb19c777ed1e956dbad0925ca795701552d22e68fd130a032008b9f9","impliedFormat":1},{"version":"a384610388221cd70cffb4503cee7853b8b076f2b4a55324b20a4bdbd25a3538","affectsGlobalScope":true},"7b550dda9686c16f36a17bf9051d5dbf31e98555b30d114ac49fc49a1e712651","3c9b6a95ecc9ce426259b37490dad34bbb8439b50489f9fd4c933d30c3af7802",{"version":"cfe559f6e9ef59d6d9f1c43d2f556de466dee11e19ac8087fd56a37133e664c2","signature":"5dd0fecd91e513ed3b4ececbc458cbf97dfa8b2ff18876010acccc8812838bb3"},"73b731c5c9e98b95c740966044321a7ff44cb07e3f154aa0ea3ea7f9c4679251","b56c632f26be7a6bf7c74542393f9a2ac6731610fab0e2dc6dcf28c97ec3c935",{"version":"c57b441e0c0a9cbdfa7d850dae1f8a387d6f81cbffbc3cd0465d530084c2417d","impliedFormat":99},{"version":"51954e948be6a5b728fcfaf561f12331b4f54f068934c77adfc8f70eea17d285","impliedFormat":1},"e46429536f43f5910f5b2b0c50bb2769b510a4558bb4b5d20a3b0a9091dbf7c3",{"version":"b59ecd181e9f1087f3f474315ff6f69d0cb18c4ecf5383ff31969e1c7cdefaa8","impliedFormat":1},{"version":"0769b4cc5711c0bd94cab03825f89ce8b8abe4e5718f19c228b5e23c107b251d","impliedFormat":1},{"version":"294fe7185fe4e86eef16f92ac437c23871b0276aca199fc0f83efcce7cce0f15","impliedFormat":1},{"version":"b249a28da8393a81f18a55419ef239745eb3b4aab61a3ec890a5e67b1a0927d4","impliedFormat":1},{"version":"52f935a88dd280e8abfeff842478b9c078cf3b65583ee774b6c14d5e292acc69","impliedFormat":1},{"version":"352c972b4227dd4f464f4ae057ea45f604bec93de292c409eef42596c25e2c5c","impliedFormat":1},"0cf4d4727a80cc61cdc63ec91275a92b26740609de6ec8649e533584b64126c2",{"version":"fe93c474ab38ac02e30e3af073412b4f92b740152cf3a751fdaee8cbea982341","impliedFormat":1},{"version":"1bddafb2bee422e871de305b43a484ec058de25c3605b8da7dc8e63dc074e09f","impliedFormat":1},{"version":"1e00b8bf9e3766c958218cd6144ffe08418286f89ff44ba5a2cc830c03dd22c7","impliedFormat":1},{"version":"23aee0495d88432738dd693b534e86543a2654c518a99504f8d9a11fd5c7a067","affectsGlobalScope":true,"impliedFormat":99},"a2718170502232e519db93a1ec0ae56f7a1c697d2bc6cc1e77dad34730924045","8aa160f1ceb81e8686f049dcb0ae250edc917627871c5522afbf40943c227dd4","8c738d7ab02122bec55d98eab2f5e875f5306ebffe56a6be96f2da0916a7ea71",{"version":"b1538a92b9bae8d230267210c5db38c2eb6bdb352128a3ce3aa8c6acf9fc9622","impliedFormat":1},{"version":"6fc1a4f64372593767a9b7b774e9b3b92bf04e8785c3f9ea98973aa9f4bbe490","impliedFormat":1},{"version":"ff09b6fbdcf74d8af4e131b8866925c5e18d225540b9b19ce9485ca93e574d84","impliedFormat":1},{"version":"d5895252efa27a50f134a9b580aa61f7def5ab73d0a8071f9b5bf9a317c01c2d","impliedFormat":1},{"version":"2c378d9368abcd2eba8c29b294d40909845f68557bc0b38117e4f04fc56e5f9c","impliedFormat":1},{"version":"56208c500dcb5f42be7e18e8cb578f257a1a89b94b3280c506818fed06391805","impliedFormat":1},{"version":"0c94c2e497e1b9bcfda66aea239d5d36cd980d12a6d9d59e66f4be1fa3da5d5a","impliedFormat":1},{"version":"9b048390bcffe88c023a4cd742a720b41d4cd7df83bc9270e6f2339bf38de278","affectsGlobalScope":true,"impliedFormat":1},{"version":"1f366bde16e0513fa7b64f87f86689c4d36efd85afce7eb24753e9c99b91c319","impliedFormat":1},{"version":"151ff381ef9ff8da2da9b9663ebf657eac35c4c9a19183420c05728f31a6761d","impliedFormat":1},{"version":"f3d8c757e148ad968f0d98697987db363070abada5f503da3c06aefd9d4248c1","impliedFormat":1},{"version":"a4a39b5714adfcadd3bbea6698ca2e942606d833bde62ad5fb6ec55f5e438ff8","impliedFormat":1},{"version":"bbc1d029093135d7d9bfa4b38cbf8761db505026cc458b5e9c8b74f4000e5e75","impliedFormat":1},{"version":"1f68ab0e055994eb337b67aa87d2a15e0200951e9664959b3866ee6f6b11a0fe","impliedFormat":1}],"root":[[506,511],514,521,[526,528]],"options":{"allowJs":true,"esModuleInterop":true,"jsx":4,"module":99,"skipLibCheck":true,"strict":true,"target":4},"referencedMap":[[506,1],[528,2],[521,3],[526,4],[527,5],[508,6],[509,6],[510,6],[511,7],[514,8],[507,9],[517,10],[516,1],[515,1],[264,1],[519,1],[518,1],[520,11],[529,1],[530,1],[531,1],[532,12],[533,1],[535,13],[536,14],[534,1],[537,1],[542,15],[541,16],[540,17],[538,1],[539,1],[142,18],[143,18],[144,19],[97,20],[145,21],[146,22],[147,23],[92,1],[95,24],[93,1],[94,1],[148,25],[149,26],[150,27],[151,28],[152,29],[153,30],[154,30],[155,31],[156,32],[157,33],[158,34],[98,1],[96,1],[159,35],[160,36],[161,37],[195,38],[162,39],[163,1],[164,40],[165,41],[166,42],[167,43],[168,44],[169,45],[170,46],[171,47],[172,48],[173,48],[174,49],[175,1],[176,50],[177,51],[179,52],[178,53],[180,54],[181,55],[182,56],[183,57],[184,58],[185,59],[186,60],[187,61],[188,62],[189,63],[190,64],[191,65],[192,66],[99,1],[100,1],[101,1],[139,67],[140,1],[141,1],[193,68],[194,69],[199,70],[411,71],[200,72],[198,73],[413,74],[412,75],[196,76],[409,1],[197,77],[83,1],[85,78],[408,71],[281,71],[525,71],[512,1],[84,1],[454,79],[459,80],[449,81],[230,82],[268,83],[436,84],[263,85],[245,1],[223,1],[228,1],[426,86],[294,87],[229,1],[222,88],[271,89],[272,90],[407,91],[423,92],[318,93],[430,94],[431,95],[429,96],[428,1],[427,97],[270,98],[231,99],[361,1],[362,100],[254,101],[232,102],[299,101],[296,101],[209,101],[266,103],[265,1],[435,104],[445,1],[216,1],[383,105],[384,106],[378,71],[482,1],[386,1],[387,7],[379,107],[487,108],[486,109],[481,1],[478,1],[422,110],[421,1],[480,111],[380,71],[220,112],[217,113],[219,1],[483,1],[479,1],[485,114],[484,1],[218,115],[473,116],[476,117],[306,118],[305,119],[304,120],[490,71],[303,121],[288,1],[493,1],[523,122],[522,1],[496,1],[495,71],[497,123],[202,1],[432,124],[433,125],[434,126],[215,1],[256,1],[214,127],[201,1],[399,71],[207,128],[398,129],[397,130],[388,1],[389,1],[396,1],[391,1],[394,131],[390,1],[392,132],[395,133],[393,132],[227,1],[212,1],[213,101],[276,1],[282,134],[283,135],[280,136],[278,137],[279,138],[274,1],[405,7],[321,7],[453,139],[460,140],[464,141],[439,142],[438,1],[291,1],[498,143],[448,144],[381,145],[382,146],[376,147],[367,1],[404,148],[368,149],[406,150],[401,151],[400,1],[402,1],[373,1],[360,152],[440,153],[441,154],[370,155],[374,156],[365,157],[418,158],[447,159],[298,160],[337,161],[210,162],[446,163],[206,164],[284,165],[275,1],[285,166],[349,167],[273,1],[348,168],[91,1],[342,169],[255,1],[363,170],[338,1],[211,1],[249,1],[346,171],[226,1],[286,172],[372,173],[437,174],[371,1],[345,1],[277,1],[351,175],[352,176],[224,1],[354,177],[356,178],[355,179],[258,1],[344,162],[358,180],[343,181],[350,182],[234,1],[238,1],[237,1],[236,1],[241,1],[235,1],[243,1],[240,1],[239,1],[242,1],[244,183],[233,1],[330,184],[329,1],[335,185],[331,186],[334,187],[333,187],[336,185],[332,186],[253,188],[322,189],[444,190],[499,1],[468,191],[470,192],[369,193],[469,194],[442,153],[385,153],[225,1],[323,195],[250,196],[251,197],[252,198],[248,199],[417,199],[300,199],[324,200],[301,200],[247,201],[246,1],[328,202],[327,203],[326,204],[325,205],[443,206],[416,207],[415,208],[377,209],[410,210],[414,211],[425,212],[424,213],[420,214],[317,215],[319,216],[316,217],[357,218],[347,1],[458,1],[359,219],[419,1],[287,220],[366,124],[364,221],[289,222],[292,223],[494,1],[290,224],[293,224],[456,1],[455,1],[457,1],[492,1],[295,225],[314,226],[221,227],[269,1],[205,228],[320,1],[462,71],[204,1],[472,229],[313,71],[466,7],[312,230],[451,231],[311,229],[208,1],[474,232],[309,71],[310,71],[302,1],[203,1],[308,233],[307,234],[257,235],[375,47],[297,47],[353,1],[340,236],[339,1],[403,115],[315,71],[452,237],[86,71],[89,238],[90,239],[87,71],[88,1],[267,240],[262,241],[261,1],[260,242],[259,1],[450,243],[461,244],[463,245],[465,246],[524,247],[467,248],[471,249],[505,250],[475,250],[504,251],[477,252],[488,253],[489,254],[491,255],[500,256],[503,127],[502,1],[501,257],[341,258],[513,1],[81,1],[82,1],[13,1],[14,1],[16,1],[15,1],[2,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[23,1],[24,1],[3,1],[25,1],[26,1],[4,1],[27,1],[31,1],[28,1],[29,1],[30,1],[32,1],[33,1],[34,1],[5,1],[35,1],[36,1],[37,1],[38,1],[6,1],[42,1],[39,1],[40,1],[41,1],[43,1],[7,1],[44,1],[49,1],[50,1],[45,1],[46,1],[47,1],[48,1],[8,1],[54,1],[51,1],[52,1],[53,1],[55,1],[9,1],[56,1],[57,1],[58,1],[60,1],[59,1],[61,1],[62,1],[10,1],[63,1],[64,1],[65,1],[11,1],[66,1],[67,1],[68,1],[69,1],[70,1],[1,1],[71,1],[72,1],[12,1],[76,1],[74,1],[79,1],[78,1],[73,1],[77,1],[75,1],[80,1],[117,259],[127,260],[116,259],[137,261],[108,262],[107,263],[136,257],[130,264],[135,265],[110,266],[124,267],[109,268],[133,269],[105,270],[104,257],[134,271],[106,272],[111,273],[112,1],[115,273],[102,1],[138,274],[128,275],[119,276],[120,277],[122,278],[118,279],[121,280],[131,257],[113,281],[114,282],[123,283],[103,284],[126,275],[125,273],[129,1],[132,285]],"semanticDiagnosticsPerFile":[[527,[{"start":61664,"length":25,"code":2352,"category":1,"messageText":{"messageText":"Conversion of type 'WebSocketMessage' to type 'WSIncomingMessage' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.","category":1,"code":2352,"next":[{"messageText":"Type 'WebSocketMessage' is missing the following properties from type 'WSEvent': event, payload, seq","category":1,"code":2739,"canonicalHead":{"code":2678,"messageText":"Type 'WebSocketMessage' is not comparable to type 'WSEvent'."}}]}},{"start":65022,"length":8,"code":2339,"category":1,"messageText":"Property 'thinking' does not exist on type 'ContentPart'."},{"start":65057,"length":8,"code":2339,"category":1,"messageText":"Property 'thinking' does not exist on type 'ContentPart'."}]]],"affectedFilesPendingEmit":[528,521,526,527,508,509,510,511,514],"version":"5.9.3"} \ No newline at end of file