From 026d575ca5bef0912d94d187563be32d3f6de1a0 Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Thu, 12 Feb 2026 11:15:31 +0800 Subject: [PATCH 01/14] forge(forge-test-first-loop-template): task-1 Scaffold bundled template `test-first-loop` --- .claude/settings.local.json | 13 + .../templates/test-first-loop/phases.json | 14 + .../test-first-loop/prompts/execute.md | 102 +++++ .../templates/test-first-loop/prompts/plan.md | 36 ++ .../test-first-loop/schemas/plan.schema.json | 117 +++++ .../test-first-loop/schemas/state.schema.json | 66 +++ .../test-first-loop/scripts/lib/args.mjs | 23 + .../test-first-loop/scripts/lib/context.mjs | 39 ++ .../test-first-loop/scripts/lib/execute.mjs | 206 +++++++++ .../test-first-loop/scripts/lib/markdown.mjs | 117 +++++ .../test-first-loop/scripts/lib/plan.mjs | 408 ++++++++++++++++++ .../test-first-loop/scripts/lib/render.mjs | 22 + .../test-first-loop/scripts/lib/state.mjs | 27 ++ .../test-first-loop/scripts/post-plan.mjs | 57 +++ .../test-first-loop/scripts/post-step.mjs | 60 +++ .../test-first-loop/scripts/pre-execute.mjs | 51 +++ .../test-first-loop/skills/plan/SKILL.md | 102 +++++ .../skills/plan/references/plan-schema.md | 282 ++++++++++++ .../templates/test-first-loop/template.json | 39 ++ 19 files changed, 1781 insertions(+) create mode 100644 .claude/settings.local.json create mode 100644 src-tauri/resources/forge/templates/test-first-loop/phases.json create mode 100644 src-tauri/resources/forge/templates/test-first-loop/prompts/execute.md create mode 100644 src-tauri/resources/forge/templates/test-first-loop/prompts/plan.md create mode 100644 src-tauri/resources/forge/templates/test-first-loop/schemas/plan.schema.json create mode 100644 src-tauri/resources/forge/templates/test-first-loop/schemas/state.schema.json create mode 100644 src-tauri/resources/forge/templates/test-first-loop/scripts/lib/args.mjs create mode 100644 src-tauri/resources/forge/templates/test-first-loop/scripts/lib/context.mjs create mode 100644 src-tauri/resources/forge/templates/test-first-loop/scripts/lib/execute.mjs create mode 100644 src-tauri/resources/forge/templates/test-first-loop/scripts/lib/markdown.mjs create mode 100644 src-tauri/resources/forge/templates/test-first-loop/scripts/lib/plan.mjs create mode 100644 src-tauri/resources/forge/templates/test-first-loop/scripts/lib/render.mjs create mode 100644 src-tauri/resources/forge/templates/test-first-loop/scripts/lib/state.mjs create mode 100644 src-tauri/resources/forge/templates/test-first-loop/scripts/post-plan.mjs create mode 100644 src-tauri/resources/forge/templates/test-first-loop/scripts/post-step.mjs create mode 100644 src-tauri/resources/forge/templates/test-first-loop/scripts/pre-execute.mjs create mode 100644 src-tauri/resources/forge/templates/test-first-loop/skills/plan/SKILL.md create mode 100644 src-tauri/resources/forge/templates/test-first-loop/skills/plan/references/plan-schema.md create mode 100644 src-tauri/resources/forge/templates/test-first-loop/template.json diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000000..2b58e54751 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,13 @@ +{ + "permissions": { + "allow": [ + "Bash(git push:*)", + "Bash(gh auth:*)", + "Bash(ssh:*)", + "Bash(echo:*)", + "Bash(git remote set-url:*)", + "Bash(git checkout:*)", + "Bash(git pull:*)" + ] + } +} diff --git a/src-tauri/resources/forge/templates/test-first-loop/phases.json b/src-tauri/resources/forge/templates/test-first-loop/phases.json new file mode 100644 index 0000000000..dfc6606a1b --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/phases.json @@ -0,0 +1,14 @@ +{ + "schema": "forge-phases-v1", + "phases": [ + { + "id": "implementation", + "title": "Implementation", + "iconId": "code_blocks", + "order": 1, + "goal": "Implement the task changes and record progress in state.json.", + "description": "Complete the task in one commit. If checks fail after committing, fix issues and amend the same commit until checks pass.", + "checks": [] + } + ] +} diff --git a/src-tauri/resources/forge/templates/test-first-loop/prompts/execute.md b/src-tauri/resources/forge/templates/test-first-loop/prompts/execute.md new file mode 100644 index 0000000000..91e36e2f7a --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/prompts/execute.md @@ -0,0 +1,102 @@ +# Mode: execute + +You are executing a single task from a development plan. Your context is cleared +between tasks - everything you need is below. + +## Runtime contract (read first) + +`Forge` is the Forge backend orchestrator driving this loop. + +- Forge selects the current task/phase from `plans/{{plan_id}}/state.json`. +- Forge starts fresh task-scoped threads, runs backend checks, and manages final task commits. +- Your job is to implement the requested phase and keep `state.json`/`progress.md` accurate. + +--- + +## Plan + +**Goal:** {{goal}} +**Tech Stack:** {{tech_stack}} +**Constraints:** +{{constraints}} + +## Progress (iteration {{iteration}}) + +{{summary}} + +## All tasks + +{{task_list}} + +## Learnings from previous iterations + +{{progress_notes}} + +--- + +## YOUR TASK: {{current_task_id}} - {{current_task_name}} + +{{current_task_description}} + +## Current phase: {{current_phase_id}} - {{current_phase_title}} + +**Phase goal:** {{current_phase_goal}} + +{{current_phase_description}} + +**Files:** {{current_task_files}} + +**Verification:** +{{current_task_verification}} + +**Attempts so far:** {{current_task_attempts}} +{{current_task_previous_notes}} + +**What dependencies produced:** +{{dependency_notes}} + +--- + +## Phase protocol (important) + +1. Implement the current phase for the current task. +2. Update `plans/{{plan_id}}/state.json`: + - Set this phase `status` to `completed` (or `blocked`/`failed` if truly stuck). + - Increment this phase `attempts`. + - Append concise notes (paths/decisions). + - Keep task `status` as `in_progress` while handing off to Forge checks. +3. Forge will run backend checks after your phase is marked complete. + - Forge finalizes phase/task completion statuses after checks. + - If checks fail, Forge reopens the phase and you retry. + - If checks pass on the last phase, Forge creates the task commit and records `commit_sha`. +4. Do NOT run `git` commands yourself in execute mode. + - Do NOT run `git add`, `git commit`, `git commit --amend`, or `git push`. + - Do NOT set `commit_sha` in `state.json`; Forge manages it. +5. End your message with this exact single line marker: + +```text +[[cm_forge:done plan={{plan_id}} task={{current_task_id}} phase={{current_phase_id}}]] +``` + - Use the exact `plan/task/phase` values shown above. Do not reuse marker values from a previous task or phase. + +--- + +## After implementation - update state + +Update `plans/{{plan_id}}/state.json` following these rules: + +1. Keep your task's `status` as `in_progress` while implementing (or `failed` if truly stuck after multiple attempts) +2. Write `notes` explaining what you did - file paths, decisions, config values. The next + iteration has no memory of you; these notes are its only link to your work. +3. Update `summary` - orient a newcomer: what's done, what's next (max 300 chars) +4. Increment your task's `attempts` count +5. Do NOT change any other task's status +6. Do NOT modify `plan.json` - it is immutable +7. Do NOT set `commit_sha`; Forge writes it after final-phase checks pass. + +If you learned something useful beyond this task (a gotcha, a project convention, +a tool quirk), append a one-liner to `plans/{{plan_id}}/progress.md`: + +```text +- {{date}} iter {{iteration}}: +``` diff --git a/src-tauri/resources/forge/templates/test-first-loop/prompts/plan.md b/src-tauri/resources/forge/templates/test-first-loop/prompts/plan.md new file mode 100644 index 0000000000..54ad942085 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/prompts/plan.md @@ -0,0 +1,36 @@ +@plan + +# Mode: plan + +You are generating a development plan. + +## Two-step flow (important) + +This message is only the planning template injection. Do NOT generate a plan yet. + +1. First, reply only with: `Ready for your request.` +2. Then wait for the user to describe what they want to build in their next message. +3. Only after you receive the user's request, follow the instructions below to generate the plan. + +## Instructions + +Read the @plan skill and its reference schemas before generating anything: + +1. `.agents/skills/plan/SKILL.md` - rules, field guidelines, sizing advice +2. `.agents/skills/plan/references/plan-schema.md` - full plan.json JSON Schema + example + +## Output + +- Choose a `plan_id` slug matching `^[a-z0-9][a-z0-9-]*[a-z0-9]$` (max 64 chars). +- Output the plan as the exact `plan-v1` JSON object inside a single `...` block. +- Do NOT write any files yet. + +Inside the JSON, include: + +- `"$schema": "plan-v1"` +- `"id": ""` +- `"title": ""` + +## Hard requirement + +Do NOT implement the plan. Stop after outputting the `` block. diff --git a/src-tauri/resources/forge/templates/test-first-loop/schemas/plan.schema.json b/src-tauri/resources/forge/templates/test-first-loop/schemas/plan.schema.json new file mode 100644 index 0000000000..462256aaa4 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/schemas/plan.schema.json @@ -0,0 +1,117 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Plan", + "description": "A structured development plan for agentic coding orchestrators", + "type": "object", + "required": ["$schema", "id", "goal", "context", "tasks"], + "additionalProperties": false, + "properties": { + "$schema": { + "type": "string", + "const": "plan-v1", + "description": "Schema version identifier" + }, + "id": { + "type": "string", + "pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$", + "maxLength": 64, + "description": "URL-safe slug identifying this plan" + }, + "title": { + "type": "string", + "minLength": 3, + "maxLength": 80, + "description": "Short friendly label for UI/menus (keep under ~60 chars)" + }, + "goal": { + "type": "string", + "minLength": 10, + "maxLength": 500, + "description": "One sentence describing the desired end state" + }, + "context": { + "type": "object", + "required": ["tech_stack", "constraints"], + "additionalProperties": false, + "properties": { + "tech_stack": { + "type": "array", + "items": { "type": "string" }, + "minItems": 1, + "description": "Technologies to use" + }, + "constraints": { + "type": "array", + "items": { "type": "string" }, + "description": "Hard rules and boundaries" + }, + "references": { + "type": "array", + "items": { + "type": "object", + "required": ["path", "description"], + "additionalProperties": false, + "properties": { + "path": { "type": "string" }, + "description": { "type": "string" } + } + }, + "description": "Files the LLM should read for context" + } + } + }, + "tasks": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "id", + "name", + "description", + "depends_on", + "files", + "verification" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "pattern": "^task-[0-9]+$", + "description": "Format: task-{sequence}" + }, + "name": { + "type": "string", + "maxLength": 80, + "description": "Short display name for UI" + }, + "description": { + "type": "string", + "minLength": 20, + "description": "Detailed implementation instructions" + }, + "depends_on": { + "type": "array", + "items": { + "type": "string", + "pattern": "^task-[0-9]+$" + }, + "description": "Task IDs that must complete before this task can start" + }, + "files": { + "type": "array", + "items": { "type": "string" }, + "minItems": 1, + "description": "File paths this task will create or modify" + }, + "verification": { + "type": "array", + "items": { "type": "string" }, + "minItems": 1, + "description": "Concrete, testable assertions for completion" + } + } + } + } + } +} diff --git a/src-tauri/resources/forge/templates/test-first-loop/schemas/state.schema.json b/src-tauri/resources/forge/templates/test-first-loop/schemas/state.schema.json new file mode 100644 index 0000000000..582e5c9caf --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/schemas/state.schema.json @@ -0,0 +1,66 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "State", + "description": "Execution progress tracking for a development plan", + "type": "object", + "required": ["$schema", "plan_id", "iteration", "summary", "tasks"], + "additionalProperties": false, + "properties": { + "$schema": { + "type": "string", + "const": "state-v2" + }, + "plan_id": { + "type": "string", + "description": "Must match the id field in plan.json" + }, + "iteration": { + "type": "integer", + "minimum": 0, + "description": "Incremented by the agent before each phase completion" + }, + "summary": { + "type": "string", + "maxLength": 300, + "description": "Cumulative progress summary for context continuity" + }, + "tasks": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["id", "status", "attempts", "notes", "commit_sha", "phases"], + "additionalProperties": false, + "properties": { + "id": { "type": "string", "pattern": "^task-[0-9]+$" }, + "status": { + "type": "string", + "enum": ["pending", "in_progress", "completed", "blocked", "failed"] + }, + "attempts": { "type": "integer", "minimum": 0 }, + "notes": { "type": "string" }, + "commit_sha": { "type": ["string", "null"] }, + "phases": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["id", "status", "attempts", "notes"], + "additionalProperties": false, + "properties": { + "id": { "type": "string" }, + "status": { + "type": "string", + "enum": ["pending", "in_progress", "completed", "blocked", "failed"] + }, + "attempts": { "type": "integer", "minimum": 0 }, + "notes": { "type": "string" } + } + } + } + } + } + } + } +} + diff --git a/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/args.mjs b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/args.mjs new file mode 100644 index 0000000000..4773dcc1b8 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/args.mjs @@ -0,0 +1,23 @@ +export function parseFlagValue(argv, flagName) { + const exact = `--${flagName}`; + const prefix = `--${flagName}=`; + for (let i = 0; i < argv.length; i++) { + const arg = argv[i]; + if (arg === exact) { + return argv[i + 1] ?? null; + } + if (arg.startsWith(prefix)) { + return arg.slice(prefix.length); + } + } + return null; +} + +export function requireFlagValue(argv, flagName) { + const value = parseFlagValue(argv, flagName); + if (!value || !String(value).trim()) { + throw new Error(`Missing required flag: --${flagName} `); + } + return value; +} + diff --git a/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/context.mjs b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/context.mjs new file mode 100644 index 0000000000..7d5ed44f4c --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/context.mjs @@ -0,0 +1,39 @@ +import fs from "node:fs/promises"; + +const REQUIRED_STRING_FIELDS = [ + "workspaceRoot", + "templateRoot", + "planId", + "planDir", + "planPath", + "statePath", + "progressPath", + "generatedPlanMdPath", + "generatedExecutePromptPath", + "todayIso", +]; + +export async function readContext(contextPath) { + const raw = await fs.readFile(contextPath, "utf8"); + let parsed; + try { + parsed = JSON.parse(raw); + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + throw new Error(`Invalid JSON in context file: ${contextPath} (${message})`); + } + + if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { + throw new Error(`Context must be a JSON object: ${contextPath}`); + } + + for (const field of REQUIRED_STRING_FIELDS) { + const value = parsed[field]; + if (typeof value !== "string" || value.trim() === "") { + throw new Error(`Context missing required string field: ${field}`); + } + } + + return parsed; +} + diff --git a/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/execute.mjs b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/execute.mjs new file mode 100644 index 0000000000..9afa7c7b2c --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/execute.mjs @@ -0,0 +1,206 @@ +import { formatBulletList, renderTemplate } from "./render.mjs"; + +function statusMark(status) { + switch (status) { + case "completed": + return "[x]"; + case "in_progress": + return "[*]"; + case "blocked": + return "[!]"; + case "failed": + return "[~]"; + case "pending": + default: + return "[ ]"; + } +} + +function normalizeNotes(notes) { + if (typeof notes !== "string") { + return ""; + } + return notes.trim(); +} + +function buildTaskList(plan, state) { + const planTasks = Array.isArray(plan?.tasks) ? plan.tasks : []; + const stateTasks = Array.isArray(state?.tasks) ? state.tasks : []; + const byId = new Map(stateTasks.map((t) => [t.id, t])); + + const lines = []; + for (const task of planTasks) { + const st = byId.get(task.id) ?? { status: "pending", notes: "" }; + const notes = normalizeNotes(st.notes); + const noteSuffix = notes ? ` - ${notes.slice(0, 120)}` : ""; + lines.push(`${statusMark(st.status)} ${task.id} ${task.name}${noteSuffix}`); + } + return lines.join("\n"); +} + +function mapStateTasks(state) { + const stateTasks = Array.isArray(state?.tasks) ? state.tasks : []; + return new Map(stateTasks.map((t) => [t.id, t])); +} + +function isCompletedStatus(status) { + return typeof status === "string" && status.trim() === "completed"; +} + +function isTaskCompleted(stateTask) { + const phases = Array.isArray(stateTask?.phases) ? stateTask.phases : []; + return phases.length > 0 && phases.every((phase) => isCompletedStatus(phase.status)); +} + +function isDepsSatisfied(task, stateById) { + const deps = Array.isArray(task?.depends_on) ? task.depends_on : []; + for (const dep of deps) { + const st = stateById.get(dep); + if (!st || !isTaskCompleted(st)) { + return false; + } + } + return true; +} + +export function findNextRunnableTask(plan, state) { + const planTasks = Array.isArray(plan?.tasks) ? plan.tasks : []; + const stateById = mapStateTasks(state); + + for (const task of planTasks) { + const st = stateById.get(task.id); + if (!st) { + continue; + } + if (isTaskCompleted(st)) { + continue; + } + if (isDepsSatisfied(task, stateById)) { + return task; + } + } + return null; +} + +function findNextRunnablePhase(stateTask) { + const phases = Array.isArray(stateTask?.phases) ? stateTask.phases : []; + for (const phase of phases) { + if (!isCompletedStatus(phase.status)) { + return phase; + } + } + return null; +} + +function mapTemplatePhases(templatePhases) { + const phases = Array.isArray(templatePhases) ? templatePhases : []; + return new Map(phases.map((p) => [p.id, p])); +} + +function dependencyNotesForTask(task, stateById) { + const deps = Array.isArray(task?.depends_on) ? task.depends_on : []; + if (deps.length === 0) { + return "(none)"; + } + const lines = []; + for (const dep of deps) { + const st = stateById.get(dep); + const notes = normalizeNotes(st?.notes ?? ""); + lines.push(`- ${dep}: ${notes || "(no notes)"}`); + } + return lines.join("\n"); +} + +export function renderExecutePrompt({ + templateText, + plan, + state, + templatePhases, + progressNotes, + todayIso, +}) { + const techStack = Array.isArray(plan?.context?.tech_stack) + ? plan.context.tech_stack.join(", ") + : ""; + const constraints = Array.isArray(plan?.context?.constraints) + ? formatBulletList(plan.context.constraints) + : ""; + + const stateById = mapStateTasks(state); + const current = findNextRunnableTask(plan, state); + const templatePhaseById = mapTemplatePhases(templatePhases); + + if (!current) { + const values = { + plan_id: plan.id ?? "", + goal: plan.goal ?? "", + tech_stack: techStack, + constraints, + iteration: String(state?.iteration ?? 0), + summary: state?.summary ?? "", + task_list: buildTaskList(plan, state), + progress_notes: progressNotes ?? "", + current_task_id: "(none)", + current_task_name: "All tasks completed", + current_task_description: "No runnable pending task found. The plan may be complete.", + current_phase_id: "(none)", + current_phase_title: "", + current_phase_goal: "", + current_phase_description: "", + current_task_files: "", + current_task_verification: "", + current_task_attempts: "0", + current_task_previous_notes: "", + dependency_notes: "", + date: todayIso, + }; + return renderTemplate(templateText, values); + } + + const st = stateById.get(current.id) ?? { + status: "pending", + attempts: 0, + notes: "", + phases: [], + }; + + const phase = findNextRunnablePhase(st) ?? { id: "implementation", status: "pending", attempts: 0, notes: "" }; + const phaseMeta = templatePhaseById.get(phase.id) ?? { id: phase.id, title: phase.id, goal: "", description: "" }; + + const previousNotes = normalizeNotes(st.notes); + const phaseNotes = normalizeNotes(phase.notes); + const notesBlocks = []; + if (previousNotes) { + notesBlocks.push(`Task notes:\n${previousNotes}`); + } + if (phaseNotes) { + notesBlocks.push(`Phase notes:\n${phaseNotes}`); + } + const currentTaskPreviousNotes = notesBlocks.length > 0 ? `\nPrevious notes:\n${notesBlocks.join("\n\n")}` : ""; + + const values = { + plan_id: plan.id ?? "", + goal: plan.goal ?? "", + tech_stack: techStack, + constraints, + iteration: String(state?.iteration ?? 0), + summary: state?.summary ?? "", + task_list: buildTaskList(plan, state), + progress_notes: progressNotes ?? "", + current_task_id: current.id, + current_task_name: current.name ?? "", + current_task_description: current.description ?? "", + current_phase_id: phase.id ?? "", + current_phase_title: phaseMeta.title ?? phaseMeta.id ?? "", + current_phase_goal: phaseMeta.goal ?? "", + current_phase_description: phaseMeta.description ?? "", + current_task_files: `\n${formatBulletList(current.files ?? [])}`, + current_task_verification: formatBulletList(current.verification ?? []), + current_task_attempts: String(phase.attempts ?? 0), + current_task_previous_notes: currentTaskPreviousNotes, + dependency_notes: dependencyNotesForTask(current, stateById), + date: todayIso, + }; + + return renderTemplate(templateText, values); +} diff --git a/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/markdown.mjs b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/markdown.mjs new file mode 100644 index 0000000000..2e13f0bb31 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/markdown.mjs @@ -0,0 +1,117 @@ +import { formatBulletList } from "./render.mjs"; + +export function planToMarkdown(plan) { + const techStack = Array.isArray(plan?.context?.tech_stack) + ? plan.context.tech_stack.join(", ") + : ""; + const constraints = Array.isArray(plan?.context?.constraints) + ? formatBulletList(plan.context.constraints) + : ""; + + const tasks = Array.isArray(plan?.tasks) ? plan.tasks : []; + + const lines = []; + lines.push(`# Plan: ${plan.id}`); + lines.push(""); + lines.push(`## Goal`); + lines.push(""); + lines.push(plan.goal ?? ""); + lines.push(""); + lines.push("## Context"); + lines.push(""); + lines.push(`- Tech stack: ${techStack}`); + lines.push(""); + if (constraints) { + lines.push("### Constraints"); + lines.push(""); + lines.push(constraints); + lines.push(""); + } + + lines.push("## Tasks"); + lines.push(""); + for (const task of tasks) { + lines.push(`### ${task.id}: ${task.name}`); + lines.push(""); + lines.push(`- Depends on: ${Array.isArray(task.depends_on) && task.depends_on.length > 0 ? task.depends_on.join(", ") : "(none)"}`); + lines.push(""); + lines.push(task.description ?? ""); + lines.push(""); + if (Array.isArray(task.files) && task.files.length > 0) { + lines.push("Files:"); + lines.push(formatBulletList(task.files)); + lines.push(""); + } + if (Array.isArray(task.verification) && task.verification.length > 0) { + lines.push("Verification:"); + lines.push(formatBulletList(task.verification)); + lines.push(""); + } + } + + return `${lines.join("\n").trimEnd()}\n`; +} + +function statusMark(status) { + switch (String(status ?? "").trim()) { + case "completed": + return "[x]"; + case "in_progress": + return "[*]"; + case "blocked": + return "[!]"; + case "failed": + return "[~]"; + case "pending": + default: + return "[ ]"; + } +} + +export function planStateToMarkdown(plan, state, templatePhases) { + const planTasks = Array.isArray(plan?.tasks) ? plan.tasks : []; + const stateTasks = Array.isArray(state?.tasks) ? state.tasks : []; + const stateById = new Map(stateTasks.map((t) => [t.id, t])); + const phases = Array.isArray(templatePhases) ? templatePhases : []; + + const lines = []; + lines.push(`# Plan: ${plan?.id ?? ""}`); + lines.push(""); + lines.push(`## Goal`); + lines.push(""); + lines.push(String(plan?.goal ?? "")); + lines.push(""); + lines.push("## Execution State"); + lines.push(""); + lines.push(`- Iteration: ${String(state?.iteration ?? 0)}`); + lines.push(`- Summary: ${String(state?.summary ?? "").trim()}`); + lines.push(""); + lines.push("## Tasks"); + lines.push(""); + + for (const task of planTasks) { + const st = stateById.get(task.id) ?? { status: "pending", notes: "", phases: [] }; + lines.push(`### ${statusMark(st.status)} ${task.id}: ${task.name}`); + lines.push(""); + const notes = String(st.notes ?? "").trim(); + if (notes) { + lines.push("Notes:"); + lines.push(formatBulletList(notes.split("\n").map((l) => l.trim()).filter(Boolean))); + lines.push(""); + } + + const stPhases = Array.isArray(st.phases) ? st.phases : []; + const phaseById = new Map(stPhases.map((p) => [p.id, p])); + if (phases.length > 0) { + lines.push("Phases:"); + for (const phase of phases) { + const p = phaseById.get(phase.id) ?? { status: "pending", notes: "" }; + const title = phase.title ?? phase.id; + lines.push(`- ${statusMark(p.status)} ${phase.id}: ${title}`); + } + lines.push(""); + } + } + + return `${lines.join("\n").trimEnd()}\n`; +} diff --git a/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/plan.mjs b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/plan.mjs new file mode 100644 index 0000000000..8749d86157 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/plan.mjs @@ -0,0 +1,408 @@ +function isPlainObject(value) { + return Boolean(value) && typeof value === "object" && !Array.isArray(value); +} + +function pushError(errors, path, message) { + errors.push(`${path}: ${message}`); +} + +function expectNoExtraKeys(errors, obj, allowedKeys, path) { + if (!isPlainObject(obj)) { + return; + } + for (const key of Object.keys(obj)) { + if (!allowedKeys.includes(key)) { + pushError(errors, path, `Unexpected property: ${key}`); + } + } +} + +function expectString(errors, value, path, { minLength, maxLength, pattern } = {}) { + if (typeof value !== "string") { + pushError(errors, path, "Expected string"); + return; + } + if (minLength != null && value.length < minLength) { + pushError(errors, path, `Too short (minLength ${minLength})`); + } + if (maxLength != null && value.length > maxLength) { + pushError(errors, path, `Too long (maxLength ${maxLength})`); + } + if (pattern && !pattern.test(value)) { + pushError(errors, path, `Does not match pattern ${pattern}`); + } +} + +function expectArray(errors, value, path, { minItems } = {}) { + if (!Array.isArray(value)) { + pushError(errors, path, "Expected array"); + return; + } + if (minItems != null && value.length < minItems) { + pushError(errors, path, `Too few items (minItems ${minItems})`); + } +} + +function expectArrayOfStrings(errors, value, path, { minItems } = {}) { + expectArray(errors, value, path, { minItems }); + if (!Array.isArray(value)) { + return; + } + for (let i = 0; i < value.length; i++) { + if (typeof value[i] !== "string") { + pushError(errors, `${path}[${i}]`, "Expected string"); + } + } +} + +const PLAN_ID_RE = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/; +const TASK_ID_RE = /^task-[0-9]+$/; +const NOTES_TRUNCATED_SUFFIX = " ... [truncated]"; + +export const STATE_SUMMARY_MAX_LENGTH = 300; +export const TASK_NOTES_MAX_LENGTH = 2000; +export const PHASE_NOTES_MAX_LENGTH = 800; + +function truncateNotes(value, maxLength) { + if (typeof value !== "string" || value.length <= maxLength) { + return [value, false]; + } + const suffix = maxLength > NOTES_TRUNCATED_SUFFIX.length ? NOTES_TRUNCATED_SUFFIX : ""; + const sliceLength = Math.max(maxLength - suffix.length, 0); + const truncated = `${value.slice(0, sliceLength)}${suffix}`; + return [truncated, true]; +} + +function parseTaskNumber(taskId) { + const match = /^task-([0-9]+)$/.exec(taskId); + if (!match) { + return null; + } + const value = Number(match[1]); + if (!Number.isInteger(value) || value < 1) { + return null; + } + return value; +} + +function validateDag(errors, tasksById) { + const visiting = new Set(); + const visited = new Set(); + + function dfs(id) { + if (visited.has(id)) { + return; + } + if (visiting.has(id)) { + pushError(errors, "tasks", `Cycle detected at ${id}`); + return; + } + visiting.add(id); + const task = tasksById.get(id); + const deps = Array.isArray(task?.depends_on) ? task.depends_on : []; + for (const dep of deps) { + if (tasksById.has(dep)) { + dfs(dep); + } + } + visiting.delete(id); + visited.add(id); + } + + for (const id of tasksById.keys()) { + dfs(id); + } +} + +export function validatePlan(plan) { + const errors = []; + + if (!isPlainObject(plan)) { + pushError(errors, "plan", "Expected object"); + throw new Error(errors.join("\n")); + } + + expectNoExtraKeys( + errors, + plan, + ["$schema", "id", "title", "goal", "context", "tasks"], + "plan", + ); + if (plan.$schema !== "plan-v1") { + pushError(errors, "plan.$schema", 'Expected "plan-v1"'); + } + expectString(errors, plan.id, "plan.id", { + maxLength: 64, + pattern: PLAN_ID_RE, + }); + if (plan.title != null) { + expectString(errors, plan.title, "plan.title", { minLength: 3, maxLength: 80 }); + } + expectString(errors, plan.goal, "plan.goal", { minLength: 10, maxLength: 500 }); + + if (!isPlainObject(plan.context)) { + pushError(errors, "plan.context", "Expected object"); + } else { + expectNoExtraKeys(errors, plan.context, ["tech_stack", "constraints", "references"], "plan.context"); + expectArrayOfStrings(errors, plan.context.tech_stack, "plan.context.tech_stack", { minItems: 1 }); + expectArrayOfStrings(errors, plan.context.constraints, "plan.context.constraints"); + if (plan.context.references != null) { + expectArray(errors, plan.context.references, "plan.context.references"); + if (Array.isArray(plan.context.references)) { + for (let i = 0; i < plan.context.references.length; i++) { + const ref = plan.context.references[i]; + const refPath = `plan.context.references[${i}]`; + if (!isPlainObject(ref)) { + pushError(errors, refPath, "Expected object"); + continue; + } + expectNoExtraKeys(errors, ref, ["path", "description"], refPath); + expectString(errors, ref.path, `${refPath}.path`); + expectString(errors, ref.description, `${refPath}.description`); + } + } + } + } + + expectArray(errors, plan.tasks, "plan.tasks", { minItems: 1 }); + const tasksById = new Map(); + let hasEntryPoint = false; + + if (Array.isArray(plan.tasks)) { + for (let i = 0; i < plan.tasks.length; i++) { + const task = plan.tasks[i]; + const taskPath = `plan.tasks[${i}]`; + if (!isPlainObject(task)) { + pushError(errors, taskPath, "Expected object"); + continue; + } + expectNoExtraKeys( + errors, + task, + ["id", "name", "description", "depends_on", "files", "verification"], + taskPath, + ); + + expectString(errors, task.id, `${taskPath}.id`, { pattern: TASK_ID_RE }); + expectString(errors, task.name, `${taskPath}.name`, { maxLength: 80 }); + expectString(errors, task.description, `${taskPath}.description`, { minLength: 20 }); + expectArrayOfStrings(errors, task.depends_on, `${taskPath}.depends_on`); + expectArrayOfStrings(errors, task.files, `${taskPath}.files`, { minItems: 1 }); + expectArrayOfStrings(errors, task.verification, `${taskPath}.verification`, { minItems: 1 }); + + if (Array.isArray(task.depends_on) && task.depends_on.length === 0) { + hasEntryPoint = true; + } + + if (typeof task.id === "string") { + if (tasksById.has(task.id)) { + pushError(errors, `${taskPath}.id`, `Duplicate task id: ${task.id}`); + } else { + tasksById.set(task.id, task); + } + const taskNumber = parseTaskNumber(task.id); + const expectedId = `task-${i + 1}`; + if (taskNumber == null) { + pushError(errors, `${taskPath}.id`, "Task id must be task- with n >= 1"); + } else if (task.id !== expectedId) { + pushError(errors, `${taskPath}.id`, `Task ids must match array order (expected ${expectedId})`); + } + } + } + } + + if (!hasEntryPoint) { + pushError(errors, "plan.tasks", "At least one task must have depends_on: []"); + } + + // depends_on referential integrity + self-deps + for (const [id, task] of tasksById.entries()) { + const deps = Array.isArray(task.depends_on) ? task.depends_on : []; + for (const dep of deps) { + if (dep === id) { + pushError(errors, `task:${id}.depends_on`, "Task cannot depend on itself"); + } else if (!tasksById.has(dep)) { + pushError(errors, `task:${id}.depends_on`, `Unknown dependency: ${dep}`); + } + } + } + + validateDag(errors, tasksById); + + if (errors.length > 0) { + throw new Error(`plan.json is invalid:\n${errors.join("\n")}`); + } +} + +function validatePhaseList(errors, phases, path) { + expectArray(errors, phases, path, { minItems: 1 }); + if (!Array.isArray(phases)) { + return; + } + for (let i = 0; i < phases.length; i++) { + const phase = phases[i]; + const phasePath = `${path}[${i}]`; + if (!isPlainObject(phase)) { + pushError(errors, phasePath, "Expected object"); + continue; + } + expectNoExtraKeys( + errors, + phase, + ["id", "title", "order", "iconId", "goal", "description", "checks"], + phasePath, + ); + expectString(errors, phase.id, `${phasePath}.id`, { minLength: 1, maxLength: 64 }); + expectString(errors, phase.title, `${phasePath}.title`, { minLength: 1, maxLength: 80 }); + } +} + +export function buildInitialState(plan, templatePhases) { + const tasks = Array.isArray(plan?.tasks) ? plan.tasks : []; + const phases = Array.isArray(templatePhases) ? templatePhases : []; + return { + $schema: "state-v2", + plan_id: plan.id, + iteration: 0, + summary: "", + tasks: tasks.map((task) => ({ + id: task.id, + status: "pending", + attempts: 0, + notes: "", + commit_sha: null, + phases: phases.map((phase) => ({ + id: phase.id, + status: "pending", + attempts: 0, + notes: "", + })), + })), + }; +} + +export function normalizeStateNotes(state) { + let changed = false; + + if (!isPlainObject(state) || !Array.isArray(state.tasks)) { + return { state, changed }; + } + + for (const task of state.tasks) { + if (!isPlainObject(task)) { + continue; + } + const [taskNotes, taskChanged] = truncateNotes(task.notes, TASK_NOTES_MAX_LENGTH); + if (taskChanged) { + task.notes = taskNotes; + changed = true; + } + + if (!Array.isArray(task.phases)) { + continue; + } + for (const phase of task.phases) { + if (!isPlainObject(phase)) { + continue; + } + const [phaseNotes, phaseChanged] = truncateNotes(phase.notes, PHASE_NOTES_MAX_LENGTH); + if (phaseChanged) { + phase.notes = phaseNotes; + changed = true; + } + } + } + + return { state, changed }; +} + +export function validateStateAgainstPlan(state, plan, templatePhases) { + const errors = []; + + if (!isPlainObject(state)) { + pushError(errors, "state", "Expected object"); + return errors; + } + + expectNoExtraKeys(errors, state, ["$schema", "plan_id", "iteration", "summary", "tasks"], "state"); + if (state.$schema !== "state-v2") { + pushError(errors, "state.$schema", 'Expected "state-v2"'); + } + if (state.plan_id !== plan.id) { + pushError(errors, "state.plan_id", `Expected ${plan.id}`); + } + if (!Number.isInteger(state.iteration) || state.iteration < 0) { + pushError(errors, "state.iteration", "Expected integer >= 0"); + } + expectString(errors, state.summary, "state.summary", { maxLength: STATE_SUMMARY_MAX_LENGTH }); + + expectArray(errors, state.tasks, "state.tasks", { minItems: 1 }); + + const planTasks = Array.isArray(plan?.tasks) ? plan.tasks : []; + if (Array.isArray(state.tasks) && state.tasks.length !== planTasks.length) { + pushError(errors, "state.tasks", "Must match plan.tasks length"); + } + + const allowedStatus = new Set(["pending", "in_progress", "completed", "blocked", "failed"]); + validatePhaseList(errors, templatePhases, "templatePhases"); + const expectedPhaseIds = Array.isArray(templatePhases) + ? templatePhases.map((p) => String(p.id ?? "")).filter(Boolean) + : []; + + if (Array.isArray(state.tasks)) { + for (let i = 0; i < state.tasks.length; i++) { + const entry = state.tasks[i]; + const entryPath = `state.tasks[${i}]`; + if (!isPlainObject(entry)) { + pushError(errors, entryPath, "Expected object"); + continue; + } + expectNoExtraKeys(errors, entry, ["id", "status", "attempts", "notes", "commit_sha", "phases"], entryPath); + expectString(errors, entry.id, `${entryPath}.id`, { pattern: TASK_ID_RE }); + if (typeof entry.status !== "string" || !allowedStatus.has(entry.status)) { + pushError(errors, `${entryPath}.status`, "Invalid status"); + } + if (!Number.isInteger(entry.attempts) || entry.attempts < 0) { + pushError(errors, `${entryPath}.attempts`, "Expected integer >= 0"); + } + expectString(errors, entry.notes, `${entryPath}.notes`, { maxLength: TASK_NOTES_MAX_LENGTH }); + + if (entry.commit_sha != null && typeof entry.commit_sha !== "string") { + pushError(errors, `${entryPath}.commit_sha`, "Expected string or null"); + } + + if (planTasks[i]?.id && entry.id !== planTasks[i].id) { + pushError(errors, entryPath, `Task id mismatch at index ${i} (expected ${planTasks[i].id})`); + } + + expectArray(errors, entry.phases, `${entryPath}.phases`, { minItems: 1 }); + if (Array.isArray(entry.phases) && expectedPhaseIds.length > 0 && entry.phases.length !== expectedPhaseIds.length) { + pushError(errors, `${entryPath}.phases`, "Must match templatePhases length"); + } + if (Array.isArray(entry.phases)) { + for (let j = 0; j < entry.phases.length; j++) { + const phase = entry.phases[j]; + const phasePath = `${entryPath}.phases[${j}]`; + if (!isPlainObject(phase)) { + pushError(errors, phasePath, "Expected object"); + continue; + } + expectNoExtraKeys(errors, phase, ["id", "status", "attempts", "notes"], phasePath); + expectString(errors, phase.id, `${phasePath}.id`, { minLength: 1, maxLength: 64 }); + if (expectedPhaseIds[j] && phase.id !== expectedPhaseIds[j]) { + pushError(errors, `${phasePath}.id`, `Phase id mismatch at index ${j} (expected ${expectedPhaseIds[j]})`); + } + if (typeof phase.status !== "string" || !allowedStatus.has(phase.status)) { + pushError(errors, `${phasePath}.status`, "Invalid status"); + } + if (!Number.isInteger(phase.attempts) || phase.attempts < 0) { + pushError(errors, `${phasePath}.attempts`, "Expected integer >= 0"); + } + expectString(errors, phase.notes, `${phasePath}.notes`, { maxLength: PHASE_NOTES_MAX_LENGTH }); + } + } + } + } + + return errors; +} diff --git a/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/render.mjs b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/render.mjs new file mode 100644 index 0000000000..477583fff6 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/render.mjs @@ -0,0 +1,22 @@ +function escapeRegExp(text) { + return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + +export function renderTemplate(templateText, values) { + let output = templateText; + for (const [key, rawValue] of Object.entries(values)) { + const value = rawValue == null ? "" : String(rawValue); + const pattern = new RegExp(`\\{\\{${escapeRegExp(key)}\\}\\}`, "g"); + output = output.replace(pattern, value); + } + return output; +} + +export function formatBulletList(items) { + const list = Array.isArray(items) ? items : []; + if (list.length === 0) { + return ""; + } + return list.map((item) => `- ${item}`).join("\n"); +} + diff --git a/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/state.mjs b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/state.mjs new file mode 100644 index 0000000000..8e68063045 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/scripts/lib/state.mjs @@ -0,0 +1,27 @@ +import fs from "node:fs/promises"; +import path from "node:path"; + +export async function readJsonFile(filePath) { + const raw = await fs.readFile(filePath, "utf8"); + try { + return JSON.parse(raw); + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + throw new Error(`Invalid JSON: ${filePath} (${message})`); + } +} + +export async function writeJsonFile(filePath, value) { + await fs.mkdir(path.dirname(filePath), { recursive: true }); + await fs.writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8"); +} + +export async function ensureFileExists(filePath, initialContent = "") { + try { + await fs.access(filePath); + } catch { + await fs.mkdir(path.dirname(filePath), { recursive: true }); + await fs.writeFile(filePath, initialContent, "utf8"); + } +} + diff --git a/src-tauri/resources/forge/templates/test-first-loop/scripts/post-plan.mjs b/src-tauri/resources/forge/templates/test-first-loop/scripts/post-plan.mjs new file mode 100644 index 0000000000..9becd81953 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/scripts/post-plan.mjs @@ -0,0 +1,57 @@ +import fs from "node:fs/promises"; +import path from "node:path"; + +import { requireFlagValue } from "./lib/args.mjs"; +import { readContext } from "./lib/context.mjs"; +import { renderExecutePrompt } from "./lib/execute.mjs"; +import { planStateToMarkdown } from "./lib/markdown.mjs"; +import { buildInitialState, validatePlan } from "./lib/plan.mjs"; +import { ensureFileExists, readJsonFile, writeJsonFile } from "./lib/state.mjs"; + +async function main() { + const contextPath = requireFlagValue(process.argv.slice(2), "context"); + const ctx = await readContext(contextPath); + + const plan = await readJsonFile(ctx.planPath); + validatePlan(plan); + + const phases = await readJsonFile(path.join(ctx.templateRoot, "phases.json")); + const templatePhases = Array.isArray(phases?.phases) ? phases.phases : []; + + // Initialize plans//state.json + const state = buildInitialState(plan, templatePhases); + await writeJsonFile(ctx.statePath, state); + + // Write plans//plan.md (derived, includes state) + await fs.mkdir(path.dirname(ctx.generatedPlanMdPath), { recursive: true }); + await fs.writeFile( + ctx.generatedPlanMdPath, + planStateToMarkdown(plan, state, templatePhases), + "utf8", + ); + + // Ensure plans//progress.md exists. + await ensureFileExists(ctx.progressPath, ""); + + // Render initial execute prompt for the first runnable task. + const templateText = await fs.readFile( + path.join(ctx.templateRoot, "prompts", "execute.md"), + "utf8", + ); + const progressNotes = await fs.readFile(ctx.progressPath, "utf8").catch(() => ""); + const prompt = renderExecutePrompt({ + templateText, + plan, + state, + templatePhases, + progressNotes, + todayIso: ctx.todayIso, + }); + await fs.mkdir(path.dirname(ctx.generatedExecutePromptPath), { recursive: true }); + await fs.writeFile(ctx.generatedExecutePromptPath, prompt, "utf8"); +} + +main().catch((err) => { + console.error(err instanceof Error ? err.message : String(err)); + process.exit(1); +}); diff --git a/src-tauri/resources/forge/templates/test-first-loop/scripts/post-step.mjs b/src-tauri/resources/forge/templates/test-first-loop/scripts/post-step.mjs new file mode 100644 index 0000000000..157a27a371 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/scripts/post-step.mjs @@ -0,0 +1,60 @@ +import fs from "node:fs/promises"; +import path from "node:path"; + +import { requireFlagValue } from "./lib/args.mjs"; +import { readContext } from "./lib/context.mjs"; +import { renderExecutePrompt } from "./lib/execute.mjs"; +import { planStateToMarkdown } from "./lib/markdown.mjs"; +import { normalizeStateNotes, validatePlan, validateStateAgainstPlan } from "./lib/plan.mjs"; +import { readJsonFile, writeJsonFile } from "./lib/state.mjs"; + +async function main() { + const contextPath = requireFlagValue(process.argv.slice(2), "context"); + const ctx = await readContext(contextPath); + + const plan = await readJsonFile(ctx.planPath); + validatePlan(plan); + + const phases = await readJsonFile(path.join(ctx.templateRoot, "phases.json")); + const templatePhases = Array.isArray(phases?.phases) ? phases.phases : []; + + const rawState = await readJsonFile(ctx.statePath); + const { state, changed: notesWereTruncated } = normalizeStateNotes(rawState); + if (notesWereTruncated) { + await writeJsonFile(ctx.statePath, state); + } + const stateErrors = validateStateAgainstPlan(state, plan, templatePhases); + if (stateErrors.length > 0) { + throw new Error(`state.json is invalid:\n${stateErrors.join("\n")}`); + } + + await fs.mkdir(path.dirname(ctx.generatedPlanMdPath), { recursive: true }); + await fs.writeFile( + ctx.generatedPlanMdPath, + planStateToMarkdown(plan, state, templatePhases), + "utf8", + ); + + const templateText = await fs.readFile( + path.join(ctx.templateRoot, "prompts", "execute.md"), + "utf8", + ); + const progressNotes = await fs.readFile(ctx.progressPath, "utf8").catch(() => ""); + + const prompt = renderExecutePrompt({ + templateText, + plan, + state, + templatePhases, + progressNotes, + todayIso: ctx.todayIso, + }); + + await fs.mkdir(path.dirname(ctx.generatedExecutePromptPath), { recursive: true }); + await fs.writeFile(ctx.generatedExecutePromptPath, prompt, "utf8"); +} + +main().catch((err) => { + console.error(err instanceof Error ? err.message : String(err)); + process.exit(1); +}); diff --git a/src-tauri/resources/forge/templates/test-first-loop/scripts/pre-execute.mjs b/src-tauri/resources/forge/templates/test-first-loop/scripts/pre-execute.mjs new file mode 100644 index 0000000000..249997e760 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/scripts/pre-execute.mjs @@ -0,0 +1,51 @@ +import fs from "node:fs/promises"; +import path from "node:path"; + +import { requireFlagValue } from "./lib/args.mjs"; +import { readContext } from "./lib/context.mjs"; +import { readJsonFile } from "./lib/state.mjs"; + +async function fileExists(filePath) { + try { + const stat = await fs.stat(filePath); + return stat.isFile(); + } catch { + return false; + } +} + +async function main() { + const contextPath = requireFlagValue(process.argv.slice(2), "context"); + const ctx = await readContext(contextPath); + + // Validate template completeness (manifest-driven). + const manifestPath = path.join(ctx.templateRoot, "template.json"); + const manifest = await readJsonFile(manifestPath); + const files = Array.isArray(manifest?.files) ? manifest.files : []; + for (const rel of files) { + const abs = path.join(ctx.templateRoot, rel); + if (!(await fileExists(abs))) { + throw new Error(`Template file missing: ${rel}`); + } + } + + // Validate required skill is installed into the workspace. + const skillPath = path.join(ctx.workspaceRoot, ".agent", "skills", "plan", "SKILL.md"); + if (!(await fileExists(skillPath))) { + throw new Error(`Missing required workspace skill: ${skillPath}`); + } + + // Validate that plan + state exist. + if (!(await fileExists(ctx.planPath))) { + throw new Error(`Missing plan.json: ${ctx.planPath}`); + } + if (!(await fileExists(ctx.statePath))) { + throw new Error(`Missing state.json: ${ctx.statePath}`); + } +} + +main().catch((err) => { + console.error(err instanceof Error ? err.message : String(err)); + process.exit(1); +}); + diff --git a/src-tauri/resources/forge/templates/test-first-loop/skills/plan/SKILL.md b/src-tauri/resources/forge/templates/test-first-loop/skills/plan/SKILL.md new file mode 100644 index 0000000000..bbc395ff57 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/skills/plan/SKILL.md @@ -0,0 +1,102 @@ +--- +name: plan +description: | + How to create structured development plans for agentic coding orchestrators. + Use this skill whenever asked to create a plan, break down a feature, generate + a task list, or prepare work for an AI agent loop. Triggers: "plan this", + "break this down", "create tasks for", or any reference to spec-driven + development, ralph loop, or agentic task execution. +--- + +# @plan -- Create a Development Plan + +Generate a structured `plan.json` that an orchestrator will feed to stateless +LLM iterations, one task at a time. + +## What you produce + +This skill supports two outputs depending on collaboration mode: + +- In **Plan** collaboration mode: output the plan as the exact `plan-v1` JSON object inside a single `...` block. Do not write files. +- In **Default** (or any non-Plan) mode: write the plan file to `plans//plan.json` (create the folder if needed). + +The orchestrator initializes state/progress files programmatically. + +## Read the schema first + +Before generating anything, read: +- `references/plan-schema.md` -- Full plan.json JSON Schema + complete example + +## plan.json structure (summary) + +```json +{ + "$schema": "plan-v1", + "id": "", + "title": "Short UI title (<= 60 chars)", + "goal": "One sentence - the desired end state", + "context": { + "tech_stack": ["Node.js", "Express"], + "constraints": ["Must use existing schema in db/schema.sql"], + "references": [{ "path": "db/schema.sql", "description": "Existing DB schema" }] + }, + "tasks": [ + { + "id": "task-1", + "name": "Project setup", + "description": "Detailed implementation instructions...", + "depends_on": [], + "files": ["src/index.ts"], + "verification": ["GET /health returns 200"] + } + ] +} +``` + +## Key rules + +### IDs +- Task IDs: `task-{n}` -- e.g. `task-1`, `task-2`, ... +- Plan ID: URL-safe slug -- e.g. `auth-system`, `notification-service` + +### Title +- Add a short, friendly `title` for UI/menus (aim for <= 60 chars). +- Keep `goal` longer and more descriptive (the desired end state). + +### Tasks +- Each completable in one LLM iteration (~5-30 min agent work) +- Too big: >5 files, >200 lines new code, mixes unrelated concerns +- Too small: single line change, no meaningful verification + +### Dependencies +- `depends_on` lists direct dependencies only (task IDs) +- At least one task with `"depends_on": []` (entry point) +- No circular dependencies +- Minimize chain length -- long chains serialize execution + +### Descriptions -- be extremely specific + +Bad: +``` +"Add authentication to the API" +``` + +Good: +``` +"Implement POST /auth/login accepting { email, password }. Validate against users +table using bcrypt.compare(). On success, return { accessToken, refreshToken } as +httpOnly cookies. Access token: JWT with { userId, email } payload, 15min expiry, +signed with ACCESS_TOKEN_SECRET. On failure, return 401." +``` + +### Verification -- concrete, testable assertions + +Bad: `"Auth works correctly"` +Good: `"POST /auth/login with valid credentials returns 200 with Set-Cookie headers"` + +### Constraints -- include what NOT to build + +Good constraints: +- "Do NOT add a frontend -- API only" +- "Do NOT modify existing tables, extend only" +- "Max 3 external dependencies" diff --git a/src-tauri/resources/forge/templates/test-first-loop/skills/plan/references/plan-schema.md b/src-tauri/resources/forge/templates/test-first-loop/skills/plan/references/plan-schema.md new file mode 100644 index 0000000000..970ede8856 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/skills/plan/references/plan-schema.md @@ -0,0 +1,282 @@ +# Plan Schema Reference + +Full JSON Schema for `plan.json` files. Read this before generating a plan. + +## Complete JSON Schema + +```json +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Plan", + "description": "A structured development plan for agentic coding orchestrators", + "type": "object", + "required": ["$schema", "id", "goal", "context", "tasks"], + "additionalProperties": false, + "properties": { + "$schema": { + "type": "string", + "const": "plan-v1", + "description": "Schema version identifier" + }, + "id": { + "type": "string", + "pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$", + "maxLength": 64, + "description": "URL-safe slug identifying this plan" + }, + "title": { + "type": "string", + "minLength": 3, + "maxLength": 80, + "description": "Short friendly label for UI/menus (keep under ~60 chars)" + }, + "goal": { + "type": "string", + "minLength": 10, + "maxLength": 500, + "description": "One sentence describing the desired end state" + }, + "context": { + "type": "object", + "required": ["tech_stack", "constraints"], + "additionalProperties": false, + "properties": { + "tech_stack": { + "type": "array", + "items": { "type": "string" }, + "minItems": 1, + "description": "Technologies to use" + }, + "constraints": { + "type": "array", + "items": { "type": "string" }, + "description": "Hard rules and boundaries" + }, + "references": { + "type": "array", + "items": { + "type": "object", + "required": ["path", "description"], + "additionalProperties": false, + "properties": { + "path": { "type": "string" }, + "description": { "type": "string" } + } + }, + "description": "Files the LLM should read for context" + } + } + }, + "tasks": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["id", "name", "description", "depends_on", "files", "verification"], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "pattern": "^task-[0-9]+$", + "description": "Format: task-{sequence}" + }, + "name": { + "type": "string", + "maxLength": 80, + "description": "Short display name for UI" + }, + "description": { + "type": "string", + "minLength": 20, + "description": "Detailed implementation instructions" + }, + "depends_on": { + "type": "array", + "items": { + "type": "string", + "pattern": "^task-[0-9]+$" + }, + "description": "Task IDs that must complete before this task can start" + }, + "files": { + "type": "array", + "items": { "type": "string" }, + "minItems": 1, + "description": "File paths this task will create or modify" + }, + "verification": { + "type": "array", + "items": { "type": "string" }, + "minItems": 1, + "description": "Concrete, testable assertions for completion" + } + } + } + } + } +} +``` + +## Validation rules (beyond JSON Schema) + +The orchestrator should enforce these rules programmatically after the LLM generates a plan: + +### Referential integrity +- Every entry in `depends_on` must match an existing task `id` +- No task can depend on itself + +### Dependency graph +- The dependency graph must be a DAG (no cycles) +- At least one task must have `"depends_on": []` (an entry point) + +### ID consistency +- Task IDs must use the format `task-{sequence}` +- Task IDs must be sequential starting at 1 with no gaps: `task-1`, `task-2`, ..., `task-n` +- Task IDs must match the array order: `plan.tasks[0].id` is `task-1`, etc. + +### Content quality checks +- `description` should contain concrete specifics (endpoint paths, field names, config values) +- `verification` items should be testable (contain expected status codes, return values, observable behaviors) +- `files` should not be empty - every task must touch at least one file + +## Complete example + +```json +{ + "$schema": "plan-v1", + "id": "task-api", + "title": "Tasks API", + "goal": "A REST API with JWT auth, task CRUD with pagination, and WebSocket notifications, fully tested with OpenAPI docs", + "context": { + "tech_stack": ["Node.js", "TypeScript", "Express", "PostgreSQL", "Socket.io", "JWT"], + "constraints": [ + "Must use existing PostgreSQL schema in db/schema.sql", + "Auth must support email/password and OAuth2 Google login", + "All endpoints must have OpenAPI documentation", + "Minimum 80% test coverage on business logic", + "Do NOT add a frontend - API only" + ], + "references": [ + { "path": "db/schema.sql", "description": "Existing database schema - do not modify, extend only" }, + { "path": "src/middleware/auth.ts", "description": "Existing auth middleware skeleton to build upon" }, + { "path": "docs/api-contract.md", "description": "Agreed API contract with frontend team" } + ] + }, + "tasks": [ + { + "id": "task-1", + "name": "Project setup and database connection", + "description": "Initialize Express+TypeScript app with tsconfig (strict mode). Configure dotenv for DATABASE_URL, PORT, ACCESS_TOKEN_SECRET, REFRESH_TOKEN_SECRET env vars. Set up PostgreSQL connection pool using pg library with max 20 connections. Create GET /health endpoint returning { status: 'ok', db: boolean } where db reflects a successful SELECT 1 query.", + "depends_on": [], + "files": ["src/index.ts", "src/db.ts", "src/routes/health.ts", "tsconfig.json", ".env.example"], + "verification": [ + "npm run build compiles without errors", + "GET /health returns 200 with { status: 'ok', db: true } when DB is connected", + "GET /health returns 200 with { status: 'ok', db: false } when DB is unreachable", + "App reads PORT from environment variable, defaults to 3000" + ] + }, + { + "id": "task-2", + "name": "Error handling middleware", + "description": "Create centralized error handling middleware. Define AppError class extending Error with statusCode and isOperational fields. Global error handler catches all errors, logs stack traces for 5xx, returns { error: string, code: string } to client. Add request ID middleware using uuid v4, attach to req and include in error responses.", + "depends_on": ["task-1"], + "files": ["src/middleware/error-handler.ts", "src/errors/app-error.ts", "src/middleware/request-id.ts"], + "verification": [ + "Throwing AppError(404, 'Not found') returns { error: 'Not found', code: 'NOT_FOUND', requestId: '...' }", + "Unhandled errors return 500 with generic message (no stack leak)", + "Every response includes x-request-id header" + ] + }, + { + "id": "task-3", + "name": "JWT authentication endpoints", + "description": "Implement POST /auth/register accepting { email, password, name }. Validate email format and password length >= 8. Hash password with bcrypt cost 12. Store in users table. Return { accessToken, refreshToken } as httpOnly cookies. Implement POST /auth/login with same response format. Access tokens: JWT with { userId, email } payload, 15min expiry signed with ACCESS_TOKEN_SECRET. Refresh tokens: opaque UUID stored in refresh_tokens table, 7-day expiry. POST /auth/refresh rotates refresh token (invalidate old, issue new pair). Rate limit login: 5 attempts per email per 15 minutes.", + "depends_on": ["task-1", "task-2"], + "files": ["src/routes/auth.ts", "src/services/auth.service.ts", "src/types/auth.ts"], + "verification": [ + "POST /auth/register with valid data returns 201 with Set-Cookie headers", + "POST /auth/register with duplicate email returns 409", + "POST /auth/register with password < 8 chars returns 400", + "POST /auth/login with valid credentials returns 200 with tokens", + "POST /auth/login with wrong password returns 401", + "POST /auth/refresh with valid refresh token returns new token pair", + "POST /auth/refresh invalidates the old refresh token", + "6th login attempt for same email within 15 minutes returns 429" + ] + }, + { + "id": "task-4", + "name": "Google OAuth2 integration", + "description": "Add Google OAuth2 using passport-google-oauth20. Configure with GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET env vars. GET /auth/google redirects to Google consent screen requesting email and profile scopes. GET /auth/google/callback handles the response: if a user with matching email exists, link the Google ID to their account; if not, create a new user. Return same token format as /auth/login. Store google_id in users table (nullable column).", + "depends_on": ["task-3"], + "files": ["src/routes/auth-google.ts", "src/services/oauth.service.ts", "src/config/passport.ts"], + "verification": [ + "GET /auth/google returns 302 redirect to accounts.google.com", + "Callback with new Google user creates user record and returns tokens", + "Callback with existing email links Google ID without creating duplicate", + "GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in .env.example" + ] + }, + { + "id": "task-5", + "name": "Task CRUD endpoints", + "description": "Implement authenticated CRUD for /tasks. POST /tasks creates a task with { title, description, status, assigneeId }. GET /tasks returns paginated list (default 20 per page) with ?page, ?status, ?assignee query filters, sorted by createdAt desc. GET /tasks/:id returns single task. PUT /tasks/:id updates task fields. DELETE /tasks/:id soft-deletes (sets deletedAt). All routes require valid access token via auth middleware. Users can only see/modify tasks they created or are assigned to.", + "depends_on": ["task-3"], + "files": ["src/routes/tasks.ts", "src/services/task.service.ts", "src/types/task.ts"], + "verification": [ + "POST /tasks without auth returns 401", + "POST /tasks with auth creates task and returns 201", + "GET /tasks returns paginated array with total count in response", + "GET /tasks?status=done filters by status", + "GET /tasks?page=2 returns second page", + "PUT /tasks/:id updates fields and returns 200", + "DELETE /tasks/:id sets deletedAt, subsequent GET returns 404", + "User A cannot GET/PUT/DELETE tasks owned by User B" + ] + }, + { + "id": "task-6", + "name": "WebSocket notifications", + "description": "Set up Socket.io server attached to the Express http server. Authenticate WebSocket connections by extracting JWT from the handshake auth header. On task.created, task.updated, and task.assigned events, broadcast to relevant users (creator and assignee). Event payload: { type, taskId, taskTitle, actorId, timestamp }. Store notification in notifications table with userId, type, payload, readAt (nullable). Add GET /notifications for authenticated user with ?unread=true filter.", + "depends_on": ["task-5"], + "files": ["src/websocket/server.ts", "src/websocket/handlers.ts", "src/services/notification.service.ts", "src/routes/notifications.ts"], + "verification": [ + "WebSocket connection without valid JWT is rejected", + "Creating a task emits task.created to the creator's socket", + "Assigning a task emits task.assigned to the assignee's socket", + "Notifications are persisted in the notifications table", + "GET /notifications returns user's notifications", + "GET /notifications?unread=true filters to readAt IS NULL" + ] + }, + { + "id": "task-7", + "name": "Integration tests", + "description": "Write Jest integration tests using supertest. Set up test database with docker-compose.test.yml running PostgreSQL. Before each test suite: run migrations, seed test data. After each suite: truncate all tables. Cover: full auth flow (register -> login -> refresh -> access protected route), task CRUD with auth, pagination edge cases (empty results, last page), WebSocket connection and event delivery. Aim for 80%+ coverage on src/services/ and src/routes/.", + "depends_on": ["task-4", "task-6"], + "files": ["tests/auth.test.ts", "tests/tasks.test.ts", "tests/notifications.test.ts", "tests/setup.ts", "docker-compose.test.yml", "jest.config.ts"], + "verification": [ + "npm test runs all tests and exits 0", + "Auth tests cover register, login, refresh, and token expiry", + "Task tests cover CRUD, pagination, filtering, and authorization", + "Coverage report shows >= 80% on src/services/ and src/routes/" + ] + }, + { + "id": "task-8", + "name": "OpenAPI documentation", + "description": "Add swagger-jsdoc and swagger-ui-express. Write JSDoc annotations on all route handlers with @openapi tags. Include request/response schemas, auth requirements (bearerAuth), error responses, and query parameter descriptions. Serve Swagger UI at GET /docs. Generate openapi.json at build time via a script in package.json.", + "depends_on": ["task-6"], + "files": ["src/config/swagger.ts", "src/routes/*.ts", "scripts/generate-openapi.ts"], + "verification": [ + "GET /docs serves Swagger UI page", + "Every endpoint appears in the documentation", + "npm run generate:openapi produces a valid openapi.json", + "Auth endpoints show request/response body schemas", + "Protected endpoints show bearerAuth requirement" + ] + } + ] +} +``` diff --git a/src-tauri/resources/forge/templates/test-first-loop/template.json b/src-tauri/resources/forge/templates/test-first-loop/template.json new file mode 100644 index 0000000000..650cb182d2 --- /dev/null +++ b/src-tauri/resources/forge/templates/test-first-loop/template.json @@ -0,0 +1,39 @@ +{ + "schema": "forge-template-v1", + "id": "test-first-loop", + "title": "Test-First Loop", + "version": "0.1.0", + "files": [ + "template.json", + "phases.json", + "prompts/plan.md", + "prompts/execute.md", + "skills/plan/SKILL.md", + "skills/plan/references/plan-schema.md", + "schemas/plan.schema.json", + "schemas/state.schema.json", + "scripts/post-plan.mjs", + "scripts/pre-execute.mjs", + "scripts/post-step.mjs", + "scripts/lib/args.mjs", + "scripts/lib/context.mjs", + "scripts/lib/execute.mjs", + "scripts/lib/markdown.mjs", + "scripts/lib/plan.mjs", + "scripts/lib/render.mjs", + "scripts/lib/state.mjs" + ], + "entrypoints": { + "phases": "phases.json", + "planPrompt": "prompts/plan.md", + "executePrompt": "prompts/execute.md", + "planSchema": "schemas/plan.schema.json", + "stateSchema": "schemas/state.schema.json", + "requiredSkills": ["plan"], + "hooks": { + "postPlan": "scripts/post-plan.mjs", + "preExecute": "scripts/pre-execute.mjs", + "postStep": "scripts/post-step.mjs" + } + } +} From d294a87ae16f9d390ee4a9dbcdf05a0a3b0187e3 Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Thu, 12 Feb 2026 11:17:12 +0800 Subject: [PATCH 02/14] forge(forge-test-first-loop-template): task-2 Define 6-phase workflow, completion criteria, and AI review gate --- .../templates/test-first-loop/phases.json | 53 +++++++++++++++++-- .../test-first-loop/prompts/execute.md | 16 ++++-- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src-tauri/resources/forge/templates/test-first-loop/phases.json b/src-tauri/resources/forge/templates/test-first-loop/phases.json index dfc6606a1b..b380669493 100644 --- a/src-tauri/resources/forge/templates/test-first-loop/phases.json +++ b/src-tauri/resources/forge/templates/test-first-loop/phases.json @@ -1,13 +1,58 @@ { "schema": "forge-phases-v1", "phases": [ + { + "id": "test-case-mapping", + "title": "Test Case Mapping", + "iconId": "taskfile", + "order": 1, + "goal": "Translate requirements into a concrete, risk-prioritized test map before writing implementation code.", + "description": "Create an explicit test inventory that maps each acceptance criterion and risk to planned automated coverage. Completion checks: (1) every requirement is mapped to at least one planned test, (2) edge cases and failure paths are called out, (3) high-risk behaviors are prioritized first, and (4) assumptions and unresolved questions are documented.", + "checks": [] + }, + { + "id": "behavioral-tests", + "title": "Behavioral Tests", + "iconId": "cucumber", + "order": 2, + "goal": "Implement behavioral tests that codify intended external behavior before core implementation changes.", + "description": "Add or update behavior-focused tests (for example integration/BDD/contract style) that fail for the right reasons before implementation and pass only when behavior is correct. Completion checks: (1) new behavior is covered by executable tests, (2) tests fail before implementation changes and pass afterward, (3) assertions verify outcomes rather than internals, and (4) flaky or nondeterministic cases are removed or stabilized.", + "checks": [] + }, { "id": "implementation", "title": "Implementation", - "iconId": "code_blocks", - "order": 1, - "goal": "Implement the task changes and record progress in state.json.", - "description": "Complete the task in one commit. If checks fail after committing, fix issues and amend the same commit until checks pass.", + "iconId": "console", + "order": 3, + "goal": "Implement the minimum production changes needed to satisfy mapped requirements and behavioral tests.", + "description": "Apply focused code changes that satisfy tests without broad refactors unless required for correctness. Completion checks: (1) all phase-targeted tests pass locally, (2) changes are limited to necessary scope, (3) state/progress notes capture key decisions, and (4) no known regressions are introduced.", + "checks": [] + }, + { + "id": "coverage-hardening", + "title": "Coverage Hardening", + "iconId": "codecov", + "order": 4, + "goal": "Raise confidence by hardening regression coverage and closing high-risk testing gaps.", + "description": "Expand regression tests and quality checks until coverage and risk goals are met. Completion checks: (1) measured coverage is at least 80%, (2) uncovered high-risk behaviors are identified explicitly, (3) property-based tests are added for remaining high-risk gaps, and (4) resulting test evidence is documented in task notes.", + "checks": [] + }, + { + "id": "documentation", + "title": "Documentation", + "iconId": "readme", + "order": 5, + "goal": "Update operator-facing and developer-facing documentation to reflect the delivered behavior.", + "description": "Revise docs, runbooks, and inline guidance so future work uses current live behavior. Completion checks: (1) changed behavior is documented in canonical docs, (2) setup/run/validation instructions are current, (3) removed or obsolete guidance is deleted, and (4) documentation paths are referenced in notes.", + "checks": [] + }, + { + "id": "ai-review", + "title": "AI Review Gate", + "iconId": "folder-review", + "order": 6, + "goal": "Run an AI quality review pass and enforce a strict zero-findings completion gate.", + "description": "Execute an AI review over the final change set and treat any finding as a release blocker for this phase. Completion checks: (1) AI review is run against the final diff, (2) all findings are resolved and rechecked, and (3) the phase is marked completed only with zero findings. If any finding remains, phase status must stay non-completed (`failed` or `blocked`) and execution must stop until fixes are applied and the review is rerun clean.", "checks": [] } ] diff --git a/src-tauri/resources/forge/templates/test-first-loop/prompts/execute.md b/src-tauri/resources/forge/templates/test-first-loop/prompts/execute.md index 91e36e2f7a..13806a6406 100644 --- a/src-tauri/resources/forge/templates/test-first-loop/prompts/execute.md +++ b/src-tauri/resources/forge/templates/test-first-loop/prompts/execute.md @@ -44,6 +44,10 @@ between tasks - everything you need is below. {{current_phase_description}} +Treat the phase description above as the required completion checklist for this phase. +Before handoff, explicitly verify each completion check in your notes. +If any completion check is unmet, do not mark the phase `completed`; use `in_progress`, `blocked`, or `failed` as appropriate. + **Files:** {{current_task_files}} **Verification:** @@ -60,19 +64,21 @@ between tasks - everything you need is below. ## Phase protocol (important) 1. Implement the current phase for the current task. -2. Update `plans/{{plan_id}}/state.json`: - - Set this phase `status` to `completed` (or `blocked`/`failed` if truly stuck). +2. Verify all completion checks in the current phase description are satisfied before setting phase status. +3. Update `plans/{{plan_id}}/state.json`: + - Set this phase `status` to `completed` only when every completion check is satisfied. + - If any check is unmet (including any AI-review finding), keep this phase non-completed as `blocked` or `failed` so execution stops until fixed. - Increment this phase `attempts`. - Append concise notes (paths/decisions). - Keep task `status` as `in_progress` while handing off to Forge checks. -3. Forge will run backend checks after your phase is marked complete. +4. Forge will run backend checks after your phase is marked complete. - Forge finalizes phase/task completion statuses after checks. - If checks fail, Forge reopens the phase and you retry. - If checks pass on the last phase, Forge creates the task commit and records `commit_sha`. -4. Do NOT run `git` commands yourself in execute mode. +5. Do NOT run `git` commands yourself in execute mode. - Do NOT run `git add`, `git commit`, `git commit --amend`, or `git push`. - Do NOT set `commit_sha` in `state.json`; Forge manages it. -5. End your message with this exact single line marker: +6. End your message with this exact single line marker: ```text [[cm_forge:done plan={{plan_id}} task={{current_task_id}} phase={{current_phase_id}}]] From 64c30401de97224dd9f46802ed5d01a4cc5aab17 Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Thu, 12 Feb 2026 11:20:09 +0800 Subject: [PATCH 03/14] forge(forge-test-first-loop-template): task-3 Add Forge phase-view data loader interfaces --- src/services/tauri.test.ts | 129 ++++++++++++++++++++++++++ src/services/tauri.ts | 184 +++++++++++++++++++++++++++++++++++++ 2 files changed, 313 insertions(+) diff --git a/src/services/tauri.test.ts b/src/services/tauri.test.ts index b980e24a00..f443dbdf18 100644 --- a/src/services/tauri.test.ts +++ b/src/services/tauri.test.ts @@ -47,6 +47,7 @@ import { forgeInstallTemplate, forgeListBundledTemplates, forgeListPlans, + forgeLoadPhaseView, forgeUninstallTemplate, } from "./tauri"; @@ -215,6 +216,134 @@ describe("tauri invoke wrappers", () => { expect(invokeMock).toHaveBeenCalledWith("forge_get_plan_prompt", { workspaceId: "ws-1" }); }); + it("loads forge phase view from state and template phases files", async () => { + const invokeMock = vi.mocked(invoke); + invokeMock.mockImplementation(async (command: string, args?: unknown) => { + if (command === "is_macos_debug_build") { + return false; + } + if (command !== "read_workspace_file") { + return undefined; + } + + const path = + typeof args === "object" && args !== null && "path" in args + ? (args as { path?: unknown }).path + : undefined; + if (path === "plans/alpha/state.json") { + return { + content: JSON.stringify({ + tasks: [ + { + id: "task-1", + phases: [ + { id: "implementation", status: " COMPLETED " }, + { id: "verification", status: "unknown-value" }, + ], + }, + ], + }), + truncated: false, + }; + } + if (path === ".agent/templates/test-first-loop/phases.json") { + return { + content: JSON.stringify({ + schema: "forge-phases-v1", + phases: [ + { id: "verification", title: "Verification", iconId: "fact_check", order: 2 }, + { id: "implementation", title: "Implementation", iconId: "code_blocks", order: 1 }, + ], + }), + truncated: false, + }; + } + + throw new Error(`unexpected path: ${String(path)}`); + }); + + await expect(forgeLoadPhaseView("ws-1", "alpha", "test-first-loop")).resolves.toEqual({ + phases: [ + { id: "implementation", title: "Implementation", iconId: "code_blocks", order: 1 }, + { id: "verification", title: "Verification", iconId: "fact_check", order: 2 }, + ], + taskPhaseStatusByTaskId: { + "task-1": { + implementation: "completed", + verification: "pending", + }, + }, + }); + + expect(invokeMock).toHaveBeenCalledWith("read_workspace_file", { + workspaceId: "ws-1", + path: "plans/alpha/state.json", + }); + expect(invokeMock).toHaveBeenCalledWith("read_workspace_file", { + workspaceId: "ws-1", + path: ".agent/templates/test-first-loop/phases.json", + }); + }); + + it("returns a safe fallback when forge phase-view files are malformed or truncated", async () => { + const invokeMock = vi.mocked(invoke); + invokeMock.mockImplementation(async (command: string, args?: unknown) => { + if (command === "is_macos_debug_build") { + return false; + } + if (command !== "read_workspace_file") { + return undefined; + } + + const path = + typeof args === "object" && args !== null && "path" in args + ? (args as { path?: unknown }).path + : undefined; + if (path === "plans/alpha/state.json") { + return { content: "{not-json", truncated: false }; + } + if (path === ".agent/templates/test-first-loop/phases.json") { + return { + content: JSON.stringify({ + schema: "forge-phases-v1", + phases: [{ id: "implementation", title: "Implementation", iconId: "code_blocks", order: 1 }], + }), + truncated: true, + }; + } + + throw new Error(`unexpected path: ${String(path)}`); + }); + + await expect(forgeLoadPhaseView("ws-1", "alpha", "test-first-loop")).resolves.toEqual({ + phases: [], + taskPhaseStatusByTaskId: {}, + }); + }); + + it("returns a safe fallback when forge phase-view files are missing", async () => { + const invokeMock = vi.mocked(invoke); + invokeMock.mockImplementation(async (command: string) => { + if (command === "is_macos_debug_build") { + return false; + } + if (command === "read_workspace_file") { + throw new Error("missing"); + } + return undefined; + }); + + await expect(forgeLoadPhaseView("ws-1", "alpha", null)).resolves.toEqual({ + phases: [], + taskPhaseStatusByTaskId: {}, + }); + + expect(invokeMock).toHaveBeenCalledWith("read_workspace_file", { + workspaceId: "ws-1", + path: "plans/alpha/state.json", + }); + }); + it("returns fallbacks for forge wrappers when Tauri invoke bridge is missing", async () => { const invokeMock = vi.mocked(invoke); invokeMock.mockRejectedValueOnce( diff --git a/src/services/tauri.ts b/src/services/tauri.ts index d00fd497e8..4987cfacfe 100644 --- a/src/services/tauri.ts +++ b/src/services/tauri.ts @@ -1011,6 +1011,190 @@ export type ForgeRunPhaseChecksResponse = { results: ForgePhaseCheckResult[]; }; +export type ForgePhaseViewStatus = + | "pending" + | "in_progress" + | "completed" + | "blocked" + | "failed"; + +export type ForgePhaseViewMetadata = { + id: string; + title: string; + iconId: string; + order: number; +}; + +export type ForgePhaseView = { + phases: ForgePhaseViewMetadata[]; + taskPhaseStatusByTaskId: Record>; +}; + +const EMPTY_FORGE_PHASE_VIEW: ForgePhaseView = { + phases: [], + taskPhaseStatusByTaskId: {}, +}; + +const DEFAULT_FORGE_PHASE_ICON_ID = "check_circle"; + +function normalizeForgePhaseViewStatus(value: unknown): ForgePhaseViewStatus { + if (typeof value !== "string") { + return "pending"; + } + const normalized = value.trim().toLowerCase(); + if ( + normalized === "pending" || + normalized === "in_progress" || + normalized === "completed" || + normalized === "blocked" || + normalized === "failed" + ) { + return normalized; + } + return "pending"; +} + +function parseForgeStatePhaseStatuses( + value: unknown, +): Record> { + if (!value || typeof value !== "object") { + return {}; + } + const tasks = (value as { tasks?: unknown }).tasks; + if (!Array.isArray(tasks)) { + return {}; + } + const taskPhaseStatusByTaskId: Record> = {}; + + for (const taskValue of tasks) { + if (!taskValue || typeof taskValue !== "object") { + continue; + } + const taskIdRaw = (taskValue as { id?: unknown }).id; + if (typeof taskIdRaw !== "string") { + continue; + } + const taskId = taskIdRaw.trim(); + if (!taskId) { + continue; + } + + const phases = (taskValue as { phases?: unknown }).phases; + if (!Array.isArray(phases)) { + continue; + } + + const phaseStatusById: Record = {}; + for (const phaseValue of phases) { + if (!phaseValue || typeof phaseValue !== "object") { + continue; + } + const phaseIdRaw = (phaseValue as { id?: unknown }).id; + if (typeof phaseIdRaw !== "string") { + continue; + } + const phaseId = phaseIdRaw.trim(); + if (!phaseId) { + continue; + } + phaseStatusById[phaseId] = normalizeForgePhaseViewStatus( + (phaseValue as { status?: unknown }).status, + ); + } + + if (Object.keys(phaseStatusById).length > 0) { + taskPhaseStatusByTaskId[taskId] = phaseStatusById; + } + } + + return taskPhaseStatusByTaskId; +} + +function parseForgePhaseMetadata(value: unknown): ForgePhaseViewMetadata[] { + if (!value || typeof value !== "object") { + return []; + } + const phases = (value as { phases?: unknown }).phases; + if (!Array.isArray(phases)) { + return []; + } + + const parsed = phases + .map((phaseValue, index): ForgePhaseViewMetadata | null => { + if (!phaseValue || typeof phaseValue !== "object") { + return null; + } + const phaseIdRaw = (phaseValue as { id?: unknown }).id; + if (typeof phaseIdRaw !== "string") { + return null; + } + const id = phaseIdRaw.trim(); + if (!id) { + return null; + } + + const titleRaw = (phaseValue as { title?: unknown }).title; + const iconIdRaw = (phaseValue as { iconId?: unknown }).iconId; + const orderRaw = (phaseValue as { order?: unknown }).order; + + const title = typeof titleRaw === "string" && titleRaw.trim() ? titleRaw.trim() : id; + const iconId = + typeof iconIdRaw === "string" && iconIdRaw.trim() + ? iconIdRaw.trim() + : DEFAULT_FORGE_PHASE_ICON_ID; + const order = + typeof orderRaw === "number" && Number.isFinite(orderRaw) ? orderRaw : index + 1; + + return { id, title, iconId, order }; + }) + .filter((phase): phase is ForgePhaseViewMetadata => Boolean(phase)); + + parsed.sort((a, b) => a.order - b.order); + return parsed; +} + +async function readWorkspaceJsonValue( + workspaceId: string, + path: string, +): Promise { + try { + const response = await readWorkspaceFile(workspaceId, path); + if (response.truncated) { + return null; + } + return JSON.parse(response.content); + } catch { + return null; + } +} + +export async function forgeLoadPhaseView( + workspaceId: string, + planId: string, + installedTemplateId: string | null, +): Promise { + const normalizedPlanId = planId.trim(); + if (!normalizedPlanId) { + return EMPTY_FORGE_PHASE_VIEW; + } + + const normalizedTemplateId = installedTemplateId?.trim() ?? ""; + const statePath = `plans/${normalizedPlanId}/state.json`; + const phasesPath = normalizedTemplateId + ? `.agent/templates/${normalizedTemplateId}/phases.json` + : null; + + const [stateJson, phasesJson] = await Promise.all([ + readWorkspaceJsonValue(workspaceId, statePath), + phasesPath ? readWorkspaceJsonValue(workspaceId, phasesPath) : Promise.resolve(null), + ]); + + return { + phases: parseForgePhaseMetadata(phasesJson), + taskPhaseStatusByTaskId: parseForgeStatePhaseStatuses(stateJson), + }; +} + export async function forgeListBundledTemplates(): Promise { try { return await invoke("forge_list_bundled_templates"); From ea4afd50dc13946b1df0abb6ee3418a8347ad8fe Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Thu, 12 Feb 2026 11:23:26 +0800 Subject: [PATCH 04/14] forge(forge-test-first-loop-template): task-4 Render phase rows with Material icons in Forge UI --- src/features/forge/components/Forge.tsx | 107 ++++++++++++++++++++++++ src/styles/forge.css | 10 +++ src/utils/forgePhaseIcons.ts | 29 +++++++ 3 files changed, 146 insertions(+) create mode 100644 src/utils/forgePhaseIcons.ts diff --git a/src/features/forge/components/Forge.tsx b/src/features/forge/components/Forge.tsx index 26a02e3113..d2977c162b 100644 --- a/src/features/forge/components/Forge.tsx +++ b/src/features/forge/components/Forge.tsx @@ -17,10 +17,13 @@ import { useDismissibleMenu } from "../../app/hooks/useDismissibleMenu"; import { forgeGetInstalledTemplate, forgeInstallTemplate, + forgeLoadPhaseView, forgeListBundledTemplates, forgeUninstallTemplate, type ForgeBundledTemplateInfo, type ForgeNextPhasePrompt, + type ForgePhaseViewStatus, + type ForgePhaseView, type ForgePhaseStatus, type ForgeRunPhaseChecksResponse, type ForgeTemplateLock, @@ -40,6 +43,7 @@ import { startThread, } from "../../../services/tauri"; import { useForgeExecution } from "../hooks/useForgeExecution"; +import { getForgePhaseIconUrl } from "../../../utils/forgePhaseIcons"; export type ForgeTemplatesClient = { listBundledTemplates: () => Promise; @@ -50,6 +54,11 @@ export type ForgeTemplatesClient = { export type ForgePlansClient = { listPlans: (workspaceId: string) => Promise; + loadPhaseView?: ( + workspaceId: string, + planId: string, + installedTemplateId: string | null, + ) => Promise; getPlanPrompt: (workspaceId: string) => Promise; prepareExecution: (workspaceId: string, planId: string) => Promise; resetExecutionProgress: (workspaceId: string, planId: string) => Promise; @@ -95,6 +104,7 @@ const defaultForgeTemplatesClient: ForgeTemplatesClient = { const defaultForgePlansClient: ForgePlansClient = { listPlans: forgeListPlans, + loadPhaseView: forgeLoadPhaseView, getPlanPrompt: forgeGetPlanPrompt, prepareExecution: forgePrepareExecution, resetExecutionProgress: forgeResetExecutionProgress, @@ -121,6 +131,13 @@ type ForgePlan = { items: ForgePlanItem[]; }; +const EMPTY_PHASE_VIEW: ForgePhaseView = { + phases: [], + taskPhaseStatusByTaskId: {}, +}; + +type ForgePhaseChipState = "is-complete" | "is-current" | "is-pending"; + function formatPlanLabel(plan: ForgeWorkspacePlan): string { const title = plan.title?.trim() ?? ""; const goal = plan.goal?.trim() ?? ""; @@ -150,6 +167,25 @@ function mapForgeItemStatus(status: string): ForgeItemStatus { return "pending"; } +function mapForgePhaseChipState( + taskId: string, + phaseId: string, + phaseStatus: ForgePhaseViewStatus, + runningInfo: { taskId: string; phaseId: string } | null, +): ForgePhaseChipState { + const normalizedStatus = phaseStatus.trim().toLowerCase(); + if (runningInfo?.taskId === taskId && runningInfo.phaseId === phaseId) { + return "is-current"; + } + if (normalizedStatus === "in_progress") { + return "is-current"; + } + if (normalizedStatus === "completed") { + return "is-complete"; + } + return "is-pending"; +} + function ForgeTemplatesModal({ templates, installedTemplate, @@ -304,6 +340,7 @@ export function Forge({ const installTemplate = client.installTemplate; const uninstallTemplate = client.uninstallTemplate; const listPlans = plansApi.listPlans; + const loadPhaseView = plansApi.loadPhaseView ?? forgeLoadPhaseView; const getPlanPrompt = plansApi.getPlanPrompt; const prepareExecution = plansApi.prepareExecution; const resetExecutionProgress = plansApi.resetExecutionProgress; @@ -502,6 +539,7 @@ export function Forge({ const selectedPlan = selectedPlanId ? plans.find((p) => p.id === selectedPlanId) ?? null : null; + const [phaseView, setPhaseView] = useState(EMPTY_PHASE_VIEW); const [planMenuOpen, setPlanMenuOpen] = useState(false); const planMenuRef = useRef(null); @@ -523,6 +561,49 @@ export function Forge({ } }, [plans, selectedPlanId]); + useEffect(() => { + let cancelled = false; + if (!activeWorkspaceId || !selectedPlanId) { + setPhaseView(EMPTY_PHASE_VIEW); + return () => { + cancelled = true; + }; + } + + const installedTemplateId = installedTemplate?.installedTemplateId ?? null; + const refreshPhaseView = async () => { + try { + const next = await loadPhaseView( + activeWorkspaceId, + selectedPlanId, + installedTemplateId, + ); + if (cancelled) { + return; + } + setPhaseView(next); + } catch (error) { + if (cancelled) { + return; + } + console.warn("Failed to load Forge phase view.", { error }); + setPhaseView(EMPTY_PHASE_VIEW); + } + }; + + void refreshPhaseView(); + const interval = window.setInterval(refreshPhaseView, 2000); + return () => { + cancelled = true; + window.clearInterval(interval); + }; + }, [ + activeWorkspaceId, + installedTemplate?.installedTemplateId, + loadPhaseView, + selectedPlanId, + ]); + const executionMode = useMemo(() => { const mode = findCollaborationMode("default") ?? @@ -804,6 +885,7 @@ export function Forge({ const isCompleted = effectiveStatus === "completed"; const isRunning = effectiveStatus === "inProgress"; const isActivePhase = isActiveTask && runningInfo?.phaseId; + const taskPhaseStatuses = phaseView.taskPhaseStatusByTaskId[item.id] ?? {}; return (
  • @@ -824,6 +906,31 @@ export function Forge({ ) : null} + {phaseView.phases.length > 0 ? ( +
    + {phaseView.phases.map((phase) => { + const chipState = mapForgePhaseChipState( + item.id, + phase.id, + taskPhaseStatuses[phase.id] ?? "pending", + runningInfo, + ); + const iconUrl = getForgePhaseIconUrl(phase.iconId); + return ( + + + + + {phase.title} + + ); + })} +
    + ) : null}
  • ); })} diff --git a/src/styles/forge.css b/src/styles/forge.css index 0b9c207c0a..de9add981c 100644 --- a/src/styles/forge.css +++ b/src/styles/forge.css @@ -306,10 +306,20 @@ flex-shrink: 0; } +.forge-phase-icon img { + width: 14px; + height: 14px; + display: block; +} + .forge-phase-name { font-size: 12px; } +.forge-phase.is-pending { + color: var(--text-muted); +} + .forge-phase.is-complete { color: var(--status-success); } diff --git a/src/utils/forgePhaseIcons.ts b/src/utils/forgePhaseIcons.ts new file mode 100644 index 0000000000..98fdc4623c --- /dev/null +++ b/src/utils/forgePhaseIcons.ts @@ -0,0 +1,29 @@ +import { + getIconUrlByName, + isMaterialIconName, + type MaterialIcon, +} from "vscode-material-icons"; + +const MATERIAL_ICONS_BASE_URL = "/assets/material-icons"; +const DEFAULT_FORGE_PHASE_ICON_ID: MaterialIcon = "file"; +const forgePhaseIconUrlCache = new Map(); + +function resolveForgePhaseIconId(iconId: string): MaterialIcon { + const normalized = iconId.trim(); + if (isMaterialIconName(normalized)) { + return normalized; + } + return DEFAULT_FORGE_PHASE_ICON_ID; +} + +export function getForgePhaseIconUrl(iconId: string): string { + const resolvedIconId = resolveForgePhaseIconId(iconId); + const cached = forgePhaseIconUrlCache.get(resolvedIconId); + if (cached) { + return cached; + } + + const iconUrl = getIconUrlByName(resolvedIconId, MATERIAL_ICONS_BASE_URL); + forgePhaseIconUrlCache.set(resolvedIconId, iconUrl); + return iconUrl; +} From 536684ca4b93876d2e2861f6bc4927e0b8684887 Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Thu, 12 Feb 2026 11:23:37 +0800 Subject: [PATCH 05/14] forge(forge-test-first-loop-template): task-3 Add Forge phase-view data loader interfaces --- src/styles/forge.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/styles/forge.css b/src/styles/forge.css index de9add981c..359c345e85 100644 --- a/src/styles/forge.css +++ b/src/styles/forge.css @@ -316,10 +316,6 @@ font-size: 12px; } -.forge-phase.is-pending { - color: var(--text-muted); -} - .forge-phase.is-complete { color: var(--status-success); } From 29251823be06a82a9ab05ec367cecbe66869a995 Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Thu, 12 Feb 2026 11:25:37 +0800 Subject: [PATCH 06/14] forge(forge-test-first-loop-template): task-5 Add frontend regression tests for phase rendering --- .../forge/components/Forge.plans.test.tsx | 129 ++++++++++++++++++ src/services/tauri.test.ts | 44 ++++++ src/utils/forgePhaseIcons.test.ts | 14 ++ src/utils/forgePhaseIcons.ts | 8 +- 4 files changed, 191 insertions(+), 4 deletions(-) create mode 100644 src/utils/forgePhaseIcons.test.ts diff --git a/src/features/forge/components/Forge.plans.test.tsx b/src/features/forge/components/Forge.plans.test.tsx index 9cdee85641..94346f366f 100644 --- a/src/features/forge/components/Forge.plans.test.tsx +++ b/src/features/forge/components/Forge.plans.test.tsx @@ -567,6 +567,135 @@ describe("Forge plans", () => { fireEvent.click(screen.getByRole("button", { name: "Pause plan" })); }); + it("renders ordered phase chips with status classes and keeps failed ai-review blocking", async () => { + const loadPhaseView = vi + .fn>() + .mockResolvedValue({ + phases: [ + { + id: "test-case-mapping", + title: "Test Case Mapping", + iconId: "taskfile", + order: 1, + }, + { + id: "behavioral-tests", + title: "Behavioral Tests", + iconId: "cucumber", + order: 2, + }, + { + id: "implementation", + title: "Implementation", + iconId: "console", + order: 3, + }, + { + id: "coverage-hardening", + title: "Coverage Hardening", + iconId: "codecov", + order: 4, + }, + { + id: "documentation", + title: "Documentation", + iconId: "readme", + order: 5, + }, + { + id: "ai-review", + title: "AI Review Gate", + iconId: "totally-invalid-icon", + order: 6, + }, + ], + taskPhaseStatusByTaskId: { + "task-1": { + "test-case-mapping": "completed", + "behavioral-tests": "in_progress", + implementation: "pending", + "coverage-hardening": "failed", + documentation: "pending", + "ai-review": "failed", + }, + }, + }); + + const plansClient: ForgePlansClient = { + listPlans: async () => [ + { + id: "alpha", + title: "Alpha", + goal: "Alpha goal", + tasks: [{ id: "task-1", name: "Task 1", status: "pending" }], + currentTaskId: null, + planPath: "plans/alpha/plan.json", + updatedAtMs: 0, + }, + ], + loadPhaseView, + getPlanPrompt: async () => "", + prepareExecution: async () => {}, + resetExecutionProgress: async () => {}, + getNextPhasePrompt: async () => null, + getPhaseStatus: async () => ({ status: "pending", commitSha: null }), + runPhaseChecks: async () => ({ ok: true, results: [] }), + interruptTurn: async () => ({}), + connectWorkspace: async () => {}, + startThread: async () => ({ result: { thread: { id: "thread-1" } } }), + sendUserMessage: async () => ({}), + }; + + render( + , + ); + + fireEvent.click(await screen.findByRole("button", { name: /Click to select/i })); + fireEvent.click(screen.getByRole("menuitemradio", { name: "Alpha (alpha)" })); + + await waitFor(() => + expect(loadPhaseView).toHaveBeenCalledWith("ws-1", "alpha", null), + ); + + const taskRow = screen.getByText("Task 1").closest("li"); + expect(taskRow).toBeTruthy(); + const rowElement = taskRow as HTMLLIElement; + const chips = Array.from(rowElement.querySelectorAll(".forge-phase")); + expect(chips.map((chip) => chip.getAttribute("data-phase-id"))).toEqual([ + "test-case-mapping", + "behavioral-tests", + "implementation", + "coverage-hardening", + "documentation", + "ai-review", + ]); + + const chipFor = (phaseId: string) => + rowElement.querySelector(`.forge-phase[data-phase-id="${phaseId}"]`) as HTMLElement | null; + + expect(chipFor("test-case-mapping")?.className.includes("is-complete")).toBe(true); + expect(chipFor("behavioral-tests")?.className.includes("is-current")).toBe(true); + expect(chipFor("implementation")?.className.includes("is-pending")).toBe(true); + expect(chipFor("coverage-hardening")?.className.includes("is-pending")).toBe(true); + expect(chipFor("ai-review")?.className.includes("is-pending")).toBe(true); + expect(chipFor("ai-review")?.className.includes("is-complete")).toBe(false); + + const behavioralIcon = chipFor("behavioral-tests") + ?.querySelector(".forge-phase-icon img") + ?.getAttribute("src"); + const aiReviewIcon = chipFor("ai-review") + ?.querySelector(".forge-phase-icon img") + ?.getAttribute("src"); + + expect(behavioralIcon).toBe("/assets/material-icons/cucumber.svg"); + expect(aiReviewIcon).toBe("/assets/material-icons/file.svg"); + }); + it("keeps a pending phase on a single prompt without auto-resending", async () => { vi.useFakeTimers(); diff --git a/src/services/tauri.test.ts b/src/services/tauri.test.ts index f443dbdf18..73f6643f82 100644 --- a/src/services/tauri.test.ts +++ b/src/services/tauri.test.ts @@ -321,6 +321,50 @@ describe("tauri invoke wrappers", () => { }); }); + it("keeps failed phase statuses from state for downstream blocking UI", async () => { + const invokeMock = vi.mocked(invoke); + invokeMock.mockImplementation(async (command: string, args?: unknown) => { + if (command === "is_macos_debug_build") { + return false; + } + if (command !== "read_workspace_file") { + return undefined; + } + + const path = + typeof args === "object" && args !== null && "path" in args + ? (args as { path?: unknown }).path + : undefined; + if (path === "plans/alpha/state.json") { + return { + content: JSON.stringify({ + tasks: [ + { + id: "task-1", + phases: [ + { id: "ai-review", status: "failed" }, + { id: "documentation", status: "blocked" }, + ], + }, + ], + }), + truncated: false, + }; + } + throw new Error(`unexpected path: ${String(path)}`); + }); + + await expect(forgeLoadPhaseView("ws-1", "alpha", null)).resolves.toEqual({ + phases: [], + taskPhaseStatusByTaskId: { + "task-1": { + "ai-review": "failed", + documentation: "blocked", + }, + }, + }); + }); + it("returns a safe fallback when forge phase-view files are missing", async () => { const invokeMock = vi.mocked(invoke); invokeMock.mockImplementation(async (command: string) => { diff --git a/src/utils/forgePhaseIcons.test.ts b/src/utils/forgePhaseIcons.test.ts new file mode 100644 index 0000000000..8de1049bf5 --- /dev/null +++ b/src/utils/forgePhaseIcons.test.ts @@ -0,0 +1,14 @@ +import { describe, expect, it } from "vitest"; +import { getForgePhaseIconUrl } from "./forgePhaseIcons"; + +describe("forgePhaseIcons", () => { + it("resolves valid material icon ids to material icon asset URLs", () => { + expect(getForgePhaseIconUrl("codecov")).toBe("/assets/material-icons/codecov.svg"); + }); + + it("falls back to the safe default icon URL for invalid icon ids", () => { + expect(getForgePhaseIconUrl("not-a-material-icon")).toBe( + "/assets/material-icons/file.svg", + ); + }); +}); diff --git a/src/utils/forgePhaseIcons.ts b/src/utils/forgePhaseIcons.ts index 98fdc4623c..b3f90b6828 100644 --- a/src/utils/forgePhaseIcons.ts +++ b/src/utils/forgePhaseIcons.ts @@ -8,15 +8,15 @@ const MATERIAL_ICONS_BASE_URL = "/assets/material-icons"; const DEFAULT_FORGE_PHASE_ICON_ID: MaterialIcon = "file"; const forgePhaseIconUrlCache = new Map(); -function resolveForgePhaseIconId(iconId: string): MaterialIcon { - const normalized = iconId.trim(); - if (isMaterialIconName(normalized)) { +function resolveForgePhaseIconId(iconId: string | null | undefined): MaterialIcon { + const normalized = typeof iconId === "string" ? iconId.trim() : ""; + if (normalized && isMaterialIconName(normalized)) { return normalized; } return DEFAULT_FORGE_PHASE_ICON_ID; } -export function getForgePhaseIconUrl(iconId: string): string { +export function getForgePhaseIconUrl(iconId: string | null | undefined): string { const resolvedIconId = resolveForgePhaseIconId(iconId); const cached = forgePhaseIconUrlCache.get(resolvedIconId); if (cached) { From 3cf69ff3c85ffabd520a78314f13b57e9414f82c Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Thu, 12 Feb 2026 11:27:16 +0800 Subject: [PATCH 07/14] forge(forge-test-first-loop-template): task-6 Add template hook tests for true multi-phase initialization --- .../forge/components/Forge.plans.test.tsx | 13 ++ .../scripts/testFirstLoopScripts.test.ts | 174 ++++++++++++++++++ src/services/tauri.test.ts | 60 ++++++ src/utils/forgePhaseIcons.test.ts | 8 +- 4 files changed, 251 insertions(+), 4 deletions(-) create mode 100644 src/features/forge/scripts/testFirstLoopScripts.test.ts diff --git a/src/features/forge/components/Forge.plans.test.tsx b/src/features/forge/components/Forge.plans.test.tsx index 94346f366f..5dd92df29b 100644 --- a/src/features/forge/components/Forge.plans.test.tsx +++ b/src/features/forge/components/Forge.plans.test.tsx @@ -674,6 +674,18 @@ describe("Forge plans", () => { "documentation", "ai-review", ]); + expect( + chips.map((chip) => + chip.querySelector(".forge-phase-name")?.textContent?.trim(), + ), + ).toEqual([ + "Test Case Mapping", + "Behavioral Tests", + "Implementation", + "Coverage Hardening", + "Documentation", + "AI Review Gate", + ]); const chipFor = (phaseId: string) => rowElement.querySelector(`.forge-phase[data-phase-id="${phaseId}"]`) as HTMLElement | null; @@ -682,6 +694,7 @@ describe("Forge plans", () => { expect(chipFor("behavioral-tests")?.className.includes("is-current")).toBe(true); expect(chipFor("implementation")?.className.includes("is-pending")).toBe(true); expect(chipFor("coverage-hardening")?.className.includes("is-pending")).toBe(true); + expect(chipFor("documentation")?.className.includes("is-pending")).toBe(true); expect(chipFor("ai-review")?.className.includes("is-pending")).toBe(true); expect(chipFor("ai-review")?.className.includes("is-complete")).toBe(false); diff --git a/src/features/forge/scripts/testFirstLoopScripts.test.ts b/src/features/forge/scripts/testFirstLoopScripts.test.ts new file mode 100644 index 0000000000..370c88019b --- /dev/null +++ b/src/features/forge/scripts/testFirstLoopScripts.test.ts @@ -0,0 +1,174 @@ +import { execFile } from "node:child_process"; +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { promisify } from "node:util"; +import { describe, expect, it } from "vitest"; + +const execFileAsync = promisify(execFile); + +const TEMPLATE_ROOT = path.resolve( + "src-tauri/resources/forge/templates/test-first-loop", +); +const PHASE_IDS = [ + "test-case-mapping", + "behavioral-tests", + "implementation", + "coverage-hardening", + "documentation", + "ai-review", +]; + +type ScriptContext = { + workspaceRoot: string; + templateRoot: string; + planId: string; + planDir: string; + planPath: string; + statePath: string; + progressPath: string; + generatedPlanMdPath: string; + generatedExecutePromptPath: string; + todayIso: string; +}; + +async function createScriptContext(planId: string): Promise<{ + contextPath: string; + context: ScriptContext; +}> { + const tempRoot = await fs.mkdtemp( + path.join(os.tmpdir(), "codex-monitor-test-first-loop-"), + ); + const planDir = path.join(tempRoot, "plans", planId); + const planPath = path.join(planDir, "plan.json"); + const statePath = path.join(planDir, "state.json"); + const progressPath = path.join(planDir, "progress.md"); + const generatedPlanMdPath = path.join(planDir, "plan.md"); + const generatedExecutePromptPath = path.join(planDir, "execute-prompt.md"); + const contextPath = path.join(tempRoot, "context.json"); + + await fs.mkdir(planDir, { recursive: true }); + await fs.writeFile( + planPath, + `${JSON.stringify( + { + $schema: "plan-v1", + id: planId, + title: "Test-First Loop Script Test", + goal: "Validate test-first-loop script behavior for multi-phase execution.", + context: { + tech_stack: ["Node.js", "Vitest"], + constraints: ["Keep script tests deterministic."], + }, + tasks: [ + { + id: "task-1", + name: "Template hook regression", + description: + "Ensure phase initialization and prompt routing follow test-first-loop metadata.", + depends_on: [], + files: ["src/features/forge/scripts/testFirstLoopScripts.test.ts"], + verification: [ + "State initializes all template phases.", + "Prompt selects first non-completed phase metadata.", + ], + }, + ], + }, + null, + 2, + )}\n`, + "utf8", + ); + + const context: ScriptContext = { + workspaceRoot: tempRoot, + templateRoot: TEMPLATE_ROOT, + planId, + planDir, + planPath, + statePath, + progressPath, + generatedPlanMdPath, + generatedExecutePromptPath, + todayIso: "2026-02-12", + }; + + await fs.writeFile(contextPath, `${JSON.stringify(context, null, 2)}\n`, "utf8"); + return { contextPath, context }; +} + +async function runScript(scriptName: "post-plan.mjs" | "post-step.mjs", contextPath: string) { + const scriptPath = path.join(TEMPLATE_ROOT, "scripts", scriptName); + await execFileAsync(process.execPath, [scriptPath, "--context", contextPath]); +} + +describe("test-first-loop template scripts", () => { + it("post-plan initializes all six task phases as pending in template order", async () => { + const { contextPath, context } = await createScriptContext("phase-init"); + await runScript("post-plan.mjs", contextPath); + + const state = JSON.parse(await fs.readFile(context.statePath, "utf8")); + expect(state.tasks).toHaveLength(1); + expect(state.tasks[0].phases).toHaveLength(6); + expect(state.tasks[0].phases.map((phase: { id: string }) => phase.id)).toEqual( + PHASE_IDS, + ); + expect( + state.tasks[0].phases.map( + (phase: { status: string; attempts: number; notes: string }) => ({ + status: phase.status, + attempts: phase.attempts, + notes: phase.notes, + }), + ), + ).toEqual( + PHASE_IDS.map(() => ({ + status: "pending", + attempts: 0, + notes: "", + })), + ); + }); + + it("post-step advances prompt to the first non-completed phase, including ai-review", async () => { + const { contextPath, context } = await createScriptContext("phase-advance"); + await runScript("post-plan.mjs", contextPath); + + const firstPrompt = await fs.readFile(context.generatedExecutePromptPath, "utf8"); + expect(firstPrompt).toContain("Current phase: test-case-mapping - Test Case Mapping"); + + const state = JSON.parse(await fs.readFile(context.statePath, "utf8")); + state.tasks[0].status = "in_progress"; + state.tasks[0].phases[0].status = "completed"; + state.tasks[0].phases[0].attempts = 1; + state.tasks[0].phases[0].notes = "Mapped coverage criteria."; + await fs.writeFile(context.statePath, `${JSON.stringify(state, null, 2)}\n`, "utf8"); + + await runScript("post-step.mjs", contextPath); + const behavioralPrompt = await fs.readFile( + context.generatedExecutePromptPath, + "utf8", + ); + expect(behavioralPrompt).toContain( + "Current phase: behavioral-tests - Behavioral Tests", + ); + + for (let i = 1; i < 5; i += 1) { + state.tasks[0].phases[i].status = "completed"; + state.tasks[0].phases[i].attempts = 1; + state.tasks[0].phases[i].notes = `Completed ${state.tasks[0].phases[i].id}.`; + } + await fs.writeFile(context.statePath, `${JSON.stringify(state, null, 2)}\n`, "utf8"); + + await runScript("post-step.mjs", contextPath); + const aiReviewPrompt = await fs.readFile( + context.generatedExecutePromptPath, + "utf8", + ); + expect(aiReviewPrompt).toContain("Current phase: ai-review - AI Review Gate"); + expect(aiReviewPrompt).toContain( + "Run an AI quality review pass and enforce a strict zero-findings completion gate.", + ); + }); +}); diff --git a/src/services/tauri.test.ts b/src/services/tauri.test.ts index 73f6643f82..2b2716f2ec 100644 --- a/src/services/tauri.test.ts +++ b/src/services/tauri.test.ts @@ -285,6 +285,66 @@ describe("tauri invoke wrappers", () => { }); }); + it("preserves blocked and failed phase statuses for forge phase view", async () => { + const invokeMock = vi.mocked(invoke); + invokeMock.mockImplementation(async (command: string, args?: unknown) => { + if (command === "is_macos_debug_build") { + return false; + } + if (command !== "read_workspace_file") { + return undefined; + } + + const path = + typeof args === "object" && args !== null && "path" in args + ? (args as { path?: unknown }).path + : undefined; + if (path === "plans/alpha/state.json") { + return { + content: JSON.stringify({ + tasks: [ + { + id: "task-1", + phases: [ + { id: "implementation", status: "blocked" }, + { id: "ai-review", status: "failed" }, + ], + }, + ], + }), + truncated: false, + }; + } + if (path === ".agent/templates/test-first-loop/phases.json") { + return { + content: JSON.stringify({ + schema: "forge-phases-v1", + phases: [ + { id: "implementation", title: "Implementation", iconId: "console", order: 1 }, + { id: "ai-review", title: "AI Review", iconId: "folder-review", order: 2 }, + ], + }), + truncated: false, + }; + } + + throw new Error(`unexpected path: ${String(path)}`); + }); + + await expect(forgeLoadPhaseView("ws-1", "alpha", "test-first-loop")).resolves.toEqual({ + phases: [ + { id: "implementation", title: "Implementation", iconId: "console", order: 1 }, + { id: "ai-review", title: "AI Review", iconId: "folder-review", order: 2 }, + ], + taskPhaseStatusByTaskId: { + "task-1": { + implementation: "blocked", + "ai-review": "failed", + }, + }, + }); + }); + it("returns a safe fallback when forge phase-view files are malformed or truncated", async () => { const invokeMock = vi.mocked(invoke); invokeMock.mockImplementation(async (command: string, args?: unknown) => { diff --git a/src/utils/forgePhaseIcons.test.ts b/src/utils/forgePhaseIcons.test.ts index 8de1049bf5..c8107eccce 100644 --- a/src/utils/forgePhaseIcons.test.ts +++ b/src/utils/forgePhaseIcons.test.ts @@ -2,12 +2,12 @@ import { describe, expect, it } from "vitest"; import { getForgePhaseIconUrl } from "./forgePhaseIcons"; describe("forgePhaseIcons", () => { - it("resolves valid material icon ids to material icon asset URLs", () => { - expect(getForgePhaseIconUrl("codecov")).toBe("/assets/material-icons/codecov.svg"); + it("resolves valid material icon ids to the expected asset url", () => { + expect(getForgePhaseIconUrl("cucumber")).toBe("/assets/material-icons/cucumber.svg"); }); - it("falls back to the safe default icon URL for invalid icon ids", () => { - expect(getForgePhaseIconUrl("not-a-material-icon")).toBe( + it("falls back to the safe default icon when the id is invalid", () => { + expect(getForgePhaseIconUrl("definitely-not-a-real-material-icon")).toBe( "/assets/material-icons/file.svg", ); }); From 4efba0efc8faf160c86186782e5e6708283125c0 Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Thu, 12 Feb 2026 11:31:08 +0800 Subject: [PATCH 08/14] forge(forge-test-first-loop-template): task-7 Add Rust multi-phase execution core regressions --- src-tauri/src/shared/forge_execute_core.rs | 441 ++++++++++++++++-- .../forge/components/Forge.plans.test.tsx | 85 ++++ src/services/tauri.test.ts | 60 +++ src/utils/forgePhaseIcons.test.ts | 4 + 4 files changed, 560 insertions(+), 30 deletions(-) diff --git a/src-tauri/src/shared/forge_execute_core.rs b/src-tauri/src/shared/forge_execute_core.rs index 1ce45431aa..4267864eed 100644 --- a/src-tauri/src/shared/forge_execute_core.rs +++ b/src-tauri/src/shared/forge_execute_core.rs @@ -1067,6 +1067,27 @@ pub(crate) async fn forge_run_phase_checks_core( mod tests { use super::*; use serde_json::json; + use std::future::Future; + use std::process::Command; + + const SIX_PHASE_IDS: [&str; 6] = [ + "test-case-mapping", + "behavioral-tests", + "implementation", + "coverage-hardening", + "documentation", + "ai-review", + ]; + + struct TestWorkspace { + root: PathBuf, + } + + impl Drop for TestWorkspace { + fn drop(&mut self) { + let _ = std::fs::remove_dir_all(&self.root); + } + } fn temp_workspace_root() -> PathBuf { std::env::temp_dir().join(format!("codex-monitor-forge-execute-test-{}", Uuid::new_v4())) @@ -1083,26 +1104,72 @@ mod tests { write_text(path, &format!("{}\n", serde_json::to_string_pretty(&value).expect("json encode"))); } - #[test] - fn get_next_phase_prompt_regenerates_even_when_cached_prompt_exists() { + fn run_async_test(future: F) + where + F: Future, + { let rt = tokio::runtime::Builder::new_current_thread() .enable_all() .build() .expect("build runtime"); - rt.block_on(async { + rt.block_on(future); + } + + fn run_git(workspace: &Path, args: &[&str]) { + let output = Command::new("git") + .args(args) + .current_dir(workspace) + .output() + .expect("run git"); + assert!( + output.status.success(), + "git {:?} failed: stdout={} stderr={}", + args, + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ); + } + + fn init_git_repo(workspace: &Path) { + run_git(workspace, &["init"]); + run_git(workspace, &["config", "user.email", "forge-tests@example.com"]); + run_git(workspace, &["config", "user.name", "Forge Tests"]); + } + + fn build_task_phase_state(statuses: [&str; 6]) -> Vec { + SIX_PHASE_IDS + .iter() + .enumerate() + .map(|(index, phase_id)| { + json!({ + "id": phase_id, + "status": statuses[index], + "attempts": 0, + "notes": "" + }) + }) + .collect() + } + + fn setup_six_phase_workspace( + task_one_status: &str, + task_one_phase_statuses: [&str; 6], + ai_review_exit_code: i32, + ) -> TestWorkspace { let workspace = temp_workspace_root(); std::fs::create_dir_all(&workspace).expect("create workspace"); - let template_root = workspace.join(".agent").join("templates").join("ralph-loop"); + let template_id = "test-first-loop"; + let template_root = workspace.join(".agent").join("templates").join(template_id); std::fs::create_dir_all(template_root.join("scripts")).expect("create scripts dir"); write_json( &workspace.join(".agent").join("template-lock.json"), json!({ "schema": "forge-template-lock-v1", - "installedTemplateId": "ralph-loop", - "installedTemplateVersion": "0.2.1", - "installedAtIso": "2026-02-11T00:00:00Z", + "installedTemplateId": template_id, + "installedTemplateVersion": "0.1.0", + "installedAtIso": "2026-02-12T00:00:00Z", "installedFiles": ["template.json"] }), ); @@ -1111,9 +1178,9 @@ mod tests { &template_root.join("template.json"), json!({ "schema": "forge-template-v1", - "id": "ralph-loop", - "title": "Ralph Loop", - "version": "0.2.1", + "id": template_id, + "title": "Test-First Loop", + "version": "0.1.0", "files": [ "template.json", "phases.json", @@ -1140,13 +1207,26 @@ mod tests { } }), ); + + let phases = SIX_PHASE_IDS + .iter() + .map(|phase_id| { + let exit_code = if *phase_id == "ai-review" { + ai_review_exit_code + } else { + 0 + }; + json!({ + "id": phase_id, + "checks": [format!("node -e \"process.exit({exit_code})\"")] + }) + }) + .collect::>(); write_json( &template_root.join("phases.json"), json!({ "schema": "forge-phases-v1", - "phases": [ - { "id": "implementation", "checks": [] } - ] + "phases": phases }), ); write_text(&template_root.join("prompts").join("plan.md"), "# Mode: plan\n"); @@ -1169,7 +1249,7 @@ const i = process.argv.indexOf('--context');\n\ if (i < 0 || !process.argv[i + 1]) process.exit(2);\n\ const ctx = JSON.parse(await fs.readFile(process.argv[i + 1], 'utf8'));\n\ await fs.mkdir(path.dirname(ctx.generatedExecutePromptPath), { recursive: true });\n\ -await fs.writeFile(ctx.generatedExecutePromptPath, 'fresh prompt from post-step\\n', 'utf8');\n", +await fs.writeFile(ctx.generatedExecutePromptPath, 'generated prompt from post-step\\n', 'utf8');\n", ); let plan_dir = workspace.join("plans").join("alpha"); @@ -1196,11 +1276,11 @@ await fs.writeFile(ctx.generatedExecutePromptPath, 'fresh prompt from post-step\ "tasks": [ { "id": "task-1", - "status": "completed", + "status": task_one_status, "attempts": 0, "notes": "", - "commit_sha": "abc123", - "phases": [{ "id": "implementation", "status": "completed", "attempts": 0, "notes": "" }] + "commit_sha": null, + "phases": build_task_phase_state(task_one_phase_statuses) }, { "id": "task-2", @@ -1208,25 +1288,326 @@ await fs.writeFile(ctx.generatedExecutePromptPath, 'fresh prompt from post-step\ "attempts": 0, "notes": "", "commit_sha": null, - "phases": [{ "id": "implementation", "status": "pending", "attempts": 0, "notes": "" }] + "phases": [ + { "id": "implementation", "status": "pending", "attempts": 0, "notes": "" } + ] } ] }), ); - write_text( - &plan_dir.join("execute-prompt.md"), - "stale prompt that should not be returned\n", - ); - let next = forge_get_next_phase_prompt_core(&workspace, "alpha") - .await - .expect("get next phase prompt") - .expect("expected runnable phase"); - assert_eq!(next.task_id, "task-2"); - assert_eq!(next.phase_id, "implementation"); - assert_eq!(next.prompt_text.trim(), "fresh prompt from post-step"); + TestWorkspace { root: workspace } + } + + fn load_state_task(workspace: &Path, plan_id: &str, task_id: &str) -> StateTaskV2 { + let state_path = workspace.join("plans").join(plan_id).join("state.json"); + let state = read_json_file::(&state_path).expect("load state"); + state + .tasks + .into_iter() + .find(|task| task.id == task_id) + .expect("task in state") + } - let _ = std::fs::remove_dir_all(&workspace); + fn phase_status(task: &StateTaskV2, phase_id: &str) -> String { + task.phases + .iter() + .find(|phase| phase.id == phase_id) + .map(|phase| phase.status.clone()) + .expect("phase in task") + } + + #[test] + fn get_next_phase_prompt_regenerates_even_when_cached_prompt_exists() { + run_async_test(async { + let workspace = temp_workspace_root(); + std::fs::create_dir_all(&workspace).expect("create workspace"); + + let template_root = workspace.join(".agent").join("templates").join("ralph-loop"); + std::fs::create_dir_all(template_root.join("scripts")).expect("create scripts dir"); + + write_json( + &workspace.join(".agent").join("template-lock.json"), + json!({ + "schema": "forge-template-lock-v1", + "installedTemplateId": "ralph-loop", + "installedTemplateVersion": "0.2.1", + "installedAtIso": "2026-02-11T00:00:00Z", + "installedFiles": ["template.json"] + }), + ); + + write_json( + &template_root.join("template.json"), + json!({ + "schema": "forge-template-v1", + "id": "ralph-loop", + "title": "Ralph Loop", + "version": "0.2.1", + "files": [ + "template.json", + "phases.json", + "prompts/plan.md", + "prompts/execute.md", + "schemas/plan.schema.json", + "schemas/state.schema.json", + "scripts/post-plan.mjs", + "scripts/pre-execute.mjs", + "scripts/post-step.mjs" + ], + "entrypoints": { + "phases": "phases.json", + "planPrompt": "prompts/plan.md", + "executePrompt": "prompts/execute.md", + "planSchema": "schemas/plan.schema.json", + "stateSchema": "schemas/state.schema.json", + "requiredSkills": [], + "hooks": { + "postPlan": "scripts/post-plan.mjs", + "preExecute": "scripts/pre-execute.mjs", + "postStep": "scripts/post-step.mjs" + } + } + }), + ); + write_json( + &template_root.join("phases.json"), + json!({ + "schema": "forge-phases-v1", + "phases": [ + { "id": "implementation", "checks": [] } + ] + }), + ); + write_text(&template_root.join("prompts").join("plan.md"), "# Mode: plan\n"); + write_text(&template_root.join("prompts").join("execute.md"), "# Mode: execute\n"); + write_text(&template_root.join("schemas").join("plan.schema.json"), "{}\n"); + write_text(&template_root.join("schemas").join("state.schema.json"), "{}\n"); + write_text( + &template_root.join("scripts").join("post-plan.mjs"), + "process.exit(0);\n", + ); + write_text( + &template_root.join("scripts").join("pre-execute.mjs"), + "process.exit(0);\n", + ); + write_text( + &template_root.join("scripts").join("post-step.mjs"), + "import fs from 'node:fs/promises';\n\ +import path from 'node:path';\n\ +const i = process.argv.indexOf('--context');\n\ +if (i < 0 || !process.argv[i + 1]) process.exit(2);\n\ +const ctx = JSON.parse(await fs.readFile(process.argv[i + 1], 'utf8'));\n\ +await fs.mkdir(path.dirname(ctx.generatedExecutePromptPath), { recursive: true });\n\ +await fs.writeFile(ctx.generatedExecutePromptPath, 'fresh prompt from post-step\\n', 'utf8');\n", + ); + + let plan_dir = workspace.join("plans").join("alpha"); + std::fs::create_dir_all(&plan_dir).expect("create plan dir"); + write_json( + &plan_dir.join("plan.json"), + json!({ + "$schema": "plan-v1", + "id": "alpha", + "goal": "Test goal", + "tasks": [ + { "id": "task-1", "name": "Task 1", "depends_on": [] }, + { "id": "task-2", "name": "Task 2", "depends_on": ["task-1"] } + ] + }), + ); + write_json( + &plan_dir.join("state.json"), + json!({ + "$schema": "state-v2", + "plan_id": "alpha", + "iteration": 0, + "summary": "", + "tasks": [ + { + "id": "task-1", + "status": "completed", + "attempts": 0, + "notes": "", + "commit_sha": "abc123", + "phases": [{ "id": "implementation", "status": "completed", "attempts": 0, "notes": "" }] + }, + { + "id": "task-2", + "status": "pending", + "attempts": 0, + "notes": "", + "commit_sha": null, + "phases": [{ "id": "implementation", "status": "pending", "attempts": 0, "notes": "" }] + } + ] + }), + ); + write_text( + &plan_dir.join("execute-prompt.md"), + "stale prompt that should not be returned\n", + ); + + let next = forge_get_next_phase_prompt_core(&workspace, "alpha") + .await + .expect("get next phase prompt") + .expect("expected runnable phase"); + assert_eq!(next.task_id, "task-2"); + assert_eq!(next.phase_id, "implementation"); + assert_eq!(next.prompt_text.trim(), "fresh prompt from post-step"); + + let _ = std::fs::remove_dir_all(&workspace); + }); + } + + #[test] + fn get_next_phase_prompt_selects_first_incomplete_phase_for_partially_completed_task() { + run_async_test(async { + let fixture = setup_six_phase_workspace( + "in_progress", + [ + "completed", + "completed", + "completed", + "in_progress", + "pending", + "pending", + ], + 0, + ); + + let next = forge_get_next_phase_prompt_core(&fixture.root, "alpha") + .await + .expect("get next phase") + .expect("expected next phase"); + assert_eq!(next.task_id, "task-1"); + assert_eq!(next.phase_id, "coverage-hardening"); + assert!(!next.is_last_phase); + assert_eq!(next.prompt_text.trim(), "generated prompt from post-step"); + }); + } + + #[test] + fn run_phase_checks_non_final_success_completes_only_current_phase_without_commit() { + run_async_test(async { + let fixture = setup_six_phase_workspace( + "pending", + [ + "pending", + "pending", + "pending", + "pending", + "pending", + "pending", + ], + 0, + ); + + let result = + forge_run_phase_checks_core(&fixture.root, "alpha", "task-1", "test-case-mapping") + .await + .expect("run phase checks"); + assert!(result.ok); + assert!(!result.results.iter().any(|check| check.id == "forge-commit")); + + let task = load_state_task(&fixture.root, "alpha", "task-1"); + assert_eq!(task.status, "in_progress"); + assert_eq!(task.commit_sha, None); + assert_eq!(phase_status(&task, "test-case-mapping"), "completed"); + assert_eq!(phase_status(&task, "behavioral-tests"), "pending"); + assert_eq!(phase_status(&task, "ai-review"), "pending"); + + let next = forge_get_next_phase_prompt_core(&fixture.root, "alpha") + .await + .expect("get next phase") + .expect("expected next phase"); + assert_eq!(next.task_id, "task-1"); + assert_eq!(next.phase_id, "behavioral-tests"); + assert!(!next.is_last_phase); + }); + } + + #[test] + fn run_phase_checks_final_ai_review_failure_blocks_completion_and_progression() { + run_async_test(async { + let fixture = setup_six_phase_workspace( + "in_progress", + [ + "completed", + "completed", + "completed", + "completed", + "completed", + "pending", + ], + 1, + ); + + let result = forge_run_phase_checks_core(&fixture.root, "alpha", "task-1", "ai-review") + .await + .expect("run phase checks"); + assert!(!result.ok); + assert!(result.results.iter().any(|check| check.exit_code != 0)); + assert!(!result.results.iter().any(|check| check.id == "forge-commit")); + + let task = load_state_task(&fixture.root, "alpha", "task-1"); + assert_eq!(task.status, "in_progress"); + assert_eq!(task.commit_sha, None); + assert_eq!(phase_status(&task, "ai-review"), "in_progress"); + + let next = forge_get_next_phase_prompt_core(&fixture.root, "alpha") + .await + .expect("get next phase") + .expect("expected next phase"); + assert_eq!(next.task_id, "task-1"); + assert_eq!(next.phase_id, "ai-review"); + assert!(next.is_last_phase); + }); + } + + #[test] + fn run_phase_checks_final_ai_review_success_completes_task_and_records_commit() { + run_async_test(async { + let fixture = setup_six_phase_workspace( + "in_progress", + [ + "completed", + "completed", + "completed", + "completed", + "completed", + "pending", + ], + 0, + ); + init_git_repo(&fixture.root); + + let result = forge_run_phase_checks_core(&fixture.root, "alpha", "task-1", "ai-review") + .await + .expect("run phase checks"); + assert!(result.ok); + assert!(result + .results + .iter() + .any(|check| check.id == "forge-commit" && check.exit_code == 0)); + + let task = load_state_task(&fixture.root, "alpha", "task-1"); + assert_eq!(task.status, "completed"); + assert_eq!(phase_status(&task, "ai-review"), "completed"); + assert!( + task.commit_sha + .as_ref() + .map(|sha| !sha.trim().is_empty()) + .unwrap_or(false) + ); + + let next = forge_get_next_phase_prompt_core(&fixture.root, "alpha") + .await + .expect("get next phase") + .expect("expected next phase"); + assert_eq!(next.task_id, "task-2"); + assert_eq!(next.phase_id, "implementation"); + assert!(next.is_last_phase); }); } } diff --git a/src/features/forge/components/Forge.plans.test.tsx b/src/features/forge/components/Forge.plans.test.tsx index 5dd92df29b..22e85787ce 100644 --- a/src/features/forge/components/Forge.plans.test.tsx +++ b/src/features/forge/components/Forge.plans.test.tsx @@ -709,6 +709,91 @@ describe("Forge plans", () => { expect(aiReviewIcon).toBe("/assets/material-icons/file.svg"); }); + it("keeps terminal ai-review failures visibly non-completed even after prior phases complete", async () => { + const loadPhaseView = vi + .fn>() + .mockResolvedValue({ + phases: [ + { id: "test-case-mapping", title: "Test Case Mapping", iconId: "taskfile", order: 1 }, + { id: "behavioral-tests", title: "Behavioral Tests", iconId: "cucumber", order: 2 }, + { id: "implementation", title: "Implementation", iconId: "console", order: 3 }, + { + id: "coverage-hardening", + title: "Coverage Hardening", + iconId: "codecov", + order: 4, + }, + { id: "documentation", title: "Documentation", iconId: "readme", order: 5 }, + { id: "ai-review", title: "AI Review Gate", iconId: "folder-review", order: 6 }, + ], + taskPhaseStatusByTaskId: { + "task-1": { + "test-case-mapping": "completed", + "behavioral-tests": "completed", + implementation: "completed", + "coverage-hardening": "completed", + documentation: "completed", + "ai-review": "failed", + }, + }, + }); + + const plansClient: ForgePlansClient = { + listPlans: async () => [ + { + id: "alpha", + title: "Alpha", + goal: "Alpha goal", + tasks: [{ id: "task-1", name: "Task 1", status: "completed" }], + currentTaskId: null, + planPath: "plans/alpha/plan.json", + updatedAtMs: 0, + }, + ], + loadPhaseView, + getPlanPrompt: async () => "", + prepareExecution: async () => {}, + resetExecutionProgress: async () => {}, + getNextPhasePrompt: async () => null, + getPhaseStatus: async () => ({ status: "pending", commitSha: null }), + runPhaseChecks: async () => ({ ok: true, results: [] }), + interruptTurn: async () => ({}), + connectWorkspace: async () => {}, + startThread: async () => ({ result: { thread: { id: "thread-1" } } }), + sendUserMessage: async () => ({}), + }; + + render( + , + ); + + fireEvent.click(await screen.findByRole("button", { name: /Click to select/i })); + fireEvent.click(screen.getByRole("menuitemradio", { name: "Alpha (alpha)" })); + + await waitFor(() => + expect(loadPhaseView).toHaveBeenCalledWith("ws-1", "alpha", null), + ); + + const taskRow = screen.getByText("Task 1").closest("li"); + expect(taskRow).toBeTruthy(); + const rowElement = taskRow as HTMLLIElement; + const aiReviewChip = rowElement.querySelector( + '.forge-phase[data-phase-id="ai-review"]', + ) as HTMLElement | null; + const docsChip = rowElement.querySelector( + '.forge-phase[data-phase-id="documentation"]', + ) as HTMLElement | null; + + expect(docsChip?.className.includes("is-complete")).toBe(true); + expect(aiReviewChip?.className.includes("is-pending")).toBe(true); + expect(aiReviewChip?.className.includes("is-complete")).toBe(false); + }); + it("keeps a pending phase on a single prompt without auto-resending", async () => { vi.useFakeTimers(); diff --git a/src/services/tauri.test.ts b/src/services/tauri.test.ts index 2b2716f2ec..222b309e7b 100644 --- a/src/services/tauri.test.ts +++ b/src/services/tauri.test.ts @@ -345,6 +345,66 @@ describe("tauri invoke wrappers", () => { }); }); + it("normalizes forge phase view statuses with case and whitespace", async () => { + const invokeMock = vi.mocked(invoke); + invokeMock.mockImplementation(async (command: string, args?: unknown) => { + if (command === "is_macos_debug_build") { + return false; + } + if (command !== "read_workspace_file") { + return undefined; + } + + const path = + typeof args === "object" && args !== null && "path" in args + ? (args as { path?: unknown }).path + : undefined; + if (path === "plans/alpha/state.json") { + return { + content: JSON.stringify({ + tasks: [ + { + id: "task-1", + phases: [ + { id: "implementation", status: " BLOCKED " }, + { id: "ai-review", status: " Failed " }, + ], + }, + ], + }), + truncated: false, + }; + } + if (path === ".agent/templates/test-first-loop/phases.json") { + return { + content: JSON.stringify({ + schema: "forge-phases-v1", + phases: [ + { id: "implementation", title: "Implementation", iconId: "console", order: 1 }, + { id: "ai-review", title: "AI Review", iconId: "folder-review", order: 2 }, + ], + }), + truncated: false, + }; + } + + throw new Error(`unexpected path: ${String(path)}`); + }); + + await expect(forgeLoadPhaseView("ws-1", "alpha", "test-first-loop")).resolves.toEqual({ + phases: [ + { id: "implementation", title: "Implementation", iconId: "console", order: 1 }, + { id: "ai-review", title: "AI Review", iconId: "folder-review", order: 2 }, + ], + taskPhaseStatusByTaskId: { + "task-1": { + implementation: "blocked", + "ai-review": "failed", + }, + }, + }); + }); + it("returns a safe fallback when forge phase-view files are malformed or truncated", async () => { const invokeMock = vi.mocked(invoke); invokeMock.mockImplementation(async (command: string, args?: unknown) => { diff --git a/src/utils/forgePhaseIcons.test.ts b/src/utils/forgePhaseIcons.test.ts index c8107eccce..2b725a41a1 100644 --- a/src/utils/forgePhaseIcons.test.ts +++ b/src/utils/forgePhaseIcons.test.ts @@ -11,4 +11,8 @@ describe("forgePhaseIcons", () => { "/assets/material-icons/file.svg", ); }); + + it("accepts valid icon ids with surrounding whitespace", () => { + expect(getForgePhaseIconUrl(" taskfile ")).toBe("/assets/material-icons/taskfile.svg"); + }); }); From 5d325d4626fc0f13a99d16fe0dfb8dd21f31e219 Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Thu, 12 Feb 2026 11:33:12 +0800 Subject: [PATCH 09/14] forge(forge-test-first-loop-template): task-8 Update Forge documentation and validate matrix --- docs/forge.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/docs/forge.md b/docs/forge.md index 1b83842c84..65de5c1384 100644 --- a/docs/forge.md +++ b/docs/forge.md @@ -40,6 +40,37 @@ Notes: - In remote mode, each app handler calls `remote_backend::call_remote`; daemon `rpc.rs` parses the same camelCase keys with `parse_string`. - `remote_backend::can_retry_after_disconnect` includes all Forge methods above, so disconnect errors are retried once after reconnect. +## UI Phase Metadata and Icon Resolution + +Forge execution chips use a frontend-composed phase-view model rather than a dedicated `forge_*` backend command: + +- Loader: `src/services/tauri.ts::forgeLoadPhaseView` +- File reads (via `read_workspace_file`): + - `plans//state.json` + - `.agent/templates//phases.json` (when a template is installed) + +`forgeLoadPhaseView` behavior: + +- Missing, malformed, or truncated files are treated as non-fatal and return empty phase metadata/status maps. +- State phase statuses are normalized to: + - `pending` + - `in_progress` + - `completed` + - `blocked` + - `failed` +- Unknown statuses normalize to `pending`. +- Template phase metadata is sorted by `order` (fallback: array index + 1). +- Missing/blank `iconId` metadata falls back to `check_circle` during metadata parsing. + +Execution UI rendering behavior: + +- `src/features/forge/components/Forge.tsx::mapForgePhaseChipState` maps states as: + - running phase or `in_progress` -> `is-current` + - `completed` -> `is-complete` + - `pending` / `blocked` / `failed` -> `is-pending` +- `src/utils/forgePhaseIcons.ts::getForgePhaseIconUrl` validates icon ids with `isMaterialIconName` and resolves URLs with `getIconUrlByName(id, "/assets/material-icons")`. +- Invalid/empty icon ids fall back to safe icon id `file` (`/assets/material-icons/file.svg`). + ## Local vs Remote Command Routing Each app handler in `src-tauri/src/forge/mod.rs` follows the same branch: @@ -81,9 +112,10 @@ Bundled templates are stored under: Each template folder must contain `template.json` (read by `read_manifest` in `src-tauri/src/shared/forge_templates_core.rs`). `forge_list_bundled_templates` ignores folders that are missing or fail to parse `template.json`. -Current bundled example: +Current bundled templates: - `src-tauri/resources/forge/templates/ralph-loop/template.json` +- `src-tauri/resources/forge/templates/test-first-loop/template.json` `template.json` fields (schema `forge-template-v1`): @@ -102,7 +134,43 @@ Current bundled example: - `entrypoints.hooks.preExecute`: hook script run by `forge_prepare_execution`/`forge_reset_execution_progress` before execution. - `entrypoints.hooks.postStep`: hook script run by `forge_get_next_phase_prompt` and `forge_run_phase_checks` to regenerate `plans//execute-prompt.md`. -`template.json` should also be included in `files` so installed templates at `.agent/templates//` remain self-describing (the bundled `ralph-loop` template does this). +`template.json` should also be included in `files` so installed templates at `.agent/templates//` remain self-describing (both bundled templates do this). + +## `test-first-loop` Phase Contract (6 Phases) + +`src-tauri/resources/forge/templates/test-first-loop/phases.json` defines six ordered phases: + +| Order | Phase id | Title | iconId | Completion contract highlights | +| --- | --- | --- | --- | --- | +| 1 | `test-case-mapping` | `Test Case Mapping` | `taskfile` | Requirement-to-test mapping, edge/failure paths, risk prioritization, assumptions documented | +| 2 | `behavioral-tests` | `Behavioral Tests` | `cucumber` | Behavior-focused executable tests, fail-before/pass-after flow, outcome assertions, stabilized determinism | +| 3 | `implementation` | `Implementation` | `console` | Minimal scoped code changes with passing targeted tests and recorded decisions | +| 4 | `coverage-hardening` | `Coverage Hardening` | `codecov` | Fixed coverage floor of **80%**, explicit remaining risk gaps, property-based tests for high-risk gaps | +| 5 | `documentation` | `Documentation` | `readme` | Canonical docs/runbooks updated to live behavior, obsolete guidance removed | +| 6 | `ai-review` | `AI Review Gate` | `folder-review` | Zero-findings gate: any remaining finding keeps the phase non-completed (`failed` or `blocked`) and execution must stop | + +The `ai-review` phase is terminal and is treated as a hard gate for task completion. +`forge_execute_core` only records task completion commit SHA on successful final-phase checks. When terminal `ai-review` checks fail, the phase remains non-completed and progression does not advance. + +## Regression Coverage Snapshot + +Current regression coverage for this behavior spans frontend, template hooks, and shared Rust execution core: + +- Frontend execution chip rendering: + - `src/features/forge/components/Forge.plans.test.tsx` + - Covers template-order chip rendering, class-state mapping, icon URL fallback, and terminal `ai-review` staying non-completed/visibly blocking. +- Frontend icon resolver: + - `src/utils/forgePhaseIcons.test.ts` + - Covers valid icon URL resolution, invalid-id fallback to `file`, and whitespace-trimmed valid ids. +- Frontend phase-view loader: + - `src/services/tauri.test.ts` + - Covers `forgeLoadPhaseView` parsing/fallbacks plus normalization/preservation of `blocked` and `failed` statuses. +- Template hook behavior: + - `src/features/forge/scripts/testFirstLoopScripts.test.ts` + - Covers six-phase initialization and post-step selection of first non-completed phase, including `ai-review`. +- Shared execution core: + - `src-tauri/src/shared/forge_execute_core.rs` tests under `forge_execute_core::tests` + - Covers partial progression, non-final no-commit success, final `ai-review` failure blocking completion, and final `ai-review` success commit gating. ## Workspace Artifacts Created by Install From a2d6a0927d8cdc9862af2e7b98274b2e50544aa3 Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Thu, 12 Feb 2026 12:13:43 +0800 Subject: [PATCH 10/14] forge(forge-execution-stability-project-gate): task-1 Add project-selection gate to Forge UI --- README.md | 6 +- coverage/Forge.tsx.html | 3028 +++++++++++++++++ coverage/base.css | 224 ++ coverage/block-navigation.js | 87 + coverage/clover.xml | 778 +++++ coverage/coverage-final.json | 2 + coverage/favicon.png | Bin 0 -> 445 bytes coverage/index.html | 116 + coverage/prettify.css | 1 + coverage/prettify.js | 2 + coverage/sort-arrow-sprite.png | Bin 0 -> 138 bytes coverage/sorter.js | 210 ++ docs/codebase-map.md | 8 + docs/forge.md | 15 + src/features/app/components/Sidebar.test.tsx | 20 +- .../forge/components/Forge.plans.test.tsx | 266 ++ src/features/forge/components/Forge.tsx | 37 +- 17 files changed, 4785 insertions(+), 15 deletions(-) create mode 100644 coverage/Forge.tsx.html create mode 100644 coverage/base.css create mode 100644 coverage/block-navigation.js create mode 100644 coverage/clover.xml create mode 100644 coverage/coverage-final.json create mode 100644 coverage/favicon.png create mode 100644 coverage/index.html create mode 100644 coverage/prettify.css create mode 100644 coverage/prettify.js create mode 100644 coverage/sort-arrow-sprite.png create mode 100644 coverage/sorter.js diff --git a/README.md b/README.md index 115f673cb9..c4c85a28fd 100644 --- a/README.md +++ b/README.md @@ -46,9 +46,9 @@ CodexMonitor is a Tauri app for orchestrating multiple Codex agents across local ## Forge - Canonical Forge module docs: [docs/forge.md](docs/forge.md). -- Installs and uninstalls bundled Forge templates into workspace-scoped `.agent` artifacts. -- Returns a normalized template plan prompt for plan mode (including compatibility rewrites and `@plan` enforcement). -- Lists workspace plans and joins task status from matching `state-v2` files. +- Forge panel remains available from the sidebar header even when no project is selected. +- No-project mode is explicit and blocking: Forge shows `Select a project first to use Forge.` and disables template, plan, execution, and clean-progress actions. +- With a selected project, Forge installs/uninstalls bundled templates into workspace-scoped `.agent` artifacts, returns normalized plan prompts, and lists workspace plans with `state-v2` task status joins. ## Requirements diff --git a/coverage/Forge.tsx.html b/coverage/Forge.tsx.html new file mode 100644 index 0000000000..6654b519ef --- /dev/null +++ b/coverage/Forge.tsx.html @@ -0,0 +1,3028 @@ + + + + + + Code coverage report for Forge.tsx + + + + + + + + + +
    +
    +

    All files Forge.tsx

    +
    + +
    + 90.5% + Statements + 696/769 +
    + + +
    + 75.5% + Branches + 151/200 +
    + + +
    + 85% + Functions + 17/20 +
    + + +
    + 90.5% + Lines + 696/769 +
    + + +
    +

    + Press n or j to go to the next uncovered block, b, p or k for the previous block. +

    + +
    +
    +
    
    +
    1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +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 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +9821x +1x +1x +1x +1x +1x +1x +1x +1x +  +1x +1x +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +1x +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +  +  +  +13x +13x +13x +13x +13x +13x +13x +  +  +  +  +13x +13x +  +  +13x +13x +  +15x +15x +15x +1x +1x +15x +  +  +14x +14x +  +12x +12x +12x +12x +12x +12x +12x +12x +  +  +12x +1x +1x +12x +6x +6x +5x +5x +  +4x +4x +4x +4x +4x +4x +4x +4x +  +  +  +  +  +  +4x +4x +4x +1x +  +  +1x +1x +1x +4x +4x +4x +  +4x +3x +1x +1x +1x +1x +1x +4x +3x +1x +  +4x +4x +4x +4x +4x +  +4x +4x +  +4x +4x +4x +4x +3x +3x +3x +3x +3x +3x +3x +3x +3x +3x +3x +3x +3x +3x +  +  +  +3x +3x +3x +3x +3x +3x +1x +1x +1x +3x +3x +  +3x +3x +3x +  +1x +  +  +4x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +1x +1x +1x +5x +  +5x +5x +5x +5x +  +4x +4x +4x +4x +  +4x +4x +4x +  +4x +  +1x +104x +104x +104x +104x +104x +104x +104x +104x +104x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +  +104x +104x +35x +35x +  +  +35x +35x +35x +35x +34x +34x +34x +34x +  +35x +104x +104x +  +104x +104x +18x +16x +16x +18x +18x +  +  +18x +18x +  +  +  +  +2x +2x +18x +18x +18x +2x +2x +2x +18x +104x +104x +  +104x +104x +104x +104x +104x +  +104x +17x +17x +17x +17x +  +  +17x +17x +17x +  +17x +17x +17x +17x +104x +  +104x +17x +17x +3x +3x +3x +3x +3x +3x +14x +14x +14x +  +  +14x +14x +14x +  +14x +14x +14x +14x +104x +  +104x +104x +167x +  +  +167x +167x +167x +167x +167x +  +167x +167x +167x +167x +104x +104x +  +104x +17x +17x +3x +3x +3x +3x +3x +  +14x +166x +  +  +166x +166x +  +14x +14x +14x +14x +14x +14x +104x +  +104x +36x +13x +15x +15x +15x +15x +15x +15x +13x +  +13x +13x +13x +13x +13x +36x +104x +  +104x +104x +1x +  +  +1x +1x +1x +1x +1x +  +1x +1x +104x +104x +  +104x +1x +  +  +1x +1x +1x +1x +1x +  +1x +104x +  +104x +104x +42x +62x +104x +  +104x +104x +  +104x +  +104x +104x +104x +104x +104x +  +104x +17x +14x +14x +3x +104x +  +104x +46x +34x +34x +46x +  +  +104x +  +104x +31x +31x +21x +21x +21x +21x +21x +  +31x +31x +161x +161x +161x +161x +161x +161x +161x +  +  +161x +161x +  +  +  +  +  +  +161x +  +31x +31x +31x +10x +10x +10x +104x +104x +104x +104x +104x +104x +  +104x +17x +17x +17x +17x +16x +17x +104x +  +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +  +104x +  +27x +104x +  +104x +1x +  +  +  +1x +  +  +  +1x +1x +1x +1x +1x +  +1x +1x +  +1x +1x +1x +  +  +1x +1x +  +  +  +  +1x +  +1x +1x +  +  +  +  +1x +1x +1x +1x +1x +  +  +  +  +1x +  +  +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +  +104x +1x +1x +1x +  +  +  +1x +1x +1x +1x +  +  +  +1x +1x +1x +  +  +1x +1x +1x +  +1x +1x +1x +104x +104x +104x +104x +104x +104x +104x +104x +104x +  +104x +104x +104x +104x +104x +  +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +  +104x +104x +104x +104x +104x +104x +104x +12x +  +  +12x +12x +104x +104x +104x +  +104x +104x +104x +104x +104x +  +104x +15x +15x +11x +11x +11x +11x +11x +11x +10x +10x +10x +11x +  +11x +11x +15x +15x +15x +15x +  +  +  +15x +15x +  +15x +15x +15x +15x +15x +  +15x +15x +  +104x +104x +  +104x +104x +104x +104x +104x +104x +42x +4x +38x +62x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +9x +95x +53x +42x +11x +31x +  +104x +10x +  +  +10x +3x +3x +3x +7x +10x +  +104x +104x +104x +104x +104x +104x +104x +104x +104x +104x +9x +95x +53x +42x +  +104x +1x +1x +  +104x +104x +104x +104x +104x +104x +1x +1x +1x +103x +104x +9x +  +9x +95x +42x +42x +50x +50x +4x +46x +50x +50x +50x +50x +  +50x +50x +50x +50x +50x +3x +47x +4x +  +43x +  +50x +50x +50x +4x +4x +4x +46x +50x +50x +2x +2x +12x +12x +12x +12x +12x +12x +12x +12x +12x +12x +12x +12x +  +12x +12x +12x +12x +12x +  +2x +2x +48x +50x +  +42x +42x +  +53x +  +53x +  +104x +104x +  +104x +4x +4x +4x +4x +4x +4x +4x +4x +  +104x +  +104x + 
    import CheckSquare2 from "lucide-react/dist/esm/icons/check-square-2";
    +import ChevronDown from "lucide-react/dist/esm/icons/chevron-down";
    +import Circle from "lucide-react/dist/esm/icons/circle";
    +import Pencil from "lucide-react/dist/esm/icons/pencil";
    +import RefreshCw from "lucide-react/dist/esm/icons/refresh-cw";
    +import LayoutTemplate from "lucide-react/dist/esm/icons/layout-template";
    +import Pause from "lucide-react/dist/esm/icons/pause";
    +import Play from "lucide-react/dist/esm/icons/play";
    +import { useCallback, useEffect, useMemo, useRef, useState } from "react";
    +import type { CollaborationModeOption, WorkspaceInfo } from "../../../types";
    +import { ModalShell } from "../../design-system/components/modal/ModalShell";
    +import {
    +  PopoverMenuItem,
    +  PopoverSurface,
    +} from "../../design-system/components/popover/PopoverPrimitives";
    +import { useDismissibleMenu } from "../../app/hooks/useDismissibleMenu";
    +import {
    +  forgeGetInstalledTemplate,
    +  forgeInstallTemplate,
    +  forgeLoadPhaseView,
    +  forgeListBundledTemplates,
    +  forgeUninstallTemplate,
    +  type ForgeBundledTemplateInfo,
    +  type ForgeNextPhasePrompt,
    +  type ForgePhaseViewStatus,
    +  type ForgePhaseView,
    +  type ForgePhaseStatus,
    +  type ForgeRunPhaseChecksResponse,
    +  type ForgeTemplateLock,
    +  type ForgeWorkspacePlan,
    +} from "../../../services/tauri";
    +import {
    +  connectWorkspace,
    +  forgeResetExecutionProgress,
    +  forgeGetNextPhasePrompt,
    +  forgeGetPlanPrompt,
    +  forgeGetPhaseStatus,
    +  forgeListPlans,
    +  forgePrepareExecution,
    +  forgeRunPhaseChecks,
    +  interruptTurn,
    +  sendUserMessage,
    +  startThread,
    +} from "../../../services/tauri";
    +import { useForgeExecution } from "../hooks/useForgeExecution";
    +import { getForgePhaseIconUrl } from "../../../utils/forgePhaseIcons";
    + 
    +export type ForgeTemplatesClient = {
    +  listBundledTemplates: () => Promise<ForgeBundledTemplateInfo[]>;
    +  getInstalledTemplate: (workspaceId: string) => Promise<ForgeTemplateLock | null>;
    +  installTemplate: (workspaceId: string, templateId: string) => Promise<ForgeTemplateLock>;
    +  uninstallTemplate: (workspaceId: string) => Promise<void>;
    +};
    + 
    +export type ForgePlansClient = {
    +  listPlans: (workspaceId: string) => Promise<ForgeWorkspacePlan[]>;
    +  loadPhaseView?: (
    +    workspaceId: string,
    +    planId: string,
    +    installedTemplateId: string | null,
    +  ) => Promise<ForgePhaseView>;
    +  getPlanPrompt: (workspaceId: string) => Promise<string>;
    +  prepareExecution: (workspaceId: string, planId: string) => Promise<void>;
    +  resetExecutionProgress: (workspaceId: string, planId: string) => Promise<void>;
    +  getNextPhasePrompt: (
    +    workspaceId: string,
    +    planId: string,
    +  ) => Promise<ForgeNextPhasePrompt | null>;
    +  getPhaseStatus: (
    +    workspaceId: string,
    +    planId: string,
    +    taskId: string,
    +    phaseId: string,
    +  ) => Promise<ForgePhaseStatus>;
    +  runPhaseChecks: (
    +    workspaceId: string,
    +    planId: string,
    +    taskId: string,
    +    phaseId: string,
    +  ) => Promise<ForgeRunPhaseChecksResponse>;
    +  interruptTurn: (
    +    workspaceId: string,
    +    threadId: string,
    +    turnId: string,
    +  ) => Promise<unknown>;
    +  connectWorkspace: (workspaceId: string) => Promise<void>;
    +  startThread: (workspaceId: string) => Promise<any>;
    +  sendUserMessage: (
    +    workspaceId: string,
    +    threadId: string,
    +    text: string,
    +    options?: {
    +      collaborationMode?: Record<string, unknown> | null;
    +    },
    +  ) => Promise<any>;
    +};
    + 
    +const defaultForgeTemplatesClient: ForgeTemplatesClient = {
    +  listBundledTemplates: forgeListBundledTemplates,
    +  getInstalledTemplate: forgeGetInstalledTemplate,
    +  installTemplate: forgeInstallTemplate,
    +  uninstallTemplate: forgeUninstallTemplate,
    +};
    + 
    +const defaultForgePlansClient: ForgePlansClient = {
    +  listPlans: forgeListPlans,
    +  loadPhaseView: forgeLoadPhaseView,
    +  getPlanPrompt: forgeGetPlanPrompt,
    +  prepareExecution: forgePrepareExecution,
    +  resetExecutionProgress: forgeResetExecutionProgress,
    +  getNextPhasePrompt: forgeGetNextPhasePrompt,
    +  getPhaseStatus: forgeGetPhaseStatus,
    +  runPhaseChecks: forgeRunPhaseChecks,
    +  interruptTurn,
    +  connectWorkspace,
    +  startThread,
    +  sendUserMessage,
    +};
    + 
    +type ForgeItemStatus = "pending" | "inProgress" | "completed";
    + 
    +type ForgePlanItem = {
    +  id: string;
    +  title: string;
    +  status: ForgeItemStatus;
    +};
    + 
    +type ForgePlan = {
    +  id: string;
    +  name: string;
    +  items: ForgePlanItem[];
    +};
    + 
    +const EMPTY_PHASE_VIEW: ForgePhaseView = {
    +  phases: [],
    +  taskPhaseStatusByTaskId: {},
    +};
    + 
    +type ForgePhaseChipState = "is-complete" | "is-current" | "is-pending";
    + 
    +function formatPlanLabel(plan: ForgeWorkspacePlan): string {
    +  const title = plan.title?.trim() ?? "";
    +  const goal = plan.goal?.trim() ?? "";
    +  const id = plan.id?.trim() ?? "";
    +  if (title && id) {
    +    return `${title} (${id})`;
    +  }
    +  if (title) {
    +    return title;
    +  }
    +  const shortGoal =
    +    goal.length > 60 ? `${goal.slice(0, 57).trimEnd()}...` : goal;
    +  if (shortGoal && id) {
    +    return `${shortGoal} (${id})`;
    +  }
    +  return shortGoal || id || "Untitled plan";
    +}
    + 
    +function mapForgeItemStatus(status: string): ForgeItemStatus {
    +  const normalized = status.trim().toLowerCase();
    +  if (normalized === "completed") {
    +    return "completed";
    +  }
    +  if (normalized === "in_progress") {
    +    return "inProgress";
    +  }
    +  return "pending";
    +}
    + 
    +function mapForgePhaseChipState(
    +  taskId: string,
    +  phaseId: string,
    +  phaseStatus: ForgePhaseViewStatus,
    +  runningInfo: { taskId: string; phaseId: string } | null,
    +): ForgePhaseChipState {
    +  const normalizedStatus = phaseStatus.trim().toLowerCase();
    +  if (runningInfo?.taskId === taskId && runningInfo.phaseId === phaseId) {
    +    return "is-current";
    +  }
    +  if (normalizedStatus === "in_progress") {
    +    return "is-current";
    +  }
    +  if (normalizedStatus === "completed") {
    +    return "is-complete";
    +  }
    +  return "is-pending";
    +}
    + 
    +function ForgeTemplatesModal({
    +  templates,
    +  installedTemplate,
    +  canManage,
    +  onInstallTemplate,
    +  onUninstallTemplate,
    +  onClose,
    +}: {
    +  templates: ForgeBundledTemplateInfo[];
    +  installedTemplate: ForgeTemplateLock | null;
    +  canManage: boolean;
    +  onInstallTemplate: (templateId: string) => void;
    +  onUninstallTemplate: () => void;
    +  onClose: () => void;
    +}) {
    +  useEffect(() => {
    +    const handleKeyDown = (event: KeyboardEvent) => {
    +      if (event.key !== "Escape") {
    +        return;
    +      }
    +      event.preventDefault();
    +      onClose();
    +    };
    +    window.addEventListener("keydown", handleKeyDown);
    +    return () => window.removeEventListener("keydown", handleKeyDown);
    +  }, [onClose]);
    + 
    +  const installed = installedTemplate
    +    ? templates.find((t) => t.id === installedTemplate.installedTemplateId) ?? {
    +        id: installedTemplate.installedTemplateId,
    +        title: installedTemplate.installedTemplateId,
    +        version: installedTemplate.installedTemplateVersion,
    +      }
    +    : null;
    +  const others = installed
    +    ? templates.filter((t) => t.id !== installed.id)
    +    : templates;
    + 
    +  return (
    +    <ModalShell
    +      className="forge-templates-modal"
    +      onBackdropClick={onClose}
    +      ariaLabel="Forge templates"
    +    >
    +      <div className="ds-modal-title forge-templates-title">Templates</div>
    +      <div className="ds-modal-subtitle forge-templates-subtitle">
    +        Choose a template to install or swap. Behaviors are stubbed for now.
    +      </div>
    +      <div className="ds-modal-divider" />
    +      <div className="forge-templates-list" role="list">
    +        {installed ? (
    +          <div className="forge-template-row" role="listitem">
    +            <div className="forge-template-main">
    +              <div className="forge-template-name">{installed.title}</div>
    +              <div className="forge-template-meta">
    +                Installed{installed.version ? ` (${installed.version})` : ""}
    +              </div>
    +            </div>
    +            <div className="forge-template-actions">
    +              <button
    +                type="button"
    +                className="ghost forge-template-icon"
    +                aria-label="Edit template"
    +                title="Edit template"
    +                onClick={() => {
    +                  // TODO(Forge): wire template edit
    +                }}
    +              >
    +                <Pencil aria-hidden />
    +              </button>
    +              <button
    +                type="button"
    +                className="ghost forge-template-action"
    +                onClick={() => {
    +                  onUninstallTemplate();
    +                  onClose();
    +                }}
    +                disabled={!canManage}
    +              >
    +                Remove
    +              </button>
    +            </div>
    +          </div>
    +        ) : (
    +          <div className="forge-template-empty">No template installed.</div>
    +        )}
    + 
    +        {others.map((template) => {
    +          const actionLabel = installed ? "Swap" : "Install";
    +          return (
    +            <div key={template.id} className="forge-template-row" role="listitem">
    +              <div className="forge-template-main">
    +                <div className="forge-template-name">{template.title}</div>
    +              </div>
    +              <div className="forge-template-actions">
    +                <button
    +                  type="button"
    +                  className="ghost forge-template-action"
    +                  onClick={() => {
    +                    onInstallTemplate(template.id);
    +                    onClose();
    +                  }}
    +                  disabled={!canManage}
    +                >
    +                  {actionLabel}
    +                </button>
    +              </div>
    +            </div>
    +          );
    +        })}
    +      </div>
    +      <div className="ds-modal-actions forge-templates-actions">
    +        <button type="button" className="ghost ds-modal-button" onClick={onClose}>
    +          Close
    +        </button>
    +      </div>
    +    </ModalShell>
    +  );
    +}
    + 
    +export function Forge({
    +  activeWorkspaceId,
    +  activeWorkspace = null,
    +  sendUserMessageToThread,
    +  templatesClient,
    +  plansClient,
    +  onSelectThread,
    +  collaborationModes = [],
    +  onSelectCollaborationMode,
    +}: {
    +  activeWorkspaceId: string | null;
    +  activeWorkspace?: WorkspaceInfo | null;
    +  sendUserMessageToThread?: (
    +    workspace: WorkspaceInfo,
    +    threadId: string,
    +    message: string,
    +    imageIds: string[],
    +    options?: {
    +      collaborationMode?: Record<string, unknown> | null;
    +    },
    +  ) => Promise<void>;
    +  templatesClient?: ForgeTemplatesClient;
    +  plansClient?: ForgePlansClient;
    +  onSelectThread?: (workspaceId: string, threadId: string) => void;
    +  collaborationModes?: CollaborationModeOption[];
    +  onSelectCollaborationMode?: (id: string | null) => void;
    +}) {
    +  const client = templatesClient ?? defaultForgeTemplatesClient;
    +  const plansApi = plansClient ?? defaultForgePlansClient;
    +  const listBundledTemplates = client.listBundledTemplates;
    +  const getInstalledTemplate = client.getInstalledTemplate;
    +  const installTemplate = client.installTemplate;
    +  const uninstallTemplate = client.uninstallTemplate;
    +  const listPlans = plansApi.listPlans;
    +  const loadPhaseView = plansApi.loadPhaseView ?? forgeLoadPhaseView;
    +  const getPlanPrompt = plansApi.getPlanPrompt;
    +  const prepareExecution = plansApi.prepareExecution;
    +  const resetExecutionProgress = plansApi.resetExecutionProgress;
    +  const getNextPhasePrompt = plansApi.getNextPhasePrompt;
    +  const getPhaseStatus = plansApi.getPhaseStatus;
    +  const runPhaseChecks = plansApi.runPhaseChecks;
    +  const interruptPlanTurn = plansApi.interruptTurn;
    +  const connectWorkspaceToRun = plansApi.connectWorkspace;
    +  const startThreadForPlan = plansApi.startThread;
    +  const sendUserMessageToPlanThread = plansApi.sendUserMessage;
    +  const hasActiveWorkspace = Boolean(activeWorkspaceId?.trim());
    + 
    +  const findCollaborationMode = useCallback(
    +    (wanted: string) => {
    +      const normalized = wanted.trim().toLowerCase();
    +      if (!normalized) {
    +        return null;
    +      }
    +      return (
    +        collaborationModes.find(
    +          (mode) => mode.id.trim().toLowerCase() === normalized,
    +        ) ??
    +        collaborationModes.find(
    +          (mode) => (mode.mode || mode.id).trim().toLowerCase() === normalized,
    +        ) ??
    +        null
    +      );
    +    },
    +    [collaborationModes],
    +  );
    + 
    +  const buildCollaborationModePayloadFor = useCallback(
    +    (mode: CollaborationModeOption | null) => {
    +      if (!mode) {
    +        return null;
    +      }
    +      const modeValue = mode.mode || mode.id;
    +      if (!modeValue) {
    +        return null;
    +      }
    +      const modelValue = (mode.model ?? "").trim();
    +      if (!modelValue) {
    +        // CollaborationMode.settings.model is required by the app-server protocol.
    +        // If we can't supply a model, don't send an override payload.
    +        return null;
    +      }
    +      const settings: Record<string, unknown> = {
    +        developer_instructions: mode.developerInstructions ?? null,
    +        model: modelValue,
    +      };
    +      if (mode.reasoningEffort !== null) {
    +        settings.reasoning_effort = mode.reasoningEffort;
    +      }
    +      return { mode: modeValue, settings };
    +    },
    +    [],
    +  );
    + 
    +  const [templates, setTemplates] = useState<ForgeBundledTemplateInfo[]>([]);
    +  const [installedTemplate, setInstalledTemplate] = useState<ForgeTemplateLock | null>(null);
    +  const [workspacePlans, setWorkspacePlans] = useState<ForgeWorkspacePlan[]>([]);
    +  const [isResettingProgress, setIsResettingProgress] = useState(false);
    +  const plansInFlightRef = useRef(false);
    + 
    +  useEffect(() => {
    +    let cancelled = false;
    +    void listBundledTemplates()
    +      .then((items) => {
    +        if (cancelled) {
    +          return;
    +        }
    +        setTemplates(items);
    +      })
    +      .catch((error) => {
    +        console.warn("Failed to load Forge templates.", { error });
    +      });
    +    return () => {
    +      cancelled = true;
    +    };
    +  }, [listBundledTemplates]);
    + 
    +  useEffect(() => {
    +    let cancelled = false;
    +    if (!activeWorkspaceId) {
    +      setInstalledTemplate(null);
    +      setWorkspacePlans([]);
    +      return () => {
    +        cancelled = true;
    +      };
    +    }
    +    void getInstalledTemplate(activeWorkspaceId)
    +      .then((installed) => {
    +        if (cancelled) {
    +          return;
    +        }
    +        setInstalledTemplate(installed);
    +      })
    +      .catch((error) => {
    +        console.warn("Failed to load installed Forge template.", { error });
    +      });
    +    return () => {
    +      cancelled = true;
    +    };
    +  }, [activeWorkspaceId, getInstalledTemplate]);
    + 
    +  const refreshPlans = useCallback(
    +    async (workspaceId: string) => {
    +      if (plansInFlightRef.current) {
    +        return;
    +      }
    +      plansInFlightRef.current = true;
    +      try {
    +        const next = await listPlans(workspaceId);
    +        setWorkspacePlans(next);
    +      } catch (error) {
    +        console.warn("Failed to load Forge plans.", { error });
    +      } finally {
    +        plansInFlightRef.current = false;
    +      }
    +    },
    +    [listPlans],
    +  );
    + 
    +  useEffect(() => {
    +    let cancelled = false;
    +    if (!activeWorkspaceId) {
    +      setWorkspacePlans([]);
    +      return () => {
    +        cancelled = true;
    +      };
    +    }
    + 
    +    const loadPlans = async () => {
    +      if (cancelled) {
    +        return;
    +      }
    +      await refreshPlans(activeWorkspaceId);
    +    };
    + 
    +    void loadPlans();
    +    const interval = window.setInterval(loadPlans, 2000);
    +    return () => {
    +      cancelled = true;
    +      window.clearInterval(interval);
    +    };
    +  }, [activeWorkspaceId, refreshPlans]);
    + 
    +  const plans: ForgePlan[] = useMemo(() => {
    +    return workspacePlans.map((plan) => {
    +      const items: ForgePlanItem[] = plan.tasks.map((task) => {
    +        const status = mapForgeItemStatus(task.status);
    +        return {
    +          id: task.id,
    +          title: task.name,
    +          status,
    +        };
    +      });
    + 
    +      return {
    +        id: plan.id,
    +        name: formatPlanLabel(plan),
    +        items,
    +      };
    +    });
    +  }, [workspacePlans]);
    + 
    +  const handleInstallTemplate = useCallback(
    +    (templateId: string) => {
    +      if (!activeWorkspaceId) {
    +        return;
    +      }
    +      void installTemplate(activeWorkspaceId, templateId)
    +        .then((lock) => {
    +          setInstalledTemplate(lock);
    +        })
    +        .catch((error) => {
    +          console.warn("Failed to install Forge template.", { error });
    +        });
    +    },
    +    [activeWorkspaceId, installTemplate],
    +  );
    + 
    +  const handleUninstallTemplate = useCallback(() => {
    +    if (!activeWorkspaceId) {
    +      return;
    +    }
    +    void uninstallTemplate(activeWorkspaceId)
    +      .then(() => {
    +        setInstalledTemplate(null);
    +      })
    +      .catch((error) => {
    +        console.warn("Failed to uninstall Forge template.", { error });
    +      });
    +  }, [activeWorkspaceId, uninstallTemplate]);
    + 
    +  const [selectedPlanId, setSelectedPlanId] = useState<string | null>(null);
    +  const selectedPlan = selectedPlanId
    +    ? plans.find((p) => p.id === selectedPlanId) ?? null
    +    : null;
    +  const [phaseView, setPhaseView] = useState<ForgePhaseView>(EMPTY_PHASE_VIEW);
    + 
    +  const [planMenuOpen, setPlanMenuOpen] = useState(false);
    +  const planMenuRef = useRef<HTMLDivElement | null>(null);
    + 
    +  const [templatesOpen, setTemplatesOpen] = useState(false);
    + 
    +  useDismissibleMenu({
    +    isOpen: planMenuOpen,
    +    containerRef: planMenuRef,
    +    onClose: () => setPlanMenuOpen(false),
    +  });
    + 
    +  useEffect(() => {
    +    if (hasActiveWorkspace) {
    +      return;
    +    }
    +    setPlanMenuOpen(false);
    +  }, [hasActiveWorkspace]);
    + 
    +  useEffect(() => {
    +    if (!selectedPlanId) {
    +      return;
    +    }
    +    if (!plans.some((plan) => plan.id === selectedPlanId)) {
    +      setSelectedPlanId(null);
    +    }
    +  }, [plans, selectedPlanId]);
    + 
    +  useEffect(() => {
    +    let cancelled = false;
    +    if (!activeWorkspaceId || !selectedPlanId) {
    +      setPhaseView(EMPTY_PHASE_VIEW);
    +      return () => {
    +        cancelled = true;
    +      };
    +    }
    + 
    +    const installedTemplateId = installedTemplate?.installedTemplateId ?? null;
    +    const refreshPhaseView = async () => {
    +      try {
    +        const next = await loadPhaseView(
    +          activeWorkspaceId,
    +          selectedPlanId,
    +          installedTemplateId,
    +        );
    +        if (cancelled) {
    +          return;
    +        }
    +        setPhaseView(next);
    +      } catch (error) {
    +        if (cancelled) {
    +          return;
    +        }
    +        console.warn("Failed to load Forge phase view.", { error });
    +        setPhaseView(EMPTY_PHASE_VIEW);
    +      }
    +    };
    + 
    +    void refreshPhaseView();
    +    const interval = window.setInterval(refreshPhaseView, 2000);
    +    return () => {
    +      cancelled = true;
    +      window.clearInterval(interval);
    +    };
    +  }, [
    +    activeWorkspaceId,
    +    installedTemplate?.installedTemplateId,
    +    loadPhaseView,
    +    selectedPlanId,
    +  ]);
    + 
    +  const executionMode = useMemo(() => {
    +    const mode =
    +      findCollaborationMode("default") ??
    +      findCollaborationMode("code") ??
    +      collaborationModes[0] ??
    +      null;
    +    return buildCollaborationModePayloadFor(mode);
    +  }, [buildCollaborationModePayloadFor, collaborationModes, findCollaborationMode]);
    + 
    +  const {
    +    isExecuting,
    +    runningInfo,
    +    lastError,
    +    startExecution,
    +    pauseExecution,
    +  } = useForgeExecution({
    +    workspaceId: activeWorkspaceId,
    +    connectWorkspace: connectWorkspaceToRun,
    +    prepareExecution,
    +    getNextPhasePrompt,
    +    getPhaseStatus,
    +    runPhaseChecks,
    +    interruptTurn: interruptPlanTurn,
    +    startThread: startThreadForPlan,
    +    sendUserMessage: sendUserMessageToPlanThread,
    +    onSelectThread,
    +    collaborationMode: executionMode,
    +  });
    + 
    +  useEffect(() => {
    +    // Avoid executing the wrong plan if the user switches selection mid-run.
    +    void pauseExecution();
    +  }, [pauseExecution, selectedPlanId]);
    + 
    +  const handleNewPlan = useCallback(async () => {
    +    if (!activeWorkspaceId) {
    +      return;
    +    }
    + 
    +    setPlanMenuOpen(false);
    + 
    +    // Start in plan collaboration mode so the UI shows the structured plan turn item.
    +    // Writing plan files is handled after planning (outside plan mode).
    +    const planMode = findCollaborationMode("plan");
    +    if (planMode?.id) {
    +      onSelectCollaborationMode?.(planMode.id);
    +    }
    +    const collaborationMode = buildCollaborationModePayloadFor(planMode);
    + 
    +    try {
    +      await connectWorkspaceToRun(activeWorkspaceId);
    + 
    +      const response = await startThreadForPlan(activeWorkspaceId);
    +      const thread =
    +        (response?.result?.thread ?? response?.thread ?? null) as
    +          | Record<string, unknown>
    +          | null;
    +      const threadId = String(thread?.id ?? "").trim();
    +      if (!threadId) {
    +        console.warn("Forge new plan: missing thread id.", { response });
    +        return;
    +      }
    + 
    +      onSelectThread?.(activeWorkspaceId, threadId);
    + 
    +      const prompt = await getPlanPrompt(activeWorkspaceId);
    +      if (!prompt.trim()) {
    +        console.warn("Forge new plan: plan prompt is empty.");
    +        return;
    +      }
    + 
    +      if (sendUserMessageToThread && activeWorkspace?.id === activeWorkspaceId) {
    +        await sendUserMessageToThread(activeWorkspace, threadId, prompt, [], {
    +          collaborationMode,
    +        });
    +      } else {
    +        await sendUserMessageToPlanThread(activeWorkspaceId, threadId, prompt, {
    +          collaborationMode,
    +        });
    +      }
    +    } catch (error) {
    +      console.warn("Forge new plan: failed to start plan thread.", { error });
    +    }
    +  }, [
    +    activeWorkspaceId,
    +    activeWorkspace,
    +    buildCollaborationModePayloadFor,
    +    connectWorkspaceToRun,
    +    findCollaborationMode,
    +    getPlanPrompt,
    +    onSelectCollaborationMode,
    +    onSelectThread,
    +    sendUserMessageToPlanThread,
    +    sendUserMessageToThread,
    +    startThreadForPlan,
    +  ]);
    + 
    +  const handleCleanProgress = useCallback(async () => {
    +    const workspaceId = activeWorkspaceId?.trim();
    +    const planId = selectedPlanId?.trim();
    +    if (!workspaceId || !planId || isResettingProgress) {
    +      return;
    +    }
    + 
    +    const confirmed = window.confirm(
    +      "Clean progress will reset this plan's state and derived execution files. Continue?",
    +    );
    +    if (!confirmed) {
    +      return;
    +    }
    + 
    +    setIsResettingProgress(true);
    +    try {
    +      if (isExecuting) {
    +        await pauseExecution();
    +      }
    +      await resetExecutionProgress(workspaceId, planId);
    +      await refreshPlans(workspaceId);
    +    } catch (error) {
    +      console.warn("Forge clean progress failed.", { error });
    +    } finally {
    +      setIsResettingProgress(false);
    +    }
    +  }, [
    +    activeWorkspaceId,
    +    isExecuting,
    +    isResettingProgress,
    +    pauseExecution,
    +    refreshPlans,
    +    resetExecutionProgress,
    +    selectedPlanId,
    +  ]);
    + 
    +  return (
    +    <div className="forge-panel" data-testid="forge-panel">
    +      <div className="forge-header">
    +        <div className="forge-title">Forge</div>
    +      </div>
    + 
    +      <section className="forge-card" aria-label="Plan selection">
    +        <div className="forge-card-header">
    +          <div className="forge-card-title">Plan</div>
    +        </div>
    +        <div className="forge-plan-select" ref={planMenuRef}>
    +          <button
    +            type="button"
    +            className="ghost forge-template-toggle"
    +            aria-label="Open templates"
    +            title="Templates"
    +            data-tauri-drag-region="false"
    +            onClick={() => setTemplatesOpen(true)}
    +            disabled={!hasActiveWorkspace}
    +          >
    +            <LayoutTemplate aria-hidden />
    +          </button>
    +          <button
    +            type="button"
    +            className={`ghost forge-plan-toggle${planMenuOpen ? " is-open" : ""}`}
    +            data-tauri-drag-region="false"
    +            onClick={() => {
    +              if (!hasActiveWorkspace) {
    +                return;
    +              }
    +              setPlanMenuOpen((open) => !open);
    +            }}
    +            aria-haspopup="menu"
    +            aria-expanded={planMenuOpen}
    +            disabled={!hasActiveWorkspace}
    +          >
    +            <span className={selectedPlan ? "forge-plan-name" : "forge-plan-empty"}>
    +              {selectedPlan ? selectedPlan.name : "Click to select"}
    +            </span>
    +            <ChevronDown aria-hidden />
    +          </button>
    + 
    +          {planMenuOpen && (
    +            <PopoverSurface className="forge-plan-menu" role="menu">
    +              {plans.map((plan) => (
    +                <PopoverMenuItem
    +                  key={plan.id}
    +                  role="menuitemradio"
    +                  aria-checked={selectedPlanId === plan.id}
    +                  active={selectedPlanId === plan.id}
    +                  onClick={() => {
    +                    setSelectedPlanId(plan.id);
    +                    setPlanMenuOpen(false);
    +                  }}
    +                  data-tauri-drag-region="false"
    +                >
    +                  {plan.name}
    +                </PopoverMenuItem>
    +              ))}
    +              <div className="forge-plan-menu-divider" aria-hidden />
    +              <PopoverMenuItem
    +                onClick={() => {
    +                  // TODO(Forge): wire file selection dialog
    +                  setPlanMenuOpen(false);
    +                }}
    +                data-tauri-drag-region="false"
    +              >
    +                Other...
    +              </PopoverMenuItem>
    +              <PopoverMenuItem
    +                onClick={handleNewPlan}
    +                data-tauri-drag-region="false"
    +              >
    +                New plan...
    +              </PopoverMenuItem>
    +            </PopoverSurface>
    +          )}
    +        </div>
    +      </section>
    + 
    +      <section className="forge-card" aria-label="Plan execution">
    +        <div className="forge-card-header">
    +          <div className="forge-card-header-left">
    +            <div className="forge-card-title">Execution</div>
    +            <div className="forge-card-subtitle">
    +              {selectedPlan
    +                ? runningInfo
    +                  ? `${selectedPlan.name} • ${runningInfo.taskId}/${runningInfo.phaseId}`
    +                  : selectedPlan.name
    +                : "No plan selected"}
    +            </div>
    +          </div>
    +          <div className="forge-card-header-actions">
    +            <button
    +              type="button"
    +              className="ghost forge-execute-toggle"
    +              data-tauri-drag-region="false"
    +              disabled={!hasActiveWorkspace || !selectedPlan}
    +              aria-label={isExecuting ? "Pause plan" : "Resume plan"}
    +              aria-pressed={isExecuting}
    +              title={
    +                !hasActiveWorkspace
    +                  ? "Select a project to use Forge"
    +                  : !selectedPlan
    +                  ? "Select a plan to run"
    +                  : isExecuting
    +                    ? "Pause plan"
    +                    : "Resume plan"
    +              }
    +              onClick={() => {
    +                if (!hasActiveWorkspace || !selectedPlan) {
    +                  return;
    +                }
    +                if (isExecuting) {
    +                  void pauseExecution();
    +                  return;
    +                }
    +                void startExecution(selectedPlan.id);
    +              }}
    +            >
    +              {isExecuting ? <Pause aria-hidden /> : <Play aria-hidden />}
    +            </button>
    +            <button
    +              type="button"
    +              className="ghost forge-reset-progress"
    +              data-tauri-drag-region="false"
    +              disabled={!hasActiveWorkspace || !selectedPlan || isResettingProgress}
    +              aria-label="Clean progress"
    +              title={
    +                !hasActiveWorkspace
    +                  ? "Select a project to use Forge"
    +                  : !selectedPlan
    +                  ? "Select a plan to clean progress"
    +                  : "Reset state and derived execution files"
    +              }
    +              onClick={() => {
    +                void handleCleanProgress();
    +              }}
    +            >
    +              {isResettingProgress ? "Resetting..." : "Clean progress"}
    +            </button>
    +          </div>
    +        </div>
    +        <div className="forge-execution">
    +          {lastError ? (
    +            <div className="forge-execution-error" role="alert">
    +              {lastError}
    +            </div>
    +          ) : null}
    +          {!hasActiveWorkspace ? (
    +            <div className="forge-empty">
    +              Select a project first to use Forge.
    +            </div>
    +          ) : selectedPlan ? (
    +            <ol className="forge-items">
    +              {selectedPlan.items.map((item, index) => {
    +                const isActiveTask = runningInfo?.taskId === item.id;
    +                const effectiveStatus: ForgeItemStatus = isActiveTask
    +                  ? "inProgress"
    +                  : item.status;
    +                const isCompleted = effectiveStatus === "completed";
    +                const isRunning = effectiveStatus === "inProgress";
    +                const isActivePhase = isActiveTask && runningInfo?.phaseId;
    +                const taskPhaseStatuses = phaseView.taskPhaseStatusByTaskId[item.id] ?? {};
    + 
    +                return (
    +                  <li key={`${item.id}-${item.title}-${index}`} className={`forge-item ${effectiveStatus}`}>
    +                    <div className="forge-item-row">
    +                      <span className="forge-item-icon" aria-hidden>
    +                        {isCompleted ? (
    +                          <CheckSquare2 aria-hidden />
    +                        ) : isRunning ? (
    +                          <RefreshCw className="forge-running-icon spinning" aria-hidden />
    +                        ) : (
    +                          <Circle aria-hidden />
    +                        )}
    +                      </span>
    +                      <span className="forge-item-title">{item.title}</span>
    +                      {isActivePhase ? (
    +                        <span className="forge-item-meta">
    +                          Phase {runningInfo.phaseId} in progress
    +                        </span>
    +                      ) : null}
    +                    </div>
    +                    {phaseView.phases.length > 0 ? (
    +                      <div className="forge-phases">
    +                        {phaseView.phases.map((phase) => {
    +                          const chipState = mapForgePhaseChipState(
    +                            item.id,
    +                            phase.id,
    +                            taskPhaseStatuses[phase.id] ?? "pending",
    +                            runningInfo,
    +                          );
    +                          const iconUrl = getForgePhaseIconUrl(phase.iconId);
    +                          return (
    +                            <span
    +                              key={`${item.id}-${phase.id}`}
    +                              className={`forge-phase ${chipState}`}
    +                              data-phase-id={phase.id}
    +                            >
    +                              <span className="forge-phase-icon" aria-hidden>
    +                                <img src={iconUrl} alt="" aria-hidden />
    +                              </span>
    +                              <span className="forge-phase-name">{phase.title}</span>
    +                            </span>
    +                          );
    +                        })}
    +                      </div>
    +                    ) : null}
    +                  </li>
    +                );
    +              })}
    +            </ol>
    +          ) : (
    +            <div className="forge-empty">
    +              Select a plan to see execution progress.
    +            </div>
    +          )}
    +        </div>
    +      </section>
    + 
    +      {templatesOpen && (
    +        <ForgeTemplatesModal
    +          templates={templates}
    +          installedTemplate={installedTemplate}
    +          canManage={Boolean(activeWorkspaceId)}
    +          onInstallTemplate={handleInstallTemplate}
    +          onUninstallTemplate={handleUninstallTemplate}
    +          onClose={() => setTemplatesOpen(false)}
    +        />
    +      )}
    +    </div>
    +  );
    +}
    + 
    + +
    +
    + + + + + + + + \ No newline at end of file diff --git a/coverage/base.css b/coverage/base.css new file mode 100644 index 0000000000..f418035b46 --- /dev/null +++ b/coverage/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/coverage/block-navigation.js b/coverage/block-navigation.js new file mode 100644 index 0000000000..530d1ed2ba --- /dev/null +++ b/coverage/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selector that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/coverage/clover.xml b/coverage/clover.xml new file mode 100644 index 0000000000..7768077e2b --- /dev/null +++ b/coverage/clover.xml @@ -0,0 +1,778 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json new file mode 100644 index 0000000000..0576991899 --- /dev/null +++ b/coverage/coverage-final.json @@ -0,0 +1,2 @@ +{"/Users/lstern/projects/forge/src/features/forge/components/Forge.tsx": {"path":"/Users/lstern/projects/forge/src/features/forge/components/Forge.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":70}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":67}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":56}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":56}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":63}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":73}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":54}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":52}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":74}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":77}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":8}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":72}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":8}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":8}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":63}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":70}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":59}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":50}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":50}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":40}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":44}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":2}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":51}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":28}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":36}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":36}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":42}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":54}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":46}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":38}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":38}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":16}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":19}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":14}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":18}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":2}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":42}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":13}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":30}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":2}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":60}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":41}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":39}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":35}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":20}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":30}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":3}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":14}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":17}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":3}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":19}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":66}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":24}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":34}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":3}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":44}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":1}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":62}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":49}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":35}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":23}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":3}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":37}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":24}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":3}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":19}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":1}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":32}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":17}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":18}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":36}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":58}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":24}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":60}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":74}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":24}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":3}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":43}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":24}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":3}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":41}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":25}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":3}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":22}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":1}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":30}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":12}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":20}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":12}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":20}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":22}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":10}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":4}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":4}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":19}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":53}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":35}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":15}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":7}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":29}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":16}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":6}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":54}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":70}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":16}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":37}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":80}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":50}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":53}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":60}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":7}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":11}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":26}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":52}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":16}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":10}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":15}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":39}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":31}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":33}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":75}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":66}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":12}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":42}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":56}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":22}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":62}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":49}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":74}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":51}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":77}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":20}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":18}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":52}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":21}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":29}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":53}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":42}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":37}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":32}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":18}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":38}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":23}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":21}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":29}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":55}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":32}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":40}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":28}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":18}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":37}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":15}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":23}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":18}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":16}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":76}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":35}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":61}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":18}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":82}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":51}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":75}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":20}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":54}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":23}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":31}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":57}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":34}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":51}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":30}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":20}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":39}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":31}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":25}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":20}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":18}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":11}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":12}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":64}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":82}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":17}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":12}},"304":{"start":{"line":305,"column":0},"end":{"line":305,"column":17}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":1}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":23}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":20}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":25}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":26}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":18}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":14}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":17}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":26}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":28}},"317":{"start":{"line":318,"column":0},"end":{"line":318,"column":4}},"334":{"start":{"line":335,"column":0},"end":{"line":335,"column":4}},"335":{"start":{"line":336,"column":0},"end":{"line":336,"column":64}},"336":{"start":{"line":337,"column":0},"end":{"line":337,"column":58}},"337":{"start":{"line":338,"column":0},"end":{"line":338,"column":59}},"338":{"start":{"line":339,"column":0},"end":{"line":339,"column":59}},"339":{"start":{"line":340,"column":0},"end":{"line":340,"column":49}},"340":{"start":{"line":341,"column":0},"end":{"line":341,"column":53}},"341":{"start":{"line":342,"column":0},"end":{"line":342,"column":39}},"342":{"start":{"line":343,"column":0},"end":{"line":343,"column":69}},"343":{"start":{"line":344,"column":0},"end":{"line":344,"column":47}},"344":{"start":{"line":345,"column":0},"end":{"line":345,"column":53}},"345":{"start":{"line":346,"column":0},"end":{"line":346,"column":65}},"346":{"start":{"line":347,"column":0},"end":{"line":347,"column":57}},"347":{"start":{"line":348,"column":0},"end":{"line":348,"column":49}},"348":{"start":{"line":349,"column":0},"end":{"line":349,"column":49}},"349":{"start":{"line":350,"column":0},"end":{"line":350,"column":51}},"350":{"start":{"line":351,"column":0},"end":{"line":351,"column":58}},"351":{"start":{"line":352,"column":0},"end":{"line":352,"column":50}},"352":{"start":{"line":353,"column":0},"end":{"line":353,"column":63}},"353":{"start":{"line":354,"column":0},"end":{"line":354,"column":64}},"355":{"start":{"line":356,"column":0},"end":{"line":356,"column":44}},"356":{"start":{"line":357,"column":0},"end":{"line":357,"column":25}},"357":{"start":{"line":358,"column":0},"end":{"line":358,"column":53}},"358":{"start":{"line":359,"column":0},"end":{"line":359,"column":24}},"359":{"start":{"line":360,"column":0},"end":{"line":360,"column":20}},"360":{"start":{"line":361,"column":0},"end":{"line":361,"column":7}},"361":{"start":{"line":362,"column":0},"end":{"line":362,"column":14}},"362":{"start":{"line":363,"column":0},"end":{"line":363,"column":32}},"363":{"start":{"line":364,"column":0},"end":{"line":364,"column":64}},"364":{"start":{"line":365,"column":0},"end":{"line":365,"column":12}},"365":{"start":{"line":366,"column":0},"end":{"line":366,"column":32}},"366":{"start":{"line":367,"column":0},"end":{"line":367,"column":79}},"367":{"start":{"line":368,"column":0},"end":{"line":368,"column":12}},"368":{"start":{"line":369,"column":0},"end":{"line":369,"column":12}},"370":{"start":{"line":371,"column":0},"end":{"line":371,"column":6}},"371":{"start":{"line":372,"column":0},"end":{"line":372,"column":25}},"372":{"start":{"line":373,"column":0},"end":{"line":373,"column":4}},"374":{"start":{"line":375,"column":0},"end":{"line":375,"column":55}},"375":{"start":{"line":376,"column":0},"end":{"line":376,"column":47}},"376":{"start":{"line":377,"column":0},"end":{"line":377,"column":18}},"377":{"start":{"line":378,"column":0},"end":{"line":378,"column":20}},"378":{"start":{"line":379,"column":0},"end":{"line":379,"column":7}},"379":{"start":{"line":380,"column":0},"end":{"line":380,"column":45}},"380":{"start":{"line":381,"column":0},"end":{"line":381,"column":23}},"381":{"start":{"line":382,"column":0},"end":{"line":382,"column":20}},"382":{"start":{"line":383,"column":0},"end":{"line":383,"column":7}},"383":{"start":{"line":384,"column":0},"end":{"line":384,"column":51}},"384":{"start":{"line":385,"column":0},"end":{"line":385,"column":24}},"387":{"start":{"line":388,"column":0},"end":{"line":388,"column":20}},"388":{"start":{"line":389,"column":0},"end":{"line":389,"column":7}},"389":{"start":{"line":390,"column":0},"end":{"line":390,"column":49}},"390":{"start":{"line":391,"column":0},"end":{"line":391,"column":67}},"391":{"start":{"line":392,"column":0},"end":{"line":392,"column":26}},"392":{"start":{"line":393,"column":0},"end":{"line":393,"column":8}},"393":{"start":{"line":394,"column":0},"end":{"line":394,"column":42}},"394":{"start":{"line":395,"column":0},"end":{"line":395,"column":57}},"395":{"start":{"line":396,"column":0},"end":{"line":396,"column":7}},"396":{"start":{"line":397,"column":0},"end":{"line":397,"column":43}},"397":{"start":{"line":398,"column":0},"end":{"line":398,"column":6}},"398":{"start":{"line":399,"column":0},"end":{"line":399,"column":7}},"399":{"start":{"line":400,"column":0},"end":{"line":400,"column":4}},"401":{"start":{"line":402,"column":0},"end":{"line":402,"column":77}},"402":{"start":{"line":403,"column":0},"end":{"line":403,"column":93}},"403":{"start":{"line":404,"column":0},"end":{"line":404,"column":81}},"404":{"start":{"line":405,"column":0},"end":{"line":405,"column":72}},"405":{"start":{"line":406,"column":0},"end":{"line":406,"column":41}},"407":{"start":{"line":408,"column":0},"end":{"line":408,"column":19}},"408":{"start":{"line":409,"column":0},"end":{"line":409,"column":26}},"409":{"start":{"line":410,"column":0},"end":{"line":410,"column":31}},"410":{"start":{"line":411,"column":0},"end":{"line":411,"column":24}},"411":{"start":{"line":412,"column":0},"end":{"line":412,"column":24}},"412":{"start":{"line":413,"column":0},"end":{"line":413,"column":17}},"413":{"start":{"line":414,"column":0},"end":{"line":414,"column":9}},"414":{"start":{"line":415,"column":0},"end":{"line":415,"column":28}},"415":{"start":{"line":416,"column":0},"end":{"line":416,"column":8}},"416":{"start":{"line":417,"column":0},"end":{"line":417,"column":25}},"417":{"start":{"line":418,"column":0},"end":{"line":418,"column":67}},"418":{"start":{"line":419,"column":0},"end":{"line":419,"column":9}},"419":{"start":{"line":420,"column":0},"end":{"line":420,"column":18}},"420":{"start":{"line":421,"column":0},"end":{"line":421,"column":23}},"421":{"start":{"line":422,"column":0},"end":{"line":422,"column":6}},"422":{"start":{"line":423,"column":0},"end":{"line":423,"column":29}},"424":{"start":{"line":425,"column":0},"end":{"line":425,"column":19}},"425":{"start":{"line":426,"column":0},"end":{"line":426,"column":26}},"426":{"start":{"line":427,"column":0},"end":{"line":427,"column":29}},"427":{"start":{"line":428,"column":0},"end":{"line":428,"column":33}},"428":{"start":{"line":429,"column":0},"end":{"line":429,"column":28}},"429":{"start":{"line":430,"column":0},"end":{"line":430,"column":20}},"430":{"start":{"line":431,"column":0},"end":{"line":431,"column":25}},"431":{"start":{"line":432,"column":0},"end":{"line":432,"column":8}},"432":{"start":{"line":433,"column":0},"end":{"line":433,"column":5}},"433":{"start":{"line":434,"column":0},"end":{"line":434,"column":48}},"434":{"start":{"line":435,"column":0},"end":{"line":435,"column":28}},"435":{"start":{"line":436,"column":0},"end":{"line":436,"column":24}},"436":{"start":{"line":437,"column":0},"end":{"line":437,"column":17}},"437":{"start":{"line":438,"column":0},"end":{"line":438,"column":9}},"438":{"start":{"line":439,"column":0},"end":{"line":439,"column":40}},"439":{"start":{"line":440,"column":0},"end":{"line":440,"column":8}},"440":{"start":{"line":441,"column":0},"end":{"line":441,"column":25}},"441":{"start":{"line":442,"column":0},"end":{"line":442,"column":76}},"442":{"start":{"line":443,"column":0},"end":{"line":443,"column":9}},"443":{"start":{"line":444,"column":0},"end":{"line":444,"column":18}},"444":{"start":{"line":445,"column":0},"end":{"line":445,"column":23}},"445":{"start":{"line":446,"column":0},"end":{"line":446,"column":6}},"446":{"start":{"line":447,"column":0},"end":{"line":447,"column":48}},"448":{"start":{"line":449,"column":0},"end":{"line":449,"column":35}},"449":{"start":{"line":450,"column":0},"end":{"line":450,"column":36}},"450":{"start":{"line":451,"column":0},"end":{"line":451,"column":37}},"451":{"start":{"line":452,"column":0},"end":{"line":452,"column":15}},"452":{"start":{"line":453,"column":0},"end":{"line":453,"column":7}},"453":{"start":{"line":454,"column":0},"end":{"line":454,"column":38}},"454":{"start":{"line":455,"column":0},"end":{"line":455,"column":11}},"455":{"start":{"line":456,"column":0},"end":{"line":456,"column":50}},"456":{"start":{"line":457,"column":0},"end":{"line":457,"column":32}},"457":{"start":{"line":458,"column":0},"end":{"line":458,"column":23}},"458":{"start":{"line":459,"column":0},"end":{"line":459,"column":63}},"459":{"start":{"line":460,"column":0},"end":{"line":460,"column":17}},"460":{"start":{"line":461,"column":0},"end":{"line":461,"column":41}},"461":{"start":{"line":462,"column":0},"end":{"line":462,"column":7}},"462":{"start":{"line":463,"column":0},"end":{"line":463,"column":6}},"463":{"start":{"line":464,"column":0},"end":{"line":464,"column":16}},"464":{"start":{"line":465,"column":0},"end":{"line":465,"column":4}},"466":{"start":{"line":467,"column":0},"end":{"line":467,"column":19}},"467":{"start":{"line":468,"column":0},"end":{"line":468,"column":26}},"468":{"start":{"line":469,"column":0},"end":{"line":469,"column":29}},"469":{"start":{"line":470,"column":0},"end":{"line":470,"column":28}},"470":{"start":{"line":471,"column":0},"end":{"line":471,"column":20}},"471":{"start":{"line":472,"column":0},"end":{"line":472,"column":25}},"472":{"start":{"line":473,"column":0},"end":{"line":473,"column":8}},"473":{"start":{"line":474,"column":0},"end":{"line":474,"column":5}},"475":{"start":{"line":476,"column":0},"end":{"line":476,"column":35}},"476":{"start":{"line":477,"column":0},"end":{"line":477,"column":22}},"477":{"start":{"line":478,"column":0},"end":{"line":478,"column":15}},"478":{"start":{"line":479,"column":0},"end":{"line":479,"column":7}},"479":{"start":{"line":480,"column":0},"end":{"line":480,"column":44}},"480":{"start":{"line":481,"column":0},"end":{"line":481,"column":6}},"482":{"start":{"line":483,"column":0},"end":{"line":483,"column":21}},"483":{"start":{"line":484,"column":0},"end":{"line":484,"column":57}},"484":{"start":{"line":485,"column":0},"end":{"line":485,"column":18}},"485":{"start":{"line":486,"column":0},"end":{"line":486,"column":23}},"486":{"start":{"line":487,"column":0},"end":{"line":487,"column":37}},"487":{"start":{"line":488,"column":0},"end":{"line":488,"column":6}},"488":{"start":{"line":489,"column":0},"end":{"line":489,"column":40}},"490":{"start":{"line":491,"column":0},"end":{"line":491,"column":44}},"491":{"start":{"line":492,"column":0},"end":{"line":492,"column":41}},"492":{"start":{"line":493,"column":0},"end":{"line":493,"column":63}},"493":{"start":{"line":494,"column":0},"end":{"line":494,"column":55}},"494":{"start":{"line":495,"column":0},"end":{"line":495,"column":16}},"495":{"start":{"line":496,"column":0},"end":{"line":496,"column":22}},"496":{"start":{"line":497,"column":0},"end":{"line":497,"column":27}},"497":{"start":{"line":498,"column":0},"end":{"line":498,"column":17}},"498":{"start":{"line":499,"column":0},"end":{"line":499,"column":10}},"499":{"start":{"line":500,"column":0},"end":{"line":500,"column":9}},"501":{"start":{"line":502,"column":0},"end":{"line":502,"column":14}},"502":{"start":{"line":503,"column":0},"end":{"line":503,"column":20}},"503":{"start":{"line":504,"column":0},"end":{"line":504,"column":36}},"504":{"start":{"line":505,"column":0},"end":{"line":505,"column":14}},"505":{"start":{"line":506,"column":0},"end":{"line":506,"column":8}},"506":{"start":{"line":507,"column":0},"end":{"line":507,"column":7}},"507":{"start":{"line":508,"column":0},"end":{"line":508,"column":23}},"509":{"start":{"line":510,"column":0},"end":{"line":510,"column":44}},"510":{"start":{"line":511,"column":0},"end":{"line":511,"column":29}},"511":{"start":{"line":512,"column":0},"end":{"line":512,"column":31}},"512":{"start":{"line":513,"column":0},"end":{"line":513,"column":15}},"513":{"start":{"line":514,"column":0},"end":{"line":514,"column":7}},"514":{"start":{"line":515,"column":0},"end":{"line":515,"column":57}},"515":{"start":{"line":516,"column":0},"end":{"line":516,"column":25}},"516":{"start":{"line":517,"column":0},"end":{"line":517,"column":37}},"517":{"start":{"line":518,"column":0},"end":{"line":518,"column":10}},"518":{"start":{"line":519,"column":0},"end":{"line":519,"column":27}},"519":{"start":{"line":520,"column":0},"end":{"line":520,"column":71}},"520":{"start":{"line":521,"column":0},"end":{"line":521,"column":11}},"521":{"start":{"line":522,"column":0},"end":{"line":522,"column":6}},"522":{"start":{"line":523,"column":0},"end":{"line":523,"column":41}},"523":{"start":{"line":524,"column":0},"end":{"line":524,"column":4}},"525":{"start":{"line":526,"column":0},"end":{"line":526,"column":53}},"526":{"start":{"line":527,"column":0},"end":{"line":527,"column":29}},"527":{"start":{"line":528,"column":0},"end":{"line":528,"column":13}},"528":{"start":{"line":529,"column":0},"end":{"line":529,"column":5}},"529":{"start":{"line":530,"column":0},"end":{"line":530,"column":45}},"530":{"start":{"line":531,"column":0},"end":{"line":531,"column":19}},"531":{"start":{"line":532,"column":0},"end":{"line":532,"column":35}},"532":{"start":{"line":533,"column":0},"end":{"line":533,"column":8}},"533":{"start":{"line":534,"column":0},"end":{"line":534,"column":25}},"534":{"start":{"line":535,"column":0},"end":{"line":535,"column":71}},"535":{"start":{"line":536,"column":0},"end":{"line":536,"column":9}},"536":{"start":{"line":537,"column":0},"end":{"line":537,"column":45}},"538":{"start":{"line":539,"column":0},"end":{"line":539,"column":76}},"539":{"start":{"line":540,"column":0},"end":{"line":540,"column":37}},"540":{"start":{"line":541,"column":0},"end":{"line":541,"column":56}},"541":{"start":{"line":542,"column":0},"end":{"line":542,"column":11}},"542":{"start":{"line":543,"column":0},"end":{"line":543,"column":79}},"544":{"start":{"line":545,"column":0},"end":{"line":545,"column":58}},"545":{"start":{"line":546,"column":0},"end":{"line":546,"column":58}},"547":{"start":{"line":548,"column":0},"end":{"line":548,"column":60}},"549":{"start":{"line":550,"column":0},"end":{"line":550,"column":22}},"550":{"start":{"line":551,"column":0},"end":{"line":551,"column":25}},"551":{"start":{"line":552,"column":0},"end":{"line":552,"column":30}},"552":{"start":{"line":553,"column":0},"end":{"line":553,"column":42}},"553":{"start":{"line":554,"column":0},"end":{"line":554,"column":5}},"555":{"start":{"line":556,"column":0},"end":{"line":556,"column":19}},"556":{"start":{"line":557,"column":0},"end":{"line":557,"column":29}},"557":{"start":{"line":558,"column":0},"end":{"line":558,"column":13}},"558":{"start":{"line":559,"column":0},"end":{"line":559,"column":5}},"559":{"start":{"line":560,"column":0},"end":{"line":560,"column":27}},"560":{"start":{"line":561,"column":0},"end":{"line":561,"column":27}},"562":{"start":{"line":563,"column":0},"end":{"line":563,"column":19}},"563":{"start":{"line":564,"column":0},"end":{"line":564,"column":26}},"564":{"start":{"line":565,"column":0},"end":{"line":565,"column":13}},"565":{"start":{"line":566,"column":0},"end":{"line":566,"column":5}},"566":{"start":{"line":567,"column":0},"end":{"line":567,"column":60}},"567":{"start":{"line":568,"column":0},"end":{"line":568,"column":30}},"568":{"start":{"line":569,"column":0},"end":{"line":569,"column":5}},"569":{"start":{"line":570,"column":0},"end":{"line":570,"column":30}},"571":{"start":{"line":572,"column":0},"end":{"line":572,"column":19}},"572":{"start":{"line":573,"column":0},"end":{"line":573,"column":26}},"573":{"start":{"line":574,"column":0},"end":{"line":574,"column":48}},"574":{"start":{"line":575,"column":0},"end":{"line":575,"column":37}},"575":{"start":{"line":576,"column":0},"end":{"line":576,"column":20}},"576":{"start":{"line":577,"column":0},"end":{"line":577,"column":25}},"577":{"start":{"line":578,"column":0},"end":{"line":578,"column":8}},"578":{"start":{"line":579,"column":0},"end":{"line":579,"column":5}},"580":{"start":{"line":581,"column":0},"end":{"line":581,"column":79}},"581":{"start":{"line":582,"column":0},"end":{"line":582,"column":42}},"582":{"start":{"line":583,"column":0},"end":{"line":583,"column":11}},"583":{"start":{"line":584,"column":0},"end":{"line":584,"column":41}},"584":{"start":{"line":585,"column":0},"end":{"line":585,"column":28}},"585":{"start":{"line":586,"column":0},"end":{"line":586,"column":25}},"586":{"start":{"line":587,"column":0},"end":{"line":587,"column":30}},"587":{"start":{"line":588,"column":0},"end":{"line":588,"column":10}},"588":{"start":{"line":589,"column":0},"end":{"line":589,"column":24}},"589":{"start":{"line":590,"column":0},"end":{"line":590,"column":17}},"590":{"start":{"line":591,"column":0},"end":{"line":591,"column":9}},"591":{"start":{"line":592,"column":0},"end":{"line":592,"column":27}},"592":{"start":{"line":593,"column":0},"end":{"line":593,"column":23}},"593":{"start":{"line":594,"column":0},"end":{"line":594,"column":24}},"594":{"start":{"line":595,"column":0},"end":{"line":595,"column":17}},"595":{"start":{"line":596,"column":0},"end":{"line":596,"column":9}},"596":{"start":{"line":597,"column":0},"end":{"line":597,"column":68}},"597":{"start":{"line":598,"column":0},"end":{"line":598,"column":39}},"598":{"start":{"line":599,"column":0},"end":{"line":599,"column":7}},"599":{"start":{"line":600,"column":0},"end":{"line":600,"column":6}},"601":{"start":{"line":602,"column":0},"end":{"line":602,"column":28}},"602":{"start":{"line":603,"column":0},"end":{"line":603,"column":64}},"603":{"start":{"line":604,"column":0},"end":{"line":604,"column":18}},"604":{"start":{"line":605,"column":0},"end":{"line":605,"column":23}},"605":{"start":{"line":606,"column":0},"end":{"line":606,"column":37}},"606":{"start":{"line":607,"column":0},"end":{"line":607,"column":6}},"607":{"start":{"line":608,"column":0},"end":{"line":608,"column":6}},"608":{"start":{"line":609,"column":0},"end":{"line":609,"column":22}},"609":{"start":{"line":610,"column":0},"end":{"line":610,"column":43}},"610":{"start":{"line":611,"column":0},"end":{"line":611,"column":18}},"611":{"start":{"line":612,"column":0},"end":{"line":612,"column":19}},"612":{"start":{"line":613,"column":0},"end":{"line":613,"column":5}},"614":{"start":{"line":615,"column":0},"end":{"line":615,"column":39}},"615":{"start":{"line":616,"column":0},"end":{"line":616,"column":16}},"616":{"start":{"line":617,"column":0},"end":{"line":617,"column":41}},"617":{"start":{"line":618,"column":0},"end":{"line":618,"column":38}},"618":{"start":{"line":619,"column":0},"end":{"line":619,"column":30}},"619":{"start":{"line":620,"column":0},"end":{"line":620,"column":11}},"620":{"start":{"line":621,"column":0},"end":{"line":621,"column":50}},"621":{"start":{"line":622,"column":0},"end":{"line":622,"column":84}},"623":{"start":{"line":624,"column":0},"end":{"line":624,"column":9}},"624":{"start":{"line":625,"column":0},"end":{"line":625,"column":16}},"625":{"start":{"line":626,"column":0},"end":{"line":626,"column":16}},"626":{"start":{"line":627,"column":0},"end":{"line":627,"column":14}},"627":{"start":{"line":628,"column":0},"end":{"line":628,"column":19}},"628":{"start":{"line":629,"column":0},"end":{"line":629,"column":19}},"629":{"start":{"line":630,"column":0},"end":{"line":630,"column":25}},"630":{"start":{"line":631,"column":0},"end":{"line":631,"column":35}},"631":{"start":{"line":632,"column":0},"end":{"line":632,"column":44}},"632":{"start":{"line":633,"column":0},"end":{"line":633,"column":21}},"633":{"start":{"line":634,"column":0},"end":{"line":634,"column":23}},"634":{"start":{"line":635,"column":0},"end":{"line":635,"column":19}},"635":{"start":{"line":636,"column":0},"end":{"line":636,"column":19}},"636":{"start":{"line":637,"column":0},"end":{"line":637,"column":37}},"637":{"start":{"line":638,"column":0},"end":{"line":638,"column":36}},"638":{"start":{"line":639,"column":0},"end":{"line":639,"column":49}},"639":{"start":{"line":640,"column":0},"end":{"line":640,"column":19}},"640":{"start":{"line":641,"column":0},"end":{"line":641,"column":37}},"641":{"start":{"line":642,"column":0},"end":{"line":642,"column":5}},"643":{"start":{"line":644,"column":0},"end":{"line":644,"column":19}},"645":{"start":{"line":646,"column":0},"end":{"line":646,"column":26}},"646":{"start":{"line":647,"column":0},"end":{"line":647,"column":39}},"648":{"start":{"line":649,"column":0},"end":{"line":649,"column":49}},"649":{"start":{"line":650,"column":0},"end":{"line":650,"column":29}},"650":{"start":{"line":651,"column":0},"end":{"line":651,"column":13}},"651":{"start":{"line":652,"column":0},"end":{"line":652,"column":5}},"653":{"start":{"line":654,"column":0},"end":{"line":654,"column":27}},"657":{"start":{"line":658,"column":0},"end":{"line":658,"column":51}},"658":{"start":{"line":659,"column":0},"end":{"line":659,"column":23}},"659":{"start":{"line":660,"column":0},"end":{"line":660,"column":47}},"660":{"start":{"line":661,"column":0},"end":{"line":661,"column":5}},"661":{"start":{"line":662,"column":0},"end":{"line":662,"column":73}},"663":{"start":{"line":664,"column":0},"end":{"line":664,"column":9}},"664":{"start":{"line":665,"column":0},"end":{"line":665,"column":53}},"666":{"start":{"line":667,"column":0},"end":{"line":667,"column":67}},"667":{"start":{"line":668,"column":0},"end":{"line":668,"column":20}},"668":{"start":{"line":669,"column":0},"end":{"line":669,"column":65}},"671":{"start":{"line":672,"column":0},"end":{"line":672,"column":55}},"672":{"start":{"line":673,"column":0},"end":{"line":673,"column":22}},"673":{"start":{"line":674,"column":0},"end":{"line":674,"column":73}},"674":{"start":{"line":675,"column":0},"end":{"line":675,"column":15}},"675":{"start":{"line":676,"column":0},"end":{"line":676,"column":7}},"677":{"start":{"line":678,"column":0},"end":{"line":678,"column":52}},"679":{"start":{"line":680,"column":0},"end":{"line":680,"column":60}},"680":{"start":{"line":681,"column":0},"end":{"line":681,"column":27}},"681":{"start":{"line":682,"column":0},"end":{"line":682,"column":62}},"682":{"start":{"line":683,"column":0},"end":{"line":683,"column":15}},"683":{"start":{"line":684,"column":0},"end":{"line":684,"column":7}},"685":{"start":{"line":686,"column":0},"end":{"line":686,"column":81}},"686":{"start":{"line":687,"column":0},"end":{"line":687,"column":78}},"687":{"start":{"line":688,"column":0},"end":{"line":688,"column":28}},"688":{"start":{"line":689,"column":0},"end":{"line":689,"column":11}},"689":{"start":{"line":690,"column":0},"end":{"line":690,"column":14}},"690":{"start":{"line":691,"column":0},"end":{"line":691,"column":80}},"691":{"start":{"line":692,"column":0},"end":{"line":692,"column":28}},"692":{"start":{"line":693,"column":0},"end":{"line":693,"column":11}},"693":{"start":{"line":694,"column":0},"end":{"line":694,"column":7}},"694":{"start":{"line":695,"column":0},"end":{"line":695,"column":21}},"695":{"start":{"line":696,"column":0},"end":{"line":696,"column":78}},"696":{"start":{"line":697,"column":0},"end":{"line":697,"column":5}},"697":{"start":{"line":698,"column":0},"end":{"line":698,"column":6}},"698":{"start":{"line":699,"column":0},"end":{"line":699,"column":22}},"699":{"start":{"line":700,"column":0},"end":{"line":700,"column":20}},"700":{"start":{"line":701,"column":0},"end":{"line":701,"column":37}},"701":{"start":{"line":702,"column":0},"end":{"line":702,"column":26}},"702":{"start":{"line":703,"column":0},"end":{"line":703,"column":26}},"703":{"start":{"line":704,"column":0},"end":{"line":704,"column":18}},"704":{"start":{"line":705,"column":0},"end":{"line":705,"column":30}},"705":{"start":{"line":706,"column":0},"end":{"line":706,"column":19}},"706":{"start":{"line":707,"column":0},"end":{"line":707,"column":32}},"707":{"start":{"line":708,"column":0},"end":{"line":708,"column":28}},"708":{"start":{"line":709,"column":0},"end":{"line":709,"column":23}},"709":{"start":{"line":710,"column":0},"end":{"line":710,"column":5}},"711":{"start":{"line":712,"column":0},"end":{"line":712,"column":55}},"712":{"start":{"line":713,"column":0},"end":{"line":713,"column":50}},"713":{"start":{"line":714,"column":0},"end":{"line":714,"column":42}},"714":{"start":{"line":715,"column":0},"end":{"line":715,"column":57}},"715":{"start":{"line":716,"column":0},"end":{"line":716,"column":13}},"716":{"start":{"line":717,"column":0},"end":{"line":717,"column":5}},"718":{"start":{"line":719,"column":0},"end":{"line":719,"column":37}},"719":{"start":{"line":720,"column":0},"end":{"line":720,"column":91}},"720":{"start":{"line":721,"column":0},"end":{"line":721,"column":6}},"721":{"start":{"line":722,"column":0},"end":{"line":722,"column":21}},"722":{"start":{"line":723,"column":0},"end":{"line":723,"column":13}},"723":{"start":{"line":724,"column":0},"end":{"line":724,"column":5}},"725":{"start":{"line":726,"column":0},"end":{"line":726,"column":33}},"726":{"start":{"line":727,"column":0},"end":{"line":727,"column":9}},"727":{"start":{"line":728,"column":0},"end":{"line":728,"column":24}},"728":{"start":{"line":729,"column":0},"end":{"line":729,"column":31}},"729":{"start":{"line":730,"column":0},"end":{"line":730,"column":7}},"730":{"start":{"line":731,"column":0},"end":{"line":731,"column":56}},"731":{"start":{"line":732,"column":0},"end":{"line":732,"column":38}},"732":{"start":{"line":733,"column":0},"end":{"line":733,"column":21}},"733":{"start":{"line":734,"column":0},"end":{"line":734,"column":62}},"734":{"start":{"line":735,"column":0},"end":{"line":735,"column":15}},"735":{"start":{"line":736,"column":0},"end":{"line":736,"column":36}},"736":{"start":{"line":737,"column":0},"end":{"line":737,"column":5}},"737":{"start":{"line":738,"column":0},"end":{"line":738,"column":6}},"738":{"start":{"line":739,"column":0},"end":{"line":739,"column":22}},"739":{"start":{"line":740,"column":0},"end":{"line":740,"column":16}},"740":{"start":{"line":741,"column":0},"end":{"line":741,"column":24}},"741":{"start":{"line":742,"column":0},"end":{"line":742,"column":19}},"742":{"start":{"line":743,"column":0},"end":{"line":743,"column":17}},"743":{"start":{"line":744,"column":0},"end":{"line":744,"column":27}},"744":{"start":{"line":745,"column":0},"end":{"line":745,"column":19}},"745":{"start":{"line":746,"column":0},"end":{"line":746,"column":5}},"747":{"start":{"line":748,"column":0},"end":{"line":748,"column":10}},"748":{"start":{"line":749,"column":0},"end":{"line":749,"column":59}},"749":{"start":{"line":750,"column":0},"end":{"line":750,"column":36}},"750":{"start":{"line":751,"column":0},"end":{"line":751,"column":48}},"751":{"start":{"line":752,"column":0},"end":{"line":752,"column":12}},"753":{"start":{"line":754,"column":0},"end":{"line":754,"column":66}},"754":{"start":{"line":755,"column":0},"end":{"line":755,"column":43}},"755":{"start":{"line":756,"column":0},"end":{"line":756,"column":54}},"756":{"start":{"line":757,"column":0},"end":{"line":757,"column":14}},"757":{"start":{"line":758,"column":0},"end":{"line":758,"column":61}},"758":{"start":{"line":759,"column":0},"end":{"line":759,"column":17}},"759":{"start":{"line":760,"column":0},"end":{"line":760,"column":25}},"760":{"start":{"line":761,"column":0},"end":{"line":761,"column":51}},"761":{"start":{"line":762,"column":0},"end":{"line":762,"column":39}},"762":{"start":{"line":763,"column":0},"end":{"line":763,"column":29}},"763":{"start":{"line":764,"column":0},"end":{"line":764,"column":42}},"764":{"start":{"line":765,"column":0},"end":{"line":765,"column":50}},"765":{"start":{"line":766,"column":0},"end":{"line":766,"column":42}},"767":{"start":{"line":768,"column":0},"end":{"line":768,"column":42}},"768":{"start":{"line":769,"column":0},"end":{"line":769,"column":19}},"769":{"start":{"line":770,"column":0},"end":{"line":770,"column":17}},"770":{"start":{"line":771,"column":0},"end":{"line":771,"column":25}},"771":{"start":{"line":772,"column":0},"end":{"line":772,"column":82}},"772":{"start":{"line":773,"column":0},"end":{"line":773,"column":42}},"773":{"start":{"line":774,"column":0},"end":{"line":774,"column":28}},"774":{"start":{"line":775,"column":0},"end":{"line":775,"column":40}},"775":{"start":{"line":776,"column":0},"end":{"line":776,"column":23}},"776":{"start":{"line":777,"column":0},"end":{"line":777,"column":15}},"777":{"start":{"line":778,"column":0},"end":{"line":778,"column":47}},"778":{"start":{"line":779,"column":0},"end":{"line":779,"column":14}},"779":{"start":{"line":780,"column":0},"end":{"line":780,"column":32}},"780":{"start":{"line":781,"column":0},"end":{"line":781,"column":40}},"781":{"start":{"line":782,"column":0},"end":{"line":782,"column":42}},"783":{"start":{"line":784,"column":0},"end":{"line":784,"column":84}},"784":{"start":{"line":785,"column":0},"end":{"line":785,"column":68}},"785":{"start":{"line":786,"column":0},"end":{"line":786,"column":19}},"786":{"start":{"line":787,"column":0},"end":{"line":787,"column":39}},"787":{"start":{"line":788,"column":0},"end":{"line":788,"column":19}},"789":{"start":{"line":790,"column":0},"end":{"line":790,"column":28}},"790":{"start":{"line":791,"column":0},"end":{"line":791,"column":68}},"791":{"start":{"line":792,"column":0},"end":{"line":792,"column":36}},"792":{"start":{"line":793,"column":0},"end":{"line":793,"column":32}},"793":{"start":{"line":794,"column":0},"end":{"line":794,"column":31}},"794":{"start":{"line":795,"column":0},"end":{"line":795,"column":38}},"795":{"start":{"line":796,"column":0},"end":{"line":796,"column":59}},"796":{"start":{"line":797,"column":0},"end":{"line":797,"column":53}},"797":{"start":{"line":798,"column":0},"end":{"line":798,"column":34}},"798":{"start":{"line":799,"column":0},"end":{"line":799,"column":47}},"799":{"start":{"line":800,"column":0},"end":{"line":800,"column":43}},"800":{"start":{"line":801,"column":0},"end":{"line":801,"column":20}},"801":{"start":{"line":802,"column":0},"end":{"line":802,"column":48}},"803":{"start":{"line":804,"column":0},"end":{"line":804,"column":29}},"804":{"start":{"line":805,"column":0},"end":{"line":805,"column":34}},"805":{"start":{"line":806,"column":0},"end":{"line":806,"column":17}},"806":{"start":{"line":807,"column":0},"end":{"line":807,"column":69}},"807":{"start":{"line":808,"column":0},"end":{"line":808,"column":30}},"808":{"start":{"line":809,"column":0},"end":{"line":809,"column":32}},"810":{"start":{"line":811,"column":0},"end":{"line":811,"column":41}},"811":{"start":{"line":812,"column":0},"end":{"line":812,"column":18}},"812":{"start":{"line":813,"column":0},"end":{"line":813,"column":46}},"813":{"start":{"line":814,"column":0},"end":{"line":814,"column":15}},"815":{"start":{"line":816,"column":0},"end":{"line":816,"column":32}},"816":{"start":{"line":817,"column":0},"end":{"line":817,"column":30}},"817":{"start":{"line":818,"column":0},"end":{"line":818,"column":39}},"818":{"start":{"line":819,"column":0},"end":{"line":819,"column":46}},"819":{"start":{"line":820,"column":0},"end":{"line":820,"column":15}},"821":{"start":{"line":822,"column":0},"end":{"line":822,"column":32}},"822":{"start":{"line":823,"column":0},"end":{"line":823,"column":29}},"824":{"start":{"line":825,"column":0},"end":{"line":825,"column":14}},"825":{"start":{"line":826,"column":0},"end":{"line":826,"column":16}},"827":{"start":{"line":828,"column":0},"end":{"line":828,"column":66}},"828":{"start":{"line":829,"column":0},"end":{"line":829,"column":43}},"829":{"start":{"line":830,"column":0},"end":{"line":830,"column":50}},"830":{"start":{"line":831,"column":0},"end":{"line":831,"column":61}},"831":{"start":{"line":832,"column":0},"end":{"line":832,"column":49}},"832":{"start":{"line":833,"column":0},"end":{"line":833,"column":27}},"833":{"start":{"line":834,"column":0},"end":{"line":834,"column":29}},"834":{"start":{"line":835,"column":0},"end":{"line":835,"column":89}},"835":{"start":{"line":836,"column":0},"end":{"line":836,"column":37}},"836":{"start":{"line":837,"column":0},"end":{"line":837,"column":37}},"837":{"start":{"line":838,"column":0},"end":{"line":838,"column":18}},"838":{"start":{"line":839,"column":0},"end":{"line":839,"column":16}},"839":{"start":{"line":840,"column":0},"end":{"line":840,"column":53}},"840":{"start":{"line":841,"column":0},"end":{"line":841,"column":19}},"841":{"start":{"line":842,"column":0},"end":{"line":842,"column":27}},"842":{"start":{"line":843,"column":0},"end":{"line":843,"column":52}},"843":{"start":{"line":844,"column":0},"end":{"line":844,"column":44}},"844":{"start":{"line":845,"column":0},"end":{"line":845,"column":61}},"845":{"start":{"line":846,"column":0},"end":{"line":846,"column":69}},"846":{"start":{"line":847,"column":0},"end":{"line":847,"column":40}},"847":{"start":{"line":848,"column":0},"end":{"line":848,"column":21}},"848":{"start":{"line":849,"column":0},"end":{"line":849,"column":35}},"849":{"start":{"line":850,"column":0},"end":{"line":850,"column":51}},"850":{"start":{"line":851,"column":0},"end":{"line":851,"column":33}},"851":{"start":{"line":852,"column":0},"end":{"line":852,"column":42}},"852":{"start":{"line":853,"column":0},"end":{"line":853,"column":31}},"853":{"start":{"line":854,"column":0},"end":{"line":854,"column":34}},"854":{"start":{"line":855,"column":0},"end":{"line":855,"column":35}},"856":{"start":{"line":857,"column":0},"end":{"line":857,"column":30}},"857":{"start":{"line":858,"column":0},"end":{"line":858,"column":59}},"858":{"start":{"line":859,"column":0},"end":{"line":859,"column":25}},"859":{"start":{"line":860,"column":0},"end":{"line":860,"column":17}},"860":{"start":{"line":861,"column":0},"end":{"line":861,"column":34}},"861":{"start":{"line":862,"column":0},"end":{"line":862,"column":40}},"862":{"start":{"line":863,"column":0},"end":{"line":863,"column":25}},"863":{"start":{"line":864,"column":0},"end":{"line":864,"column":17}},"864":{"start":{"line":865,"column":0},"end":{"line":865,"column":53}},"865":{"start":{"line":866,"column":0},"end":{"line":866,"column":16}},"867":{"start":{"line":868,"column":0},"end":{"line":868,"column":74}},"868":{"start":{"line":869,"column":0},"end":{"line":869,"column":21}},"869":{"start":{"line":870,"column":0},"end":{"line":870,"column":19}},"870":{"start":{"line":871,"column":0},"end":{"line":871,"column":27}},"871":{"start":{"line":872,"column":0},"end":{"line":872,"column":52}},"872":{"start":{"line":873,"column":0},"end":{"line":873,"column":44}},"873":{"start":{"line":874,"column":0},"end":{"line":874,"column":84}},"874":{"start":{"line":875,"column":0},"end":{"line":875,"column":41}},"875":{"start":{"line":876,"column":0},"end":{"line":876,"column":21}},"876":{"start":{"line":877,"column":0},"end":{"line":877,"column":35}},"877":{"start":{"line":878,"column":0},"end":{"line":878,"column":51}},"878":{"start":{"line":879,"column":0},"end":{"line":879,"column":33}},"879":{"start":{"line":880,"column":0},"end":{"line":880,"column":53}},"880":{"start":{"line":881,"column":0},"end":{"line":881,"column":61}},"882":{"start":{"line":883,"column":0},"end":{"line":883,"column":30}},"883":{"start":{"line":884,"column":0},"end":{"line":884,"column":43}},"884":{"start":{"line":885,"column":0},"end":{"line":885,"column":16}},"886":{"start":{"line":887,"column":0},"end":{"line":887,"column":71}},"887":{"start":{"line":888,"column":0},"end":{"line":888,"column":21}},"888":{"start":{"line":889,"column":0},"end":{"line":889,"column":16}},"889":{"start":{"line":890,"column":0},"end":{"line":890,"column":14}},"890":{"start":{"line":891,"column":0},"end":{"line":891,"column":41}},"891":{"start":{"line":892,"column":0},"end":{"line":892,"column":24}},"892":{"start":{"line":893,"column":0},"end":{"line":893,"column":64}},"893":{"start":{"line":894,"column":0},"end":{"line":894,"column":25}},"894":{"start":{"line":895,"column":0},"end":{"line":895,"column":18}},"895":{"start":{"line":896,"column":0},"end":{"line":896,"column":19}},"896":{"start":{"line":897,"column":0},"end":{"line":897,"column":34}},"897":{"start":{"line":898,"column":0},"end":{"line":898,"column":41}},"899":{"start":{"line":900,"column":0},"end":{"line":900,"column":18}},"900":{"start":{"line":901,"column":0},"end":{"line":901,"column":30}},"901":{"start":{"line":902,"column":0},"end":{"line":902,"column":40}},"902":{"start":{"line":903,"column":0},"end":{"line":903,"column":56}},"903":{"start":{"line":904,"column":0},"end":{"line":904,"column":69}},"904":{"start":{"line":905,"column":0},"end":{"line":905,"column":69}},"905":{"start":{"line":906,"column":0},"end":{"line":906,"column":32}},"906":{"start":{"line":907,"column":0},"end":{"line":907,"column":32}},"907":{"start":{"line":908,"column":0},"end":{"line":908,"column":68}},"908":{"start":{"line":909,"column":0},"end":{"line":909,"column":67}},"909":{"start":{"line":910,"column":0},"end":{"line":910,"column":75}},"910":{"start":{"line":911,"column":0},"end":{"line":911,"column":91}},"912":{"start":{"line":913,"column":0},"end":{"line":913,"column":24}},"913":{"start":{"line":914,"column":0},"end":{"line":914,"column":108}},"914":{"start":{"line":915,"column":0},"end":{"line":915,"column":52}},"915":{"start":{"line":916,"column":0},"end":{"line":916,"column":68}},"916":{"start":{"line":917,"column":0},"end":{"line":917,"column":40}},"917":{"start":{"line":918,"column":0},"end":{"line":918,"column":54}},"918":{"start":{"line":919,"column":0},"end":{"line":919,"column":41}},"919":{"start":{"line":920,"column":0},"end":{"line":920,"column":91}},"921":{"start":{"line":922,"column":0},"end":{"line":922,"column":48}},"923":{"start":{"line":924,"column":0},"end":{"line":924,"column":29}},"924":{"start":{"line":925,"column":0},"end":{"line":925,"column":76}},"925":{"start":{"line":926,"column":0},"end":{"line":926,"column":40}},"926":{"start":{"line":927,"column":0},"end":{"line":927,"column":58}},"927":{"start":{"line":928,"column":0},"end":{"line":928,"column":65}},"928":{"start":{"line":929,"column":0},"end":{"line":929,"column":31}},"929":{"start":{"line":930,"column":0},"end":{"line":930,"column":31}},"930":{"start":{"line":931,"column":0},"end":{"line":931,"column":26}},"931":{"start":{"line":932,"column":0},"end":{"line":932,"column":52}},"932":{"start":{"line":933,"column":0},"end":{"line":933,"column":52}},"933":{"start":{"line":934,"column":0},"end":{"line":934,"column":58}},"934":{"start":{"line":935,"column":0},"end":{"line":935,"column":67}},"935":{"start":{"line":936,"column":0},"end":{"line":936,"column":36}},"936":{"start":{"line":937,"column":0},"end":{"line":937,"column":37}},"937":{"start":{"line":938,"column":0},"end":{"line":938,"column":69}},"938":{"start":{"line":939,"column":0},"end":{"line":939,"column":40}},"939":{"start":{"line":940,"column":0},"end":{"line":940,"column":28}},"940":{"start":{"line":941,"column":0},"end":{"line":941,"column":77}},"941":{"start":{"line":942,"column":0},"end":{"line":942,"column":34}},"942":{"start":{"line":943,"column":0},"end":{"line":943,"column":33}},"943":{"start":{"line":944,"column":0},"end":{"line":944,"column":60}},"944":{"start":{"line":945,"column":0},"end":{"line":945,"column":68}},"945":{"start":{"line":946,"column":0},"end":{"line":946,"column":54}},"947":{"start":{"line":948,"column":0},"end":{"line":948,"column":77}},"948":{"start":{"line":949,"column":0},"end":{"line":949,"column":72}},"949":{"start":{"line":950,"column":0},"end":{"line":950,"column":37}},"950":{"start":{"line":951,"column":0},"end":{"line":951,"column":85}},"951":{"start":{"line":952,"column":0},"end":{"line":952,"column":35}},"953":{"start":{"line":954,"column":0},"end":{"line":954,"column":27}},"954":{"start":{"line":955,"column":0},"end":{"line":955,"column":28}},"955":{"start":{"line":956,"column":0},"end":{"line":956,"column":29}},"956":{"start":{"line":957,"column":0},"end":{"line":957,"column":23}},"958":{"start":{"line":959,"column":0},"end":{"line":959,"column":17}},"959":{"start":{"line":960,"column":0},"end":{"line":960,"column":17}},"961":{"start":{"line":962,"column":0},"end":{"line":962,"column":41}},"963":{"start":{"line":964,"column":0},"end":{"line":964,"column":18}},"965":{"start":{"line":966,"column":0},"end":{"line":966,"column":14}},"966":{"start":{"line":967,"column":0},"end":{"line":967,"column":16}},"968":{"start":{"line":969,"column":0},"end":{"line":969,"column":25}},"969":{"start":{"line":970,"column":0},"end":{"line":970,"column":28}},"970":{"start":{"line":971,"column":0},"end":{"line":971,"column":31}},"971":{"start":{"line":972,"column":0},"end":{"line":972,"column":47}},"972":{"start":{"line":973,"column":0},"end":{"line":973,"column":48}},"973":{"start":{"line":974,"column":0},"end":{"line":974,"column":51}},"974":{"start":{"line":975,"column":0},"end":{"line":975,"column":55}},"975":{"start":{"line":976,"column":0},"end":{"line":976,"column":49}},"976":{"start":{"line":977,"column":0},"end":{"line":977,"column":10}},"978":{"start":{"line":979,"column":0},"end":{"line":979,"column":10}},"980":{"start":{"line":981,"column":0},"end":{"line":981,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"10":1,"11":1,"15":1,"16":1,"31":1,"44":1,"45":1,"97":1,"98":1,"99":1,"100":1,"101":1,"102":1,"104":1,"105":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"133":1,"134":1,"135":1,"136":1,"140":13,"141":13,"142":13,"143":13,"144":13,"145":13,"146":13,"147":0,"148":0,"149":0,"150":0,"151":13,"152":13,"153":0,"154":0,"155":13,"156":13,"158":15,"159":15,"160":15,"161":1,"162":1,"163":15,"164":0,"165":0,"166":14,"167":14,"169":12,"170":12,"171":12,"172":12,"173":12,"174":12,"175":12,"176":12,"177":0,"178":0,"179":12,"180":1,"181":1,"182":12,"183":6,"184":6,"185":5,"186":5,"188":4,"189":4,"190":4,"191":4,"192":4,"193":4,"194":4,"195":4,"202":4,"203":4,"204":4,"205":1,"206":0,"207":0,"208":1,"209":1,"210":1,"211":4,"212":4,"213":4,"215":4,"216":3,"217":1,"218":1,"219":1,"220":1,"221":1,"222":4,"223":3,"224":1,"226":4,"227":4,"228":4,"229":4,"230":4,"232":4,"233":4,"235":4,"236":4,"237":4,"238":4,"239":3,"240":3,"241":3,"242":3,"243":3,"244":3,"245":3,"246":3,"247":3,"248":3,"249":3,"250":3,"251":3,"252":3,"254":0,"256":3,"257":3,"258":3,"259":3,"260":3,"261":3,"262":1,"263":1,"264":1,"265":3,"266":3,"268":3,"269":3,"270":3,"272":1,"275":4,"276":5,"277":5,"278":5,"279":5,"280":5,"281":5,"282":5,"283":5,"284":5,"285":5,"286":5,"287":1,"288":1,"289":1,"290":5,"292":5,"293":5,"294":5,"295":5,"297":4,"298":4,"299":4,"300":4,"302":4,"303":4,"304":4,"306":4,"308":1,"309":104,"310":104,"311":104,"312":104,"313":104,"314":104,"315":104,"316":104,"317":104,"334":104,"335":104,"336":104,"337":104,"338":104,"339":104,"340":104,"341":104,"342":104,"343":104,"344":104,"345":104,"346":104,"347":104,"348":104,"349":104,"350":104,"351":104,"352":104,"353":104,"355":104,"356":104,"357":35,"358":35,"359":0,"360":0,"361":35,"362":35,"363":35,"364":35,"365":34,"366":34,"367":34,"368":34,"370":35,"371":104,"372":104,"374":104,"375":104,"376":18,"377":16,"378":16,"379":18,"380":18,"381":0,"382":0,"383":18,"384":18,"387":0,"388":0,"389":2,"390":2,"391":18,"392":18,"393":18,"394":2,"395":2,"396":2,"397":18,"398":104,"399":104,"401":104,"402":104,"403":104,"404":104,"405":104,"407":104,"408":17,"409":17,"410":17,"411":17,"412":0,"413":0,"414":17,"415":17,"416":17,"417":0,"418":17,"419":17,"420":17,"421":17,"422":104,"424":104,"425":17,"426":17,"427":3,"428":3,"429":3,"430":3,"431":3,"432":3,"433":14,"434":14,"435":14,"436":0,"437":0,"438":14,"439":14,"440":14,"441":0,"442":14,"443":14,"444":14,"445":14,"446":104,"448":104,"449":104,"450":167,"451":0,"452":0,"453":167,"454":167,"455":167,"456":167,"457":167,"458":0,"459":167,"460":167,"461":167,"462":167,"463":104,"464":104,"466":104,"467":17,"468":17,"469":3,"470":3,"471":3,"472":3,"473":3,"475":14,"476":166,"477":0,"478":0,"479":166,"480":166,"482":14,"483":14,"484":14,"485":14,"486":14,"487":14,"488":104,"490":104,"491":36,"492":13,"493":15,"494":15,"495":15,"496":15,"497":15,"498":15,"499":13,"501":13,"502":13,"503":13,"504":13,"505":13,"506":36,"507":104,"509":104,"510":104,"511":1,"512":0,"513":0,"514":1,"515":1,"516":1,"517":1,"518":1,"519":0,"520":1,"521":1,"522":104,"523":104,"525":104,"526":1,"527":0,"528":0,"529":1,"530":1,"531":1,"532":1,"533":1,"534":0,"535":1,"536":104,"538":104,"539":104,"540":42,"541":62,"542":104,"544":104,"545":104,"547":104,"549":104,"550":104,"551":104,"552":104,"553":104,"555":104,"556":17,"557":14,"558":14,"559":3,"560":104,"562":104,"563":46,"564":34,"565":34,"566":46,"567":0,"568":0,"569":104,"571":104,"572":31,"573":31,"574":21,"575":21,"576":21,"577":21,"578":21,"580":31,"581":31,"582":161,"583":161,"584":161,"585":161,"586":161,"587":161,"588":161,"589":0,"590":0,"591":161,"592":161,"593":0,"594":0,"595":0,"596":0,"597":0,"598":0,"599":161,"601":31,"602":31,"603":31,"604":10,"605":10,"606":10,"607":104,"608":104,"609":104,"610":104,"611":104,"612":104,"614":104,"615":17,"616":17,"617":17,"618":17,"619":16,"620":17,"621":104,"623":104,"624":104,"625":104,"626":104,"627":104,"628":104,"629":104,"630":104,"631":104,"632":104,"633":104,"634":104,"635":104,"636":104,"637":104,"638":104,"639":104,"640":104,"641":104,"643":104,"645":27,"646":104,"648":104,"649":1,"650":0,"651":0,"653":1,"657":1,"658":1,"659":1,"660":1,"661":1,"663":1,"664":1,"666":1,"667":1,"668":1,"671":1,"672":1,"673":0,"674":0,"675":0,"677":1,"679":1,"680":1,"681":0,"682":0,"683":0,"685":1,"686":1,"687":1,"688":1,"689":1,"690":0,"691":0,"692":0,"693":0,"694":1,"695":0,"696":0,"697":104,"698":104,"699":104,"700":104,"701":104,"702":104,"703":104,"704":104,"705":104,"706":104,"707":104,"708":104,"709":104,"711":104,"712":1,"713":1,"714":1,"715":0,"716":0,"718":1,"719":1,"720":1,"721":1,"722":0,"723":0,"725":1,"726":1,"727":1,"728":0,"729":0,"730":1,"731":1,"732":1,"733":0,"734":1,"735":1,"736":1,"737":104,"738":104,"739":104,"740":104,"741":104,"742":104,"743":104,"744":104,"745":104,"747":104,"748":104,"749":104,"750":104,"751":104,"753":104,"754":104,"755":104,"756":104,"757":104,"758":104,"759":104,"760":104,"761":104,"762":104,"763":104,"764":104,"765":104,"767":104,"768":104,"769":104,"770":104,"771":104,"772":104,"773":104,"774":12,"775":0,"776":0,"777":12,"778":12,"779":104,"780":104,"781":104,"783":104,"784":104,"785":104,"786":104,"787":104,"789":104,"790":15,"791":15,"792":11,"793":11,"794":11,"795":11,"796":11,"797":11,"798":10,"799":10,"800":10,"801":11,"803":11,"804":11,"805":15,"806":15,"807":15,"808":15,"810":0,"811":0,"812":15,"813":15,"815":15,"816":15,"817":15,"818":15,"819":15,"821":15,"822":15,"824":104,"825":104,"827":104,"828":104,"829":104,"830":104,"831":104,"832":104,"833":42,"834":4,"835":38,"836":62,"837":104,"838":104,"839":104,"840":104,"841":104,"842":104,"843":104,"844":104,"845":104,"846":104,"847":104,"848":104,"849":9,"850":95,"851":53,"852":42,"853":11,"854":31,"856":104,"857":10,"858":0,"859":0,"860":10,"861":3,"862":3,"863":3,"864":7,"865":10,"867":104,"868":104,"869":104,"870":104,"871":104,"872":104,"873":104,"874":104,"875":104,"876":104,"877":9,"878":95,"879":53,"880":42,"882":104,"883":1,"884":1,"886":104,"887":104,"888":104,"889":104,"890":104,"891":104,"892":1,"893":1,"894":1,"895":103,"896":104,"897":9,"899":9,"900":95,"901":42,"902":42,"903":50,"904":50,"905":4,"906":46,"907":50,"908":50,"909":50,"910":50,"912":50,"913":50,"914":50,"915":50,"916":50,"917":3,"918":47,"919":4,"921":43,"923":50,"924":50,"925":50,"926":4,"927":4,"928":4,"929":46,"930":50,"931":50,"932":2,"933":2,"934":12,"935":12,"936":12,"937":12,"938":12,"939":12,"940":12,"941":12,"942":12,"943":12,"944":12,"945":12,"947":12,"948":12,"949":12,"950":12,"951":12,"953":2,"954":2,"955":48,"956":50,"958":42,"959":42,"961":53,"963":53,"965":104,"966":104,"968":104,"969":4,"970":4,"971":4,"972":4,"973":4,"974":4,"975":4,"976":4,"978":104,"980":104},"branchMap":{"0":{"type":"branch","line":141,"loc":{"start":{"line":141,"column":0},"end":{"line":157,"column":1}},"locations":[{"start":{"line":141,"column":0},"end":{"line":157,"column":1}}]},"1":{"type":"branch","line":142,"loc":{"start":{"line":142,"column":33},"end":{"line":142,"column":41}},"locations":[{"start":{"line":142,"column":33},"end":{"line":142,"column":41}}]},"2":{"type":"branch","line":143,"loc":{"start":{"line":143,"column":31},"end":{"line":143,"column":39}},"locations":[{"start":{"line":143,"column":31},"end":{"line":143,"column":39}}]},"3":{"type":"branch","line":144,"loc":{"start":{"line":144,"column":27},"end":{"line":144,"column":35}},"locations":[{"start":{"line":144,"column":27},"end":{"line":144,"column":35}}]},"4":{"type":"branch","line":147,"loc":{"start":{"line":147,"column":2},"end":{"line":152,"column":61}},"locations":[{"start":{"line":147,"column":2},"end":{"line":152,"column":61}}]},"5":{"type":"branch","line":152,"loc":{"start":{"line":152,"column":53},"end":{"line":152,"column":66}},"locations":[{"start":{"line":152,"column":53},"end":{"line":152,"column":66}}]},"6":{"type":"branch","line":153,"loc":{"start":{"line":153,"column":6},"end":{"line":153,"column":23}},"locations":[{"start":{"line":153,"column":6},"end":{"line":153,"column":23}}]},"7":{"type":"branch","line":153,"loc":{"start":{"line":153,"column":23},"end":{"line":156,"column":28}},"locations":[{"start":{"line":153,"column":23},"end":{"line":156,"column":28}}]},"8":{"type":"branch","line":156,"loc":{"start":{"line":156,"column":22},"end":{"line":156,"column":44}},"locations":[{"start":{"line":156,"column":22},"end":{"line":156,"column":44}}]},"9":{"type":"branch","line":159,"loc":{"start":{"line":159,"column":0},"end":{"line":168,"column":1}},"locations":[{"start":{"line":159,"column":0},"end":{"line":168,"column":1}}]},"10":{"type":"branch","line":161,"loc":{"start":{"line":161,"column":34},"end":{"line":163,"column":3}},"locations":[{"start":{"line":161,"column":34},"end":{"line":163,"column":3}}]},"11":{"type":"branch","line":163,"loc":{"start":{"line":163,"column":2},"end":{"line":164,"column":36}},"locations":[{"start":{"line":163,"column":2},"end":{"line":164,"column":36}}]},"12":{"type":"branch","line":164,"loc":{"start":{"line":164,"column":36},"end":{"line":166,"column":3}},"locations":[{"start":{"line":164,"column":36},"end":{"line":166,"column":3}}]},"13":{"type":"branch","line":166,"loc":{"start":{"line":166,"column":2},"end":{"line":168,"column":1}},"locations":[{"start":{"line":166,"column":2},"end":{"line":168,"column":1}}]},"14":{"type":"branch","line":170,"loc":{"start":{"line":170,"column":0},"end":{"line":187,"column":1}},"locations":[{"start":{"line":170,"column":0},"end":{"line":187,"column":1}}]},"15":{"type":"branch","line":177,"loc":{"start":{"line":177,"column":6},"end":{"line":177,"column":30}},"locations":[{"start":{"line":177,"column":6},"end":{"line":177,"column":30}}]},"16":{"type":"branch","line":177,"loc":{"start":{"line":177,"column":30},"end":{"line":177,"column":73}},"locations":[{"start":{"line":177,"column":30},"end":{"line":177,"column":73}}]},"17":{"type":"branch","line":177,"loc":{"start":{"line":177,"column":73},"end":{"line":179,"column":3}},"locations":[{"start":{"line":177,"column":73},"end":{"line":179,"column":3}}]},"18":{"type":"branch","line":180,"loc":{"start":{"line":180,"column":42},"end":{"line":182,"column":3}},"locations":[{"start":{"line":180,"column":42},"end":{"line":182,"column":3}}]},"19":{"type":"branch","line":182,"loc":{"start":{"line":182,"column":2},"end":{"line":183,"column":40}},"locations":[{"start":{"line":182,"column":2},"end":{"line":183,"column":40}}]},"20":{"type":"branch","line":183,"loc":{"start":{"line":183,"column":40},"end":{"line":185,"column":3}},"locations":[{"start":{"line":183,"column":40},"end":{"line":185,"column":3}}]},"21":{"type":"branch","line":185,"loc":{"start":{"line":185,"column":2},"end":{"line":187,"column":1}},"locations":[{"start":{"line":185,"column":2},"end":{"line":187,"column":1}}]},"22":{"type":"branch","line":189,"loc":{"start":{"line":189,"column":0},"end":{"line":307,"column":1}},"locations":[{"start":{"line":189,"column":0},"end":{"line":307,"column":1}}]},"23":{"type":"branch","line":216,"loc":{"start":{"line":216,"column":20},"end":{"line":221,"column":7}},"locations":[{"start":{"line":216,"column":20},"end":{"line":221,"column":7}}]},"24":{"type":"branch","line":217,"loc":{"start":{"line":217,"column":74},"end":{"line":221,"column":7}},"locations":[{"start":{"line":217,"column":74},"end":{"line":221,"column":7}}]},"25":{"type":"branch","line":221,"loc":{"start":{"line":221,"column":6},"end":{"line":222,"column":11}},"locations":[{"start":{"line":221,"column":6},"end":{"line":222,"column":11}}]},"26":{"type":"branch","line":223,"loc":{"start":{"line":223,"column":17},"end":{"line":224,"column":52}},"locations":[{"start":{"line":223,"column":17},"end":{"line":224,"column":52}}]},"27":{"type":"branch","line":224,"loc":{"start":{"line":224,"column":51},"end":{"line":225,"column":16}},"locations":[{"start":{"line":224,"column":51},"end":{"line":225,"column":16}}]},"28":{"type":"branch","line":239,"loc":{"start":{"line":239,"column":9},"end":{"line":271,"column":16}},"locations":[{"start":{"line":239,"column":9},"end":{"line":271,"column":16}}]},"29":{"type":"branch","line":244,"loc":{"start":{"line":244,"column":68},"end":{"line":244,"column":77}},"locations":[{"start":{"line":244,"column":68},"end":{"line":244,"column":77}}]},"30":{"type":"branch","line":271,"loc":{"start":{"line":271,"column":10},"end":{"line":273,"column":76}},"locations":[{"start":{"line":271,"column":10},"end":{"line":273,"column":76}}]},"31":{"type":"branch","line":204,"loc":{"start":{"line":204,"column":12},"end":{"line":214,"column":5}},"locations":[{"start":{"line":204,"column":12},"end":{"line":214,"column":5}}]},"32":{"type":"branch","line":205,"loc":{"start":{"line":205,"column":26},"end":{"line":211,"column":6}},"locations":[{"start":{"line":205,"column":26},"end":{"line":211,"column":6}}]},"33":{"type":"branch","line":206,"loc":{"start":{"line":206,"column":34},"end":{"line":208,"column":7}},"locations":[{"start":{"line":206,"column":34},"end":{"line":208,"column":7}}]},"34":{"type":"branch","line":213,"loc":{"start":{"line":213,"column":11},"end":{"line":213,"column":70}},"locations":[{"start":{"line":213,"column":11},"end":{"line":213,"column":70}}]},"35":{"type":"branch","line":217,"loc":{"start":{"line":217,"column":21},"end":{"line":217,"column":74}},"locations":[{"start":{"line":217,"column":21},"end":{"line":217,"column":74}}]},"36":{"type":"branch","line":224,"loc":{"start":{"line":224,"column":23},"end":{"line":224,"column":51}},"locations":[{"start":{"line":224,"column":23},"end":{"line":224,"column":51}}]},"37":{"type":"branch","line":262,"loc":{"start":{"line":262,"column":25},"end":{"line":265,"column":18}},"locations":[{"start":{"line":262,"column":25},"end":{"line":265,"column":18}}]},"38":{"type":"branch","line":276,"loc":{"start":{"line":276,"column":20},"end":{"line":298,"column":9}},"locations":[{"start":{"line":276,"column":20},"end":{"line":298,"column":9}}]},"39":{"type":"branch","line":277,"loc":{"start":{"line":277,"column":30},"end":{"line":277,"column":51}},"locations":[{"start":{"line":277,"column":30},"end":{"line":277,"column":51}}]},"40":{"type":"branch","line":277,"loc":{"start":{"line":277,"column":42},"end":{"line":277,"column":61}},"locations":[{"start":{"line":277,"column":42},"end":{"line":277,"column":61}}]},"41":{"type":"branch","line":287,"loc":{"start":{"line":287,"column":27},"end":{"line":290,"column":20}},"locations":[{"start":{"line":287,"column":27},"end":{"line":290,"column":20}}]},"42":{"type":"branch","line":309,"loc":{"start":{"line":309,"column":7},"end":{"line":981,"column":1}},"locations":[{"start":{"line":309,"column":7},"end":{"line":981,"column":1}}]},"43":{"type":"branch","line":336,"loc":{"start":{"line":336,"column":17},"end":{"line":336,"column":64}},"locations":[{"start":{"line":336,"column":17},"end":{"line":336,"column":64}}]},"44":{"type":"branch","line":337,"loc":{"start":{"line":337,"column":19},"end":{"line":337,"column":58}},"locations":[{"start":{"line":337,"column":19},"end":{"line":337,"column":58}}]},"45":{"type":"branch","line":343,"loc":{"start":{"line":343,"column":33},"end":{"line":343,"column":69}},"locations":[{"start":{"line":343,"column":33},"end":{"line":343,"column":69}}]},"46":{"type":"branch","line":354,"loc":{"start":{"line":354,"column":37},"end":{"line":354,"column":61}},"locations":[{"start":{"line":354,"column":37},"end":{"line":354,"column":61}}]},"47":{"type":"branch","line":540,"loc":{"start":{"line":540,"column":23},"end":{"line":541,"column":56}},"locations":[{"start":{"line":540,"column":23},"end":{"line":541,"column":56}}]},"48":{"type":"branch","line":541,"loc":{"start":{"line":541,"column":47},"end":{"line":541,"column":56}},"locations":[{"start":{"line":541,"column":47},"end":{"line":541,"column":56}}]},"49":{"type":"branch","line":541,"loc":{"start":{"line":541,"column":52},"end":{"line":542,"column":11}},"locations":[{"start":{"line":541,"column":52},"end":{"line":542,"column":11}}]},"50":{"type":"branch","line":610,"loc":{"start":{"line":610,"column":4},"end":{"line":610,"column":43}},"locations":[{"start":{"line":610,"column":4},"end":{"line":610,"column":43}}]},"51":{"type":"branch","line":772,"loc":{"start":{"line":772,"column":49},"end":{"line":772,"column":77}},"locations":[{"start":{"line":772,"column":49},"end":{"line":772,"column":77}}]},"52":{"type":"branch","line":772,"loc":{"start":{"line":772,"column":64},"end":{"line":772,"column":79}},"locations":[{"start":{"line":772,"column":64},"end":{"line":772,"column":79}}]},"53":{"type":"branch","line":784,"loc":{"start":{"line":784,"column":29},"end":{"line":784,"column":64}},"locations":[{"start":{"line":784,"column":29},"end":{"line":784,"column":64}}]},"54":{"type":"branch","line":784,"loc":{"start":{"line":784,"column":44},"end":{"line":784,"column":84}},"locations":[{"start":{"line":784,"column":44},"end":{"line":784,"column":84}}]},"55":{"type":"branch","line":785,"loc":{"start":{"line":785,"column":15},"end":{"line":785,"column":50}},"locations":[{"start":{"line":785,"column":15},"end":{"line":785,"column":50}}]},"56":{"type":"branch","line":785,"loc":{"start":{"line":785,"column":43},"end":{"line":785,"column":68}},"locations":[{"start":{"line":785,"column":43},"end":{"line":785,"column":68}}]},"57":{"type":"branch","line":790,"loc":{"start":{"line":790,"column":11},"end":{"line":823,"column":29}},"locations":[{"start":{"line":790,"column":11},"end":{"line":823,"column":29}}]},"58":{"type":"branch","line":833,"loc":{"start":{"line":833,"column":15},"end":{"line":836,"column":37}},"locations":[{"start":{"line":833,"column":15},"end":{"line":836,"column":37}}]},"59":{"type":"branch","line":834,"loc":{"start":{"line":834,"column":18},"end":{"line":835,"column":89}},"locations":[{"start":{"line":834,"column":18},"end":{"line":835,"column":89}}]},"60":{"type":"branch","line":835,"loc":{"start":{"line":835,"column":87},"end":{"line":836,"column":37}},"locations":[{"start":{"line":835,"column":87},"end":{"line":836,"column":37}}]},"61":{"type":"branch","line":836,"loc":{"start":{"line":836,"column":33},"end":{"line":837,"column":37}},"locations":[{"start":{"line":836,"column":33},"end":{"line":837,"column":37}}]},"62":{"type":"branch","line":845,"loc":{"start":{"line":845,"column":25},"end":{"line":845,"column":61}},"locations":[{"start":{"line":845,"column":25},"end":{"line":845,"column":61}}]},"63":{"type":"branch","line":846,"loc":{"start":{"line":846,"column":26},"end":{"line":846,"column":55}},"locations":[{"start":{"line":846,"column":26},"end":{"line":846,"column":55}}]},"64":{"type":"branch","line":846,"loc":{"start":{"line":846,"column":40},"end":{"line":846,"column":69}},"locations":[{"start":{"line":846,"column":40},"end":{"line":846,"column":69}}]},"65":{"type":"branch","line":849,"loc":{"start":{"line":849,"column":17},"end":{"line":850,"column":51}},"locations":[{"start":{"line":849,"column":17},"end":{"line":850,"column":51}}]},"66":{"type":"branch","line":850,"loc":{"start":{"line":850,"column":20},"end":{"line":855,"column":35}},"locations":[{"start":{"line":850,"column":20},"end":{"line":855,"column":35}}]},"67":{"type":"branch","line":851,"loc":{"start":{"line":851,"column":21},"end":{"line":852,"column":42}},"locations":[{"start":{"line":851,"column":21},"end":{"line":852,"column":42}}]},"68":{"type":"branch","line":852,"loc":{"start":{"line":852,"column":20},"end":{"line":855,"column":35}},"locations":[{"start":{"line":852,"column":20},"end":{"line":855,"column":35}}]},"69":{"type":"branch","line":853,"loc":{"start":{"line":853,"column":20},"end":{"line":854,"column":34}},"locations":[{"start":{"line":853,"column":20},"end":{"line":854,"column":34}}]},"70":{"type":"branch","line":854,"loc":{"start":{"line":854,"column":22},"end":{"line":855,"column":35}},"locations":[{"start":{"line":854,"column":22},"end":{"line":855,"column":35}}]},"71":{"type":"branch","line":868,"loc":{"start":{"line":868,"column":15},"end":{"line":868,"column":53}},"locations":[{"start":{"line":868,"column":15},"end":{"line":868,"column":53}}]},"72":{"type":"branch","line":868,"loc":{"start":{"line":868,"column":48},"end":{"line":868,"column":74}},"locations":[{"start":{"line":868,"column":48},"end":{"line":868,"column":74}}]},"73":{"type":"branch","line":874,"loc":{"start":{"line":874,"column":25},"end":{"line":874,"column":64}},"locations":[{"start":{"line":874,"column":25},"end":{"line":874,"column":64}}]},"74":{"type":"branch","line":874,"loc":{"start":{"line":874,"column":48},"end":{"line":874,"column":84}},"locations":[{"start":{"line":874,"column":48},"end":{"line":874,"column":84}}]},"75":{"type":"branch","line":877,"loc":{"start":{"line":877,"column":17},"end":{"line":878,"column":51}},"locations":[{"start":{"line":877,"column":17},"end":{"line":878,"column":51}}]},"76":{"type":"branch","line":878,"loc":{"start":{"line":878,"column":20},"end":{"line":881,"column":61}},"locations":[{"start":{"line":878,"column":20},"end":{"line":881,"column":61}}]},"77":{"type":"branch","line":879,"loc":{"start":{"line":879,"column":21},"end":{"line":880,"column":53}},"locations":[{"start":{"line":879,"column":21},"end":{"line":880,"column":53}}]},"78":{"type":"branch","line":880,"loc":{"start":{"line":880,"column":20},"end":{"line":881,"column":61}},"locations":[{"start":{"line":880,"column":20},"end":{"line":881,"column":61}}]},"79":{"type":"branch","line":887,"loc":{"start":{"line":887,"column":15},"end":{"line":887,"column":54}},"locations":[{"start":{"line":887,"column":15},"end":{"line":887,"column":54}}]},"80":{"type":"branch","line":887,"loc":{"start":{"line":887,"column":37},"end":{"line":887,"column":71}},"locations":[{"start":{"line":887,"column":37},"end":{"line":887,"column":71}}]},"81":{"type":"branch","line":892,"loc":{"start":{"line":892,"column":11},"end":{"line":895,"column":18}},"locations":[{"start":{"line":892,"column":11},"end":{"line":895,"column":18}}]},"82":{"type":"branch","line":895,"loc":{"start":{"line":895,"column":12},"end":{"line":896,"column":19}},"locations":[{"start":{"line":895,"column":12},"end":{"line":896,"column":19}}]},"83":{"type":"branch","line":897,"loc":{"start":{"line":897,"column":12},"end":{"line":900,"column":18}},"locations":[{"start":{"line":897,"column":12},"end":{"line":900,"column":18}}]},"84":{"type":"branch","line":900,"loc":{"start":{"line":900,"column":12},"end":{"line":964,"column":18}},"locations":[{"start":{"line":900,"column":12},"end":{"line":964,"column":18}}]},"85":{"type":"branch","line":901,"loc":{"start":{"line":901,"column":14},"end":{"line":960,"column":17}},"locations":[{"start":{"line":901,"column":14},"end":{"line":960,"column":17}}]},"86":{"type":"branch","line":960,"loc":{"start":{"line":960,"column":12},"end":{"line":964,"column":18}},"locations":[{"start":{"line":960,"column":12},"end":{"line":964,"column":18}}]},"87":{"type":"branch","line":969,"loc":{"start":{"line":969,"column":7},"end":{"line":977,"column":10}},"locations":[{"start":{"line":969,"column":7},"end":{"line":977,"column":10}}]},"88":{"type":"branch","line":357,"loc":{"start":{"line":357,"column":4},"end":{"line":371,"column":6}},"locations":[{"start":{"line":357,"column":4},"end":{"line":371,"column":6}}]},"89":{"type":"branch","line":359,"loc":{"start":{"line":359,"column":23},"end":{"line":361,"column":7}},"locations":[{"start":{"line":359,"column":23},"end":{"line":361,"column":7}}]},"90":{"type":"branch","line":365,"loc":{"start":{"line":365,"column":8},"end":{"line":368,"column":12}},"locations":[{"start":{"line":365,"column":8},"end":{"line":368,"column":12}}]},"91":{"type":"branch","line":368,"loc":{"start":{"line":368,"column":8},"end":{"line":369,"column":12}},"locations":[{"start":{"line":368,"column":8},"end":{"line":369,"column":12}}]},"92":{"type":"branch","line":364,"loc":{"start":{"line":364,"column":10},"end":{"line":364,"column":64}},"locations":[{"start":{"line":364,"column":10},"end":{"line":364,"column":64}}]},"93":{"type":"branch","line":367,"loc":{"start":{"line":367,"column":10},"end":{"line":367,"column":79}},"locations":[{"start":{"line":367,"column":10},"end":{"line":367,"column":79}}]},"94":{"type":"branch","line":367,"loc":{"start":{"line":367,"column":26},"end":{"line":367,"column":43}},"locations":[{"start":{"line":367,"column":26},"end":{"line":367,"column":43}}]},"95":{"type":"branch","line":376,"loc":{"start":{"line":376,"column":4},"end":{"line":398,"column":6}},"locations":[{"start":{"line":376,"column":4},"end":{"line":398,"column":6}}]},"96":{"type":"branch","line":377,"loc":{"start":{"line":377,"column":17},"end":{"line":379,"column":7}},"locations":[{"start":{"line":377,"column":17},"end":{"line":379,"column":7}}]},"97":{"type":"branch","line":379,"loc":{"start":{"line":379,"column":6},"end":{"line":380,"column":37}},"locations":[{"start":{"line":379,"column":6},"end":{"line":380,"column":37}}]},"98":{"type":"branch","line":380,"loc":{"start":{"line":380,"column":29},"end":{"line":380,"column":45}},"locations":[{"start":{"line":380,"column":29},"end":{"line":380,"column":45}}]},"99":{"type":"branch","line":381,"loc":{"start":{"line":381,"column":22},"end":{"line":383,"column":7}},"locations":[{"start":{"line":381,"column":22},"end":{"line":383,"column":7}}]},"100":{"type":"branch","line":383,"loc":{"start":{"line":383,"column":6},"end":{"line":384,"column":40}},"locations":[{"start":{"line":383,"column":6},"end":{"line":384,"column":40}}]},"101":{"type":"branch","line":384,"loc":{"start":{"line":384,"column":31},"end":{"line":384,"column":44}},"locations":[{"start":{"line":384,"column":31},"end":{"line":384,"column":44}}]},"102":{"type":"branch","line":385,"loc":{"start":{"line":385,"column":23},"end":{"line":389,"column":7}},"locations":[{"start":{"line":385,"column":23},"end":{"line":389,"column":7}}]},"103":{"type":"branch","line":389,"loc":{"start":{"line":389,"column":6},"end":{"line":391,"column":67}},"locations":[{"start":{"line":389,"column":6},"end":{"line":391,"column":67}}]},"104":{"type":"branch","line":394,"loc":{"start":{"line":394,"column":41},"end":{"line":397,"column":43}},"locations":[{"start":{"line":394,"column":41},"end":{"line":397,"column":43}}]},"105":{"type":"branch","line":408,"loc":{"start":{"line":408,"column":12},"end":{"line":423,"column":5}},"locations":[{"start":{"line":408,"column":12},"end":{"line":423,"column":5}}]},"106":{"type":"branch","line":411,"loc":{"start":{"line":411,"column":12},"end":{"line":416,"column":7}},"locations":[{"start":{"line":411,"column":12},"end":{"line":416,"column":7}}]},"107":{"type":"branch","line":412,"loc":{"start":{"line":412,"column":23},"end":{"line":414,"column":9}},"locations":[{"start":{"line":412,"column":23},"end":{"line":414,"column":9}}]},"108":{"type":"branch","line":420,"loc":{"start":{"line":420,"column":11},"end":{"line":422,"column":6}},"locations":[{"start":{"line":420,"column":11},"end":{"line":422,"column":6}}]},"109":{"type":"branch","line":425,"loc":{"start":{"line":425,"column":12},"end":{"line":447,"column":5}},"locations":[{"start":{"line":425,"column":12},"end":{"line":447,"column":5}}]},"110":{"type":"branch","line":427,"loc":{"start":{"line":427,"column":28},"end":{"line":433,"column":5}},"locations":[{"start":{"line":427,"column":28},"end":{"line":433,"column":5}}]},"111":{"type":"branch","line":433,"loc":{"start":{"line":433,"column":4},"end":{"line":446,"column":6}},"locations":[{"start":{"line":433,"column":4},"end":{"line":446,"column":6}}]},"112":{"type":"branch","line":430,"loc":{"start":{"line":430,"column":13},"end":{"line":432,"column":8}},"locations":[{"start":{"line":430,"column":13},"end":{"line":432,"column":8}}]},"113":{"type":"branch","line":435,"loc":{"start":{"line":435,"column":12},"end":{"line":440,"column":7}},"locations":[{"start":{"line":435,"column":12},"end":{"line":440,"column":7}}]},"114":{"type":"branch","line":436,"loc":{"start":{"line":436,"column":23},"end":{"line":438,"column":9}},"locations":[{"start":{"line":436,"column":23},"end":{"line":438,"column":9}}]},"115":{"type":"branch","line":444,"loc":{"start":{"line":444,"column":11},"end":{"line":446,"column":6}},"locations":[{"start":{"line":444,"column":11},"end":{"line":446,"column":6}}]},"116":{"type":"branch","line":450,"loc":{"start":{"line":450,"column":4},"end":{"line":463,"column":6}},"locations":[{"start":{"line":450,"column":4},"end":{"line":463,"column":6}}]},"117":{"type":"branch","line":451,"loc":{"start":{"line":451,"column":36},"end":{"line":453,"column":7}},"locations":[{"start":{"line":451,"column":36},"end":{"line":453,"column":7}}]},"118":{"type":"branch","line":458,"loc":{"start":{"line":458,"column":6},"end":{"line":460,"column":8}},"locations":[{"start":{"line":458,"column":6},"end":{"line":460,"column":8}}]},"119":{"type":"branch","line":467,"loc":{"start":{"line":467,"column":12},"end":{"line":489,"column":5}},"locations":[{"start":{"line":467,"column":12},"end":{"line":489,"column":5}}]},"120":{"type":"branch","line":469,"loc":{"start":{"line":469,"column":28},"end":{"line":474,"column":5}},"locations":[{"start":{"line":469,"column":28},"end":{"line":474,"column":5}}]},"121":{"type":"branch","line":474,"loc":{"start":{"line":474,"column":4},"end":{"line":488,"column":6}},"locations":[{"start":{"line":474,"column":4},"end":{"line":488,"column":6}}]},"122":{"type":"branch","line":471,"loc":{"start":{"line":471,"column":13},"end":{"line":473,"column":8}},"locations":[{"start":{"line":471,"column":13},"end":{"line":473,"column":8}}]},"123":{"type":"branch","line":476,"loc":{"start":{"line":476,"column":22},"end":{"line":481,"column":6}},"locations":[{"start":{"line":476,"column":22},"end":{"line":481,"column":6}}]},"124":{"type":"branch","line":477,"loc":{"start":{"line":477,"column":21},"end":{"line":479,"column":7}},"locations":[{"start":{"line":477,"column":21},"end":{"line":479,"column":7}}]},"125":{"type":"branch","line":485,"loc":{"start":{"line":485,"column":11},"end":{"line":488,"column":6}},"locations":[{"start":{"line":485,"column":11},"end":{"line":488,"column":6}}]},"126":{"type":"branch","line":491,"loc":{"start":{"line":491,"column":37},"end":{"line":508,"column":5}},"locations":[{"start":{"line":491,"column":37},"end":{"line":508,"column":5}}]},"127":{"type":"branch","line":492,"loc":{"start":{"line":492,"column":30},"end":{"line":507,"column":5}},"locations":[{"start":{"line":492,"column":30},"end":{"line":507,"column":5}}]},"128":{"type":"branch","line":493,"loc":{"start":{"line":493,"column":52},"end":{"line":500,"column":7}},"locations":[{"start":{"line":493,"column":52},"end":{"line":500,"column":7}}]},"129":{"type":"branch","line":511,"loc":{"start":{"line":511,"column":4},"end":{"line":522,"column":6}},"locations":[{"start":{"line":511,"column":4},"end":{"line":522,"column":6}}]},"130":{"type":"branch","line":512,"loc":{"start":{"line":512,"column":30},"end":{"line":514,"column":7}},"locations":[{"start":{"line":512,"column":30},"end":{"line":514,"column":7}}]},"131":{"type":"branch","line":516,"loc":{"start":{"line":516,"column":14},"end":{"line":518,"column":9}},"locations":[{"start":{"line":516,"column":14},"end":{"line":518,"column":9}}]},"132":{"type":"branch","line":526,"loc":{"start":{"line":526,"column":46},"end":{"line":537,"column":5}},"locations":[{"start":{"line":526,"column":46},"end":{"line":537,"column":5}}]},"133":{"type":"branch","line":527,"loc":{"start":{"line":527,"column":28},"end":{"line":529,"column":5}},"locations":[{"start":{"line":527,"column":28},"end":{"line":529,"column":5}}]},"134":{"type":"branch","line":531,"loc":{"start":{"line":531,"column":12},"end":{"line":533,"column":7}},"locations":[{"start":{"line":531,"column":12},"end":{"line":533,"column":7}}]},"135":{"type":"branch","line":541,"loc":{"start":{"line":541,"column":17},"end":{"line":541,"column":47}},"locations":[{"start":{"line":541,"column":17},"end":{"line":541,"column":47}}]},"136":{"type":"branch","line":556,"loc":{"start":{"line":556,"column":12},"end":{"line":561,"column":5}},"locations":[{"start":{"line":556,"column":12},"end":{"line":561,"column":5}}]},"137":{"type":"branch","line":557,"loc":{"start":{"line":557,"column":28},"end":{"line":559,"column":5}},"locations":[{"start":{"line":557,"column":28},"end":{"line":559,"column":5}}]},"138":{"type":"branch","line":559,"loc":{"start":{"line":559,"column":4},"end":{"line":560,"column":27}},"locations":[{"start":{"line":559,"column":4},"end":{"line":560,"column":27}}]},"139":{"type":"branch","line":563,"loc":{"start":{"line":563,"column":12},"end":{"line":570,"column":5}},"locations":[{"start":{"line":563,"column":12},"end":{"line":570,"column":5}}]},"140":{"type":"branch","line":564,"loc":{"start":{"line":564,"column":25},"end":{"line":566,"column":5}},"locations":[{"start":{"line":564,"column":25},"end":{"line":566,"column":5}}]},"141":{"type":"branch","line":566,"loc":{"start":{"line":566,"column":4},"end":{"line":567,"column":59}},"locations":[{"start":{"line":566,"column":4},"end":{"line":567,"column":59}}]},"142":{"type":"branch","line":567,"loc":{"start":{"line":567,"column":59},"end":{"line":569,"column":5}},"locations":[{"start":{"line":567,"column":59},"end":{"line":569,"column":5}}]},"143":{"type":"branch","line":567,"loc":{"start":{"line":567,"column":20},"end":{"line":567,"column":56}},"locations":[{"start":{"line":567,"column":20},"end":{"line":567,"column":56}}]},"144":{"type":"branch","line":572,"loc":{"start":{"line":572,"column":12},"end":{"line":608,"column":5}},"locations":[{"start":{"line":572,"column":12},"end":{"line":608,"column":5}}]},"145":{"type":"branch","line":574,"loc":{"start":{"line":574,"column":9},"end":{"line":574,"column":47}},"locations":[{"start":{"line":574,"column":9},"end":{"line":574,"column":47}}]},"146":{"type":"branch","line":574,"loc":{"start":{"line":574,"column":47},"end":{"line":579,"column":5}},"locations":[{"start":{"line":574,"column":47},"end":{"line":579,"column":5}}]},"147":{"type":"branch","line":579,"loc":{"start":{"line":579,"column":4},"end":{"line":581,"column":51}},"locations":[{"start":{"line":579,"column":4},"end":{"line":581,"column":51}}]},"148":{"type":"branch","line":581,"loc":{"start":{"line":581,"column":32},"end":{"line":581,"column":74}},"locations":[{"start":{"line":581,"column":32},"end":{"line":581,"column":74}}]},"149":{"type":"branch","line":581,"loc":{"start":{"line":581,"column":51},"end":{"line":581,"column":79}},"locations":[{"start":{"line":581,"column":51},"end":{"line":581,"column":79}}]},"150":{"type":"branch","line":576,"loc":{"start":{"line":576,"column":13},"end":{"line":578,"column":8}},"locations":[{"start":{"line":576,"column":13},"end":{"line":578,"column":8}}]},"151":{"type":"branch","line":582,"loc":{"start":{"line":582,"column":29},"end":{"line":600,"column":6}},"locations":[{"start":{"line":582,"column":29},"end":{"line":600,"column":6}}]},"152":{"type":"branch","line":589,"loc":{"start":{"line":589,"column":23},"end":{"line":591,"column":9}},"locations":[{"start":{"line":589,"column":23},"end":{"line":591,"column":9}}]},"153":{"type":"branch","line":593,"loc":{"start":{"line":593,"column":6},"end":{"line":599,"column":7}},"locations":[{"start":{"line":593,"column":6},"end":{"line":599,"column":7}}]},"154":{"type":"branch","line":604,"loc":{"start":{"line":604,"column":11},"end":{"line":607,"column":6}},"locations":[{"start":{"line":604,"column":11},"end":{"line":607,"column":6}}]},"155":{"type":"branch","line":615,"loc":{"start":{"line":615,"column":32},"end":{"line":622,"column":5}},"locations":[{"start":{"line":615,"column":32},"end":{"line":622,"column":5}}]},"156":{"type":"branch","line":619,"loc":{"start":{"line":619,"column":26},"end":{"line":620,"column":11}},"locations":[{"start":{"line":619,"column":26},"end":{"line":620,"column":11}}]},"157":{"type":"branch","line":644,"loc":{"start":{"line":644,"column":12},"end":{"line":647,"column":5}},"locations":[{"start":{"line":644,"column":12},"end":{"line":647,"column":5}}]},"158":{"type":"branch","line":649,"loc":{"start":{"line":649,"column":36},"end":{"line":698,"column":5}},"locations":[{"start":{"line":649,"column":36},"end":{"line":698,"column":5}}]},"159":{"type":"branch","line":650,"loc":{"start":{"line":650,"column":28},"end":{"line":652,"column":5}},"locations":[{"start":{"line":650,"column":28},"end":{"line":652,"column":5}}]},"160":{"type":"branch","line":669,"loc":{"start":{"line":669,"column":27},"end":{"line":669,"column":57}},"locations":[{"start":{"line":669,"column":27},"end":{"line":669,"column":57}}]},"161":{"type":"branch","line":669,"loc":{"start":{"line":669,"column":47},"end":{"line":669,"column":65}},"locations":[{"start":{"line":669,"column":47},"end":{"line":669,"column":65}}]},"162":{"type":"branch","line":672,"loc":{"start":{"line":672,"column":38},"end":{"line":672,"column":46}},"locations":[{"start":{"line":672,"column":38},"end":{"line":672,"column":46}}]},"163":{"type":"branch","line":673,"loc":{"start":{"line":673,"column":21},"end":{"line":676,"column":7}},"locations":[{"start":{"line":673,"column":21},"end":{"line":676,"column":7}}]},"164":{"type":"branch","line":681,"loc":{"start":{"line":681,"column":26},"end":{"line":684,"column":7}},"locations":[{"start":{"line":681,"column":26},"end":{"line":684,"column":7}}]},"165":{"type":"branch","line":690,"loc":{"start":{"line":690,"column":6},"end":{"line":694,"column":7}},"locations":[{"start":{"line":690,"column":6},"end":{"line":694,"column":7}}]},"166":{"type":"branch","line":695,"loc":{"start":{"line":695,"column":4},"end":{"line":697,"column":5}},"locations":[{"start":{"line":695,"column":4},"end":{"line":697,"column":5}}]},"167":{"type":"branch","line":712,"loc":{"start":{"line":712,"column":42},"end":{"line":738,"column":5}},"locations":[{"start":{"line":712,"column":42},"end":{"line":738,"column":5}}]},"168":{"type":"branch","line":715,"loc":{"start":{"line":715,"column":56},"end":{"line":717,"column":5}},"locations":[{"start":{"line":715,"column":56},"end":{"line":717,"column":5}}]},"169":{"type":"branch","line":722,"loc":{"start":{"line":722,"column":20},"end":{"line":724,"column":5}},"locations":[{"start":{"line":722,"column":20},"end":{"line":724,"column":5}}]},"170":{"type":"branch","line":728,"loc":{"start":{"line":728,"column":23},"end":{"line":730,"column":7}},"locations":[{"start":{"line":728,"column":23},"end":{"line":730,"column":7}}]},"171":{"type":"branch","line":733,"loc":{"start":{"line":733,"column":4},"end":{"line":735,"column":6}},"locations":[{"start":{"line":733,"column":4},"end":{"line":735,"column":6}}]},"172":{"type":"branch","line":765,"loc":{"start":{"line":765,"column":21},"end":{"line":765,"column":50}},"locations":[{"start":{"line":765,"column":21},"end":{"line":765,"column":50}}]},"173":{"type":"branch","line":774,"loc":{"start":{"line":774,"column":21},"end":{"line":779,"column":14}},"locations":[{"start":{"line":774,"column":21},"end":{"line":779,"column":14}}]},"174":{"type":"branch","line":775,"loc":{"start":{"line":775,"column":39},"end":{"line":777,"column":15}},"locations":[{"start":{"line":775,"column":39},"end":{"line":777,"column":15}}]},"175":{"type":"branch","line":778,"loc":{"start":{"line":778,"column":30},"end":{"line":778,"column":45}},"locations":[{"start":{"line":778,"column":30},"end":{"line":778,"column":45}}]},"176":{"type":"branch","line":792,"loc":{"start":{"line":792,"column":25},"end":{"line":805,"column":34}},"locations":[{"start":{"line":792,"column":25},"end":{"line":805,"column":34}}]},"177":{"type":"branch","line":798,"loc":{"start":{"line":798,"column":27},"end":{"line":801,"column":20}},"locations":[{"start":{"line":798,"column":27},"end":{"line":801,"column":20}}]},"178":{"type":"branch","line":857,"loc":{"start":{"line":857,"column":23},"end":{"line":866,"column":16}},"locations":[{"start":{"line":857,"column":23},"end":{"line":866,"column":16}}]},"179":{"type":"branch","line":858,"loc":{"start":{"line":858,"column":58},"end":{"line":860,"column":17}},"locations":[{"start":{"line":858,"column":58},"end":{"line":860,"column":17}}]},"180":{"type":"branch","line":861,"loc":{"start":{"line":861,"column":33},"end":{"line":864,"column":17}},"locations":[{"start":{"line":861,"column":33},"end":{"line":864,"column":17}}]},"181":{"type":"branch","line":864,"loc":{"start":{"line":864,"column":16},"end":{"line":865,"column":53}},"locations":[{"start":{"line":864,"column":16},"end":{"line":865,"column":53}}]},"182":{"type":"branch","line":883,"loc":{"start":{"line":883,"column":23},"end":{"line":885,"column":16}},"locations":[{"start":{"line":883,"column":23},"end":{"line":885,"column":16}}]},"183":{"type":"branch","line":903,"loc":{"start":{"line":903,"column":38},"end":{"line":959,"column":15}},"locations":[{"start":{"line":903,"column":38},"end":{"line":959,"column":15}}]},"184":{"type":"branch","line":904,"loc":{"start":{"line":904,"column":37},"end":{"line":904,"column":61}},"locations":[{"start":{"line":904,"column":37},"end":{"line":904,"column":61}}]},"185":{"type":"branch","line":905,"loc":{"start":{"line":905,"column":57},"end":{"line":906,"column":32}},"locations":[{"start":{"line":905,"column":57},"end":{"line":906,"column":32}}]},"186":{"type":"branch","line":906,"loc":{"start":{"line":906,"column":20},"end":{"line":907,"column":32}},"locations":[{"start":{"line":906,"column":20},"end":{"line":907,"column":32}}]},"187":{"type":"branch","line":910,"loc":{"start":{"line":910,"column":38},"end":{"line":910,"column":75}},"locations":[{"start":{"line":910,"column":38},"end":{"line":910,"column":75}}]},"188":{"type":"branch","line":911,"loc":{"start":{"line":911,"column":83},"end":{"line":911,"column":91}},"locations":[{"start":{"line":911,"column":83},"end":{"line":911,"column":91}}]},"189":{"type":"branch","line":917,"loc":{"start":{"line":917,"column":25},"end":{"line":918,"column":54}},"locations":[{"start":{"line":917,"column":25},"end":{"line":918,"column":54}}]},"190":{"type":"branch","line":918,"loc":{"start":{"line":918,"column":52},"end":{"line":922,"column":48}},"locations":[{"start":{"line":918,"column":52},"end":{"line":922,"column":48}}]},"191":{"type":"branch","line":919,"loc":{"start":{"line":919,"column":28},"end":{"line":920,"column":91}},"locations":[{"start":{"line":919,"column":28},"end":{"line":920,"column":91}}]},"192":{"type":"branch","line":920,"loc":{"start":{"line":920,"column":89},"end":{"line":922,"column":48}},"locations":[{"start":{"line":920,"column":89},"end":{"line":922,"column":48}}]},"193":{"type":"branch","line":926,"loc":{"start":{"line":926,"column":23},"end":{"line":929,"column":31}},"locations":[{"start":{"line":926,"column":23},"end":{"line":929,"column":31}}]},"194":{"type":"branch","line":929,"loc":{"start":{"line":929,"column":24},"end":{"line":930,"column":31}},"locations":[{"start":{"line":929,"column":24},"end":{"line":930,"column":31}}]},"195":{"type":"branch","line":932,"loc":{"start":{"line":932,"column":47},"end":{"line":955,"column":28}},"locations":[{"start":{"line":932,"column":47},"end":{"line":955,"column":28}}]},"196":{"type":"branch","line":955,"loc":{"start":{"line":955,"column":22},"end":{"line":956,"column":29}},"locations":[{"start":{"line":955,"column":22},"end":{"line":956,"column":29}}]},"197":{"type":"branch","line":934,"loc":{"start":{"line":934,"column":46},"end":{"line":954,"column":25}},"locations":[{"start":{"line":934,"column":46},"end":{"line":954,"column":25}}]},"198":{"type":"branch","line":938,"loc":{"start":{"line":938,"column":54},"end":{"line":938,"column":69}},"locations":[{"start":{"line":938,"column":54},"end":{"line":938,"column":69}}]},"199":{"type":"branch","line":976,"loc":{"start":{"line":976,"column":19},"end":{"line":976,"column":49}},"locations":[{"start":{"line":976,"column":19},"end":{"line":976,"column":49}}]}},"b":{"0":[13],"1":[0],"2":[0],"3":[0],"4":[0],"5":[0],"6":[0],"7":[0],"8":[0],"9":[15],"10":[1],"11":[14],"12":[0],"13":[14],"14":[12],"15":[0],"16":[0],"17":[0],"18":[1],"19":[11],"20":[6],"21":[5],"22":[4],"23":[3],"24":[1],"25":[1],"26":[3],"27":[1],"28":[3],"29":[0],"30":[1],"31":[4],"32":[1],"33":[0],"34":[4],"35":[4],"36":[5],"37":[1],"38":[5],"39":[3],"40":[2],"41":[1],"42":[104],"43":[0],"44":[0],"45":[92],"46":[95],"47":[42],"48":[0],"49":[62],"50":[9],"51":[15],"52":[89],"53":[42],"54":[62],"55":[42],"56":[62],"57":[15],"58":[42],"59":[4],"60":[38],"61":[62],"62":[95],"63":[11],"64":[93],"65":[9],"66":[95],"67":[53],"68":[42],"69":[11],"70":[31],"71":[11],"72":[93],"73":[95],"74":[42],"75":[9],"76":[95],"77":[53],"78":[42],"79":[1],"80":[103],"81":[1],"82":[103],"83":[9],"84":[95],"85":[42],"86":[53],"87":[4],"88":[35],"89":[0],"90":[34],"91":[34],"92":[3],"93":[2],"94":[0],"95":[18],"96":[16],"97":[2],"98":[0],"99":[0],"100":[2],"101":[0],"102":[0],"103":[2],"104":[2],"105":[17],"106":[17],"107":[0],"108":[17],"109":[17],"110":[3],"111":[14],"112":[3],"113":[14],"114":[0],"115":[14],"116":[167],"117":[0],"118":[0],"119":[17],"120":[3],"121":[14],"122":[3],"123":[166],"124":[0],"125":[14],"126":[36],"127":[13],"128":[15],"129":[1],"130":[0],"131":[1],"132":[1],"133":[0],"134":[1],"135":[42],"136":[17],"137":[14],"138":[3],"139":[46],"140":[34],"141":[12],"142":[0],"143":[12],"144":[31],"145":[28],"146":[21],"147":[10],"148":[0],"149":[10],"150":[21],"151":[161],"152":[0],"153":[0],"154":[10],"155":[17],"156":[16],"157":[27],"158":[1],"159":[0],"160":[0],"161":[0],"162":[0],"163":[0],"164":[0],"165":[0],"166":[0],"167":[1],"168":[0],"169":[0],"170":[0],"171":[0],"172":[4],"173":[12],"174":[0],"175":[12],"176":[11],"177":[10],"178":[10],"179":[0],"180":[3],"181":[7],"182":[1],"183":[50],"184":[4],"185":[4],"186":[46],"187":[4],"188":[48],"189":[3],"190":[47],"191":[4],"192":[43],"193":[4],"194":[46],"195":[2],"196":[48],"197":[12],"198":[0],"199":[3]},"fnMap":{"0":{"name":"formatPlanLabel","decl":{"start":{"line":141,"column":0},"end":{"line":157,"column":1}},"loc":{"start":{"line":141,"column":0},"end":{"line":157,"column":1}},"line":141},"1":{"name":"mapForgeItemStatus","decl":{"start":{"line":159,"column":0},"end":{"line":168,"column":1}},"loc":{"start":{"line":159,"column":0},"end":{"line":168,"column":1}},"line":159},"2":{"name":"mapForgePhaseChipState","decl":{"start":{"line":170,"column":0},"end":{"line":187,"column":1}},"loc":{"start":{"line":170,"column":0},"end":{"line":187,"column":1}},"line":170},"3":{"name":"ForgeTemplatesModal","decl":{"start":{"line":189,"column":0},"end":{"line":307,"column":1}},"loc":{"start":{"line":189,"column":0},"end":{"line":307,"column":1}},"line":189},"4":{"name":"handleKeyDown","decl":{"start":{"line":205,"column":26},"end":{"line":211,"column":6}},"loc":{"start":{"line":205,"column":26},"end":{"line":211,"column":6}},"line":205},"5":{"name":"onClick","decl":{"start":{"line":253,"column":25},"end":{"line":255,"column":18}},"loc":{"start":{"line":253,"column":25},"end":{"line":255,"column":18}},"line":253},"6":{"name":"onClick","decl":{"start":{"line":262,"column":25},"end":{"line":265,"column":18}},"loc":{"start":{"line":262,"column":25},"end":{"line":265,"column":18}},"line":262},"7":{"name":"onClick","decl":{"start":{"line":287,"column":27},"end":{"line":290,"column":20}},"loc":{"start":{"line":287,"column":27},"end":{"line":290,"column":20}},"line":287},"8":{"name":"Forge","decl":{"start":{"line":309,"column":7},"end":{"line":981,"column":1}},"loc":{"start":{"line":309,"column":7},"end":{"line":981,"column":1}},"line":309},"9":{"name":"loadPlans","decl":{"start":{"line":476,"column":22},"end":{"line":481,"column":6}},"loc":{"start":{"line":476,"column":22},"end":{"line":481,"column":6}},"line":476},"10":{"name":"onClose","decl":{"start":{"line":553,"column":13},"end":{"line":553,"column":42}},"loc":{"start":{"line":553,"column":13},"end":{"line":553,"column":42}},"line":553},"11":{"name":"installedTemplateId","decl":{"start":{"line":576,"column":13},"end":{"line":578,"column":8}},"loc":{"start":{"line":576,"column":13},"end":{"line":578,"column":8}},"line":576},"12":{"name":"refreshPhaseView","decl":{"start":{"line":582,"column":29},"end":{"line":600,"column":6}},"loc":{"start":{"line":582,"column":29},"end":{"line":600,"column":6}},"line":582},"13":{"name":"onClick","decl":{"start":{"line":765,"column":21},"end":{"line":765,"column":50}},"loc":{"start":{"line":765,"column":21},"end":{"line":765,"column":50}},"line":765},"14":{"name":"onClick","decl":{"start":{"line":774,"column":21},"end":{"line":779,"column":14}},"loc":{"start":{"line":774,"column":21},"end":{"line":779,"column":14}},"line":774},"15":{"name":"onClick","decl":{"start":{"line":798,"column":27},"end":{"line":801,"column":20}},"loc":{"start":{"line":798,"column":27},"end":{"line":801,"column":20}},"line":798},"16":{"name":"onClick","decl":{"start":{"line":809,"column":25},"end":{"line":812,"column":18}},"loc":{"start":{"line":809,"column":25},"end":{"line":812,"column":18}},"line":809},"17":{"name":"onClick","decl":{"start":{"line":857,"column":23},"end":{"line":866,"column":16}},"loc":{"start":{"line":857,"column":23},"end":{"line":866,"column":16}},"line":857},"18":{"name":"onClick","decl":{"start":{"line":883,"column":23},"end":{"line":885,"column":16}},"loc":{"start":{"line":883,"column":23},"end":{"line":885,"column":16}},"line":883},"19":{"name":"onClose","decl":{"start":{"line":976,"column":19},"end":{"line":976,"column":49}},"loc":{"start":{"line":976,"column":19},"end":{"line":976,"column":49}},"line":976}},"f":{"0":13,"1":15,"2":12,"3":4,"4":1,"5":0,"6":1,"7":1,"8":104,"9":166,"10":0,"11":21,"12":161,"13":4,"14":12,"15":10,"16":0,"17":10,"18":1,"19":3}} +} diff --git a/coverage/favicon.png b/coverage/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c1525b811a167671e9de1fa78aab9f5c0b61cef7 GIT binary patch literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> + + + + Code coverage report for All files + + + + + + + + + +
    +
    +

    All files

    +
    + +
    + 90.5% + Statements + 696/769 +
    + + +
    + 75.5% + Branches + 151/200 +
    + + +
    + 85% + Functions + 17/20 +
    + + +
    + 90.5% + Lines + 696/769 +
    + + +
    +

    + Press n or j to go to the next uncovered block, b, p or k for the previous block. +

    + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FileStatementsBranchesFunctionsLines
    Forge.tsx +
    +
    90.5%696/76975.5%151/20085%17/2090.5%696/769
    +
    +
    +
    + + + + + + + + \ No newline at end of file diff --git a/coverage/prettify.css b/coverage/prettify.css new file mode 100644 index 0000000000..b317a7cda3 --- /dev/null +++ b/coverage/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/prettify.js b/coverage/prettify.js new file mode 100644 index 0000000000..b3225238f2 --- /dev/null +++ b/coverage/prettify.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/sort-arrow-sprite.png b/coverage/sort-arrow-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed68316eb3f65dec9063332d2f69bf3093bbfab GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc literal 0 HcmV?d00001 diff --git a/coverage/sorter.js b/coverage/sorter.js new file mode 100644 index 0000000000..4ed70ae5ac --- /dev/null +++ b/coverage/sorter.js @@ -0,0 +1,210 @@ +/* eslint-disable */ +var addSorting = (function() { + 'use strict'; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; + } + + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + + // Try to create a RegExp from the searchValue. If it fails (invalid regex), + // it will be treated as a plain text search + let searchRegex; + try { + searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive + } catch (error) { + searchRegex = null; + } + + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + let isMatch = false; + + if (searchRegex) { + // If a valid regex was created, use it for matching + isMatch = searchRegex.test(row.textContent); + } else { + // Otherwise, fall back to the original plain text search + isMatch = row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase()); + } + + row.style.display = isMatch ? '' : 'none'; + } + } + + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); + } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function(a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function(a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function() { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function() { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/docs/codebase-map.md b/docs/codebase-map.md index c3a92a03e7..2946c00371 100644 --- a/docs/codebase-map.md +++ b/docs/codebase-map.md @@ -21,6 +21,7 @@ If a behavior must work in both app and daemon, implement it in `src-tauri/src/s | Need | Primary files to edit | | --- | --- | | App-level UI composition/layout wiring | `src/App.tsx`, `src/features/app/components/AppLayout.tsx`, `src/features/app/bootstrap/*`, `src/features/app/orchestration/*`, `src/features/app/hooks/*` | +| Change Forge sidebar panel behavior (project gate, plan actions, execution controls) | `src/features/forge/components/Forge.tsx`, `src/features/app/components/Sidebar.tsx`, `src/features/forge/hooks/useForgeExecution.ts`, `src/features/forge/components/Forge.plans.test.tsx`, `src/features/app/components/Sidebar.test.tsx`, `docs/forge.md` | | Add/change Tauri IPC methods used by frontend | `src/services/tauri.ts`, `src-tauri/src/lib.rs`, matching backend adapter module | | Add/change app-server event handling in UI | `src/services/events.ts`, `src/features/app/hooks/useAppServerEvents.ts`, `src/utils/appServerEvents.ts`, `src/features/threads/utils/threadNormalize.ts` | | Change thread state transitions | `src/features/threads/hooks/useThreadsReducer.ts`, `src/features/threads/hooks/threadReducer/*`, `src/features/threads/hooks/useThreads.ts`, focused thread hooks under `src/features/threads/hooks/*` | @@ -84,6 +85,13 @@ Use TS/Vite aliases for refactor-safe imports: - Prompt UI and workflow: `src/features/prompts/components/PromptPanel.tsx`, `src/features/prompts/hooks/useCustomPrompts.ts` +### Forge + +- Forge panel UI and controls: `src/features/forge/components/Forge.tsx` +- Forge execution loop wiring: `src/features/forge/hooks/useForgeExecution.ts` +- Sidebar Forge panel toggle wiring: `src/features/app/components/Sidebar.tsx` +- Forge behavior tests: `src/features/forge/components/Forge.plans.test.tsx`, `src/features/app/components/Sidebar.test.tsx` + ## Backend App (Tauri) Navigation - Command registry (what frontend can invoke): `src-tauri/src/lib.rs` diff --git a/docs/forge.md b/docs/forge.md index 65de5c1384..0cd5057a52 100644 --- a/docs/forge.md +++ b/docs/forge.md @@ -68,6 +68,11 @@ Execution UI rendering behavior: - running phase or `in_progress` -> `is-current` - `completed` -> `is-complete` - `pending` / `blocked` / `failed` -> `is-pending` +- Forge sidebar panel project gate (`src/features/forge/components/Forge.tsx` + `src/features/app/components/Sidebar.tsx`): + - Forge panel can be opened from the sidebar header even when no workspace is active. + - If `activeWorkspaceId` is null/blank, Forge renders blocker copy `Select a project first to use Forge.`. + - In no-project mode, these controls are disabled and blocked from backend side effects: `Open templates`, plan selector, `Resume plan`, and `Clean progress`. + - Plan menu actions (`New plan...`, `Other...`) are not reachable while blocked, and no-project control clicks do not call `connectWorkspace`, `startThread`, or `sendUserMessage`. - `src/utils/forgePhaseIcons.ts::getForgePhaseIconUrl` validates icon ids with `isMaterialIconName` and resolves URLs with `getIconUrlByName(id, "/assets/material-icons")`. - Invalid/empty icon ids fall back to safe icon id `file` (`/assets/material-icons/file.svg`). @@ -156,6 +161,10 @@ The `ai-review` phase is terminal and is treated as a hard gate for task complet Current regression coverage for this behavior spans frontend, template hooks, and shared Rust execution core: +- Frontend project-gate behavior: + - `src/features/app/components/Sidebar.test.tsx` + - `src/features/forge/components/Forge.plans.test.tsx` + - Covers no-project blocker copy, disabled Forge controls, blocked menu reachability, no backend calls in blocked mode, and unchanged sidebar Forge open/close toggling. - Frontend execution chip rendering: - `src/features/forge/components/Forge.plans.test.tsx` - Covers template-order chip rendering, class-state mapping, icon URL fallback, and terminal `ai-review` staying non-completed/visibly blocking. @@ -172,6 +181,12 @@ Current regression coverage for this behavior spans frontend, template hooks, an - `src-tauri/src/shared/forge_execute_core.rs` tests under `forge_execute_core::tests` - Covers partial progression, non-final no-commit success, final `ai-review` failure blocking completion, and final `ai-review` success commit gating. +Task-local validation commands for project-gate behavior: + +- `npm run test -- src/features/forge/components/Forge.plans.test.tsx src/features/app/components/Sidebar.test.tsx` +- `npm run test -- --coverage --coverage.include=src/features/forge/components/Forge.tsx src/features/forge/components/Forge.plans.test.tsx` +- `npm run typecheck` + ## Workspace Artifacts Created by Install `install_bundled_template_core` writes these paths in the workspace root: diff --git a/src/features/app/components/Sidebar.test.tsx b/src/features/app/components/Sidebar.test.tsx index eb655c1311..18611b1a9c 100644 --- a/src/features/app/components/Sidebar.test.tsx +++ b/src/features/app/components/Sidebar.test.tsx @@ -72,7 +72,7 @@ const baseProps = { }; describe("Sidebar", () => { - it("toggles Forge panel from the header anvil icon", () => { + it("toggles Forge panel from the header anvil icon and shows no-project blocker state", () => { render(); expect(screen.queryByText("Forge")).toBeNull(); @@ -81,11 +81,21 @@ describe("Sidebar", () => { fireEvent.click(screen.getByRole("button", { name: "Toggle Forge" })); expect(screen.getByText("Forge")).toBeTruthy(); - expect(screen.getByText("Click to select")).toBeTruthy(); + expect(screen.getByText(/Select a project first to use Forge/i)).toBeTruthy(); expect(screen.queryByText("Add a workspace to start.")).toBeNull(); + const templateButton = screen.getByRole("button", { name: "Open templates" }); + expect(templateButton.hasAttribute("disabled")).toBe(true); + const planSelectButton = screen.getByRole("button", { name: /Click to select/i }); + expect(planSelectButton.hasAttribute("disabled")).toBe(true); const runButton = screen.getByRole("button", { name: "Resume plan" }); expect(runButton.hasAttribute("disabled")).toBe(true); + const cleanProgressButton = screen.getByRole("button", { name: "Clean progress" }); + expect(cleanProgressButton.hasAttribute("disabled")).toBe(true); + + fireEvent.click(screen.getByRole("button", { name: "Toggle Forge" })); + expect(screen.queryByText("Forge")).toBeNull(); + expect(screen.getByText("Add a workspace to start.")).toBeTruthy(); }); it("closes Forge when the search toggle is activated", () => { @@ -99,15 +109,15 @@ describe("Sidebar", () => { expect(screen.getByLabelText("Search projects")).toBeTruthy(); }); - it("shows Forge plan menu actions", () => { + it("does not show Forge plan menu actions when no project is selected", () => { render(); fireEvent.click(screen.getByRole("button", { name: "Toggle Forge" })); fireEvent.click(screen.getByRole("button", { name: /Click to select/i })); - expect(screen.getByText("Other...")).toBeTruthy(); - expect(screen.getByText("New plan...")).toBeTruthy(); + expect(screen.queryByText("Other...")).toBeNull(); + expect(screen.queryByText("New plan...")).toBeNull(); }); it("toggles the search bar from the header icon", () => { diff --git a/src/features/forge/components/Forge.plans.test.tsx b/src/features/forge/components/Forge.plans.test.tsx index 22e85787ce..3d0c23f91b 100644 --- a/src/features/forge/components/Forge.plans.test.tsx +++ b/src/features/forge/components/Forge.plans.test.tsx @@ -22,6 +22,272 @@ const templatesClient: ForgeTemplatesClient = { }; describe("Forge plans", () => { + it("opens templates modal, supports swap/remove actions, and closes on escape", async () => { + const installTemplate = vi.fn(async () => ({ + schema: "forge-template-lock-v1", + installedTemplateId: "tpl-beta", + installedTemplateVersion: "2.0.0", + installedAtIso: "2026-02-12T00:00:00.000Z", + installedFiles: [], + })); + const uninstallTemplate = vi.fn(async () => {}); + const templatesClientWithInstall: ForgeTemplatesClient = { + listBundledTemplates: async () => [ + { id: "tpl-alpha", title: "Alpha Template", version: "1.0.0" }, + { id: "tpl-beta", title: "Beta Template", version: "2.0.0" }, + ], + getInstalledTemplate: async () => ({ + schema: "forge-template-lock-v1", + installedTemplateId: "tpl-alpha", + installedTemplateVersion: "1.0.0", + installedAtIso: "2026-02-12T00:00:00.000Z", + installedFiles: [], + }), + installTemplate, + uninstallTemplate, + }; + + const plansClient: ForgePlansClient = { + listPlans: async () => [], + getPlanPrompt: async () => "", + prepareExecution: async () => {}, + resetExecutionProgress: async () => {}, + getNextPhasePrompt: async () => null, + getPhaseStatus: async () => ({ status: "pending", commitSha: null }), + runPhaseChecks: async () => ({ ok: true, results: [] }), + interruptTurn: async () => ({}), + connectWorkspace: async () => {}, + startThread: async () => ({ result: { thread: { id: "thread-1" } } }), + sendUserMessage: async () => ({}), + }; + + render( + , + ); + + fireEvent.click(await screen.findByRole("button", { name: "Open templates" })); + expect(await screen.findByText("Templates")).toBeTruthy(); + expect(screen.getByText("Alpha Template")).toBeTruthy(); + fireEvent.click(screen.getByRole("button", { name: "Swap" })); + + await waitFor(() => expect(installTemplate).toHaveBeenCalledWith("ws-1", "tpl-beta")); + await waitFor(() => expect(screen.queryByText("Templates")).toBeNull()); + + fireEvent.click(screen.getByRole("button", { name: "Open templates" })); + await waitFor(() => expect(screen.getByText("Beta Template")).toBeTruthy()); + fireEvent.click(screen.getByRole("button", { name: "Remove" })); + await waitFor(() => expect(uninstallTemplate).toHaveBeenCalledWith("ws-1")); + await waitFor(() => expect(screen.queryByText("Templates")).toBeNull()); + + fireEvent.click(screen.getByRole("button", { name: "Open templates" })); + await waitFor(() => expect(screen.getByText("Templates")).toBeTruthy()); + fireEvent.keyDown(window, { key: "Escape" }); + await waitFor(() => expect(screen.queryByText("Templates")).toBeNull()); + }); + + it("renders unknown installed template fallback text when lock is not in bundled list", async () => { + const templatesClientWithUnknownInstall: ForgeTemplatesClient = { + listBundledTemplates: async () => [ + { id: "tpl-known", title: "Known Template", version: "1.0.0" }, + ], + getInstalledTemplate: async () => ({ + schema: "forge-template-lock-v1", + installedTemplateId: "tpl-missing", + installedTemplateVersion: "9.9.9", + installedAtIso: "2026-02-12T00:00:00.000Z", + installedFiles: [], + }), + installTemplate: async () => { + throw new Error("unexpected install"); + }, + uninstallTemplate: async () => {}, + }; + + const plansClient: ForgePlansClient = { + listPlans: async () => [], + getPlanPrompt: async () => "", + prepareExecution: async () => {}, + resetExecutionProgress: async () => {}, + getNextPhasePrompt: async () => null, + getPhaseStatus: async () => ({ status: "pending", commitSha: null }), + runPhaseChecks: async () => ({ ok: true, results: [] }), + interruptTurn: async () => ({}), + connectWorkspace: async () => {}, + startThread: async () => ({ result: { thread: { id: "thread-1" } } }), + sendUserMessage: async () => ({}), + }; + + render( + , + ); + + fireEvent.click(await screen.findByRole("button", { name: "Open templates" })); + expect(await screen.findByText("tpl-missing")).toBeTruthy(); + expect(screen.getByText("Installed (9.9.9)")).toBeTruthy(); + }); + + it("shows a no-project blocker and disables Forge controls when no workspace is selected", async () => { + const listPlans = vi.fn().mockResolvedValue([]); + const plansClient: ForgePlansClient = { + listPlans, + getPlanPrompt: async () => "", + prepareExecution: async () => {}, + resetExecutionProgress: async () => {}, + getNextPhasePrompt: async () => null, + getPhaseStatus: async () => ({ status: "pending", commitSha: null }), + runPhaseChecks: async () => ({ ok: true, results: [] }), + interruptTurn: async () => ({}), + connectWorkspace: async () => {}, + startThread: async () => ({ result: { thread: { id: "thread-1" } } }), + sendUserMessage: async () => ({}), + }; + + render( + , + ); + + expect( + await screen.findByText(/Select a project first to use Forge/i), + ).toBeTruthy(); + + const templatesButton = screen.getByRole("button", { name: "Open templates" }); + expect(templatesButton.hasAttribute("disabled")).toBe(true); + const planSelectButton = screen.getByRole("button", { name: /Click to select/i }); + expect(planSelectButton.hasAttribute("disabled")).toBe(true); + const runButton = screen.getByRole("button", { name: "Resume plan" }); + expect(runButton.hasAttribute("disabled")).toBe(true); + const cleanProgressButton = screen.getByRole("button", { name: "Clean progress" }); + expect(cleanProgressButton.hasAttribute("disabled")).toBe(true); + + fireEvent.click(planSelectButton); + expect(screen.queryByText("New plan...")).toBeNull(); + expect(screen.queryByText("Other...")).toBeNull(); + expect(listPlans).not.toHaveBeenCalled(); + }); + + it("never calls connect/start/send plan backends in no-project mode", async () => { + const connectWorkspace = vi.fn(async () => {}); + const startThread = vi.fn(async () => ({ result: { thread: { id: "thread-1" } } })); + const sendUserMessage = vi.fn(async () => ({})); + + const plansClient: ForgePlansClient = { + listPlans: async () => [], + getPlanPrompt: async () => "", + prepareExecution: async () => {}, + resetExecutionProgress: async () => {}, + getNextPhasePrompt: async () => null, + getPhaseStatus: async () => ({ status: "pending", commitSha: null }), + runPhaseChecks: async () => ({ ok: true, results: [] }), + interruptTurn: async () => ({}), + connectWorkspace, + startThread, + sendUserMessage, + }; + + render( + , + ); + + const planSelectButton = screen.getByRole("button", { name: /Click to select/i }); + fireEvent.click(planSelectButton); + const newPlanAction = screen.queryByText("New plan..."); + if (newPlanAction) { + fireEvent.click(newPlanAction); + } + fireEvent.click(screen.getByRole("button", { name: "Resume plan" })); + fireEvent.click(screen.getByRole("button", { name: "Clean progress" })); + + await act(async () => { + await Promise.resolve(); + }); + + expect(connectWorkspace).not.toHaveBeenCalled(); + expect(startThread).not.toHaveBeenCalled(); + expect(sendUserMessage).not.toHaveBeenCalled(); + }); + + it("keeps no-project invariants under deterministic random click sequences", async () => { + const connectWorkspace = vi.fn(async () => {}); + const startThread = vi.fn(async () => ({ result: { thread: { id: "thread-1" } } })); + const sendUserMessage = vi.fn(async () => ({})); + + const plansClient: ForgePlansClient = { + listPlans: async () => [], + getPlanPrompt: async () => "", + prepareExecution: async () => {}, + resetExecutionProgress: async () => {}, + getNextPhasePrompt: async () => null, + getPhaseStatus: async () => ({ status: "pending", commitSha: null }), + runPhaseChecks: async () => ({ ok: true, results: [] }), + interruptTurn: async () => ({}), + connectWorkspace, + startThread, + sendUserMessage, + }; + + render( + , + ); + + const controls = () => ({ + templates: screen.getByRole("button", { name: "Open templates" }), + planSelect: screen.getByRole("button", { name: /Click to select/i }), + run: screen.getByRole("button", { name: "Resume plan" }), + clean: screen.getByRole("button", { name: "Clean progress" }), + }); + + let seed = 1337; + const next = () => { + seed = (seed * 1103515245 + 12345) % 2147483648; + return seed; + }; + + const actions = [ + () => fireEvent.click(controls().templates), + () => fireEvent.click(controls().planSelect), + () => fireEvent.click(controls().run), + () => fireEvent.click(controls().clean), + ]; + + for (let i = 0; i < 64; i += 1) { + await act(async () => { + actions[next() % actions.length](); + }); + expect(screen.getByText(/Select a project first to use Forge/i)).toBeTruthy(); + expect(screen.queryByText("New plan...")).toBeNull(); + expect(screen.queryByText("Templates")).toBeNull(); + } + + expect(connectWorkspace).not.toHaveBeenCalled(); + expect(startThread).not.toHaveBeenCalled(); + expect(sendUserMessage).not.toHaveBeenCalled(); + }); + it("lists workspace plans and enables the execute toggle after selecting one", async () => { const getNextPhasePrompt = vi .fn() diff --git a/src/features/forge/components/Forge.tsx b/src/features/forge/components/Forge.tsx index d2977c162b..909d205686 100644 --- a/src/features/forge/components/Forge.tsx +++ b/src/features/forge/components/Forge.tsx @@ -351,6 +351,7 @@ export function Forge({ const connectWorkspaceToRun = plansApi.connectWorkspace; const startThreadForPlan = plansApi.startThread; const sendUserMessageToPlanThread = plansApi.sendUserMessage; + const hasActiveWorkspace = Boolean(activeWorkspaceId?.trim()); const findCollaborationMode = useCallback( (wanted: string) => { @@ -552,6 +553,13 @@ export function Forge({ onClose: () => setPlanMenuOpen(false), }); + useEffect(() => { + if (hasActiveWorkspace) { + return; + } + setPlanMenuOpen(false); + }, [hasActiveWorkspace]); + useEffect(() => { if (!selectedPlanId) { return; @@ -755,6 +763,7 @@ export function Forge({ title="Templates" data-tauri-drag-region="false" onClick={() => setTemplatesOpen(true)} + disabled={!hasActiveWorkspace} > @@ -762,9 +771,15 @@ export function Forge({ type="button" className={`ghost forge-plan-toggle${planMenuOpen ? " is-open" : ""}`} data-tauri-drag-region="false" - onClick={() => setPlanMenuOpen((open) => !open)} + onClick={() => { + if (!hasActiveWorkspace) { + return; + } + setPlanMenuOpen((open) => !open); + }} aria-haspopup="menu" aria-expanded={planMenuOpen} + disabled={!hasActiveWorkspace} > {selectedPlan ? selectedPlan.name : "Click to select"} @@ -827,18 +842,20 @@ export function Forge({ type="button" className="ghost forge-execute-toggle" data-tauri-drag-region="false" - disabled={!selectedPlan} + disabled={!hasActiveWorkspace || !selectedPlan} aria-label={isExecuting ? "Pause plan" : "Resume plan"} aria-pressed={isExecuting} title={ - !selectedPlan + !hasActiveWorkspace + ? "Select a project to use Forge" + : !selectedPlan ? "Select a plan to run" : isExecuting ? "Pause plan" : "Resume plan" } onClick={() => { - if (!selectedPlan) { + if (!hasActiveWorkspace || !selectedPlan) { return; } if (isExecuting) { @@ -854,10 +871,12 @@ export function Forge({ type="button" className="ghost forge-reset-progress" data-tauri-drag-region="false" - disabled={!selectedPlan || isResettingProgress} + disabled={!hasActiveWorkspace || !selectedPlan || isResettingProgress} aria-label="Clean progress" title={ - !selectedPlan + !hasActiveWorkspace + ? "Select a project to use Forge" + : !selectedPlan ? "Select a plan to clean progress" : "Reset state and derived execution files" } @@ -875,7 +894,11 @@ export function Forge({ {lastError} ) : null} - {selectedPlan ? ( + {!hasActiveWorkspace ? ( +
    + Select a project first to use Forge. +
    + ) : selectedPlan ? (
      {selectedPlan.items.map((item, index) => { const isActiveTask = runningInfo?.taskId === item.id; From 4e3112ae76d27d778661939ebdd358e739914447 Mon Sep 17 00:00:00 2001 From: Leonardo Stern Date: Thu, 12 Feb 2026 12:22:16 +0800 Subject: [PATCH 11/14] forge(forge-execution-stability-project-gate): task-2 Make task-row running status single-source and deterministic --- README.md | 1 + coverage/Forge.tsx.html | 1251 ++++++++------ coverage/clover.xml | 1482 +++++++++-------- coverage/coverage-final.json | 2 +- coverage/index.html | 38 +- docs/codebase-map.md | 2 +- docs/forge.md | 12 +- .../forge/components/Forge.plans.test.tsx | 418 +++++ src/features/forge/components/Forge.tsx | 79 +- 9 files changed, 2022 insertions(+), 1263 deletions(-) diff --git a/README.md b/README.md index c4c85a28fd..2597e63d06 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ CodexMonitor is a Tauri app for orchestrating multiple Codex agents across local - Canonical Forge module docs: [docs/forge.md](docs/forge.md). - Forge panel remains available from the sidebar header even when no project is selected. - No-project mode is explicit and blocking: Forge shows `Select a project first to use Forge.` and disables template, plan, execution, and clean-progress actions. +- During execution, Forge renders exactly one running task row from live `runningInfo`; non-active stale `in_progress` rows are demoted to `completed` (all phases complete) or `pending` (otherwise). - With a selected project, Forge installs/uninstalls bundled templates into workspace-scoped `.agent` artifacts, returns normalized plan prompts, and lists workspace plans with `state-v2` task status joins. ## Requirements diff --git a/coverage/Forge.tsx.html b/coverage/Forge.tsx.html index 6654b519ef..14d064175f 100644 --- a/coverage/Forge.tsx.html +++ b/coverage/Forge.tsx.html @@ -23,30 +23,30 @@

      All files Forge.tsx

      - 90.5% + 91.03% Statements - 696/769 + 751/825
      - 75.5% + 78.18% Branches - 151/200 + 172/220
      - 85% + 86.95% Functions - 17/20 + 20/23
      - 90.5% + 91.03% Lines - 696/769 + 751/825
      @@ -1044,7 +1044,76 @@

      All files Forge.tsx

      979 980 981 -9821x +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 +1000 +1001 +1002 +1003 +1004 +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045 +1046 +1047 +1048 +1049 +1050 +10511x 1x 1x 1x @@ -1184,53 +1253,118 @@

      All files Forge.tsx

            -13x -13x -13x -13x -13x -13x -13x +  +28x +28x +28x +28x +28x +28x +28x         -13x -13x +28x +28x     -13x -13x +28x +28x   -15x -15x -15x +45x +45x +45x 1x 1x +45x 15x -  -  +15x +29x +29x +  +348x +348x +348x +348x +348x +348x +348x +348x 14x 14x +348x +59x +59x +348x +106x +106x +169x +169x   -12x -12x -12x -12x -12x -12x -12x -12x +112x +112x +112x +112x +112x +112x +112x +173x +173x +112x +112x     -12x -1x -1x -12x -6x -6x -5x -5x +  +  +  +112x +  +212x +212x +212x +212x +212x +212x +104x +104x +212x +4x +4x +212x +59x +59x +45x +45x +  +230x +230x +230x +230x +230x +230x +230x +  +  +  +  +  +230x +230x +18x +18x +  +212x +230x +  +230x +4x +  +4x +4x +  +208x +208x   4x 4x @@ -1353,15 +1487,15 @@

      All files Forge.tsx

      4x   1x -104x -104x -104x -104x -104x -104x -104x -104x -104x +240x +240x +240x +240x +240x +240x +240x +240x +240x       @@ -1378,183 +1512,183 @@

      All files Forge.tsx

            -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x   -104x -104x -35x -35x +240x +240x +65x +65x     -35x -35x -35x -35x -34x -34x -34x -34x +65x +65x +65x +65x +64x +64x +64x +64x   -35x -104x -104x +65x +240x +240x   -104x -104x -18x -16x -16x -18x -18x +240x +240x +33x +31x +31x +33x +33x     -18x -18x +33x +33x         2x 2x -18x -18x -18x +33x +33x +33x 2x 2x 2x -18x -104x -104x -  -104x -104x -104x -104x -104x -  -104x -17x -17x -17x -17x -  -  -17x -17x -17x -  -17x -17x -17x -17x -104x -  -104x -17x -17x +33x +240x +240x +  +240x +240x +240x +240x +240x +  +240x +32x +32x +32x +32x +  +  +32x +32x +32x +  +32x +32x +32x +32x +240x +  +240x +32x +32x 3x 3x 3x 3x 3x 3x -14x -14x -14x -  -  -14x -14x -14x -  -14x -14x -14x -14x -104x -  -104x -104x -167x -  -  -167x -167x -167x -167x -167x -  -167x -167x -167x -167x -104x -104x -  -104x -17x -17x +29x +29x +29x +  +  +29x +29x +29x +  +29x +29x +29x +29x +240x +  +240x +240x +182x +  +  +182x +182x +182x +182x +182x +  +182x +182x +182x +182x +240x +240x +  +240x +32x +32x 3x 3x 3x 3x 3x   -14x -166x +29x +181x     -166x -166x +181x +181x   -14x -14x -14x -14x -14x -14x -104x +29x +29x +29x +29x +29x +29x +240x   -104x -36x -13x -15x -15x -15x -15x -15x -15x -13x +240x +66x +28x +45x +45x +45x +45x +45x +45x +28x   -13x -13x -13x -13x -13x -36x -104x +28x +28x +28x +28x +28x +66x +240x   -104x -104x +240x +240x 1x     @@ -1566,10 +1700,10 @@

      All files Forge.tsx

        1x 1x -104x -104x +240x +240x   -104x +240x 1x     @@ -1580,119 +1714,119 @@

      All files Forge.tsx

      1x   1x -104x +240x   -104x -104x -42x -62x -104x +240x +240x +132x +108x +240x   -104x -104x +240x +240x   -104x +240x   -104x -104x -104x -104x -104x +240x +240x +240x +240x +240x   -104x -17x -14x -14x +240x +32x +29x +29x 3x -104x +240x   -104x -46x -34x -34x -46x +240x +91x +64x +64x +91x     -104x +240x   -104x -31x -31x -21x -21x -21x -21x -21x +240x +61x +61x +36x +36x +36x +36x +36x   -31x -31x -161x -161x -161x -161x -161x -161x -161x +61x +61x +176x +176x +176x +176x +176x +176x +176x     -161x -161x +176x +176x             -161x +176x   -31x -31x -31x -10x -10x -10x -104x -104x -104x -104x -104x -104x +61x +61x +61x +25x +25x +25x +240x +240x +240x +240x +240x +240x   -104x -17x -17x -17x -17x -16x -17x -104x +240x +32x +32x +32x +32x +31x +32x +240x   -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x   -104x +240x   -27x -104x +57x +240x   -104x +240x 1x     @@ -1741,21 +1875,21 @@

      All files Forge.tsx

      1x     -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x   -104x +240x 1x 1x 1x @@ -1781,238 +1915,242 @@

      All files Forge.tsx

      1x 1x 1x -104x -104x -104x -104x -104x -104x -104x -104x -104x +240x +240x +240x +240x +240x +240x +240x +240x +240x   -104x -104x -104x -104x -104x +240x +240x +240x +240x +240x   -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -  -104x -104x -104x -104x -104x -104x -104x -12x -  -  -12x -12x -104x -104x -104x -  -104x -104x -104x -104x -104x -  -104x -15x -15x -11x -11x -11x -11x -11x -11x -10x -10x -10x -11x -  -11x -11x -15x -15x -15x -15x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x   +240x +240x +240x +240x +240x +240x +240x +27x     -15x -15x -  -15x -15x -15x -15x -15x -  -15x -15x -  -104x -104x -  -104x -104x -104x -104x -104x -104x -42x -4x -38x -62x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x +27x +27x +240x +240x +240x +  +240x +240x +240x +240x +240x +  +240x +30x +30x +26x +26x +26x +26x +26x +26x +25x +25x +25x +26x +  +26x +26x +30x +30x +30x +30x +  +  +  +30x +30x +  +30x +30x +30x +30x +30x +  +30x +30x +  +240x +240x +  +240x +240x +240x +240x +240x +240x +132x +19x +113x +108x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x 9x -95x -53x -42x -11x -31x +231x +99x +132x +41x +91x   -104x -10x +240x +40x     -10x -3x -3x -3x -7x -10x -  -104x -104x -104x -104x -104x -104x -104x -104x -104x -104x +40x +18x +18x +18x +22x +40x +  +240x +240x +240x +240x +240x +240x +240x +240x +240x +240x 9x -95x -53x -42x +231x +99x +132x   -104x +240x 1x 1x   -104x -104x -104x -104x -104x -104x +240x +240x +240x +240x +240x +240x 1x 1x 1x -103x -104x +239x +240x 9x   9x -95x -42x -42x -50x -50x -4x -46x -50x -50x -50x -50x -  -50x -50x -50x -50x -50x -3x -47x -4x -  -43x -  -50x -50x -50x -4x -4x -4x -46x -50x -50x -2x -2x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -  -12x -12x -12x -12x -12x -  -2x -2x -48x -50x -  -42x -42x -  -53x -  -53x +231x +132x +132x +230x +230x +230x +230x +230x +230x +230x +230x +230x +230x +230x +230x +  +230x +230x +230x +230x +230x +6x +224x +103x   -104x -104x +121x   -104x +230x +230x +230x +18x +18x +18x +212x +230x +230x +122x +122x +348x +348x +348x +348x +348x +348x +348x +348x +348x +348x +348x +348x +  +348x +348x +348x +348x +348x +  +122x +122x +108x +230x +  +132x +132x +  +99x +  +99x +  +240x +240x +  +240x 4x 4x 4x @@ -2022,9 +2160,9 @@

      All files Forge.tsx

      4x 4x   -104x +240x   -104x +240x  
      import CheckSquare2 from "lucide-react/dist/esm/icons/check-square-2";
       import ChevronDown from "lucide-react/dist/esm/icons/chevron-down";
       import Circle from "lucide-react/dist/esm/icons/circle";
      @@ -2164,6 +2302,7 @@ 

      All files Forge.tsx

      };   type ForgePhaseChipState = "is-complete" | "is-current" | "is-pending"; +type ForgeRunningInfo = { taskId: string; phaseId: string } | null;   function formatPlanLabel(plan: ForgeWorkspacePlan): string { const title = plan.title?.trim() ?? ""; @@ -2188,9 +2327,9 @@

      All files Forge.tsx

      if (normalized === "completed") { return "completed"; } - if (normalized === "in_progress") { - return "inProgress"; - } + if (normalized === "in_progress") { + return "inProgress"; + } return "pending"; }   @@ -2198,12 +2337,12 @@

      All files Forge.tsx

      taskId: string, phaseId: string, phaseStatus: ForgePhaseViewStatus, - runningInfo: { taskId: string; phaseId: string } | null, + runningInfo: ForgeRunningInfo, ): ForgePhaseChipState { const normalizedStatus = phaseStatus.trim().toLowerCase(); - if (runningInfo?.taskId === taskId && runningInfo.phaseId === phaseId) { - return "is-current"; - } + if (runningInfo?.taskId === taskId && runningInfo.phaseId === phaseId) { + return "is-current"; + } if (normalizedStatus === "in_progress") { return "is-current"; } @@ -2213,6 +2352,70 @@

      All files Forge.tsx

      return "is-pending"; }   +function allTaskPhasesCompleted( + taskPhaseStatuses: Record<string, ForgePhaseViewStatus>, + phases: ForgePhaseView["phases"], +): boolean { + if (phases.length > 0) { + return phases.every( + (phase) => + (taskPhaseStatuses[phase.id] ?? "pending").trim().toLowerCase() === + "completed", + ); + } + const phaseStatuses = Object.values(taskPhaseStatuses); + return ( + phaseStatuses.length > 0 && + phaseStatuses.every((status) => status.trim().toLowerCase() === "completed") + ); +} +  +function deriveStatusFromTaskPhases( + taskPhaseStatuses: Record<string, ForgePhaseViewStatus>, + phases: ForgePhaseView["phases"], +): ForgeItemStatus | null { + const phaseStatuses = Object.values(taskPhaseStatuses); + if (phaseStatuses.length === 0) { + return null; + } + if (allTaskPhasesCompleted(taskPhaseStatuses, phases)) { + return "completed"; + } + if (phaseStatuses.some((status) => status.trim().toLowerCase() === "in_progress")) { + return "inProgress"; + } + return "pending"; +} +  +function resolveForgeTaskRowStatus({ + taskId, + planTaskStatus, + taskPhaseStatuses, + phases, + runningInfo, +}: { + taskId: string; + planTaskStatus: ForgeItemStatus; + taskPhaseStatuses: Record<string, ForgePhaseViewStatus>; + phases: ForgePhaseView["phases"]; + runningInfo: ForgeRunningInfo; +}): ForgeItemStatus { + if (runningInfo?.taskId === taskId) { + return "inProgress"; + } +  + const phaseDerivedStatus = deriveStatusFromTaskPhases(taskPhaseStatuses, phases); + const resolvedStatus = phaseDerivedStatus ?? planTaskStatus; +  + if (runningInfo && resolvedStatus === "inProgress") { + return allTaskPhasesCompleted(taskPhaseStatuses, phases) + ? "completed" + : "pending"; + } +  + return resolvedStatus; +} +  function ForgeTemplatesModal({ templates, installedTemplate, @@ -2929,13 +3132,17 @@

      All files Forge.tsx

      <ol className="forge-items"> {selectedPlan.items.map((item, index) => { const isActiveTask = runningInfo?.taskId === item.id; - const effectiveStatus: ForgeItemStatus = isActiveTask - ? "inProgress" - : item.status; + const taskPhaseStatuses = phaseView.taskPhaseStatusByTaskId[item.id] ?? {}; + const effectiveStatus = resolveForgeTaskRowStatus({ + taskId: item.id, + planTaskStatus: item.status, + taskPhaseStatuses, + phases: phaseView.phases, + runningInfo, + }); const isCompleted = effectiveStatus === "completed"; const isRunning = effectiveStatus === "inProgress"; const isActivePhase = isActiveTask && runningInfo?.phaseId; - const taskPhaseStatuses = phaseView.taskPhaseStatusByTaskId[item.id] ?? {};   return ( <li key={`${item.id}-${item.title}-${index}`} className={`forge-item ${effectiveStatus}`}> @@ -3013,7 +3220,7 @@

      All files Forge.tsx

      + - - + + \ No newline at end of file diff --git a/coverage/components/index.html b/coverage/components/index.html new file mode 100644 index 0000000000..cecd1cb359 --- /dev/null +++ b/coverage/components/index.html @@ -0,0 +1,116 @@ + + + + + + Code coverage report for components + + + + + + + + + +
      +
      +

      All files components

      +
      + +
      + 91.08% + Statements + 756/830 +
      + + +
      + 78.57% + Branches + 176/224 +
      + + +
      + 86.95% + Functions + 20/23 +
      + + +
      + 91.08% + Lines + 756/830 +
      + + +
      +

      + Press n or j to go to the next uncovered block, b, p or k for the previous block. +

      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      FileStatementsBranchesFunctionsLines
      Forge.tsx +
      +
      91.08%756/83078.57%176/22486.95%20/2391.08%756/830
      +
      +
      +
      + + + + + + + + \ No newline at end of file diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json index c19296c53f..591feb81c6 100644 --- a/coverage/coverage-final.json +++ b/coverage/coverage-final.json @@ -1,2 +1,3 @@ -{"/Users/lstern/projects/forge/src/features/forge/components/Forge.tsx": {"path":"/Users/lstern/projects/forge/src/features/forge/components/Forge.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":70}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":67}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":56}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":56}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":63}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":73}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":54}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":52}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":74}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":77}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":8}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":72}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":8}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":8}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":63}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":70}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":59}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":50}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":50}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":40}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":44}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":2}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":51}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":28}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":36}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":36}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":42}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":54}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":46}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":38}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":38}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":16}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":19}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":14}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":18}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":2}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":42}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":13}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":30}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":2}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":60}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":41}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":39}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":35}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":20}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":30}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":3}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":14}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":17}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":3}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":19}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":66}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":24}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":34}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":3}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":44}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":1}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":62}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":49}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":35}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":23}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":3}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":37}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":24}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":3}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":19}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":1}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":32}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":17}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":18}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":36}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":32}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":24}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":60}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":74}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":24}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":3}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":43}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":24}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":3}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":41}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":25}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":3}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":22}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":1}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":32}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":58}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":35}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":12}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":26}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":24}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":16}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":75}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":20}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":6}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":3}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":57}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":10}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":31}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":80}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":1}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":36}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":58}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":35}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":27}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":57}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":35}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":16}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":3}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":58}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":23}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":3}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":86}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":24}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":3}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":19}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":1}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":36}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":9}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":17}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":20}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":9}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":14}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":4}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":21}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":39}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":24}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":3}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":83}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":62}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":55}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":60}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":19}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":18}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":3}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":24}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":1}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":30}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":12}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":20}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":12}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":20}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":22}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":10}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":4}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":4}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":19}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":53}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":35}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":15}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":7}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":29}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":16}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":6}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":54}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":70}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":16}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":37}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":80}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":50}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":53}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":60}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":7}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":11}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":26}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":52}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":16}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":10}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":15}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":39}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":31}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":33}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":75}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":66}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":12}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":42}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":56}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":22}},"304":{"start":{"line":305,"column":0},"end":{"line":305,"column":62}},"305":{"start":{"line":306,"column":0},"end":{"line":306,"column":49}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":74}},"307":{"start":{"line":308,"column":0},"end":{"line":308,"column":51}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":77}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":20}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":18}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":52}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":21}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":29}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":53}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":42}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":37}},"317":{"start":{"line":318,"column":0},"end":{"line":318,"column":32}},"319":{"start":{"line":320,"column":0},"end":{"line":320,"column":18}},"321":{"start":{"line":322,"column":0},"end":{"line":322,"column":38}},"322":{"start":{"line":323,"column":0},"end":{"line":323,"column":23}},"323":{"start":{"line":324,"column":0},"end":{"line":324,"column":21}},"324":{"start":{"line":325,"column":0},"end":{"line":325,"column":29}},"325":{"start":{"line":326,"column":0},"end":{"line":326,"column":55}},"326":{"start":{"line":327,"column":0},"end":{"line":327,"column":32}},"327":{"start":{"line":328,"column":0},"end":{"line":328,"column":40}},"328":{"start":{"line":329,"column":0},"end":{"line":329,"column":28}},"329":{"start":{"line":330,"column":0},"end":{"line":330,"column":18}},"330":{"start":{"line":331,"column":0},"end":{"line":331,"column":37}},"331":{"start":{"line":332,"column":0},"end":{"line":332,"column":15}},"333":{"start":{"line":334,"column":0},"end":{"line":334,"column":23}},"334":{"start":{"line":335,"column":0},"end":{"line":335,"column":18}},"335":{"start":{"line":336,"column":0},"end":{"line":336,"column":16}},"337":{"start":{"line":338,"column":0},"end":{"line":338,"column":76}},"340":{"start":{"line":341,"column":0},"end":{"line":341,"column":35}},"341":{"start":{"line":342,"column":0},"end":{"line":342,"column":61}},"342":{"start":{"line":343,"column":0},"end":{"line":343,"column":18}},"343":{"start":{"line":344,"column":0},"end":{"line":344,"column":82}},"344":{"start":{"line":345,"column":0},"end":{"line":345,"column":51}},"345":{"start":{"line":346,"column":0},"end":{"line":346,"column":75}},"346":{"start":{"line":347,"column":0},"end":{"line":347,"column":20}},"347":{"start":{"line":348,"column":0},"end":{"line":348,"column":54}},"348":{"start":{"line":349,"column":0},"end":{"line":349,"column":23}},"349":{"start":{"line":350,"column":0},"end":{"line":350,"column":31}},"350":{"start":{"line":351,"column":0},"end":{"line":351,"column":57}},"351":{"start":{"line":352,"column":0},"end":{"line":352,"column":34}},"352":{"start":{"line":353,"column":0},"end":{"line":353,"column":51}},"353":{"start":{"line":354,"column":0},"end":{"line":354,"column":30}},"354":{"start":{"line":355,"column":0},"end":{"line":355,"column":20}},"355":{"start":{"line":356,"column":0},"end":{"line":356,"column":39}},"357":{"start":{"line":358,"column":0},"end":{"line":358,"column":31}},"358":{"start":{"line":359,"column":0},"end":{"line":359,"column":25}},"359":{"start":{"line":360,"column":0},"end":{"line":360,"column":20}},"360":{"start":{"line":361,"column":0},"end":{"line":361,"column":18}},"362":{"start":{"line":363,"column":0},"end":{"line":363,"column":11}},"363":{"start":{"line":364,"column":0},"end":{"line":364,"column":12}},"364":{"start":{"line":365,"column":0},"end":{"line":365,"column":64}},"365":{"start":{"line":366,"column":0},"end":{"line":366,"column":82}},"367":{"start":{"line":368,"column":0},"end":{"line":368,"column":17}},"368":{"start":{"line":369,"column":0},"end":{"line":369,"column":12}},"369":{"start":{"line":370,"column":0},"end":{"line":370,"column":17}},"371":{"start":{"line":372,"column":0},"end":{"line":372,"column":1}},"373":{"start":{"line":374,"column":0},"end":{"line":374,"column":23}},"374":{"start":{"line":375,"column":0},"end":{"line":375,"column":20}},"375":{"start":{"line":376,"column":0},"end":{"line":376,"column":25}},"376":{"start":{"line":377,"column":0},"end":{"line":377,"column":26}},"377":{"start":{"line":378,"column":0},"end":{"line":378,"column":18}},"378":{"start":{"line":379,"column":0},"end":{"line":379,"column":14}},"379":{"start":{"line":380,"column":0},"end":{"line":380,"column":17}},"380":{"start":{"line":381,"column":0},"end":{"line":381,"column":26}},"381":{"start":{"line":382,"column":0},"end":{"line":382,"column":28}},"382":{"start":{"line":383,"column":0},"end":{"line":383,"column":4}},"399":{"start":{"line":400,"column":0},"end":{"line":400,"column":4}},"400":{"start":{"line":401,"column":0},"end":{"line":401,"column":64}},"401":{"start":{"line":402,"column":0},"end":{"line":402,"column":58}},"402":{"start":{"line":403,"column":0},"end":{"line":403,"column":59}},"403":{"start":{"line":404,"column":0},"end":{"line":404,"column":59}},"404":{"start":{"line":405,"column":0},"end":{"line":405,"column":49}},"405":{"start":{"line":406,"column":0},"end":{"line":406,"column":53}},"406":{"start":{"line":407,"column":0},"end":{"line":407,"column":39}},"407":{"start":{"line":408,"column":0},"end":{"line":408,"column":69}},"408":{"start":{"line":409,"column":0},"end":{"line":409,"column":47}},"409":{"start":{"line":410,"column":0},"end":{"line":410,"column":53}},"410":{"start":{"line":411,"column":0},"end":{"line":411,"column":65}},"411":{"start":{"line":412,"column":0},"end":{"line":412,"column":57}},"412":{"start":{"line":413,"column":0},"end":{"line":413,"column":49}},"413":{"start":{"line":414,"column":0},"end":{"line":414,"column":49}},"414":{"start":{"line":415,"column":0},"end":{"line":415,"column":51}},"415":{"start":{"line":416,"column":0},"end":{"line":416,"column":58}},"416":{"start":{"line":417,"column":0},"end":{"line":417,"column":50}},"417":{"start":{"line":418,"column":0},"end":{"line":418,"column":63}},"418":{"start":{"line":419,"column":0},"end":{"line":419,"column":64}},"420":{"start":{"line":421,"column":0},"end":{"line":421,"column":44}},"421":{"start":{"line":422,"column":0},"end":{"line":422,"column":25}},"422":{"start":{"line":423,"column":0},"end":{"line":423,"column":53}},"423":{"start":{"line":424,"column":0},"end":{"line":424,"column":24}},"424":{"start":{"line":425,"column":0},"end":{"line":425,"column":20}},"425":{"start":{"line":426,"column":0},"end":{"line":426,"column":7}},"426":{"start":{"line":427,"column":0},"end":{"line":427,"column":14}},"427":{"start":{"line":428,"column":0},"end":{"line":428,"column":32}},"428":{"start":{"line":429,"column":0},"end":{"line":429,"column":64}},"429":{"start":{"line":430,"column":0},"end":{"line":430,"column":12}},"430":{"start":{"line":431,"column":0},"end":{"line":431,"column":32}},"431":{"start":{"line":432,"column":0},"end":{"line":432,"column":79}},"432":{"start":{"line":433,"column":0},"end":{"line":433,"column":12}},"433":{"start":{"line":434,"column":0},"end":{"line":434,"column":12}},"435":{"start":{"line":436,"column":0},"end":{"line":436,"column":6}},"436":{"start":{"line":437,"column":0},"end":{"line":437,"column":25}},"437":{"start":{"line":438,"column":0},"end":{"line":438,"column":4}},"439":{"start":{"line":440,"column":0},"end":{"line":440,"column":55}},"440":{"start":{"line":441,"column":0},"end":{"line":441,"column":47}},"441":{"start":{"line":442,"column":0},"end":{"line":442,"column":18}},"442":{"start":{"line":443,"column":0},"end":{"line":443,"column":20}},"443":{"start":{"line":444,"column":0},"end":{"line":444,"column":7}},"444":{"start":{"line":445,"column":0},"end":{"line":445,"column":45}},"445":{"start":{"line":446,"column":0},"end":{"line":446,"column":23}},"446":{"start":{"line":447,"column":0},"end":{"line":447,"column":20}},"447":{"start":{"line":448,"column":0},"end":{"line":448,"column":7}},"448":{"start":{"line":449,"column":0},"end":{"line":449,"column":51}},"449":{"start":{"line":450,"column":0},"end":{"line":450,"column":24}},"452":{"start":{"line":453,"column":0},"end":{"line":453,"column":20}},"453":{"start":{"line":454,"column":0},"end":{"line":454,"column":7}},"454":{"start":{"line":455,"column":0},"end":{"line":455,"column":49}},"455":{"start":{"line":456,"column":0},"end":{"line":456,"column":67}},"456":{"start":{"line":457,"column":0},"end":{"line":457,"column":26}},"457":{"start":{"line":458,"column":0},"end":{"line":458,"column":8}},"458":{"start":{"line":459,"column":0},"end":{"line":459,"column":42}},"459":{"start":{"line":460,"column":0},"end":{"line":460,"column":57}},"460":{"start":{"line":461,"column":0},"end":{"line":461,"column":7}},"461":{"start":{"line":462,"column":0},"end":{"line":462,"column":43}},"462":{"start":{"line":463,"column":0},"end":{"line":463,"column":6}},"463":{"start":{"line":464,"column":0},"end":{"line":464,"column":7}},"464":{"start":{"line":465,"column":0},"end":{"line":465,"column":4}},"466":{"start":{"line":467,"column":0},"end":{"line":467,"column":77}},"467":{"start":{"line":468,"column":0},"end":{"line":468,"column":93}},"468":{"start":{"line":469,"column":0},"end":{"line":469,"column":81}},"469":{"start":{"line":470,"column":0},"end":{"line":470,"column":72}},"470":{"start":{"line":471,"column":0},"end":{"line":471,"column":41}},"472":{"start":{"line":473,"column":0},"end":{"line":473,"column":19}},"473":{"start":{"line":474,"column":0},"end":{"line":474,"column":26}},"474":{"start":{"line":475,"column":0},"end":{"line":475,"column":31}},"475":{"start":{"line":476,"column":0},"end":{"line":476,"column":24}},"476":{"start":{"line":477,"column":0},"end":{"line":477,"column":24}},"477":{"start":{"line":478,"column":0},"end":{"line":478,"column":17}},"478":{"start":{"line":479,"column":0},"end":{"line":479,"column":9}},"479":{"start":{"line":480,"column":0},"end":{"line":480,"column":28}},"480":{"start":{"line":481,"column":0},"end":{"line":481,"column":8}},"481":{"start":{"line":482,"column":0},"end":{"line":482,"column":25}},"482":{"start":{"line":483,"column":0},"end":{"line":483,"column":67}},"483":{"start":{"line":484,"column":0},"end":{"line":484,"column":9}},"484":{"start":{"line":485,"column":0},"end":{"line":485,"column":18}},"485":{"start":{"line":486,"column":0},"end":{"line":486,"column":23}},"486":{"start":{"line":487,"column":0},"end":{"line":487,"column":6}},"487":{"start":{"line":488,"column":0},"end":{"line":488,"column":29}},"489":{"start":{"line":490,"column":0},"end":{"line":490,"column":19}},"490":{"start":{"line":491,"column":0},"end":{"line":491,"column":26}},"491":{"start":{"line":492,"column":0},"end":{"line":492,"column":29}},"492":{"start":{"line":493,"column":0},"end":{"line":493,"column":33}},"493":{"start":{"line":494,"column":0},"end":{"line":494,"column":28}},"494":{"start":{"line":495,"column":0},"end":{"line":495,"column":20}},"495":{"start":{"line":496,"column":0},"end":{"line":496,"column":25}},"496":{"start":{"line":497,"column":0},"end":{"line":497,"column":8}},"497":{"start":{"line":498,"column":0},"end":{"line":498,"column":5}},"498":{"start":{"line":499,"column":0},"end":{"line":499,"column":48}},"499":{"start":{"line":500,"column":0},"end":{"line":500,"column":28}},"500":{"start":{"line":501,"column":0},"end":{"line":501,"column":24}},"501":{"start":{"line":502,"column":0},"end":{"line":502,"column":17}},"502":{"start":{"line":503,"column":0},"end":{"line":503,"column":9}},"503":{"start":{"line":504,"column":0},"end":{"line":504,"column":40}},"504":{"start":{"line":505,"column":0},"end":{"line":505,"column":8}},"505":{"start":{"line":506,"column":0},"end":{"line":506,"column":25}},"506":{"start":{"line":507,"column":0},"end":{"line":507,"column":76}},"507":{"start":{"line":508,"column":0},"end":{"line":508,"column":9}},"508":{"start":{"line":509,"column":0},"end":{"line":509,"column":18}},"509":{"start":{"line":510,"column":0},"end":{"line":510,"column":23}},"510":{"start":{"line":511,"column":0},"end":{"line":511,"column":6}},"511":{"start":{"line":512,"column":0},"end":{"line":512,"column":48}},"513":{"start":{"line":514,"column":0},"end":{"line":514,"column":35}},"514":{"start":{"line":515,"column":0},"end":{"line":515,"column":36}},"515":{"start":{"line":516,"column":0},"end":{"line":516,"column":37}},"516":{"start":{"line":517,"column":0},"end":{"line":517,"column":15}},"517":{"start":{"line":518,"column":0},"end":{"line":518,"column":7}},"518":{"start":{"line":519,"column":0},"end":{"line":519,"column":38}},"519":{"start":{"line":520,"column":0},"end":{"line":520,"column":11}},"520":{"start":{"line":521,"column":0},"end":{"line":521,"column":50}},"521":{"start":{"line":522,"column":0},"end":{"line":522,"column":32}},"522":{"start":{"line":523,"column":0},"end":{"line":523,"column":23}},"523":{"start":{"line":524,"column":0},"end":{"line":524,"column":63}},"524":{"start":{"line":525,"column":0},"end":{"line":525,"column":17}},"525":{"start":{"line":526,"column":0},"end":{"line":526,"column":41}},"526":{"start":{"line":527,"column":0},"end":{"line":527,"column":7}},"527":{"start":{"line":528,"column":0},"end":{"line":528,"column":6}},"528":{"start":{"line":529,"column":0},"end":{"line":529,"column":16}},"529":{"start":{"line":530,"column":0},"end":{"line":530,"column":4}},"531":{"start":{"line":532,"column":0},"end":{"line":532,"column":19}},"532":{"start":{"line":533,"column":0},"end":{"line":533,"column":26}},"533":{"start":{"line":534,"column":0},"end":{"line":534,"column":29}},"534":{"start":{"line":535,"column":0},"end":{"line":535,"column":28}},"535":{"start":{"line":536,"column":0},"end":{"line":536,"column":20}},"536":{"start":{"line":537,"column":0},"end":{"line":537,"column":25}},"537":{"start":{"line":538,"column":0},"end":{"line":538,"column":8}},"538":{"start":{"line":539,"column":0},"end":{"line":539,"column":5}},"540":{"start":{"line":541,"column":0},"end":{"line":541,"column":35}},"541":{"start":{"line":542,"column":0},"end":{"line":542,"column":22}},"542":{"start":{"line":543,"column":0},"end":{"line":543,"column":15}},"543":{"start":{"line":544,"column":0},"end":{"line":544,"column":7}},"544":{"start":{"line":545,"column":0},"end":{"line":545,"column":44}},"545":{"start":{"line":546,"column":0},"end":{"line":546,"column":6}},"547":{"start":{"line":548,"column":0},"end":{"line":548,"column":21}},"548":{"start":{"line":549,"column":0},"end":{"line":549,"column":57}},"549":{"start":{"line":550,"column":0},"end":{"line":550,"column":18}},"550":{"start":{"line":551,"column":0},"end":{"line":551,"column":23}},"551":{"start":{"line":552,"column":0},"end":{"line":552,"column":37}},"552":{"start":{"line":553,"column":0},"end":{"line":553,"column":6}},"553":{"start":{"line":554,"column":0},"end":{"line":554,"column":40}},"555":{"start":{"line":556,"column":0},"end":{"line":556,"column":44}},"556":{"start":{"line":557,"column":0},"end":{"line":557,"column":41}},"557":{"start":{"line":558,"column":0},"end":{"line":558,"column":63}},"558":{"start":{"line":559,"column":0},"end":{"line":559,"column":55}},"559":{"start":{"line":560,"column":0},"end":{"line":560,"column":16}},"560":{"start":{"line":561,"column":0},"end":{"line":561,"column":22}},"561":{"start":{"line":562,"column":0},"end":{"line":562,"column":27}},"562":{"start":{"line":563,"column":0},"end":{"line":563,"column":17}},"563":{"start":{"line":564,"column":0},"end":{"line":564,"column":10}},"564":{"start":{"line":565,"column":0},"end":{"line":565,"column":9}},"566":{"start":{"line":567,"column":0},"end":{"line":567,"column":14}},"567":{"start":{"line":568,"column":0},"end":{"line":568,"column":20}},"568":{"start":{"line":569,"column":0},"end":{"line":569,"column":36}},"569":{"start":{"line":570,"column":0},"end":{"line":570,"column":14}},"570":{"start":{"line":571,"column":0},"end":{"line":571,"column":8}},"571":{"start":{"line":572,"column":0},"end":{"line":572,"column":7}},"572":{"start":{"line":573,"column":0},"end":{"line":573,"column":23}},"574":{"start":{"line":575,"column":0},"end":{"line":575,"column":44}},"575":{"start":{"line":576,"column":0},"end":{"line":576,"column":29}},"576":{"start":{"line":577,"column":0},"end":{"line":577,"column":31}},"577":{"start":{"line":578,"column":0},"end":{"line":578,"column":15}},"578":{"start":{"line":579,"column":0},"end":{"line":579,"column":7}},"579":{"start":{"line":580,"column":0},"end":{"line":580,"column":57}},"580":{"start":{"line":581,"column":0},"end":{"line":581,"column":25}},"581":{"start":{"line":582,"column":0},"end":{"line":582,"column":37}},"582":{"start":{"line":583,"column":0},"end":{"line":583,"column":10}},"583":{"start":{"line":584,"column":0},"end":{"line":584,"column":27}},"584":{"start":{"line":585,"column":0},"end":{"line":585,"column":71}},"585":{"start":{"line":586,"column":0},"end":{"line":586,"column":11}},"586":{"start":{"line":587,"column":0},"end":{"line":587,"column":6}},"587":{"start":{"line":588,"column":0},"end":{"line":588,"column":41}},"588":{"start":{"line":589,"column":0},"end":{"line":589,"column":4}},"590":{"start":{"line":591,"column":0},"end":{"line":591,"column":53}},"591":{"start":{"line":592,"column":0},"end":{"line":592,"column":29}},"592":{"start":{"line":593,"column":0},"end":{"line":593,"column":13}},"593":{"start":{"line":594,"column":0},"end":{"line":594,"column":5}},"594":{"start":{"line":595,"column":0},"end":{"line":595,"column":45}},"595":{"start":{"line":596,"column":0},"end":{"line":596,"column":19}},"596":{"start":{"line":597,"column":0},"end":{"line":597,"column":35}},"597":{"start":{"line":598,"column":0},"end":{"line":598,"column":8}},"598":{"start":{"line":599,"column":0},"end":{"line":599,"column":25}},"599":{"start":{"line":600,"column":0},"end":{"line":600,"column":71}},"600":{"start":{"line":601,"column":0},"end":{"line":601,"column":9}},"601":{"start":{"line":602,"column":0},"end":{"line":602,"column":45}},"603":{"start":{"line":604,"column":0},"end":{"line":604,"column":76}},"604":{"start":{"line":605,"column":0},"end":{"line":605,"column":37}},"605":{"start":{"line":606,"column":0},"end":{"line":606,"column":56}},"606":{"start":{"line":607,"column":0},"end":{"line":607,"column":11}},"607":{"start":{"line":608,"column":0},"end":{"line":608,"column":79}},"609":{"start":{"line":610,"column":0},"end":{"line":610,"column":58}},"610":{"start":{"line":611,"column":0},"end":{"line":611,"column":58}},"612":{"start":{"line":613,"column":0},"end":{"line":613,"column":60}},"614":{"start":{"line":615,"column":0},"end":{"line":615,"column":22}},"615":{"start":{"line":616,"column":0},"end":{"line":616,"column":25}},"616":{"start":{"line":617,"column":0},"end":{"line":617,"column":30}},"617":{"start":{"line":618,"column":0},"end":{"line":618,"column":42}},"618":{"start":{"line":619,"column":0},"end":{"line":619,"column":5}},"620":{"start":{"line":621,"column":0},"end":{"line":621,"column":19}},"621":{"start":{"line":622,"column":0},"end":{"line":622,"column":29}},"622":{"start":{"line":623,"column":0},"end":{"line":623,"column":13}},"623":{"start":{"line":624,"column":0},"end":{"line":624,"column":5}},"624":{"start":{"line":625,"column":0},"end":{"line":625,"column":27}},"625":{"start":{"line":626,"column":0},"end":{"line":626,"column":27}},"627":{"start":{"line":628,"column":0},"end":{"line":628,"column":19}},"628":{"start":{"line":629,"column":0},"end":{"line":629,"column":26}},"629":{"start":{"line":630,"column":0},"end":{"line":630,"column":13}},"630":{"start":{"line":631,"column":0},"end":{"line":631,"column":5}},"631":{"start":{"line":632,"column":0},"end":{"line":632,"column":60}},"632":{"start":{"line":633,"column":0},"end":{"line":633,"column":30}},"633":{"start":{"line":634,"column":0},"end":{"line":634,"column":5}},"634":{"start":{"line":635,"column":0},"end":{"line":635,"column":30}},"636":{"start":{"line":637,"column":0},"end":{"line":637,"column":19}},"637":{"start":{"line":638,"column":0},"end":{"line":638,"column":26}},"638":{"start":{"line":639,"column":0},"end":{"line":639,"column":48}},"639":{"start":{"line":640,"column":0},"end":{"line":640,"column":37}},"640":{"start":{"line":641,"column":0},"end":{"line":641,"column":20}},"641":{"start":{"line":642,"column":0},"end":{"line":642,"column":25}},"642":{"start":{"line":643,"column":0},"end":{"line":643,"column":8}},"643":{"start":{"line":644,"column":0},"end":{"line":644,"column":5}},"645":{"start":{"line":646,"column":0},"end":{"line":646,"column":79}},"646":{"start":{"line":647,"column":0},"end":{"line":647,"column":42}},"647":{"start":{"line":648,"column":0},"end":{"line":648,"column":11}},"648":{"start":{"line":649,"column":0},"end":{"line":649,"column":41}},"649":{"start":{"line":650,"column":0},"end":{"line":650,"column":28}},"650":{"start":{"line":651,"column":0},"end":{"line":651,"column":25}},"651":{"start":{"line":652,"column":0},"end":{"line":652,"column":30}},"652":{"start":{"line":653,"column":0},"end":{"line":653,"column":10}},"653":{"start":{"line":654,"column":0},"end":{"line":654,"column":24}},"654":{"start":{"line":655,"column":0},"end":{"line":655,"column":17}},"655":{"start":{"line":656,"column":0},"end":{"line":656,"column":9}},"656":{"start":{"line":657,"column":0},"end":{"line":657,"column":27}},"657":{"start":{"line":658,"column":0},"end":{"line":658,"column":23}},"658":{"start":{"line":659,"column":0},"end":{"line":659,"column":24}},"659":{"start":{"line":660,"column":0},"end":{"line":660,"column":17}},"660":{"start":{"line":661,"column":0},"end":{"line":661,"column":9}},"661":{"start":{"line":662,"column":0},"end":{"line":662,"column":68}},"662":{"start":{"line":663,"column":0},"end":{"line":663,"column":39}},"663":{"start":{"line":664,"column":0},"end":{"line":664,"column":7}},"664":{"start":{"line":665,"column":0},"end":{"line":665,"column":6}},"666":{"start":{"line":667,"column":0},"end":{"line":667,"column":28}},"667":{"start":{"line":668,"column":0},"end":{"line":668,"column":64}},"668":{"start":{"line":669,"column":0},"end":{"line":669,"column":18}},"669":{"start":{"line":670,"column":0},"end":{"line":670,"column":23}},"670":{"start":{"line":671,"column":0},"end":{"line":671,"column":37}},"671":{"start":{"line":672,"column":0},"end":{"line":672,"column":6}},"672":{"start":{"line":673,"column":0},"end":{"line":673,"column":6}},"673":{"start":{"line":674,"column":0},"end":{"line":674,"column":22}},"674":{"start":{"line":675,"column":0},"end":{"line":675,"column":43}},"675":{"start":{"line":676,"column":0},"end":{"line":676,"column":18}},"676":{"start":{"line":677,"column":0},"end":{"line":677,"column":19}},"677":{"start":{"line":678,"column":0},"end":{"line":678,"column":5}},"679":{"start":{"line":680,"column":0},"end":{"line":680,"column":39}},"680":{"start":{"line":681,"column":0},"end":{"line":681,"column":16}},"681":{"start":{"line":682,"column":0},"end":{"line":682,"column":41}},"682":{"start":{"line":683,"column":0},"end":{"line":683,"column":38}},"683":{"start":{"line":684,"column":0},"end":{"line":684,"column":30}},"684":{"start":{"line":685,"column":0},"end":{"line":685,"column":11}},"685":{"start":{"line":686,"column":0},"end":{"line":686,"column":50}},"686":{"start":{"line":687,"column":0},"end":{"line":687,"column":84}},"688":{"start":{"line":689,"column":0},"end":{"line":689,"column":9}},"689":{"start":{"line":690,"column":0},"end":{"line":690,"column":16}},"690":{"start":{"line":691,"column":0},"end":{"line":691,"column":16}},"691":{"start":{"line":692,"column":0},"end":{"line":692,"column":14}},"692":{"start":{"line":693,"column":0},"end":{"line":693,"column":19}},"693":{"start":{"line":694,"column":0},"end":{"line":694,"column":19}},"694":{"start":{"line":695,"column":0},"end":{"line":695,"column":25}},"695":{"start":{"line":696,"column":0},"end":{"line":696,"column":35}},"696":{"start":{"line":697,"column":0},"end":{"line":697,"column":44}},"697":{"start":{"line":698,"column":0},"end":{"line":698,"column":21}},"698":{"start":{"line":699,"column":0},"end":{"line":699,"column":23}},"699":{"start":{"line":700,"column":0},"end":{"line":700,"column":19}},"700":{"start":{"line":701,"column":0},"end":{"line":701,"column":19}},"701":{"start":{"line":702,"column":0},"end":{"line":702,"column":37}},"702":{"start":{"line":703,"column":0},"end":{"line":703,"column":36}},"703":{"start":{"line":704,"column":0},"end":{"line":704,"column":49}},"704":{"start":{"line":705,"column":0},"end":{"line":705,"column":19}},"705":{"start":{"line":706,"column":0},"end":{"line":706,"column":37}},"706":{"start":{"line":707,"column":0},"end":{"line":707,"column":5}},"708":{"start":{"line":709,"column":0},"end":{"line":709,"column":19}},"710":{"start":{"line":711,"column":0},"end":{"line":711,"column":26}},"711":{"start":{"line":712,"column":0},"end":{"line":712,"column":39}},"713":{"start":{"line":714,"column":0},"end":{"line":714,"column":49}},"714":{"start":{"line":715,"column":0},"end":{"line":715,"column":29}},"715":{"start":{"line":716,"column":0},"end":{"line":716,"column":13}},"716":{"start":{"line":717,"column":0},"end":{"line":717,"column":5}},"718":{"start":{"line":719,"column":0},"end":{"line":719,"column":27}},"722":{"start":{"line":723,"column":0},"end":{"line":723,"column":51}},"723":{"start":{"line":724,"column":0},"end":{"line":724,"column":23}},"724":{"start":{"line":725,"column":0},"end":{"line":725,"column":47}},"725":{"start":{"line":726,"column":0},"end":{"line":726,"column":5}},"726":{"start":{"line":727,"column":0},"end":{"line":727,"column":73}},"728":{"start":{"line":729,"column":0},"end":{"line":729,"column":9}},"729":{"start":{"line":730,"column":0},"end":{"line":730,"column":53}},"731":{"start":{"line":732,"column":0},"end":{"line":732,"column":67}},"732":{"start":{"line":733,"column":0},"end":{"line":733,"column":20}},"733":{"start":{"line":734,"column":0},"end":{"line":734,"column":65}},"736":{"start":{"line":737,"column":0},"end":{"line":737,"column":55}},"737":{"start":{"line":738,"column":0},"end":{"line":738,"column":22}},"738":{"start":{"line":739,"column":0},"end":{"line":739,"column":73}},"739":{"start":{"line":740,"column":0},"end":{"line":740,"column":15}},"740":{"start":{"line":741,"column":0},"end":{"line":741,"column":7}},"742":{"start":{"line":743,"column":0},"end":{"line":743,"column":52}},"744":{"start":{"line":745,"column":0},"end":{"line":745,"column":60}},"745":{"start":{"line":746,"column":0},"end":{"line":746,"column":27}},"746":{"start":{"line":747,"column":0},"end":{"line":747,"column":62}},"747":{"start":{"line":748,"column":0},"end":{"line":748,"column":15}},"748":{"start":{"line":749,"column":0},"end":{"line":749,"column":7}},"750":{"start":{"line":751,"column":0},"end":{"line":751,"column":81}},"751":{"start":{"line":752,"column":0},"end":{"line":752,"column":78}},"752":{"start":{"line":753,"column":0},"end":{"line":753,"column":28}},"753":{"start":{"line":754,"column":0},"end":{"line":754,"column":11}},"754":{"start":{"line":755,"column":0},"end":{"line":755,"column":14}},"755":{"start":{"line":756,"column":0},"end":{"line":756,"column":80}},"756":{"start":{"line":757,"column":0},"end":{"line":757,"column":28}},"757":{"start":{"line":758,"column":0},"end":{"line":758,"column":11}},"758":{"start":{"line":759,"column":0},"end":{"line":759,"column":7}},"759":{"start":{"line":760,"column":0},"end":{"line":760,"column":21}},"760":{"start":{"line":761,"column":0},"end":{"line":761,"column":78}},"761":{"start":{"line":762,"column":0},"end":{"line":762,"column":5}},"762":{"start":{"line":763,"column":0},"end":{"line":763,"column":6}},"763":{"start":{"line":764,"column":0},"end":{"line":764,"column":22}},"764":{"start":{"line":765,"column":0},"end":{"line":765,"column":20}},"765":{"start":{"line":766,"column":0},"end":{"line":766,"column":37}},"766":{"start":{"line":767,"column":0},"end":{"line":767,"column":26}},"767":{"start":{"line":768,"column":0},"end":{"line":768,"column":26}},"768":{"start":{"line":769,"column":0},"end":{"line":769,"column":18}},"769":{"start":{"line":770,"column":0},"end":{"line":770,"column":30}},"770":{"start":{"line":771,"column":0},"end":{"line":771,"column":19}},"771":{"start":{"line":772,"column":0},"end":{"line":772,"column":32}},"772":{"start":{"line":773,"column":0},"end":{"line":773,"column":28}},"773":{"start":{"line":774,"column":0},"end":{"line":774,"column":23}},"774":{"start":{"line":775,"column":0},"end":{"line":775,"column":5}},"776":{"start":{"line":777,"column":0},"end":{"line":777,"column":55}},"777":{"start":{"line":778,"column":0},"end":{"line":778,"column":50}},"778":{"start":{"line":779,"column":0},"end":{"line":779,"column":42}},"779":{"start":{"line":780,"column":0},"end":{"line":780,"column":57}},"780":{"start":{"line":781,"column":0},"end":{"line":781,"column":13}},"781":{"start":{"line":782,"column":0},"end":{"line":782,"column":5}},"783":{"start":{"line":784,"column":0},"end":{"line":784,"column":37}},"784":{"start":{"line":785,"column":0},"end":{"line":785,"column":91}},"785":{"start":{"line":786,"column":0},"end":{"line":786,"column":6}},"786":{"start":{"line":787,"column":0},"end":{"line":787,"column":21}},"787":{"start":{"line":788,"column":0},"end":{"line":788,"column":13}},"788":{"start":{"line":789,"column":0},"end":{"line":789,"column":5}},"790":{"start":{"line":791,"column":0},"end":{"line":791,"column":33}},"791":{"start":{"line":792,"column":0},"end":{"line":792,"column":9}},"792":{"start":{"line":793,"column":0},"end":{"line":793,"column":24}},"793":{"start":{"line":794,"column":0},"end":{"line":794,"column":31}},"794":{"start":{"line":795,"column":0},"end":{"line":795,"column":7}},"795":{"start":{"line":796,"column":0},"end":{"line":796,"column":56}},"796":{"start":{"line":797,"column":0},"end":{"line":797,"column":38}},"797":{"start":{"line":798,"column":0},"end":{"line":798,"column":21}},"798":{"start":{"line":799,"column":0},"end":{"line":799,"column":62}},"799":{"start":{"line":800,"column":0},"end":{"line":800,"column":15}},"800":{"start":{"line":801,"column":0},"end":{"line":801,"column":36}},"801":{"start":{"line":802,"column":0},"end":{"line":802,"column":5}},"802":{"start":{"line":803,"column":0},"end":{"line":803,"column":6}},"803":{"start":{"line":804,"column":0},"end":{"line":804,"column":22}},"804":{"start":{"line":805,"column":0},"end":{"line":805,"column":16}},"805":{"start":{"line":806,"column":0},"end":{"line":806,"column":24}},"806":{"start":{"line":807,"column":0},"end":{"line":807,"column":19}},"807":{"start":{"line":808,"column":0},"end":{"line":808,"column":17}},"808":{"start":{"line":809,"column":0},"end":{"line":809,"column":27}},"809":{"start":{"line":810,"column":0},"end":{"line":810,"column":19}},"810":{"start":{"line":811,"column":0},"end":{"line":811,"column":5}},"812":{"start":{"line":813,"column":0},"end":{"line":813,"column":10}},"813":{"start":{"line":814,"column":0},"end":{"line":814,"column":59}},"814":{"start":{"line":815,"column":0},"end":{"line":815,"column":36}},"815":{"start":{"line":816,"column":0},"end":{"line":816,"column":48}},"816":{"start":{"line":817,"column":0},"end":{"line":817,"column":12}},"818":{"start":{"line":819,"column":0},"end":{"line":819,"column":66}},"819":{"start":{"line":820,"column":0},"end":{"line":820,"column":43}},"820":{"start":{"line":821,"column":0},"end":{"line":821,"column":54}},"821":{"start":{"line":822,"column":0},"end":{"line":822,"column":14}},"822":{"start":{"line":823,"column":0},"end":{"line":823,"column":61}},"823":{"start":{"line":824,"column":0},"end":{"line":824,"column":17}},"824":{"start":{"line":825,"column":0},"end":{"line":825,"column":25}},"825":{"start":{"line":826,"column":0},"end":{"line":826,"column":51}},"826":{"start":{"line":827,"column":0},"end":{"line":827,"column":39}},"827":{"start":{"line":828,"column":0},"end":{"line":828,"column":29}},"828":{"start":{"line":829,"column":0},"end":{"line":829,"column":42}},"829":{"start":{"line":830,"column":0},"end":{"line":830,"column":50}},"830":{"start":{"line":831,"column":0},"end":{"line":831,"column":42}},"832":{"start":{"line":833,"column":0},"end":{"line":833,"column":42}},"833":{"start":{"line":834,"column":0},"end":{"line":834,"column":19}},"834":{"start":{"line":835,"column":0},"end":{"line":835,"column":17}},"835":{"start":{"line":836,"column":0},"end":{"line":836,"column":25}},"836":{"start":{"line":837,"column":0},"end":{"line":837,"column":82}},"837":{"start":{"line":838,"column":0},"end":{"line":838,"column":42}},"838":{"start":{"line":839,"column":0},"end":{"line":839,"column":28}},"839":{"start":{"line":840,"column":0},"end":{"line":840,"column":40}},"840":{"start":{"line":841,"column":0},"end":{"line":841,"column":23}},"841":{"start":{"line":842,"column":0},"end":{"line":842,"column":15}},"842":{"start":{"line":843,"column":0},"end":{"line":843,"column":47}},"843":{"start":{"line":844,"column":0},"end":{"line":844,"column":14}},"844":{"start":{"line":845,"column":0},"end":{"line":845,"column":32}},"845":{"start":{"line":846,"column":0},"end":{"line":846,"column":40}},"846":{"start":{"line":847,"column":0},"end":{"line":847,"column":42}},"848":{"start":{"line":849,"column":0},"end":{"line":849,"column":84}},"849":{"start":{"line":850,"column":0},"end":{"line":850,"column":68}},"850":{"start":{"line":851,"column":0},"end":{"line":851,"column":19}},"851":{"start":{"line":852,"column":0},"end":{"line":852,"column":39}},"852":{"start":{"line":853,"column":0},"end":{"line":853,"column":19}},"854":{"start":{"line":855,"column":0},"end":{"line":855,"column":28}},"855":{"start":{"line":856,"column":0},"end":{"line":856,"column":68}},"856":{"start":{"line":857,"column":0},"end":{"line":857,"column":36}},"857":{"start":{"line":858,"column":0},"end":{"line":858,"column":32}},"858":{"start":{"line":859,"column":0},"end":{"line":859,"column":31}},"859":{"start":{"line":860,"column":0},"end":{"line":860,"column":38}},"860":{"start":{"line":861,"column":0},"end":{"line":861,"column":59}},"861":{"start":{"line":862,"column":0},"end":{"line":862,"column":53}},"862":{"start":{"line":863,"column":0},"end":{"line":863,"column":34}},"863":{"start":{"line":864,"column":0},"end":{"line":864,"column":47}},"864":{"start":{"line":865,"column":0},"end":{"line":865,"column":43}},"865":{"start":{"line":866,"column":0},"end":{"line":866,"column":20}},"866":{"start":{"line":867,"column":0},"end":{"line":867,"column":48}},"868":{"start":{"line":869,"column":0},"end":{"line":869,"column":29}},"869":{"start":{"line":870,"column":0},"end":{"line":870,"column":34}},"870":{"start":{"line":871,"column":0},"end":{"line":871,"column":17}},"871":{"start":{"line":872,"column":0},"end":{"line":872,"column":69}},"872":{"start":{"line":873,"column":0},"end":{"line":873,"column":30}},"873":{"start":{"line":874,"column":0},"end":{"line":874,"column":32}},"875":{"start":{"line":876,"column":0},"end":{"line":876,"column":41}},"876":{"start":{"line":877,"column":0},"end":{"line":877,"column":18}},"877":{"start":{"line":878,"column":0},"end":{"line":878,"column":46}},"878":{"start":{"line":879,"column":0},"end":{"line":879,"column":15}},"880":{"start":{"line":881,"column":0},"end":{"line":881,"column":32}},"881":{"start":{"line":882,"column":0},"end":{"line":882,"column":30}},"882":{"start":{"line":883,"column":0},"end":{"line":883,"column":39}},"883":{"start":{"line":884,"column":0},"end":{"line":884,"column":46}},"884":{"start":{"line":885,"column":0},"end":{"line":885,"column":15}},"886":{"start":{"line":887,"column":0},"end":{"line":887,"column":32}},"887":{"start":{"line":888,"column":0},"end":{"line":888,"column":29}},"889":{"start":{"line":890,"column":0},"end":{"line":890,"column":14}},"890":{"start":{"line":891,"column":0},"end":{"line":891,"column":16}},"892":{"start":{"line":893,"column":0},"end":{"line":893,"column":66}},"893":{"start":{"line":894,"column":0},"end":{"line":894,"column":43}},"894":{"start":{"line":895,"column":0},"end":{"line":895,"column":50}},"895":{"start":{"line":896,"column":0},"end":{"line":896,"column":61}},"896":{"start":{"line":897,"column":0},"end":{"line":897,"column":49}},"897":{"start":{"line":898,"column":0},"end":{"line":898,"column":27}},"898":{"start":{"line":899,"column":0},"end":{"line":899,"column":29}},"899":{"start":{"line":900,"column":0},"end":{"line":900,"column":89}},"900":{"start":{"line":901,"column":0},"end":{"line":901,"column":37}},"901":{"start":{"line":902,"column":0},"end":{"line":902,"column":37}},"902":{"start":{"line":903,"column":0},"end":{"line":903,"column":18}},"903":{"start":{"line":904,"column":0},"end":{"line":904,"column":16}},"904":{"start":{"line":905,"column":0},"end":{"line":905,"column":53}},"905":{"start":{"line":906,"column":0},"end":{"line":906,"column":19}},"906":{"start":{"line":907,"column":0},"end":{"line":907,"column":27}},"907":{"start":{"line":908,"column":0},"end":{"line":908,"column":52}},"908":{"start":{"line":909,"column":0},"end":{"line":909,"column":44}},"909":{"start":{"line":910,"column":0},"end":{"line":910,"column":61}},"910":{"start":{"line":911,"column":0},"end":{"line":911,"column":69}},"911":{"start":{"line":912,"column":0},"end":{"line":912,"column":40}},"912":{"start":{"line":913,"column":0},"end":{"line":913,"column":21}},"913":{"start":{"line":914,"column":0},"end":{"line":914,"column":35}},"914":{"start":{"line":915,"column":0},"end":{"line":915,"column":51}},"915":{"start":{"line":916,"column":0},"end":{"line":916,"column":33}},"916":{"start":{"line":917,"column":0},"end":{"line":917,"column":42}},"917":{"start":{"line":918,"column":0},"end":{"line":918,"column":31}},"918":{"start":{"line":919,"column":0},"end":{"line":919,"column":34}},"919":{"start":{"line":920,"column":0},"end":{"line":920,"column":35}},"921":{"start":{"line":922,"column":0},"end":{"line":922,"column":30}},"922":{"start":{"line":923,"column":0},"end":{"line":923,"column":59}},"923":{"start":{"line":924,"column":0},"end":{"line":924,"column":25}},"924":{"start":{"line":925,"column":0},"end":{"line":925,"column":17}},"925":{"start":{"line":926,"column":0},"end":{"line":926,"column":34}},"926":{"start":{"line":927,"column":0},"end":{"line":927,"column":40}},"927":{"start":{"line":928,"column":0},"end":{"line":928,"column":25}},"928":{"start":{"line":929,"column":0},"end":{"line":929,"column":17}},"929":{"start":{"line":930,"column":0},"end":{"line":930,"column":53}},"930":{"start":{"line":931,"column":0},"end":{"line":931,"column":16}},"932":{"start":{"line":933,"column":0},"end":{"line":933,"column":74}},"933":{"start":{"line":934,"column":0},"end":{"line":934,"column":21}},"934":{"start":{"line":935,"column":0},"end":{"line":935,"column":19}},"935":{"start":{"line":936,"column":0},"end":{"line":936,"column":27}},"936":{"start":{"line":937,"column":0},"end":{"line":937,"column":52}},"937":{"start":{"line":938,"column":0},"end":{"line":938,"column":44}},"938":{"start":{"line":939,"column":0},"end":{"line":939,"column":84}},"939":{"start":{"line":940,"column":0},"end":{"line":940,"column":41}},"940":{"start":{"line":941,"column":0},"end":{"line":941,"column":21}},"941":{"start":{"line":942,"column":0},"end":{"line":942,"column":35}},"942":{"start":{"line":943,"column":0},"end":{"line":943,"column":51}},"943":{"start":{"line":944,"column":0},"end":{"line":944,"column":33}},"944":{"start":{"line":945,"column":0},"end":{"line":945,"column":53}},"945":{"start":{"line":946,"column":0},"end":{"line":946,"column":61}},"947":{"start":{"line":948,"column":0},"end":{"line":948,"column":30}},"948":{"start":{"line":949,"column":0},"end":{"line":949,"column":43}},"949":{"start":{"line":950,"column":0},"end":{"line":950,"column":16}},"951":{"start":{"line":952,"column":0},"end":{"line":952,"column":71}},"952":{"start":{"line":953,"column":0},"end":{"line":953,"column":21}},"953":{"start":{"line":954,"column":0},"end":{"line":954,"column":16}},"954":{"start":{"line":955,"column":0},"end":{"line":955,"column":14}},"955":{"start":{"line":956,"column":0},"end":{"line":956,"column":41}},"956":{"start":{"line":957,"column":0},"end":{"line":957,"column":24}},"957":{"start":{"line":958,"column":0},"end":{"line":958,"column":64}},"958":{"start":{"line":959,"column":0},"end":{"line":959,"column":25}},"959":{"start":{"line":960,"column":0},"end":{"line":960,"column":18}},"960":{"start":{"line":961,"column":0},"end":{"line":961,"column":19}},"961":{"start":{"line":962,"column":0},"end":{"line":962,"column":34}},"962":{"start":{"line":963,"column":0},"end":{"line":963,"column":41}},"964":{"start":{"line":965,"column":0},"end":{"line":965,"column":18}},"965":{"start":{"line":966,"column":0},"end":{"line":966,"column":30}},"966":{"start":{"line":967,"column":0},"end":{"line":967,"column":40}},"967":{"start":{"line":968,"column":0},"end":{"line":968,"column":56}},"968":{"start":{"line":969,"column":0},"end":{"line":969,"column":69}},"969":{"start":{"line":970,"column":0},"end":{"line":970,"column":91}},"970":{"start":{"line":971,"column":0},"end":{"line":971,"column":67}},"971":{"start":{"line":972,"column":0},"end":{"line":972,"column":34}},"972":{"start":{"line":973,"column":0},"end":{"line":973,"column":46}},"973":{"start":{"line":974,"column":0},"end":{"line":974,"column":36}},"974":{"start":{"line":975,"column":0},"end":{"line":975,"column":43}},"975":{"start":{"line":976,"column":0},"end":{"line":976,"column":30}},"976":{"start":{"line":977,"column":0},"end":{"line":977,"column":19}},"977":{"start":{"line":978,"column":0},"end":{"line":978,"column":68}},"978":{"start":{"line":979,"column":0},"end":{"line":979,"column":67}},"979":{"start":{"line":980,"column":0},"end":{"line":980,"column":75}},"981":{"start":{"line":982,"column":0},"end":{"line":982,"column":24}},"982":{"start":{"line":983,"column":0},"end":{"line":983,"column":108}},"983":{"start":{"line":984,"column":0},"end":{"line":984,"column":52}},"984":{"start":{"line":985,"column":0},"end":{"line":985,"column":68}},"985":{"start":{"line":986,"column":0},"end":{"line":986,"column":40}},"986":{"start":{"line":987,"column":0},"end":{"line":987,"column":54}},"987":{"start":{"line":988,"column":0},"end":{"line":988,"column":41}},"988":{"start":{"line":989,"column":0},"end":{"line":989,"column":91}},"990":{"start":{"line":991,"column":0},"end":{"line":991,"column":48}},"992":{"start":{"line":993,"column":0},"end":{"line":993,"column":29}},"993":{"start":{"line":994,"column":0},"end":{"line":994,"column":76}},"994":{"start":{"line":995,"column":0},"end":{"line":995,"column":40}},"995":{"start":{"line":996,"column":0},"end":{"line":996,"column":58}},"996":{"start":{"line":997,"column":0},"end":{"line":997,"column":65}},"997":{"start":{"line":998,"column":0},"end":{"line":998,"column":31}},"998":{"start":{"line":999,"column":0},"end":{"line":999,"column":31}},"999":{"start":{"line":1000,"column":0},"end":{"line":1000,"column":26}},"1000":{"start":{"line":1001,"column":0},"end":{"line":1001,"column":52}},"1001":{"start":{"line":1002,"column":0},"end":{"line":1002,"column":52}},"1002":{"start":{"line":1003,"column":0},"end":{"line":1003,"column":58}},"1003":{"start":{"line":1004,"column":0},"end":{"line":1004,"column":67}},"1004":{"start":{"line":1005,"column":0},"end":{"line":1005,"column":36}},"1005":{"start":{"line":1006,"column":0},"end":{"line":1006,"column":37}},"1006":{"start":{"line":1007,"column":0},"end":{"line":1007,"column":69}},"1007":{"start":{"line":1008,"column":0},"end":{"line":1008,"column":40}},"1008":{"start":{"line":1009,"column":0},"end":{"line":1009,"column":28}},"1009":{"start":{"line":1010,"column":0},"end":{"line":1010,"column":77}},"1010":{"start":{"line":1011,"column":0},"end":{"line":1011,"column":34}},"1011":{"start":{"line":1012,"column":0},"end":{"line":1012,"column":33}},"1012":{"start":{"line":1013,"column":0},"end":{"line":1013,"column":60}},"1013":{"start":{"line":1014,"column":0},"end":{"line":1014,"column":68}},"1014":{"start":{"line":1015,"column":0},"end":{"line":1015,"column":54}},"1016":{"start":{"line":1017,"column":0},"end":{"line":1017,"column":77}},"1017":{"start":{"line":1018,"column":0},"end":{"line":1018,"column":72}},"1018":{"start":{"line":1019,"column":0},"end":{"line":1019,"column":37}},"1019":{"start":{"line":1020,"column":0},"end":{"line":1020,"column":85}},"1020":{"start":{"line":1021,"column":0},"end":{"line":1021,"column":35}},"1022":{"start":{"line":1023,"column":0},"end":{"line":1023,"column":27}},"1023":{"start":{"line":1024,"column":0},"end":{"line":1024,"column":28}},"1024":{"start":{"line":1025,"column":0},"end":{"line":1025,"column":29}},"1025":{"start":{"line":1026,"column":0},"end":{"line":1026,"column":23}},"1027":{"start":{"line":1028,"column":0},"end":{"line":1028,"column":17}},"1028":{"start":{"line":1029,"column":0},"end":{"line":1029,"column":17}},"1030":{"start":{"line":1031,"column":0},"end":{"line":1031,"column":41}},"1032":{"start":{"line":1033,"column":0},"end":{"line":1033,"column":18}},"1034":{"start":{"line":1035,"column":0},"end":{"line":1035,"column":14}},"1035":{"start":{"line":1036,"column":0},"end":{"line":1036,"column":16}},"1037":{"start":{"line":1038,"column":0},"end":{"line":1038,"column":25}},"1038":{"start":{"line":1039,"column":0},"end":{"line":1039,"column":28}},"1039":{"start":{"line":1040,"column":0},"end":{"line":1040,"column":31}},"1040":{"start":{"line":1041,"column":0},"end":{"line":1041,"column":47}},"1041":{"start":{"line":1042,"column":0},"end":{"line":1042,"column":48}},"1042":{"start":{"line":1043,"column":0},"end":{"line":1043,"column":51}},"1043":{"start":{"line":1044,"column":0},"end":{"line":1044,"column":55}},"1044":{"start":{"line":1045,"column":0},"end":{"line":1045,"column":49}},"1045":{"start":{"line":1046,"column":0},"end":{"line":1046,"column":10}},"1047":{"start":{"line":1048,"column":0},"end":{"line":1048,"column":10}},"1049":{"start":{"line":1050,"column":0},"end":{"line":1050,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"10":1,"11":1,"15":1,"16":1,"31":1,"44":1,"45":1,"97":1,"98":1,"99":1,"100":1,"101":1,"102":1,"104":1,"105":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"133":1,"134":1,"135":1,"136":1,"141":28,"142":28,"143":28,"144":28,"145":28,"146":28,"147":28,"148":0,"149":0,"150":0,"151":0,"152":28,"153":28,"154":0,"155":0,"156":28,"157":28,"159":45,"160":45,"161":45,"162":1,"163":1,"164":45,"165":15,"166":15,"167":29,"168":29,"170":348,"171":348,"172":348,"173":348,"174":348,"175":348,"176":348,"177":348,"178":14,"179":14,"180":348,"181":59,"182":59,"183":348,"184":106,"185":106,"186":169,"187":169,"189":112,"190":112,"191":112,"192":112,"193":112,"194":112,"195":112,"196":173,"197":173,"198":112,"199":112,"200":0,"201":0,"202":0,"203":0,"205":112,"207":212,"208":212,"209":212,"210":212,"211":212,"212":212,"213":104,"214":104,"215":212,"216":4,"217":4,"218":212,"219":59,"220":59,"221":45,"222":45,"224":230,"225":230,"226":230,"227":230,"228":230,"229":230,"230":230,"236":230,"237":230,"238":18,"239":18,"241":212,"242":230,"244":230,"245":4,"246":0,"247":4,"248":4,"250":208,"251":208,"253":4,"254":4,"255":4,"256":4,"257":4,"258":4,"259":4,"260":4,"267":4,"268":4,"269":4,"270":1,"271":0,"272":0,"273":1,"274":1,"275":1,"276":4,"277":4,"278":4,"280":4,"281":3,"282":1,"283":1,"284":1,"285":1,"286":1,"287":4,"288":3,"289":1,"291":4,"292":4,"293":4,"294":4,"295":4,"297":4,"298":4,"300":4,"301":4,"302":4,"303":4,"304":3,"305":3,"306":3,"307":3,"308":3,"309":3,"310":3,"311":3,"312":3,"313":3,"314":3,"315":3,"316":3,"317":3,"319":0,"321":3,"322":3,"323":3,"324":3,"325":3,"326":3,"327":1,"328":1,"329":1,"330":3,"331":3,"333":3,"334":3,"335":3,"337":1,"340":4,"341":5,"342":5,"343":5,"344":5,"345":5,"346":5,"347":5,"348":5,"349":5,"350":5,"351":5,"352":1,"353":1,"354":1,"355":5,"357":5,"358":5,"359":5,"360":5,"362":4,"363":4,"364":4,"365":4,"367":4,"368":4,"369":4,"371":4,"373":1,"374":240,"375":240,"376":240,"377":240,"378":240,"379":240,"380":240,"381":240,"382":240,"399":240,"400":240,"401":240,"402":240,"403":240,"404":240,"405":240,"406":240,"407":240,"408":240,"409":240,"410":240,"411":240,"412":240,"413":240,"414":240,"415":240,"416":240,"417":240,"418":240,"420":240,"421":240,"422":65,"423":65,"424":0,"425":0,"426":65,"427":65,"428":65,"429":65,"430":64,"431":64,"432":64,"433":64,"435":65,"436":240,"437":240,"439":240,"440":240,"441":33,"442":31,"443":31,"444":33,"445":33,"446":0,"447":0,"448":33,"449":33,"452":0,"453":0,"454":2,"455":2,"456":33,"457":33,"458":33,"459":2,"460":2,"461":2,"462":33,"463":240,"464":240,"466":240,"467":240,"468":240,"469":240,"470":240,"472":240,"473":32,"474":32,"475":32,"476":32,"477":0,"478":0,"479":32,"480":32,"481":32,"482":0,"483":32,"484":32,"485":32,"486":32,"487":240,"489":240,"490":32,"491":32,"492":3,"493":3,"494":3,"495":3,"496":3,"497":3,"498":29,"499":29,"500":29,"501":0,"502":0,"503":29,"504":29,"505":29,"506":0,"507":29,"508":29,"509":29,"510":29,"511":240,"513":240,"514":240,"515":182,"516":0,"517":0,"518":182,"519":182,"520":182,"521":182,"522":182,"523":0,"524":182,"525":182,"526":182,"527":182,"528":240,"529":240,"531":240,"532":32,"533":32,"534":3,"535":3,"536":3,"537":3,"538":3,"540":29,"541":181,"542":0,"543":0,"544":181,"545":181,"547":29,"548":29,"549":29,"550":29,"551":29,"552":29,"553":240,"555":240,"556":66,"557":28,"558":45,"559":45,"560":45,"561":45,"562":45,"563":45,"564":28,"566":28,"567":28,"568":28,"569":28,"570":28,"571":66,"572":240,"574":240,"575":240,"576":1,"577":0,"578":0,"579":1,"580":1,"581":1,"582":1,"583":1,"584":0,"585":1,"586":1,"587":240,"588":240,"590":240,"591":1,"592":0,"593":0,"594":1,"595":1,"596":1,"597":1,"598":1,"599":0,"600":1,"601":240,"603":240,"604":240,"605":132,"606":108,"607":240,"609":240,"610":240,"612":240,"614":240,"615":240,"616":240,"617":240,"618":240,"620":240,"621":32,"622":29,"623":29,"624":3,"625":240,"627":240,"628":91,"629":64,"630":64,"631":91,"632":0,"633":0,"634":240,"636":240,"637":61,"638":61,"639":36,"640":36,"641":36,"642":36,"643":36,"645":61,"646":61,"647":176,"648":176,"649":176,"650":176,"651":176,"652":176,"653":176,"654":0,"655":0,"656":176,"657":176,"658":0,"659":0,"660":0,"661":0,"662":0,"663":0,"664":176,"666":61,"667":61,"668":61,"669":25,"670":25,"671":25,"672":240,"673":240,"674":240,"675":240,"676":240,"677":240,"679":240,"680":32,"681":32,"682":32,"683":32,"684":31,"685":32,"686":240,"688":240,"689":240,"690":240,"691":240,"692":240,"693":240,"694":240,"695":240,"696":240,"697":240,"698":240,"699":240,"700":240,"701":240,"702":240,"703":240,"704":240,"705":240,"706":240,"708":240,"710":57,"711":240,"713":240,"714":1,"715":0,"716":0,"718":1,"722":1,"723":1,"724":1,"725":1,"726":1,"728":1,"729":1,"731":1,"732":1,"733":1,"736":1,"737":1,"738":0,"739":0,"740":0,"742":1,"744":1,"745":1,"746":0,"747":0,"748":0,"750":1,"751":1,"752":1,"753":1,"754":1,"755":0,"756":0,"757":0,"758":0,"759":1,"760":0,"761":0,"762":240,"763":240,"764":240,"765":240,"766":240,"767":240,"768":240,"769":240,"770":240,"771":240,"772":240,"773":240,"774":240,"776":240,"777":1,"778":1,"779":1,"780":0,"781":0,"783":1,"784":1,"785":1,"786":1,"787":0,"788":0,"790":1,"791":1,"792":1,"793":0,"794":0,"795":1,"796":1,"797":1,"798":0,"799":1,"800":1,"801":1,"802":240,"803":240,"804":240,"805":240,"806":240,"807":240,"808":240,"809":240,"810":240,"812":240,"813":240,"814":240,"815":240,"816":240,"818":240,"819":240,"820":240,"821":240,"822":240,"823":240,"824":240,"825":240,"826":240,"827":240,"828":240,"829":240,"830":240,"832":240,"833":240,"834":240,"835":240,"836":240,"837":240,"838":240,"839":27,"840":0,"841":0,"842":27,"843":27,"844":240,"845":240,"846":240,"848":240,"849":240,"850":240,"851":240,"852":240,"854":240,"855":30,"856":30,"857":26,"858":26,"859":26,"860":26,"861":26,"862":26,"863":25,"864":25,"865":25,"866":26,"868":26,"869":26,"870":30,"871":30,"872":30,"873":30,"875":0,"876":0,"877":30,"878":30,"880":30,"881":30,"882":30,"883":30,"884":30,"886":30,"887":30,"889":240,"890":240,"892":240,"893":240,"894":240,"895":240,"896":240,"897":240,"898":132,"899":19,"900":113,"901":108,"902":240,"903":240,"904":240,"905":240,"906":240,"907":240,"908":240,"909":240,"910":240,"911":240,"912":240,"913":240,"914":9,"915":231,"916":99,"917":132,"918":41,"919":91,"921":240,"922":40,"923":0,"924":0,"925":40,"926":18,"927":18,"928":18,"929":22,"930":40,"932":240,"933":240,"934":240,"935":240,"936":240,"937":240,"938":240,"939":240,"940":240,"941":240,"942":9,"943":231,"944":99,"945":132,"947":240,"948":1,"949":1,"951":240,"952":240,"953":240,"954":240,"955":240,"956":240,"957":1,"958":1,"959":1,"960":239,"961":240,"962":9,"964":9,"965":231,"966":132,"967":132,"968":230,"969":230,"970":230,"971":230,"972":230,"973":230,"974":230,"975":230,"976":230,"977":230,"978":230,"979":230,"981":230,"982":230,"983":230,"984":230,"985":230,"986":6,"987":224,"988":103,"990":121,"992":230,"993":230,"994":230,"995":18,"996":18,"997":18,"998":212,"999":230,"1000":230,"1001":122,"1002":122,"1003":348,"1004":348,"1005":348,"1006":348,"1007":348,"1008":348,"1009":348,"1010":348,"1011":348,"1012":348,"1013":348,"1014":348,"1016":348,"1017":348,"1018":348,"1019":348,"1020":348,"1022":122,"1023":122,"1024":108,"1025":230,"1027":132,"1028":132,"1030":99,"1032":99,"1034":240,"1035":240,"1037":240,"1038":4,"1039":4,"1040":4,"1041":4,"1042":4,"1043":4,"1044":4,"1045":4,"1047":240,"1049":240},"branchMap":{"0":{"type":"branch","line":142,"loc":{"start":{"line":142,"column":0},"end":{"line":158,"column":1}},"locations":[{"start":{"line":142,"column":0},"end":{"line":158,"column":1}}]},"1":{"type":"branch","line":143,"loc":{"start":{"line":143,"column":33},"end":{"line":143,"column":41}},"locations":[{"start":{"line":143,"column":33},"end":{"line":143,"column":41}}]},"2":{"type":"branch","line":144,"loc":{"start":{"line":144,"column":31},"end":{"line":144,"column":39}},"locations":[{"start":{"line":144,"column":31},"end":{"line":144,"column":39}}]},"3":{"type":"branch","line":145,"loc":{"start":{"line":145,"column":27},"end":{"line":145,"column":35}},"locations":[{"start":{"line":145,"column":27},"end":{"line":145,"column":35}}]},"4":{"type":"branch","line":148,"loc":{"start":{"line":148,"column":2},"end":{"line":153,"column":61}},"locations":[{"start":{"line":148,"column":2},"end":{"line":153,"column":61}}]},"5":{"type":"branch","line":153,"loc":{"start":{"line":153,"column":53},"end":{"line":153,"column":66}},"locations":[{"start":{"line":153,"column":53},"end":{"line":153,"column":66}}]},"6":{"type":"branch","line":154,"loc":{"start":{"line":154,"column":6},"end":{"line":154,"column":23}},"locations":[{"start":{"line":154,"column":6},"end":{"line":154,"column":23}}]},"7":{"type":"branch","line":154,"loc":{"start":{"line":154,"column":23},"end":{"line":157,"column":28}},"locations":[{"start":{"line":154,"column":23},"end":{"line":157,"column":28}}]},"8":{"type":"branch","line":157,"loc":{"start":{"line":157,"column":22},"end":{"line":157,"column":44}},"locations":[{"start":{"line":157,"column":22},"end":{"line":157,"column":44}}]},"9":{"type":"branch","line":160,"loc":{"start":{"line":160,"column":0},"end":{"line":169,"column":1}},"locations":[{"start":{"line":160,"column":0},"end":{"line":169,"column":1}}]},"10":{"type":"branch","line":162,"loc":{"start":{"line":162,"column":34},"end":{"line":164,"column":3}},"locations":[{"start":{"line":162,"column":34},"end":{"line":164,"column":3}}]},"11":{"type":"branch","line":164,"loc":{"start":{"line":164,"column":2},"end":{"line":165,"column":36}},"locations":[{"start":{"line":164,"column":2},"end":{"line":165,"column":36}}]},"12":{"type":"branch","line":165,"loc":{"start":{"line":165,"column":36},"end":{"line":167,"column":3}},"locations":[{"start":{"line":165,"column":36},"end":{"line":167,"column":3}}]},"13":{"type":"branch","line":167,"loc":{"start":{"line":167,"column":2},"end":{"line":169,"column":1}},"locations":[{"start":{"line":167,"column":2},"end":{"line":169,"column":1}}]},"14":{"type":"branch","line":171,"loc":{"start":{"line":171,"column":0},"end":{"line":188,"column":1}},"locations":[{"start":{"line":171,"column":0},"end":{"line":188,"column":1}}]},"15":{"type":"branch","line":178,"loc":{"start":{"line":178,"column":6},"end":{"line":178,"column":30}},"locations":[{"start":{"line":178,"column":6},"end":{"line":178,"column":30}}]},"16":{"type":"branch","line":178,"loc":{"start":{"line":178,"column":30},"end":{"line":178,"column":73}},"locations":[{"start":{"line":178,"column":30},"end":{"line":178,"column":73}}]},"17":{"type":"branch","line":178,"loc":{"start":{"line":178,"column":73},"end":{"line":180,"column":3}},"locations":[{"start":{"line":178,"column":73},"end":{"line":180,"column":3}}]},"18":{"type":"branch","line":180,"loc":{"start":{"line":180,"column":2},"end":{"line":181,"column":42}},"locations":[{"start":{"line":180,"column":2},"end":{"line":181,"column":42}}]},"19":{"type":"branch","line":181,"loc":{"start":{"line":181,"column":42},"end":{"line":183,"column":3}},"locations":[{"start":{"line":181,"column":42},"end":{"line":183,"column":3}}]},"20":{"type":"branch","line":183,"loc":{"start":{"line":183,"column":2},"end":{"line":184,"column":40}},"locations":[{"start":{"line":183,"column":2},"end":{"line":184,"column":40}}]},"21":{"type":"branch","line":184,"loc":{"start":{"line":184,"column":40},"end":{"line":186,"column":3}},"locations":[{"start":{"line":184,"column":40},"end":{"line":186,"column":3}}]},"22":{"type":"branch","line":186,"loc":{"start":{"line":186,"column":2},"end":{"line":188,"column":1}},"locations":[{"start":{"line":186,"column":2},"end":{"line":188,"column":1}}]},"23":{"type":"branch","line":190,"loc":{"start":{"line":190,"column":0},"end":{"line":206,"column":1}},"locations":[{"start":{"line":190,"column":0},"end":{"line":206,"column":1}}]},"24":{"type":"branch","line":200,"loc":{"start":{"line":200,"column":2},"end":{"line":204,"column":80}},"locations":[{"start":{"line":200,"column":2},"end":{"line":204,"column":80}}]},"25":{"type":"branch","line":196,"loc":{"start":{"line":196,"column":6},"end":{"line":198,"column":20}},"locations":[{"start":{"line":196,"column":6},"end":{"line":198,"column":20}}]},"26":{"type":"branch","line":197,"loc":{"start":{"line":197,"column":35},"end":{"line":197,"column":51}},"locations":[{"start":{"line":197,"column":35},"end":{"line":197,"column":51}}]},"27":{"type":"branch","line":208,"loc":{"start":{"line":208,"column":0},"end":{"line":223,"column":1}},"locations":[{"start":{"line":208,"column":0},"end":{"line":223,"column":1}}]},"28":{"type":"branch","line":213,"loc":{"start":{"line":213,"column":34},"end":{"line":215,"column":3}},"locations":[{"start":{"line":213,"column":34},"end":{"line":215,"column":3}}]},"29":{"type":"branch","line":215,"loc":{"start":{"line":215,"column":2},"end":{"line":216,"column":57}},"locations":[{"start":{"line":215,"column":2},"end":{"line":216,"column":57}}]},"30":{"type":"branch","line":216,"loc":{"start":{"line":216,"column":57},"end":{"line":218,"column":3}},"locations":[{"start":{"line":216,"column":57},"end":{"line":218,"column":3}}]},"31":{"type":"branch","line":218,"loc":{"start":{"line":218,"column":2},"end":{"line":219,"column":85}},"locations":[{"start":{"line":218,"column":2},"end":{"line":219,"column":85}}]},"32":{"type":"branch","line":219,"loc":{"start":{"line":219,"column":85},"end":{"line":221,"column":3}},"locations":[{"start":{"line":219,"column":85},"end":{"line":221,"column":3}}]},"33":{"type":"branch","line":221,"loc":{"start":{"line":221,"column":2},"end":{"line":223,"column":1}},"locations":[{"start":{"line":221,"column":2},"end":{"line":223,"column":1}}]},"34":{"type":"branch","line":219,"loc":{"start":{"line":219,"column":25},"end":{"line":219,"column":82}},"locations":[{"start":{"line":219,"column":25},"end":{"line":219,"column":82}}]},"35":{"type":"branch","line":225,"loc":{"start":{"line":225,"column":0},"end":{"line":252,"column":1}},"locations":[{"start":{"line":225,"column":0},"end":{"line":252,"column":1}}]},"36":{"type":"branch","line":238,"loc":{"start":{"line":238,"column":6},"end":{"line":238,"column":30}},"locations":[{"start":{"line":238,"column":6},"end":{"line":238,"column":30}}]},"37":{"type":"branch","line":238,"loc":{"start":{"line":238,"column":38},"end":{"line":240,"column":3}},"locations":[{"start":{"line":238,"column":38},"end":{"line":240,"column":3}}]},"38":{"type":"branch","line":240,"loc":{"start":{"line":240,"column":2},"end":{"line":243,"column":47}},"locations":[{"start":{"line":240,"column":2},"end":{"line":243,"column":47}}]},"39":{"type":"branch","line":243,"loc":{"start":{"line":243,"column":25},"end":{"line":243,"column":62}},"locations":[{"start":{"line":243,"column":25},"end":{"line":243,"column":62}}]},"40":{"type":"branch","line":245,"loc":{"start":{"line":245,"column":6},"end":{"line":245,"column":54}},"locations":[{"start":{"line":245,"column":6},"end":{"line":245,"column":54}}]},"41":{"type":"branch","line":245,"loc":{"start":{"line":245,"column":54},"end":{"line":249,"column":3}},"locations":[{"start":{"line":245,"column":54},"end":{"line":249,"column":3}}]},"42":{"type":"branch","line":246,"loc":{"start":{"line":246,"column":59},"end":{"line":247,"column":19}},"locations":[{"start":{"line":246,"column":59},"end":{"line":247,"column":19}}]},"43":{"type":"branch","line":249,"loc":{"start":{"line":249,"column":2},"end":{"line":252,"column":1}},"locations":[{"start":{"line":249,"column":2},"end":{"line":252,"column":1}}]},"44":{"type":"branch","line":254,"loc":{"start":{"line":254,"column":0},"end":{"line":372,"column":1}},"locations":[{"start":{"line":254,"column":0},"end":{"line":372,"column":1}}]},"45":{"type":"branch","line":281,"loc":{"start":{"line":281,"column":20},"end":{"line":286,"column":7}},"locations":[{"start":{"line":281,"column":20},"end":{"line":286,"column":7}}]},"46":{"type":"branch","line":282,"loc":{"start":{"line":282,"column":74},"end":{"line":286,"column":7}},"locations":[{"start":{"line":282,"column":74},"end":{"line":286,"column":7}}]},"47":{"type":"branch","line":286,"loc":{"start":{"line":286,"column":6},"end":{"line":287,"column":11}},"locations":[{"start":{"line":286,"column":6},"end":{"line":287,"column":11}}]},"48":{"type":"branch","line":288,"loc":{"start":{"line":288,"column":17},"end":{"line":289,"column":52}},"locations":[{"start":{"line":288,"column":17},"end":{"line":289,"column":52}}]},"49":{"type":"branch","line":289,"loc":{"start":{"line":289,"column":51},"end":{"line":290,"column":16}},"locations":[{"start":{"line":289,"column":51},"end":{"line":290,"column":16}}]},"50":{"type":"branch","line":304,"loc":{"start":{"line":304,"column":9},"end":{"line":336,"column":16}},"locations":[{"start":{"line":304,"column":9},"end":{"line":336,"column":16}}]},"51":{"type":"branch","line":309,"loc":{"start":{"line":309,"column":68},"end":{"line":309,"column":77}},"locations":[{"start":{"line":309,"column":68},"end":{"line":309,"column":77}}]},"52":{"type":"branch","line":336,"loc":{"start":{"line":336,"column":10},"end":{"line":338,"column":76}},"locations":[{"start":{"line":336,"column":10},"end":{"line":338,"column":76}}]},"53":{"type":"branch","line":269,"loc":{"start":{"line":269,"column":12},"end":{"line":279,"column":5}},"locations":[{"start":{"line":269,"column":12},"end":{"line":279,"column":5}}]},"54":{"type":"branch","line":270,"loc":{"start":{"line":270,"column":26},"end":{"line":276,"column":6}},"locations":[{"start":{"line":270,"column":26},"end":{"line":276,"column":6}}]},"55":{"type":"branch","line":271,"loc":{"start":{"line":271,"column":34},"end":{"line":273,"column":7}},"locations":[{"start":{"line":271,"column":34},"end":{"line":273,"column":7}}]},"56":{"type":"branch","line":278,"loc":{"start":{"line":278,"column":11},"end":{"line":278,"column":70}},"locations":[{"start":{"line":278,"column":11},"end":{"line":278,"column":70}}]},"57":{"type":"branch","line":282,"loc":{"start":{"line":282,"column":21},"end":{"line":282,"column":74}},"locations":[{"start":{"line":282,"column":21},"end":{"line":282,"column":74}}]},"58":{"type":"branch","line":289,"loc":{"start":{"line":289,"column":23},"end":{"line":289,"column":51}},"locations":[{"start":{"line":289,"column":23},"end":{"line":289,"column":51}}]},"59":{"type":"branch","line":327,"loc":{"start":{"line":327,"column":25},"end":{"line":330,"column":18}},"locations":[{"start":{"line":327,"column":25},"end":{"line":330,"column":18}}]},"60":{"type":"branch","line":341,"loc":{"start":{"line":341,"column":20},"end":{"line":363,"column":9}},"locations":[{"start":{"line":341,"column":20},"end":{"line":363,"column":9}}]},"61":{"type":"branch","line":342,"loc":{"start":{"line":342,"column":30},"end":{"line":342,"column":51}},"locations":[{"start":{"line":342,"column":30},"end":{"line":342,"column":51}}]},"62":{"type":"branch","line":342,"loc":{"start":{"line":342,"column":42},"end":{"line":342,"column":61}},"locations":[{"start":{"line":342,"column":42},"end":{"line":342,"column":61}}]},"63":{"type":"branch","line":352,"loc":{"start":{"line":352,"column":27},"end":{"line":355,"column":20}},"locations":[{"start":{"line":352,"column":27},"end":{"line":355,"column":20}}]},"64":{"type":"branch","line":374,"loc":{"start":{"line":374,"column":7},"end":{"line":1050,"column":1}},"locations":[{"start":{"line":374,"column":7},"end":{"line":1050,"column":1}}]},"65":{"type":"branch","line":401,"loc":{"start":{"line":401,"column":17},"end":{"line":401,"column":64}},"locations":[{"start":{"line":401,"column":17},"end":{"line":401,"column":64}}]},"66":{"type":"branch","line":402,"loc":{"start":{"line":402,"column":19},"end":{"line":402,"column":58}},"locations":[{"start":{"line":402,"column":19},"end":{"line":402,"column":58}}]},"67":{"type":"branch","line":408,"loc":{"start":{"line":408,"column":33},"end":{"line":408,"column":69}},"locations":[{"start":{"line":408,"column":33},"end":{"line":408,"column":69}}]},"68":{"type":"branch","line":419,"loc":{"start":{"line":419,"column":37},"end":{"line":419,"column":61}},"locations":[{"start":{"line":419,"column":37},"end":{"line":419,"column":61}}]},"69":{"type":"branch","line":605,"loc":{"start":{"line":605,"column":23},"end":{"line":606,"column":56}},"locations":[{"start":{"line":605,"column":23},"end":{"line":606,"column":56}}]},"70":{"type":"branch","line":606,"loc":{"start":{"line":606,"column":47},"end":{"line":606,"column":56}},"locations":[{"start":{"line":606,"column":47},"end":{"line":606,"column":56}}]},"71":{"type":"branch","line":606,"loc":{"start":{"line":606,"column":52},"end":{"line":607,"column":11}},"locations":[{"start":{"line":606,"column":52},"end":{"line":607,"column":11}}]},"72":{"type":"branch","line":675,"loc":{"start":{"line":675,"column":4},"end":{"line":675,"column":43}},"locations":[{"start":{"line":675,"column":4},"end":{"line":675,"column":43}}]},"73":{"type":"branch","line":837,"loc":{"start":{"line":837,"column":49},"end":{"line":837,"column":77}},"locations":[{"start":{"line":837,"column":49},"end":{"line":837,"column":77}}]},"74":{"type":"branch","line":837,"loc":{"start":{"line":837,"column":64},"end":{"line":837,"column":79}},"locations":[{"start":{"line":837,"column":64},"end":{"line":837,"column":79}}]},"75":{"type":"branch","line":849,"loc":{"start":{"line":849,"column":29},"end":{"line":849,"column":64}},"locations":[{"start":{"line":849,"column":29},"end":{"line":849,"column":64}}]},"76":{"type":"branch","line":849,"loc":{"start":{"line":849,"column":44},"end":{"line":849,"column":84}},"locations":[{"start":{"line":849,"column":44},"end":{"line":849,"column":84}}]},"77":{"type":"branch","line":850,"loc":{"start":{"line":850,"column":15},"end":{"line":850,"column":50}},"locations":[{"start":{"line":850,"column":15},"end":{"line":850,"column":50}}]},"78":{"type":"branch","line":850,"loc":{"start":{"line":850,"column":43},"end":{"line":850,"column":68}},"locations":[{"start":{"line":850,"column":43},"end":{"line":850,"column":68}}]},"79":{"type":"branch","line":855,"loc":{"start":{"line":855,"column":11},"end":{"line":888,"column":29}},"locations":[{"start":{"line":855,"column":11},"end":{"line":888,"column":29}}]},"80":{"type":"branch","line":898,"loc":{"start":{"line":898,"column":15},"end":{"line":901,"column":37}},"locations":[{"start":{"line":898,"column":15},"end":{"line":901,"column":37}}]},"81":{"type":"branch","line":899,"loc":{"start":{"line":899,"column":18},"end":{"line":900,"column":89}},"locations":[{"start":{"line":899,"column":18},"end":{"line":900,"column":89}}]},"82":{"type":"branch","line":900,"loc":{"start":{"line":900,"column":87},"end":{"line":901,"column":37}},"locations":[{"start":{"line":900,"column":87},"end":{"line":901,"column":37}}]},"83":{"type":"branch","line":901,"loc":{"start":{"line":901,"column":33},"end":{"line":902,"column":37}},"locations":[{"start":{"line":901,"column":33},"end":{"line":902,"column":37}}]},"84":{"type":"branch","line":910,"loc":{"start":{"line":910,"column":25},"end":{"line":910,"column":61}},"locations":[{"start":{"line":910,"column":25},"end":{"line":910,"column":61}}]},"85":{"type":"branch","line":911,"loc":{"start":{"line":911,"column":26},"end":{"line":911,"column":55}},"locations":[{"start":{"line":911,"column":26},"end":{"line":911,"column":55}}]},"86":{"type":"branch","line":911,"loc":{"start":{"line":911,"column":40},"end":{"line":911,"column":69}},"locations":[{"start":{"line":911,"column":40},"end":{"line":911,"column":69}}]},"87":{"type":"branch","line":914,"loc":{"start":{"line":914,"column":17},"end":{"line":915,"column":51}},"locations":[{"start":{"line":914,"column":17},"end":{"line":915,"column":51}}]},"88":{"type":"branch","line":915,"loc":{"start":{"line":915,"column":20},"end":{"line":920,"column":35}},"locations":[{"start":{"line":915,"column":20},"end":{"line":920,"column":35}}]},"89":{"type":"branch","line":916,"loc":{"start":{"line":916,"column":21},"end":{"line":917,"column":42}},"locations":[{"start":{"line":916,"column":21},"end":{"line":917,"column":42}}]},"90":{"type":"branch","line":917,"loc":{"start":{"line":917,"column":20},"end":{"line":920,"column":35}},"locations":[{"start":{"line":917,"column":20},"end":{"line":920,"column":35}}]},"91":{"type":"branch","line":918,"loc":{"start":{"line":918,"column":20},"end":{"line":919,"column":34}},"locations":[{"start":{"line":918,"column":20},"end":{"line":919,"column":34}}]},"92":{"type":"branch","line":919,"loc":{"start":{"line":919,"column":22},"end":{"line":920,"column":35}},"locations":[{"start":{"line":919,"column":22},"end":{"line":920,"column":35}}]},"93":{"type":"branch","line":933,"loc":{"start":{"line":933,"column":15},"end":{"line":933,"column":53}},"locations":[{"start":{"line":933,"column":15},"end":{"line":933,"column":53}}]},"94":{"type":"branch","line":933,"loc":{"start":{"line":933,"column":48},"end":{"line":933,"column":74}},"locations":[{"start":{"line":933,"column":48},"end":{"line":933,"column":74}}]},"95":{"type":"branch","line":939,"loc":{"start":{"line":939,"column":25},"end":{"line":939,"column":64}},"locations":[{"start":{"line":939,"column":25},"end":{"line":939,"column":64}}]},"96":{"type":"branch","line":939,"loc":{"start":{"line":939,"column":48},"end":{"line":939,"column":84}},"locations":[{"start":{"line":939,"column":48},"end":{"line":939,"column":84}}]},"97":{"type":"branch","line":942,"loc":{"start":{"line":942,"column":17},"end":{"line":943,"column":51}},"locations":[{"start":{"line":942,"column":17},"end":{"line":943,"column":51}}]},"98":{"type":"branch","line":943,"loc":{"start":{"line":943,"column":20},"end":{"line":946,"column":61}},"locations":[{"start":{"line":943,"column":20},"end":{"line":946,"column":61}}]},"99":{"type":"branch","line":944,"loc":{"start":{"line":944,"column":21},"end":{"line":945,"column":53}},"locations":[{"start":{"line":944,"column":21},"end":{"line":945,"column":53}}]},"100":{"type":"branch","line":945,"loc":{"start":{"line":945,"column":20},"end":{"line":946,"column":61}},"locations":[{"start":{"line":945,"column":20},"end":{"line":946,"column":61}}]},"101":{"type":"branch","line":952,"loc":{"start":{"line":952,"column":15},"end":{"line":952,"column":54}},"locations":[{"start":{"line":952,"column":15},"end":{"line":952,"column":54}}]},"102":{"type":"branch","line":952,"loc":{"start":{"line":952,"column":37},"end":{"line":952,"column":71}},"locations":[{"start":{"line":952,"column":37},"end":{"line":952,"column":71}}]},"103":{"type":"branch","line":957,"loc":{"start":{"line":957,"column":11},"end":{"line":960,"column":18}},"locations":[{"start":{"line":957,"column":11},"end":{"line":960,"column":18}}]},"104":{"type":"branch","line":960,"loc":{"start":{"line":960,"column":12},"end":{"line":961,"column":19}},"locations":[{"start":{"line":960,"column":12},"end":{"line":961,"column":19}}]},"105":{"type":"branch","line":962,"loc":{"start":{"line":962,"column":12},"end":{"line":965,"column":18}},"locations":[{"start":{"line":962,"column":12},"end":{"line":965,"column":18}}]},"106":{"type":"branch","line":965,"loc":{"start":{"line":965,"column":12},"end":{"line":1033,"column":18}},"locations":[{"start":{"line":965,"column":12},"end":{"line":1033,"column":18}}]},"107":{"type":"branch","line":966,"loc":{"start":{"line":966,"column":14},"end":{"line":1029,"column":17}},"locations":[{"start":{"line":966,"column":14},"end":{"line":1029,"column":17}}]},"108":{"type":"branch","line":1029,"loc":{"start":{"line":1029,"column":12},"end":{"line":1033,"column":18}},"locations":[{"start":{"line":1029,"column":12},"end":{"line":1033,"column":18}}]},"109":{"type":"branch","line":1038,"loc":{"start":{"line":1038,"column":7},"end":{"line":1046,"column":10}},"locations":[{"start":{"line":1038,"column":7},"end":{"line":1046,"column":10}}]},"110":{"type":"branch","line":422,"loc":{"start":{"line":422,"column":4},"end":{"line":436,"column":6}},"locations":[{"start":{"line":422,"column":4},"end":{"line":436,"column":6}}]},"111":{"type":"branch","line":424,"loc":{"start":{"line":424,"column":23},"end":{"line":426,"column":7}},"locations":[{"start":{"line":424,"column":23},"end":{"line":426,"column":7}}]},"112":{"type":"branch","line":430,"loc":{"start":{"line":430,"column":8},"end":{"line":433,"column":12}},"locations":[{"start":{"line":430,"column":8},"end":{"line":433,"column":12}}]},"113":{"type":"branch","line":433,"loc":{"start":{"line":433,"column":8},"end":{"line":434,"column":12}},"locations":[{"start":{"line":433,"column":8},"end":{"line":434,"column":12}}]},"114":{"type":"branch","line":429,"loc":{"start":{"line":429,"column":10},"end":{"line":429,"column":64}},"locations":[{"start":{"line":429,"column":10},"end":{"line":429,"column":64}}]},"115":{"type":"branch","line":432,"loc":{"start":{"line":432,"column":10},"end":{"line":432,"column":79}},"locations":[{"start":{"line":432,"column":10},"end":{"line":432,"column":79}}]},"116":{"type":"branch","line":432,"loc":{"start":{"line":432,"column":26},"end":{"line":432,"column":43}},"locations":[{"start":{"line":432,"column":26},"end":{"line":432,"column":43}}]},"117":{"type":"branch","line":441,"loc":{"start":{"line":441,"column":4},"end":{"line":463,"column":6}},"locations":[{"start":{"line":441,"column":4},"end":{"line":463,"column":6}}]},"118":{"type":"branch","line":442,"loc":{"start":{"line":442,"column":17},"end":{"line":444,"column":7}},"locations":[{"start":{"line":442,"column":17},"end":{"line":444,"column":7}}]},"119":{"type":"branch","line":444,"loc":{"start":{"line":444,"column":6},"end":{"line":445,"column":37}},"locations":[{"start":{"line":444,"column":6},"end":{"line":445,"column":37}}]},"120":{"type":"branch","line":445,"loc":{"start":{"line":445,"column":29},"end":{"line":445,"column":45}},"locations":[{"start":{"line":445,"column":29},"end":{"line":445,"column":45}}]},"121":{"type":"branch","line":446,"loc":{"start":{"line":446,"column":22},"end":{"line":448,"column":7}},"locations":[{"start":{"line":446,"column":22},"end":{"line":448,"column":7}}]},"122":{"type":"branch","line":448,"loc":{"start":{"line":448,"column":6},"end":{"line":449,"column":40}},"locations":[{"start":{"line":448,"column":6},"end":{"line":449,"column":40}}]},"123":{"type":"branch","line":449,"loc":{"start":{"line":449,"column":31},"end":{"line":449,"column":44}},"locations":[{"start":{"line":449,"column":31},"end":{"line":449,"column":44}}]},"124":{"type":"branch","line":450,"loc":{"start":{"line":450,"column":23},"end":{"line":454,"column":7}},"locations":[{"start":{"line":450,"column":23},"end":{"line":454,"column":7}}]},"125":{"type":"branch","line":454,"loc":{"start":{"line":454,"column":6},"end":{"line":456,"column":67}},"locations":[{"start":{"line":454,"column":6},"end":{"line":456,"column":67}}]},"126":{"type":"branch","line":459,"loc":{"start":{"line":459,"column":41},"end":{"line":462,"column":43}},"locations":[{"start":{"line":459,"column":41},"end":{"line":462,"column":43}}]},"127":{"type":"branch","line":473,"loc":{"start":{"line":473,"column":12},"end":{"line":488,"column":5}},"locations":[{"start":{"line":473,"column":12},"end":{"line":488,"column":5}}]},"128":{"type":"branch","line":476,"loc":{"start":{"line":476,"column":12},"end":{"line":481,"column":7}},"locations":[{"start":{"line":476,"column":12},"end":{"line":481,"column":7}}]},"129":{"type":"branch","line":477,"loc":{"start":{"line":477,"column":23},"end":{"line":479,"column":9}},"locations":[{"start":{"line":477,"column":23},"end":{"line":479,"column":9}}]},"130":{"type":"branch","line":485,"loc":{"start":{"line":485,"column":11},"end":{"line":487,"column":6}},"locations":[{"start":{"line":485,"column":11},"end":{"line":487,"column":6}}]},"131":{"type":"branch","line":490,"loc":{"start":{"line":490,"column":12},"end":{"line":512,"column":5}},"locations":[{"start":{"line":490,"column":12},"end":{"line":512,"column":5}}]},"132":{"type":"branch","line":492,"loc":{"start":{"line":492,"column":28},"end":{"line":498,"column":5}},"locations":[{"start":{"line":492,"column":28},"end":{"line":498,"column":5}}]},"133":{"type":"branch","line":498,"loc":{"start":{"line":498,"column":4},"end":{"line":511,"column":6}},"locations":[{"start":{"line":498,"column":4},"end":{"line":511,"column":6}}]},"134":{"type":"branch","line":495,"loc":{"start":{"line":495,"column":13},"end":{"line":497,"column":8}},"locations":[{"start":{"line":495,"column":13},"end":{"line":497,"column":8}}]},"135":{"type":"branch","line":500,"loc":{"start":{"line":500,"column":12},"end":{"line":505,"column":7}},"locations":[{"start":{"line":500,"column":12},"end":{"line":505,"column":7}}]},"136":{"type":"branch","line":501,"loc":{"start":{"line":501,"column":23},"end":{"line":503,"column":9}},"locations":[{"start":{"line":501,"column":23},"end":{"line":503,"column":9}}]},"137":{"type":"branch","line":509,"loc":{"start":{"line":509,"column":11},"end":{"line":511,"column":6}},"locations":[{"start":{"line":509,"column":11},"end":{"line":511,"column":6}}]},"138":{"type":"branch","line":515,"loc":{"start":{"line":515,"column":4},"end":{"line":528,"column":6}},"locations":[{"start":{"line":515,"column":4},"end":{"line":528,"column":6}}]},"139":{"type":"branch","line":516,"loc":{"start":{"line":516,"column":36},"end":{"line":518,"column":7}},"locations":[{"start":{"line":516,"column":36},"end":{"line":518,"column":7}}]},"140":{"type":"branch","line":523,"loc":{"start":{"line":523,"column":6},"end":{"line":525,"column":8}},"locations":[{"start":{"line":523,"column":6},"end":{"line":525,"column":8}}]},"141":{"type":"branch","line":532,"loc":{"start":{"line":532,"column":12},"end":{"line":554,"column":5}},"locations":[{"start":{"line":532,"column":12},"end":{"line":554,"column":5}}]},"142":{"type":"branch","line":534,"loc":{"start":{"line":534,"column":28},"end":{"line":539,"column":5}},"locations":[{"start":{"line":534,"column":28},"end":{"line":539,"column":5}}]},"143":{"type":"branch","line":539,"loc":{"start":{"line":539,"column":4},"end":{"line":553,"column":6}},"locations":[{"start":{"line":539,"column":4},"end":{"line":553,"column":6}}]},"144":{"type":"branch","line":536,"loc":{"start":{"line":536,"column":13},"end":{"line":538,"column":8}},"locations":[{"start":{"line":536,"column":13},"end":{"line":538,"column":8}}]},"145":{"type":"branch","line":541,"loc":{"start":{"line":541,"column":22},"end":{"line":546,"column":6}},"locations":[{"start":{"line":541,"column":22},"end":{"line":546,"column":6}}]},"146":{"type":"branch","line":542,"loc":{"start":{"line":542,"column":21},"end":{"line":544,"column":7}},"locations":[{"start":{"line":542,"column":21},"end":{"line":544,"column":7}}]},"147":{"type":"branch","line":550,"loc":{"start":{"line":550,"column":11},"end":{"line":553,"column":6}},"locations":[{"start":{"line":550,"column":11},"end":{"line":553,"column":6}}]},"148":{"type":"branch","line":556,"loc":{"start":{"line":556,"column":37},"end":{"line":573,"column":5}},"locations":[{"start":{"line":556,"column":37},"end":{"line":573,"column":5}}]},"149":{"type":"branch","line":557,"loc":{"start":{"line":557,"column":30},"end":{"line":572,"column":5}},"locations":[{"start":{"line":557,"column":30},"end":{"line":572,"column":5}}]},"150":{"type":"branch","line":558,"loc":{"start":{"line":558,"column":52},"end":{"line":565,"column":7}},"locations":[{"start":{"line":558,"column":52},"end":{"line":565,"column":7}}]},"151":{"type":"branch","line":576,"loc":{"start":{"line":576,"column":4},"end":{"line":587,"column":6}},"locations":[{"start":{"line":576,"column":4},"end":{"line":587,"column":6}}]},"152":{"type":"branch","line":577,"loc":{"start":{"line":577,"column":30},"end":{"line":579,"column":7}},"locations":[{"start":{"line":577,"column":30},"end":{"line":579,"column":7}}]},"153":{"type":"branch","line":581,"loc":{"start":{"line":581,"column":14},"end":{"line":583,"column":9}},"locations":[{"start":{"line":581,"column":14},"end":{"line":583,"column":9}}]},"154":{"type":"branch","line":591,"loc":{"start":{"line":591,"column":46},"end":{"line":602,"column":5}},"locations":[{"start":{"line":591,"column":46},"end":{"line":602,"column":5}}]},"155":{"type":"branch","line":592,"loc":{"start":{"line":592,"column":28},"end":{"line":594,"column":5}},"locations":[{"start":{"line":592,"column":28},"end":{"line":594,"column":5}}]},"156":{"type":"branch","line":596,"loc":{"start":{"line":596,"column":12},"end":{"line":598,"column":7}},"locations":[{"start":{"line":596,"column":12},"end":{"line":598,"column":7}}]},"157":{"type":"branch","line":606,"loc":{"start":{"line":606,"column":17},"end":{"line":606,"column":47}},"locations":[{"start":{"line":606,"column":17},"end":{"line":606,"column":47}}]},"158":{"type":"branch","line":621,"loc":{"start":{"line":621,"column":12},"end":{"line":626,"column":5}},"locations":[{"start":{"line":621,"column":12},"end":{"line":626,"column":5}}]},"159":{"type":"branch","line":622,"loc":{"start":{"line":622,"column":28},"end":{"line":624,"column":5}},"locations":[{"start":{"line":622,"column":28},"end":{"line":624,"column":5}}]},"160":{"type":"branch","line":624,"loc":{"start":{"line":624,"column":4},"end":{"line":625,"column":27}},"locations":[{"start":{"line":624,"column":4},"end":{"line":625,"column":27}}]},"161":{"type":"branch","line":628,"loc":{"start":{"line":628,"column":12},"end":{"line":635,"column":5}},"locations":[{"start":{"line":628,"column":12},"end":{"line":635,"column":5}}]},"162":{"type":"branch","line":629,"loc":{"start":{"line":629,"column":25},"end":{"line":631,"column":5}},"locations":[{"start":{"line":629,"column":25},"end":{"line":631,"column":5}}]},"163":{"type":"branch","line":631,"loc":{"start":{"line":631,"column":4},"end":{"line":632,"column":59}},"locations":[{"start":{"line":631,"column":4},"end":{"line":632,"column":59}}]},"164":{"type":"branch","line":632,"loc":{"start":{"line":632,"column":59},"end":{"line":634,"column":5}},"locations":[{"start":{"line":632,"column":59},"end":{"line":634,"column":5}}]},"165":{"type":"branch","line":632,"loc":{"start":{"line":632,"column":20},"end":{"line":632,"column":56}},"locations":[{"start":{"line":632,"column":20},"end":{"line":632,"column":56}}]},"166":{"type":"branch","line":637,"loc":{"start":{"line":637,"column":12},"end":{"line":673,"column":5}},"locations":[{"start":{"line":637,"column":12},"end":{"line":673,"column":5}}]},"167":{"type":"branch","line":639,"loc":{"start":{"line":639,"column":9},"end":{"line":639,"column":47}},"locations":[{"start":{"line":639,"column":9},"end":{"line":639,"column":47}}]},"168":{"type":"branch","line":639,"loc":{"start":{"line":639,"column":47},"end":{"line":644,"column":5}},"locations":[{"start":{"line":639,"column":47},"end":{"line":644,"column":5}}]},"169":{"type":"branch","line":644,"loc":{"start":{"line":644,"column":4},"end":{"line":646,"column":51}},"locations":[{"start":{"line":644,"column":4},"end":{"line":646,"column":51}}]},"170":{"type":"branch","line":646,"loc":{"start":{"line":646,"column":32},"end":{"line":646,"column":74}},"locations":[{"start":{"line":646,"column":32},"end":{"line":646,"column":74}}]},"171":{"type":"branch","line":646,"loc":{"start":{"line":646,"column":51},"end":{"line":646,"column":79}},"locations":[{"start":{"line":646,"column":51},"end":{"line":646,"column":79}}]},"172":{"type":"branch","line":641,"loc":{"start":{"line":641,"column":13},"end":{"line":643,"column":8}},"locations":[{"start":{"line":641,"column":13},"end":{"line":643,"column":8}}]},"173":{"type":"branch","line":647,"loc":{"start":{"line":647,"column":29},"end":{"line":665,"column":6}},"locations":[{"start":{"line":647,"column":29},"end":{"line":665,"column":6}}]},"174":{"type":"branch","line":654,"loc":{"start":{"line":654,"column":23},"end":{"line":656,"column":9}},"locations":[{"start":{"line":654,"column":23},"end":{"line":656,"column":9}}]},"175":{"type":"branch","line":658,"loc":{"start":{"line":658,"column":6},"end":{"line":664,"column":7}},"locations":[{"start":{"line":658,"column":6},"end":{"line":664,"column":7}}]},"176":{"type":"branch","line":669,"loc":{"start":{"line":669,"column":11},"end":{"line":672,"column":6}},"locations":[{"start":{"line":669,"column":11},"end":{"line":672,"column":6}}]},"177":{"type":"branch","line":680,"loc":{"start":{"line":680,"column":32},"end":{"line":687,"column":5}},"locations":[{"start":{"line":680,"column":32},"end":{"line":687,"column":5}}]},"178":{"type":"branch","line":684,"loc":{"start":{"line":684,"column":26},"end":{"line":685,"column":11}},"locations":[{"start":{"line":684,"column":26},"end":{"line":685,"column":11}}]},"179":{"type":"branch","line":709,"loc":{"start":{"line":709,"column":12},"end":{"line":712,"column":5}},"locations":[{"start":{"line":709,"column":12},"end":{"line":712,"column":5}}]},"180":{"type":"branch","line":714,"loc":{"start":{"line":714,"column":36},"end":{"line":763,"column":5}},"locations":[{"start":{"line":714,"column":36},"end":{"line":763,"column":5}}]},"181":{"type":"branch","line":715,"loc":{"start":{"line":715,"column":28},"end":{"line":717,"column":5}},"locations":[{"start":{"line":715,"column":28},"end":{"line":717,"column":5}}]},"182":{"type":"branch","line":734,"loc":{"start":{"line":734,"column":27},"end":{"line":734,"column":57}},"locations":[{"start":{"line":734,"column":27},"end":{"line":734,"column":57}}]},"183":{"type":"branch","line":734,"loc":{"start":{"line":734,"column":47},"end":{"line":734,"column":65}},"locations":[{"start":{"line":734,"column":47},"end":{"line":734,"column":65}}]},"184":{"type":"branch","line":737,"loc":{"start":{"line":737,"column":38},"end":{"line":737,"column":46}},"locations":[{"start":{"line":737,"column":38},"end":{"line":737,"column":46}}]},"185":{"type":"branch","line":738,"loc":{"start":{"line":738,"column":21},"end":{"line":741,"column":7}},"locations":[{"start":{"line":738,"column":21},"end":{"line":741,"column":7}}]},"186":{"type":"branch","line":746,"loc":{"start":{"line":746,"column":26},"end":{"line":749,"column":7}},"locations":[{"start":{"line":746,"column":26},"end":{"line":749,"column":7}}]},"187":{"type":"branch","line":755,"loc":{"start":{"line":755,"column":6},"end":{"line":759,"column":7}},"locations":[{"start":{"line":755,"column":6},"end":{"line":759,"column":7}}]},"188":{"type":"branch","line":760,"loc":{"start":{"line":760,"column":4},"end":{"line":762,"column":5}},"locations":[{"start":{"line":760,"column":4},"end":{"line":762,"column":5}}]},"189":{"type":"branch","line":777,"loc":{"start":{"line":777,"column":42},"end":{"line":803,"column":5}},"locations":[{"start":{"line":777,"column":42},"end":{"line":803,"column":5}}]},"190":{"type":"branch","line":780,"loc":{"start":{"line":780,"column":56},"end":{"line":782,"column":5}},"locations":[{"start":{"line":780,"column":56},"end":{"line":782,"column":5}}]},"191":{"type":"branch","line":787,"loc":{"start":{"line":787,"column":20},"end":{"line":789,"column":5}},"locations":[{"start":{"line":787,"column":20},"end":{"line":789,"column":5}}]},"192":{"type":"branch","line":793,"loc":{"start":{"line":793,"column":23},"end":{"line":795,"column":7}},"locations":[{"start":{"line":793,"column":23},"end":{"line":795,"column":7}}]},"193":{"type":"branch","line":798,"loc":{"start":{"line":798,"column":4},"end":{"line":800,"column":6}},"locations":[{"start":{"line":798,"column":4},"end":{"line":800,"column":6}}]},"194":{"type":"branch","line":830,"loc":{"start":{"line":830,"column":21},"end":{"line":830,"column":50}},"locations":[{"start":{"line":830,"column":21},"end":{"line":830,"column":50}}]},"195":{"type":"branch","line":839,"loc":{"start":{"line":839,"column":21},"end":{"line":844,"column":14}},"locations":[{"start":{"line":839,"column":21},"end":{"line":844,"column":14}}]},"196":{"type":"branch","line":840,"loc":{"start":{"line":840,"column":39},"end":{"line":842,"column":15}},"locations":[{"start":{"line":840,"column":39},"end":{"line":842,"column":15}}]},"197":{"type":"branch","line":843,"loc":{"start":{"line":843,"column":30},"end":{"line":843,"column":45}},"locations":[{"start":{"line":843,"column":30},"end":{"line":843,"column":45}}]},"198":{"type":"branch","line":857,"loc":{"start":{"line":857,"column":25},"end":{"line":870,"column":34}},"locations":[{"start":{"line":857,"column":25},"end":{"line":870,"column":34}}]},"199":{"type":"branch","line":863,"loc":{"start":{"line":863,"column":27},"end":{"line":866,"column":20}},"locations":[{"start":{"line":863,"column":27},"end":{"line":866,"column":20}}]},"200":{"type":"branch","line":922,"loc":{"start":{"line":922,"column":23},"end":{"line":931,"column":16}},"locations":[{"start":{"line":922,"column":23},"end":{"line":931,"column":16}}]},"201":{"type":"branch","line":923,"loc":{"start":{"line":923,"column":58},"end":{"line":925,"column":17}},"locations":[{"start":{"line":923,"column":58},"end":{"line":925,"column":17}}]},"202":{"type":"branch","line":926,"loc":{"start":{"line":926,"column":33},"end":{"line":929,"column":17}},"locations":[{"start":{"line":926,"column":33},"end":{"line":929,"column":17}}]},"203":{"type":"branch","line":929,"loc":{"start":{"line":929,"column":16},"end":{"line":930,"column":53}},"locations":[{"start":{"line":929,"column":16},"end":{"line":930,"column":53}}]},"204":{"type":"branch","line":948,"loc":{"start":{"line":948,"column":23},"end":{"line":950,"column":16}},"locations":[{"start":{"line":948,"column":23},"end":{"line":950,"column":16}}]},"205":{"type":"branch","line":968,"loc":{"start":{"line":968,"column":38},"end":{"line":1028,"column":15}},"locations":[{"start":{"line":968,"column":38},"end":{"line":1028,"column":15}}]},"206":{"type":"branch","line":969,"loc":{"start":{"line":969,"column":37},"end":{"line":969,"column":61}},"locations":[{"start":{"line":969,"column":37},"end":{"line":969,"column":61}}]},"207":{"type":"branch","line":970,"loc":{"start":{"line":970,"column":83},"end":{"line":970,"column":91}},"locations":[{"start":{"line":970,"column":83},"end":{"line":970,"column":91}}]},"208":{"type":"branch","line":980,"loc":{"start":{"line":980,"column":38},"end":{"line":980,"column":75}},"locations":[{"start":{"line":980,"column":38},"end":{"line":980,"column":75}}]},"209":{"type":"branch","line":986,"loc":{"start":{"line":986,"column":25},"end":{"line":987,"column":54}},"locations":[{"start":{"line":986,"column":25},"end":{"line":987,"column":54}}]},"210":{"type":"branch","line":987,"loc":{"start":{"line":987,"column":52},"end":{"line":991,"column":48}},"locations":[{"start":{"line":987,"column":52},"end":{"line":991,"column":48}}]},"211":{"type":"branch","line":988,"loc":{"start":{"line":988,"column":28},"end":{"line":989,"column":91}},"locations":[{"start":{"line":988,"column":28},"end":{"line":989,"column":91}}]},"212":{"type":"branch","line":989,"loc":{"start":{"line":989,"column":89},"end":{"line":991,"column":48}},"locations":[{"start":{"line":989,"column":89},"end":{"line":991,"column":48}}]},"213":{"type":"branch","line":995,"loc":{"start":{"line":995,"column":23},"end":{"line":998,"column":31}},"locations":[{"start":{"line":995,"column":23},"end":{"line":998,"column":31}}]},"214":{"type":"branch","line":998,"loc":{"start":{"line":998,"column":24},"end":{"line":999,"column":31}},"locations":[{"start":{"line":998,"column":24},"end":{"line":999,"column":31}}]},"215":{"type":"branch","line":1001,"loc":{"start":{"line":1001,"column":47},"end":{"line":1024,"column":28}},"locations":[{"start":{"line":1001,"column":47},"end":{"line":1024,"column":28}}]},"216":{"type":"branch","line":1024,"loc":{"start":{"line":1024,"column":22},"end":{"line":1025,"column":29}},"locations":[{"start":{"line":1024,"column":22},"end":{"line":1025,"column":29}}]},"217":{"type":"branch","line":1003,"loc":{"start":{"line":1003,"column":46},"end":{"line":1023,"column":25}},"locations":[{"start":{"line":1003,"column":46},"end":{"line":1023,"column":25}}]},"218":{"type":"branch","line":1007,"loc":{"start":{"line":1007,"column":54},"end":{"line":1007,"column":69}},"locations":[{"start":{"line":1007,"column":54},"end":{"line":1007,"column":69}}]},"219":{"type":"branch","line":1045,"loc":{"start":{"line":1045,"column":19},"end":{"line":1045,"column":49}},"locations":[{"start":{"line":1045,"column":19},"end":{"line":1045,"column":49}}]}},"b":{"0":[28],"1":[0],"2":[0],"3":[0],"4":[0],"5":[0],"6":[0],"7":[0],"8":[0],"9":[45],"10":[1],"11":[44],"12":[15],"13":[29],"14":[348],"15":[84],"16":[40],"17":[14],"18":[334],"19":[59],"20":[275],"21":[106],"22":[169],"23":[112],"24":[0],"25":[173],"26":[0],"27":[212],"28":[104],"29":[108],"30":[4],"31":[104],"32":[59],"33":[45],"34":[248],"35":[230],"36":[34],"37":[18],"38":[212],"39":[104],"40":[16],"41":[4],"42":[0],"43":[208],"44":[4],"45":[3],"46":[1],"47":[1],"48":[3],"49":[1],"50":[3],"51":[0],"52":[1],"53":[4],"54":[1],"55":[0],"56":[4],"57":[4],"58":[5],"59":[1],"60":[5],"61":[3],"62":[2],"63":[1],"64":[240],"65":[0],"66":[0],"67":[93],"68":[231],"69":[132],"70":[0],"71":[108],"72":[9],"73":[30],"74":[210],"75":[132],"76":[108],"77":[132],"78":[108],"79":[30],"80":[132],"81":[19],"82":[113],"83":[108],"84":[231],"85":[41],"86":[199],"87":[9],"88":[231],"89":[99],"90":[132],"91":[41],"92":[91],"93":[41],"94":[199],"95":[231],"96":[132],"97":[9],"98":[231],"99":[99],"100":[132],"101":[1],"102":[239],"103":[1],"104":[239],"105":[9],"106":[231],"107":[132],"108":[99],"109":[4],"110":[65],"111":[0],"112":[64],"113":[64],"114":[3],"115":[2],"116":[0],"117":[33],"118":[31],"119":[2],"120":[0],"121":[0],"122":[2],"123":[0],"124":[0],"125":[2],"126":[2],"127":[32],"128":[32],"129":[0],"130":[32],"131":[32],"132":[3],"133":[29],"134":[3],"135":[29],"136":[0],"137":[29],"138":[182],"139":[0],"140":[0],"141":[32],"142":[3],"143":[29],"144":[3],"145":[181],"146":[0],"147":[29],"148":[66],"149":[28],"150":[45],"151":[1],"152":[0],"153":[1],"154":[1],"155":[0],"156":[1],"157":[132],"158":[32],"159":[29],"160":[3],"161":[91],"162":[64],"163":[27],"164":[0],"165":[27],"166":[61],"167":[58],"168":[36],"169":[25],"170":[0],"171":[25],"172":[36],"173":[176],"174":[0],"175":[0],"176":[25],"177":[32],"178":[31],"179":[57],"180":[1],"181":[0],"182":[0],"183":[0],"184":[0],"185":[0],"186":[0],"187":[0],"188":[0],"189":[1],"190":[0],"191":[0],"192":[0],"193":[0],"194":[4],"195":[27],"196":[0],"197":[27],"198":[26],"199":[25],"200":[40],"201":[0],"202":[18],"203":[22],"204":[1],"205":[230],"206":[34],"207":[108],"208":[18],"209":[6],"210":[224],"211":[103],"212":[121],"213":[18],"214":[212],"215":[122],"216":[108],"217":[348],"218":[0],"219":[3]},"fnMap":{"0":{"name":"formatPlanLabel","decl":{"start":{"line":142,"column":0},"end":{"line":158,"column":1}},"loc":{"start":{"line":142,"column":0},"end":{"line":158,"column":1}},"line":142},"1":{"name":"mapForgeItemStatus","decl":{"start":{"line":160,"column":0},"end":{"line":169,"column":1}},"loc":{"start":{"line":160,"column":0},"end":{"line":169,"column":1}},"line":160},"2":{"name":"mapForgePhaseChipState","decl":{"start":{"line":171,"column":0},"end":{"line":188,"column":1}},"loc":{"start":{"line":171,"column":0},"end":{"line":188,"column":1}},"line":171},"3":{"name":"allTaskPhasesCompleted","decl":{"start":{"line":190,"column":0},"end":{"line":206,"column":1}},"loc":{"start":{"line":190,"column":0},"end":{"line":206,"column":1}},"line":190},"4":{"name":"deriveStatusFromTaskPhases","decl":{"start":{"line":208,"column":0},"end":{"line":223,"column":1}},"loc":{"start":{"line":208,"column":0},"end":{"line":223,"column":1}},"line":208},"5":{"name":"resolveForgeTaskRowStatus","decl":{"start":{"line":225,"column":0},"end":{"line":252,"column":1}},"loc":{"start":{"line":225,"column":0},"end":{"line":252,"column":1}},"line":225},"6":{"name":"ForgeTemplatesModal","decl":{"start":{"line":254,"column":0},"end":{"line":372,"column":1}},"loc":{"start":{"line":254,"column":0},"end":{"line":372,"column":1}},"line":254},"7":{"name":"handleKeyDown","decl":{"start":{"line":270,"column":26},"end":{"line":276,"column":6}},"loc":{"start":{"line":270,"column":26},"end":{"line":276,"column":6}},"line":270},"8":{"name":"onClick","decl":{"start":{"line":318,"column":25},"end":{"line":320,"column":18}},"loc":{"start":{"line":318,"column":25},"end":{"line":320,"column":18}},"line":318},"9":{"name":"onClick","decl":{"start":{"line":327,"column":25},"end":{"line":330,"column":18}},"loc":{"start":{"line":327,"column":25},"end":{"line":330,"column":18}},"line":327},"10":{"name":"onClick","decl":{"start":{"line":352,"column":27},"end":{"line":355,"column":20}},"loc":{"start":{"line":352,"column":27},"end":{"line":355,"column":20}},"line":352},"11":{"name":"Forge","decl":{"start":{"line":374,"column":7},"end":{"line":1050,"column":1}},"loc":{"start":{"line":374,"column":7},"end":{"line":1050,"column":1}},"line":374},"12":{"name":"loadPlans","decl":{"start":{"line":541,"column":22},"end":{"line":546,"column":6}},"loc":{"start":{"line":541,"column":22},"end":{"line":546,"column":6}},"line":541},"13":{"name":"onClose","decl":{"start":{"line":618,"column":13},"end":{"line":618,"column":42}},"loc":{"start":{"line":618,"column":13},"end":{"line":618,"column":42}},"line":618},"14":{"name":"installedTemplateId","decl":{"start":{"line":641,"column":13},"end":{"line":643,"column":8}},"loc":{"start":{"line":641,"column":13},"end":{"line":643,"column":8}},"line":641},"15":{"name":"refreshPhaseView","decl":{"start":{"line":647,"column":29},"end":{"line":665,"column":6}},"loc":{"start":{"line":647,"column":29},"end":{"line":665,"column":6}},"line":647},"16":{"name":"onClick","decl":{"start":{"line":830,"column":21},"end":{"line":830,"column":50}},"loc":{"start":{"line":830,"column":21},"end":{"line":830,"column":50}},"line":830},"17":{"name":"onClick","decl":{"start":{"line":839,"column":21},"end":{"line":844,"column":14}},"loc":{"start":{"line":839,"column":21},"end":{"line":844,"column":14}},"line":839},"18":{"name":"onClick","decl":{"start":{"line":863,"column":27},"end":{"line":866,"column":20}},"loc":{"start":{"line":863,"column":27},"end":{"line":866,"column":20}},"line":863},"19":{"name":"onClick","decl":{"start":{"line":874,"column":25},"end":{"line":877,"column":18}},"loc":{"start":{"line":874,"column":25},"end":{"line":877,"column":18}},"line":874},"20":{"name":"onClick","decl":{"start":{"line":922,"column":23},"end":{"line":931,"column":16}},"loc":{"start":{"line":922,"column":23},"end":{"line":931,"column":16}},"line":922},"21":{"name":"onClick","decl":{"start":{"line":948,"column":23},"end":{"line":950,"column":16}},"loc":{"start":{"line":948,"column":23},"end":{"line":950,"column":16}},"line":948},"22":{"name":"onClose","decl":{"start":{"line":1045,"column":19},"end":{"line":1045,"column":49}},"loc":{"start":{"line":1045,"column":19},"end":{"line":1045,"column":49}},"line":1045}},"f":{"0":28,"1":45,"2":348,"3":112,"4":212,"5":230,"6":4,"7":1,"8":0,"9":1,"10":1,"11":240,"12":181,"13":0,"14":36,"15":176,"16":4,"17":27,"18":25,"19":0,"20":40,"21":1,"22":3}} +{"/Users/lstern/projects/forge/src/features/forge/components/Forge.tsx": {"path":"/Users/lstern/projects/forge/src/features/forge/components/Forge.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":70}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":67}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":56}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":56}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":63}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":73}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":54}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":52}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":74}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":77}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":8}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":72}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":8}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":8}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":63}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":70}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":59}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":50}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":50}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":40}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":44}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":2}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":51}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":28}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":36}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":36}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":42}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":54}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":46}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":38}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":38}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":16}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":19}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":14}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":18}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":2}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":42}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":13}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":30}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":2}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":60}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":41}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":39}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":35}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":20}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":30}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":3}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":14}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":17}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":3}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":19}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":66}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":24}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":34}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":3}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":44}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":1}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":62}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":49}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":35}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":23}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":3}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":37}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":24}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":3}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":19}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":1}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":32}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":17}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":18}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":36}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":32}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":24}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":60}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":74}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":24}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":3}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":43}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":24}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":3}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":41}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":25}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":3}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":22}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":1}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":32}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":58}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":35}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":12}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":26}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":24}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":16}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":75}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":20}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":6}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":3}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":57}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":10}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":31}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":80}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":1}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":36}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":58}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":35}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":27}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":57}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":35}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":16}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":3}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":58}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":23}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":3}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":86}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":24}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":3}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":19}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":1}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":36}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":9}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":17}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":20}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":9}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":14}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":4}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":21}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":39}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":24}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":3}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":83}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":62}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":55}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":60}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":19}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":18}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":3}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":24}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":1}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":30}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":12}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":20}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":12}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":20}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":22}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":10}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":4}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":4}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":19}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":53}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":35}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":15}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":7}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":29}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":16}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":6}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":54}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":70}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":16}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":37}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":80}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":50}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":53}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":60}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":7}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":11}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":26}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":52}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":16}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":10}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":15}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":39}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":31}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":33}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":75}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":66}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":12}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":42}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":56}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":22}},"304":{"start":{"line":305,"column":0},"end":{"line":305,"column":62}},"305":{"start":{"line":306,"column":0},"end":{"line":306,"column":49}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":74}},"307":{"start":{"line":308,"column":0},"end":{"line":308,"column":51}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":77}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":20}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":18}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":52}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":21}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":29}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":53}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":42}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":37}},"317":{"start":{"line":318,"column":0},"end":{"line":318,"column":32}},"319":{"start":{"line":320,"column":0},"end":{"line":320,"column":18}},"321":{"start":{"line":322,"column":0},"end":{"line":322,"column":38}},"322":{"start":{"line":323,"column":0},"end":{"line":323,"column":23}},"323":{"start":{"line":324,"column":0},"end":{"line":324,"column":21}},"324":{"start":{"line":325,"column":0},"end":{"line":325,"column":29}},"325":{"start":{"line":326,"column":0},"end":{"line":326,"column":55}},"326":{"start":{"line":327,"column":0},"end":{"line":327,"column":32}},"327":{"start":{"line":328,"column":0},"end":{"line":328,"column":40}},"328":{"start":{"line":329,"column":0},"end":{"line":329,"column":28}},"329":{"start":{"line":330,"column":0},"end":{"line":330,"column":18}},"330":{"start":{"line":331,"column":0},"end":{"line":331,"column":37}},"331":{"start":{"line":332,"column":0},"end":{"line":332,"column":15}},"333":{"start":{"line":334,"column":0},"end":{"line":334,"column":23}},"334":{"start":{"line":335,"column":0},"end":{"line":335,"column":18}},"335":{"start":{"line":336,"column":0},"end":{"line":336,"column":16}},"337":{"start":{"line":338,"column":0},"end":{"line":338,"column":76}},"340":{"start":{"line":341,"column":0},"end":{"line":341,"column":35}},"341":{"start":{"line":342,"column":0},"end":{"line":342,"column":61}},"342":{"start":{"line":343,"column":0},"end":{"line":343,"column":18}},"343":{"start":{"line":344,"column":0},"end":{"line":344,"column":82}},"344":{"start":{"line":345,"column":0},"end":{"line":345,"column":51}},"345":{"start":{"line":346,"column":0},"end":{"line":346,"column":75}},"346":{"start":{"line":347,"column":0},"end":{"line":347,"column":20}},"347":{"start":{"line":348,"column":0},"end":{"line":348,"column":54}},"348":{"start":{"line":349,"column":0},"end":{"line":349,"column":23}},"349":{"start":{"line":350,"column":0},"end":{"line":350,"column":31}},"350":{"start":{"line":351,"column":0},"end":{"line":351,"column":57}},"351":{"start":{"line":352,"column":0},"end":{"line":352,"column":34}},"352":{"start":{"line":353,"column":0},"end":{"line":353,"column":51}},"353":{"start":{"line":354,"column":0},"end":{"line":354,"column":30}},"354":{"start":{"line":355,"column":0},"end":{"line":355,"column":20}},"355":{"start":{"line":356,"column":0},"end":{"line":356,"column":39}},"357":{"start":{"line":358,"column":0},"end":{"line":358,"column":31}},"358":{"start":{"line":359,"column":0},"end":{"line":359,"column":25}},"359":{"start":{"line":360,"column":0},"end":{"line":360,"column":20}},"360":{"start":{"line":361,"column":0},"end":{"line":361,"column":18}},"362":{"start":{"line":363,"column":0},"end":{"line":363,"column":11}},"363":{"start":{"line":364,"column":0},"end":{"line":364,"column":12}},"364":{"start":{"line":365,"column":0},"end":{"line":365,"column":64}},"365":{"start":{"line":366,"column":0},"end":{"line":366,"column":82}},"367":{"start":{"line":368,"column":0},"end":{"line":368,"column":17}},"368":{"start":{"line":369,"column":0},"end":{"line":369,"column":12}},"369":{"start":{"line":370,"column":0},"end":{"line":370,"column":17}},"371":{"start":{"line":372,"column":0},"end":{"line":372,"column":1}},"373":{"start":{"line":374,"column":0},"end":{"line":374,"column":23}},"374":{"start":{"line":375,"column":0},"end":{"line":375,"column":20}},"375":{"start":{"line":376,"column":0},"end":{"line":376,"column":25}},"376":{"start":{"line":377,"column":0},"end":{"line":377,"column":26}},"377":{"start":{"line":378,"column":0},"end":{"line":378,"column":18}},"378":{"start":{"line":379,"column":0},"end":{"line":379,"column":14}},"379":{"start":{"line":380,"column":0},"end":{"line":380,"column":17}},"380":{"start":{"line":381,"column":0},"end":{"line":381,"column":26}},"381":{"start":{"line":382,"column":0},"end":{"line":382,"column":28}},"382":{"start":{"line":383,"column":0},"end":{"line":383,"column":4}},"399":{"start":{"line":400,"column":0},"end":{"line":400,"column":4}},"400":{"start":{"line":401,"column":0},"end":{"line":401,"column":64}},"401":{"start":{"line":402,"column":0},"end":{"line":402,"column":58}},"402":{"start":{"line":403,"column":0},"end":{"line":403,"column":59}},"403":{"start":{"line":404,"column":0},"end":{"line":404,"column":59}},"404":{"start":{"line":405,"column":0},"end":{"line":405,"column":49}},"405":{"start":{"line":406,"column":0},"end":{"line":406,"column":53}},"406":{"start":{"line":407,"column":0},"end":{"line":407,"column":39}},"407":{"start":{"line":408,"column":0},"end":{"line":408,"column":69}},"408":{"start":{"line":409,"column":0},"end":{"line":409,"column":47}},"409":{"start":{"line":410,"column":0},"end":{"line":410,"column":53}},"410":{"start":{"line":411,"column":0},"end":{"line":411,"column":65}},"411":{"start":{"line":412,"column":0},"end":{"line":412,"column":57}},"412":{"start":{"line":413,"column":0},"end":{"line":413,"column":49}},"413":{"start":{"line":414,"column":0},"end":{"line":414,"column":49}},"414":{"start":{"line":415,"column":0},"end":{"line":415,"column":51}},"415":{"start":{"line":416,"column":0},"end":{"line":416,"column":58}},"416":{"start":{"line":417,"column":0},"end":{"line":417,"column":50}},"417":{"start":{"line":418,"column":0},"end":{"line":418,"column":63}},"418":{"start":{"line":419,"column":0},"end":{"line":419,"column":64}},"420":{"start":{"line":421,"column":0},"end":{"line":421,"column":44}},"421":{"start":{"line":422,"column":0},"end":{"line":422,"column":25}},"422":{"start":{"line":423,"column":0},"end":{"line":423,"column":53}},"423":{"start":{"line":424,"column":0},"end":{"line":424,"column":24}},"424":{"start":{"line":425,"column":0},"end":{"line":425,"column":20}},"425":{"start":{"line":426,"column":0},"end":{"line":426,"column":7}},"426":{"start":{"line":427,"column":0},"end":{"line":427,"column":14}},"427":{"start":{"line":428,"column":0},"end":{"line":428,"column":32}},"428":{"start":{"line":429,"column":0},"end":{"line":429,"column":64}},"429":{"start":{"line":430,"column":0},"end":{"line":430,"column":12}},"430":{"start":{"line":431,"column":0},"end":{"line":431,"column":32}},"431":{"start":{"line":432,"column":0},"end":{"line":432,"column":79}},"432":{"start":{"line":433,"column":0},"end":{"line":433,"column":12}},"433":{"start":{"line":434,"column":0},"end":{"line":434,"column":12}},"435":{"start":{"line":436,"column":0},"end":{"line":436,"column":6}},"436":{"start":{"line":437,"column":0},"end":{"line":437,"column":25}},"437":{"start":{"line":438,"column":0},"end":{"line":438,"column":4}},"439":{"start":{"line":440,"column":0},"end":{"line":440,"column":55}},"440":{"start":{"line":441,"column":0},"end":{"line":441,"column":47}},"441":{"start":{"line":442,"column":0},"end":{"line":442,"column":18}},"442":{"start":{"line":443,"column":0},"end":{"line":443,"column":20}},"443":{"start":{"line":444,"column":0},"end":{"line":444,"column":7}},"444":{"start":{"line":445,"column":0},"end":{"line":445,"column":45}},"445":{"start":{"line":446,"column":0},"end":{"line":446,"column":23}},"446":{"start":{"line":447,"column":0},"end":{"line":447,"column":20}},"447":{"start":{"line":448,"column":0},"end":{"line":448,"column":7}},"448":{"start":{"line":449,"column":0},"end":{"line":449,"column":51}},"449":{"start":{"line":450,"column":0},"end":{"line":450,"column":24}},"452":{"start":{"line":453,"column":0},"end":{"line":453,"column":20}},"453":{"start":{"line":454,"column":0},"end":{"line":454,"column":7}},"454":{"start":{"line":455,"column":0},"end":{"line":455,"column":49}},"455":{"start":{"line":456,"column":0},"end":{"line":456,"column":67}},"456":{"start":{"line":457,"column":0},"end":{"line":457,"column":26}},"457":{"start":{"line":458,"column":0},"end":{"line":458,"column":8}},"458":{"start":{"line":459,"column":0},"end":{"line":459,"column":42}},"459":{"start":{"line":460,"column":0},"end":{"line":460,"column":57}},"460":{"start":{"line":461,"column":0},"end":{"line":461,"column":7}},"461":{"start":{"line":462,"column":0},"end":{"line":462,"column":43}},"462":{"start":{"line":463,"column":0},"end":{"line":463,"column":6}},"463":{"start":{"line":464,"column":0},"end":{"line":464,"column":7}},"464":{"start":{"line":465,"column":0},"end":{"line":465,"column":4}},"466":{"start":{"line":467,"column":0},"end":{"line":467,"column":77}},"467":{"start":{"line":468,"column":0},"end":{"line":468,"column":93}},"468":{"start":{"line":469,"column":0},"end":{"line":469,"column":81}},"469":{"start":{"line":470,"column":0},"end":{"line":470,"column":72}},"470":{"start":{"line":471,"column":0},"end":{"line":471,"column":41}},"472":{"start":{"line":473,"column":0},"end":{"line":473,"column":19}},"473":{"start":{"line":474,"column":0},"end":{"line":474,"column":26}},"474":{"start":{"line":475,"column":0},"end":{"line":475,"column":31}},"475":{"start":{"line":476,"column":0},"end":{"line":476,"column":24}},"476":{"start":{"line":477,"column":0},"end":{"line":477,"column":24}},"477":{"start":{"line":478,"column":0},"end":{"line":478,"column":17}},"478":{"start":{"line":479,"column":0},"end":{"line":479,"column":9}},"479":{"start":{"line":480,"column":0},"end":{"line":480,"column":28}},"480":{"start":{"line":481,"column":0},"end":{"line":481,"column":8}},"481":{"start":{"line":482,"column":0},"end":{"line":482,"column":25}},"482":{"start":{"line":483,"column":0},"end":{"line":483,"column":67}},"483":{"start":{"line":484,"column":0},"end":{"line":484,"column":9}},"484":{"start":{"line":485,"column":0},"end":{"line":485,"column":18}},"485":{"start":{"line":486,"column":0},"end":{"line":486,"column":23}},"486":{"start":{"line":487,"column":0},"end":{"line":487,"column":6}},"487":{"start":{"line":488,"column":0},"end":{"line":488,"column":29}},"489":{"start":{"line":490,"column":0},"end":{"line":490,"column":19}},"490":{"start":{"line":491,"column":0},"end":{"line":491,"column":26}},"491":{"start":{"line":492,"column":0},"end":{"line":492,"column":29}},"492":{"start":{"line":493,"column":0},"end":{"line":493,"column":33}},"493":{"start":{"line":494,"column":0},"end":{"line":494,"column":28}},"494":{"start":{"line":495,"column":0},"end":{"line":495,"column":20}},"495":{"start":{"line":496,"column":0},"end":{"line":496,"column":25}},"496":{"start":{"line":497,"column":0},"end":{"line":497,"column":8}},"497":{"start":{"line":498,"column":0},"end":{"line":498,"column":5}},"498":{"start":{"line":499,"column":0},"end":{"line":499,"column":48}},"499":{"start":{"line":500,"column":0},"end":{"line":500,"column":28}},"500":{"start":{"line":501,"column":0},"end":{"line":501,"column":24}},"501":{"start":{"line":502,"column":0},"end":{"line":502,"column":17}},"502":{"start":{"line":503,"column":0},"end":{"line":503,"column":9}},"503":{"start":{"line":504,"column":0},"end":{"line":504,"column":40}},"504":{"start":{"line":505,"column":0},"end":{"line":505,"column":8}},"505":{"start":{"line":506,"column":0},"end":{"line":506,"column":25}},"506":{"start":{"line":507,"column":0},"end":{"line":507,"column":76}},"507":{"start":{"line":508,"column":0},"end":{"line":508,"column":9}},"508":{"start":{"line":509,"column":0},"end":{"line":509,"column":18}},"509":{"start":{"line":510,"column":0},"end":{"line":510,"column":23}},"510":{"start":{"line":511,"column":0},"end":{"line":511,"column":6}},"511":{"start":{"line":512,"column":0},"end":{"line":512,"column":48}},"513":{"start":{"line":514,"column":0},"end":{"line":514,"column":35}},"514":{"start":{"line":515,"column":0},"end":{"line":515,"column":36}},"515":{"start":{"line":516,"column":0},"end":{"line":516,"column":37}},"516":{"start":{"line":517,"column":0},"end":{"line":517,"column":15}},"517":{"start":{"line":518,"column":0},"end":{"line":518,"column":7}},"518":{"start":{"line":519,"column":0},"end":{"line":519,"column":38}},"519":{"start":{"line":520,"column":0},"end":{"line":520,"column":11}},"520":{"start":{"line":521,"column":0},"end":{"line":521,"column":50}},"521":{"start":{"line":522,"column":0},"end":{"line":522,"column":32}},"522":{"start":{"line":523,"column":0},"end":{"line":523,"column":23}},"523":{"start":{"line":524,"column":0},"end":{"line":524,"column":63}},"524":{"start":{"line":525,"column":0},"end":{"line":525,"column":17}},"525":{"start":{"line":526,"column":0},"end":{"line":526,"column":41}},"526":{"start":{"line":527,"column":0},"end":{"line":527,"column":7}},"527":{"start":{"line":528,"column":0},"end":{"line":528,"column":6}},"528":{"start":{"line":529,"column":0},"end":{"line":529,"column":16}},"529":{"start":{"line":530,"column":0},"end":{"line":530,"column":4}},"531":{"start":{"line":532,"column":0},"end":{"line":532,"column":19}},"532":{"start":{"line":533,"column":0},"end":{"line":533,"column":26}},"533":{"start":{"line":534,"column":0},"end":{"line":534,"column":29}},"534":{"start":{"line":535,"column":0},"end":{"line":535,"column":28}},"535":{"start":{"line":536,"column":0},"end":{"line":536,"column":20}},"536":{"start":{"line":537,"column":0},"end":{"line":537,"column":25}},"537":{"start":{"line":538,"column":0},"end":{"line":538,"column":8}},"538":{"start":{"line":539,"column":0},"end":{"line":539,"column":5}},"540":{"start":{"line":541,"column":0},"end":{"line":541,"column":35}},"541":{"start":{"line":542,"column":0},"end":{"line":542,"column":22}},"542":{"start":{"line":543,"column":0},"end":{"line":543,"column":15}},"543":{"start":{"line":544,"column":0},"end":{"line":544,"column":7}},"544":{"start":{"line":545,"column":0},"end":{"line":545,"column":44}},"545":{"start":{"line":546,"column":0},"end":{"line":546,"column":6}},"547":{"start":{"line":548,"column":0},"end":{"line":548,"column":21}},"548":{"start":{"line":549,"column":0},"end":{"line":549,"column":57}},"549":{"start":{"line":550,"column":0},"end":{"line":550,"column":18}},"550":{"start":{"line":551,"column":0},"end":{"line":551,"column":23}},"551":{"start":{"line":552,"column":0},"end":{"line":552,"column":37}},"552":{"start":{"line":553,"column":0},"end":{"line":553,"column":6}},"553":{"start":{"line":554,"column":0},"end":{"line":554,"column":40}},"555":{"start":{"line":556,"column":0},"end":{"line":556,"column":44}},"556":{"start":{"line":557,"column":0},"end":{"line":557,"column":41}},"557":{"start":{"line":558,"column":0},"end":{"line":558,"column":63}},"558":{"start":{"line":559,"column":0},"end":{"line":559,"column":55}},"559":{"start":{"line":560,"column":0},"end":{"line":560,"column":16}},"560":{"start":{"line":561,"column":0},"end":{"line":561,"column":22}},"561":{"start":{"line":562,"column":0},"end":{"line":562,"column":27}},"562":{"start":{"line":563,"column":0},"end":{"line":563,"column":17}},"563":{"start":{"line":564,"column":0},"end":{"line":564,"column":10}},"564":{"start":{"line":565,"column":0},"end":{"line":565,"column":9}},"566":{"start":{"line":567,"column":0},"end":{"line":567,"column":14}},"567":{"start":{"line":568,"column":0},"end":{"line":568,"column":20}},"568":{"start":{"line":569,"column":0},"end":{"line":569,"column":36}},"569":{"start":{"line":570,"column":0},"end":{"line":570,"column":14}},"570":{"start":{"line":571,"column":0},"end":{"line":571,"column":8}},"571":{"start":{"line":572,"column":0},"end":{"line":572,"column":7}},"572":{"start":{"line":573,"column":0},"end":{"line":573,"column":23}},"574":{"start":{"line":575,"column":0},"end":{"line":575,"column":44}},"575":{"start":{"line":576,"column":0},"end":{"line":576,"column":29}},"576":{"start":{"line":577,"column":0},"end":{"line":577,"column":31}},"577":{"start":{"line":578,"column":0},"end":{"line":578,"column":15}},"578":{"start":{"line":579,"column":0},"end":{"line":579,"column":7}},"579":{"start":{"line":580,"column":0},"end":{"line":580,"column":57}},"580":{"start":{"line":581,"column":0},"end":{"line":581,"column":25}},"581":{"start":{"line":582,"column":0},"end":{"line":582,"column":37}},"582":{"start":{"line":583,"column":0},"end":{"line":583,"column":10}},"583":{"start":{"line":584,"column":0},"end":{"line":584,"column":27}},"584":{"start":{"line":585,"column":0},"end":{"line":585,"column":71}},"585":{"start":{"line":586,"column":0},"end":{"line":586,"column":11}},"586":{"start":{"line":587,"column":0},"end":{"line":587,"column":6}},"587":{"start":{"line":588,"column":0},"end":{"line":588,"column":41}},"588":{"start":{"line":589,"column":0},"end":{"line":589,"column":4}},"590":{"start":{"line":591,"column":0},"end":{"line":591,"column":53}},"591":{"start":{"line":592,"column":0},"end":{"line":592,"column":29}},"592":{"start":{"line":593,"column":0},"end":{"line":593,"column":13}},"593":{"start":{"line":594,"column":0},"end":{"line":594,"column":5}},"594":{"start":{"line":595,"column":0},"end":{"line":595,"column":45}},"595":{"start":{"line":596,"column":0},"end":{"line":596,"column":19}},"596":{"start":{"line":597,"column":0},"end":{"line":597,"column":35}},"597":{"start":{"line":598,"column":0},"end":{"line":598,"column":8}},"598":{"start":{"line":599,"column":0},"end":{"line":599,"column":25}},"599":{"start":{"line":600,"column":0},"end":{"line":600,"column":71}},"600":{"start":{"line":601,"column":0},"end":{"line":601,"column":9}},"601":{"start":{"line":602,"column":0},"end":{"line":602,"column":45}},"603":{"start":{"line":604,"column":0},"end":{"line":604,"column":76}},"604":{"start":{"line":605,"column":0},"end":{"line":605,"column":37}},"605":{"start":{"line":606,"column":0},"end":{"line":606,"column":56}},"606":{"start":{"line":607,"column":0},"end":{"line":607,"column":11}},"607":{"start":{"line":608,"column":0},"end":{"line":608,"column":79}},"609":{"start":{"line":610,"column":0},"end":{"line":610,"column":58}},"610":{"start":{"line":611,"column":0},"end":{"line":611,"column":58}},"612":{"start":{"line":613,"column":0},"end":{"line":613,"column":60}},"614":{"start":{"line":615,"column":0},"end":{"line":615,"column":22}},"615":{"start":{"line":616,"column":0},"end":{"line":616,"column":25}},"616":{"start":{"line":617,"column":0},"end":{"line":617,"column":30}},"617":{"start":{"line":618,"column":0},"end":{"line":618,"column":42}},"618":{"start":{"line":619,"column":0},"end":{"line":619,"column":5}},"620":{"start":{"line":621,"column":0},"end":{"line":621,"column":19}},"621":{"start":{"line":622,"column":0},"end":{"line":622,"column":29}},"622":{"start":{"line":623,"column":0},"end":{"line":623,"column":13}},"623":{"start":{"line":624,"column":0},"end":{"line":624,"column":5}},"624":{"start":{"line":625,"column":0},"end":{"line":625,"column":27}},"625":{"start":{"line":626,"column":0},"end":{"line":626,"column":27}},"627":{"start":{"line":628,"column":0},"end":{"line":628,"column":19}},"628":{"start":{"line":629,"column":0},"end":{"line":629,"column":26}},"629":{"start":{"line":630,"column":0},"end":{"line":630,"column":13}},"630":{"start":{"line":631,"column":0},"end":{"line":631,"column":5}},"631":{"start":{"line":632,"column":0},"end":{"line":632,"column":60}},"632":{"start":{"line":633,"column":0},"end":{"line":633,"column":30}},"633":{"start":{"line":634,"column":0},"end":{"line":634,"column":5}},"634":{"start":{"line":635,"column":0},"end":{"line":635,"column":30}},"636":{"start":{"line":637,"column":0},"end":{"line":637,"column":19}},"637":{"start":{"line":638,"column":0},"end":{"line":638,"column":26}},"638":{"start":{"line":639,"column":0},"end":{"line":639,"column":48}},"639":{"start":{"line":640,"column":0},"end":{"line":640,"column":37}},"640":{"start":{"line":641,"column":0},"end":{"line":641,"column":20}},"641":{"start":{"line":642,"column":0},"end":{"line":642,"column":25}},"642":{"start":{"line":643,"column":0},"end":{"line":643,"column":8}},"643":{"start":{"line":644,"column":0},"end":{"line":644,"column":5}},"645":{"start":{"line":646,"column":0},"end":{"line":646,"column":79}},"646":{"start":{"line":647,"column":0},"end":{"line":647,"column":42}},"647":{"start":{"line":648,"column":0},"end":{"line":648,"column":11}},"648":{"start":{"line":649,"column":0},"end":{"line":649,"column":41}},"649":{"start":{"line":650,"column":0},"end":{"line":650,"column":28}},"650":{"start":{"line":651,"column":0},"end":{"line":651,"column":25}},"651":{"start":{"line":652,"column":0},"end":{"line":652,"column":30}},"652":{"start":{"line":653,"column":0},"end":{"line":653,"column":10}},"653":{"start":{"line":654,"column":0},"end":{"line":654,"column":24}},"654":{"start":{"line":655,"column":0},"end":{"line":655,"column":17}},"655":{"start":{"line":656,"column":0},"end":{"line":656,"column":9}},"656":{"start":{"line":657,"column":0},"end":{"line":657,"column":27}},"657":{"start":{"line":658,"column":0},"end":{"line":658,"column":23}},"658":{"start":{"line":659,"column":0},"end":{"line":659,"column":24}},"659":{"start":{"line":660,"column":0},"end":{"line":660,"column":17}},"660":{"start":{"line":661,"column":0},"end":{"line":661,"column":9}},"661":{"start":{"line":662,"column":0},"end":{"line":662,"column":68}},"662":{"start":{"line":663,"column":0},"end":{"line":663,"column":39}},"663":{"start":{"line":664,"column":0},"end":{"line":664,"column":7}},"664":{"start":{"line":665,"column":0},"end":{"line":665,"column":6}},"666":{"start":{"line":667,"column":0},"end":{"line":667,"column":28}},"667":{"start":{"line":668,"column":0},"end":{"line":668,"column":64}},"668":{"start":{"line":669,"column":0},"end":{"line":669,"column":18}},"669":{"start":{"line":670,"column":0},"end":{"line":670,"column":23}},"670":{"start":{"line":671,"column":0},"end":{"line":671,"column":37}},"671":{"start":{"line":672,"column":0},"end":{"line":672,"column":6}},"672":{"start":{"line":673,"column":0},"end":{"line":673,"column":6}},"673":{"start":{"line":674,"column":0},"end":{"line":674,"column":22}},"674":{"start":{"line":675,"column":0},"end":{"line":675,"column":43}},"675":{"start":{"line":676,"column":0},"end":{"line":676,"column":18}},"676":{"start":{"line":677,"column":0},"end":{"line":677,"column":19}},"677":{"start":{"line":678,"column":0},"end":{"line":678,"column":5}},"679":{"start":{"line":680,"column":0},"end":{"line":680,"column":39}},"680":{"start":{"line":681,"column":0},"end":{"line":681,"column":16}},"681":{"start":{"line":682,"column":0},"end":{"line":682,"column":41}},"682":{"start":{"line":683,"column":0},"end":{"line":683,"column":38}},"683":{"start":{"line":684,"column":0},"end":{"line":684,"column":30}},"684":{"start":{"line":685,"column":0},"end":{"line":685,"column":11}},"685":{"start":{"line":686,"column":0},"end":{"line":686,"column":50}},"686":{"start":{"line":687,"column":0},"end":{"line":687,"column":84}},"687":{"start":{"line":688,"column":0},"end":{"line":688,"column":38}},"688":{"start":{"line":689,"column":0},"end":{"line":689,"column":61}},"689":{"start":{"line":690,"column":0},"end":{"line":690,"column":19}},"690":{"start":{"line":691,"column":0},"end":{"line":691,"column":4}},"692":{"start":{"line":693,"column":0},"end":{"line":693,"column":9}},"693":{"start":{"line":694,"column":0},"end":{"line":694,"column":16}},"694":{"start":{"line":695,"column":0},"end":{"line":695,"column":16}},"695":{"start":{"line":696,"column":0},"end":{"line":696,"column":14}},"696":{"start":{"line":697,"column":0},"end":{"line":697,"column":19}},"697":{"start":{"line":698,"column":0},"end":{"line":698,"column":19}},"698":{"start":{"line":699,"column":0},"end":{"line":699,"column":25}},"699":{"start":{"line":700,"column":0},"end":{"line":700,"column":35}},"700":{"start":{"line":701,"column":0},"end":{"line":701,"column":38}},"701":{"start":{"line":702,"column":0},"end":{"line":702,"column":44}},"702":{"start":{"line":703,"column":0},"end":{"line":703,"column":21}},"703":{"start":{"line":704,"column":0},"end":{"line":704,"column":23}},"704":{"start":{"line":705,"column":0},"end":{"line":705,"column":19}},"705":{"start":{"line":706,"column":0},"end":{"line":706,"column":19}},"706":{"start":{"line":707,"column":0},"end":{"line":707,"column":37}},"707":{"start":{"line":708,"column":0},"end":{"line":708,"column":36}},"708":{"start":{"line":709,"column":0},"end":{"line":709,"column":49}},"709":{"start":{"line":710,"column":0},"end":{"line":710,"column":19}},"710":{"start":{"line":711,"column":0},"end":{"line":711,"column":37}},"711":{"start":{"line":712,"column":0},"end":{"line":712,"column":5}},"713":{"start":{"line":714,"column":0},"end":{"line":714,"column":19}},"715":{"start":{"line":716,"column":0},"end":{"line":716,"column":26}},"716":{"start":{"line":717,"column":0},"end":{"line":717,"column":39}},"718":{"start":{"line":719,"column":0},"end":{"line":719,"column":49}},"719":{"start":{"line":720,"column":0},"end":{"line":720,"column":29}},"720":{"start":{"line":721,"column":0},"end":{"line":721,"column":13}},"721":{"start":{"line":722,"column":0},"end":{"line":722,"column":5}},"723":{"start":{"line":724,"column":0},"end":{"line":724,"column":27}},"727":{"start":{"line":728,"column":0},"end":{"line":728,"column":51}},"728":{"start":{"line":729,"column":0},"end":{"line":729,"column":23}},"729":{"start":{"line":730,"column":0},"end":{"line":730,"column":47}},"730":{"start":{"line":731,"column":0},"end":{"line":731,"column":5}},"731":{"start":{"line":732,"column":0},"end":{"line":732,"column":73}},"733":{"start":{"line":734,"column":0},"end":{"line":734,"column":9}},"734":{"start":{"line":735,"column":0},"end":{"line":735,"column":53}},"736":{"start":{"line":737,"column":0},"end":{"line":737,"column":67}},"737":{"start":{"line":738,"column":0},"end":{"line":738,"column":20}},"738":{"start":{"line":739,"column":0},"end":{"line":739,"column":65}},"741":{"start":{"line":742,"column":0},"end":{"line":742,"column":55}},"742":{"start":{"line":743,"column":0},"end":{"line":743,"column":22}},"743":{"start":{"line":744,"column":0},"end":{"line":744,"column":73}},"744":{"start":{"line":745,"column":0},"end":{"line":745,"column":15}},"745":{"start":{"line":746,"column":0},"end":{"line":746,"column":7}},"747":{"start":{"line":748,"column":0},"end":{"line":748,"column":52}},"749":{"start":{"line":750,"column":0},"end":{"line":750,"column":60}},"750":{"start":{"line":751,"column":0},"end":{"line":751,"column":27}},"751":{"start":{"line":752,"column":0},"end":{"line":752,"column":62}},"752":{"start":{"line":753,"column":0},"end":{"line":753,"column":15}},"753":{"start":{"line":754,"column":0},"end":{"line":754,"column":7}},"755":{"start":{"line":756,"column":0},"end":{"line":756,"column":81}},"756":{"start":{"line":757,"column":0},"end":{"line":757,"column":78}},"757":{"start":{"line":758,"column":0},"end":{"line":758,"column":28}},"758":{"start":{"line":759,"column":0},"end":{"line":759,"column":11}},"759":{"start":{"line":760,"column":0},"end":{"line":760,"column":14}},"760":{"start":{"line":761,"column":0},"end":{"line":761,"column":80}},"761":{"start":{"line":762,"column":0},"end":{"line":762,"column":28}},"762":{"start":{"line":763,"column":0},"end":{"line":763,"column":11}},"763":{"start":{"line":764,"column":0},"end":{"line":764,"column":7}},"764":{"start":{"line":765,"column":0},"end":{"line":765,"column":21}},"765":{"start":{"line":766,"column":0},"end":{"line":766,"column":78}},"766":{"start":{"line":767,"column":0},"end":{"line":767,"column":5}},"767":{"start":{"line":768,"column":0},"end":{"line":768,"column":6}},"768":{"start":{"line":769,"column":0},"end":{"line":769,"column":22}},"769":{"start":{"line":770,"column":0},"end":{"line":770,"column":20}},"770":{"start":{"line":771,"column":0},"end":{"line":771,"column":37}},"771":{"start":{"line":772,"column":0},"end":{"line":772,"column":26}},"772":{"start":{"line":773,"column":0},"end":{"line":773,"column":26}},"773":{"start":{"line":774,"column":0},"end":{"line":774,"column":18}},"774":{"start":{"line":775,"column":0},"end":{"line":775,"column":30}},"775":{"start":{"line":776,"column":0},"end":{"line":776,"column":19}},"776":{"start":{"line":777,"column":0},"end":{"line":777,"column":32}},"777":{"start":{"line":778,"column":0},"end":{"line":778,"column":28}},"778":{"start":{"line":779,"column":0},"end":{"line":779,"column":23}},"779":{"start":{"line":780,"column":0},"end":{"line":780,"column":5}},"781":{"start":{"line":782,"column":0},"end":{"line":782,"column":55}},"782":{"start":{"line":783,"column":0},"end":{"line":783,"column":50}},"783":{"start":{"line":784,"column":0},"end":{"line":784,"column":42}},"784":{"start":{"line":785,"column":0},"end":{"line":785,"column":57}},"785":{"start":{"line":786,"column":0},"end":{"line":786,"column":13}},"786":{"start":{"line":787,"column":0},"end":{"line":787,"column":5}},"788":{"start":{"line":789,"column":0},"end":{"line":789,"column":37}},"789":{"start":{"line":790,"column":0},"end":{"line":790,"column":91}},"790":{"start":{"line":791,"column":0},"end":{"line":791,"column":6}},"791":{"start":{"line":792,"column":0},"end":{"line":792,"column":21}},"792":{"start":{"line":793,"column":0},"end":{"line":793,"column":13}},"793":{"start":{"line":794,"column":0},"end":{"line":794,"column":5}},"795":{"start":{"line":796,"column":0},"end":{"line":796,"column":33}},"796":{"start":{"line":797,"column":0},"end":{"line":797,"column":9}},"797":{"start":{"line":798,"column":0},"end":{"line":798,"column":24}},"798":{"start":{"line":799,"column":0},"end":{"line":799,"column":31}},"799":{"start":{"line":800,"column":0},"end":{"line":800,"column":7}},"800":{"start":{"line":801,"column":0},"end":{"line":801,"column":56}},"801":{"start":{"line":802,"column":0},"end":{"line":802,"column":38}},"802":{"start":{"line":803,"column":0},"end":{"line":803,"column":21}},"803":{"start":{"line":804,"column":0},"end":{"line":804,"column":62}},"804":{"start":{"line":805,"column":0},"end":{"line":805,"column":15}},"805":{"start":{"line":806,"column":0},"end":{"line":806,"column":36}},"806":{"start":{"line":807,"column":0},"end":{"line":807,"column":5}},"807":{"start":{"line":808,"column":0},"end":{"line":808,"column":6}},"808":{"start":{"line":809,"column":0},"end":{"line":809,"column":22}},"809":{"start":{"line":810,"column":0},"end":{"line":810,"column":16}},"810":{"start":{"line":811,"column":0},"end":{"line":811,"column":24}},"811":{"start":{"line":812,"column":0},"end":{"line":812,"column":19}},"812":{"start":{"line":813,"column":0},"end":{"line":813,"column":17}},"813":{"start":{"line":814,"column":0},"end":{"line":814,"column":27}},"814":{"start":{"line":815,"column":0},"end":{"line":815,"column":19}},"815":{"start":{"line":816,"column":0},"end":{"line":816,"column":5}},"817":{"start":{"line":818,"column":0},"end":{"line":818,"column":10}},"818":{"start":{"line":819,"column":0},"end":{"line":819,"column":59}},"819":{"start":{"line":820,"column":0},"end":{"line":820,"column":36}},"820":{"start":{"line":821,"column":0},"end":{"line":821,"column":48}},"821":{"start":{"line":822,"column":0},"end":{"line":822,"column":12}},"823":{"start":{"line":824,"column":0},"end":{"line":824,"column":66}},"824":{"start":{"line":825,"column":0},"end":{"line":825,"column":43}},"825":{"start":{"line":826,"column":0},"end":{"line":826,"column":54}},"826":{"start":{"line":827,"column":0},"end":{"line":827,"column":14}},"827":{"start":{"line":828,"column":0},"end":{"line":828,"column":61}},"828":{"start":{"line":829,"column":0},"end":{"line":829,"column":17}},"829":{"start":{"line":830,"column":0},"end":{"line":830,"column":25}},"830":{"start":{"line":831,"column":0},"end":{"line":831,"column":51}},"831":{"start":{"line":832,"column":0},"end":{"line":832,"column":39}},"832":{"start":{"line":833,"column":0},"end":{"line":833,"column":29}},"833":{"start":{"line":834,"column":0},"end":{"line":834,"column":42}},"834":{"start":{"line":835,"column":0},"end":{"line":835,"column":50}},"835":{"start":{"line":836,"column":0},"end":{"line":836,"column":42}},"837":{"start":{"line":838,"column":0},"end":{"line":838,"column":42}},"838":{"start":{"line":839,"column":0},"end":{"line":839,"column":19}},"839":{"start":{"line":840,"column":0},"end":{"line":840,"column":17}},"840":{"start":{"line":841,"column":0},"end":{"line":841,"column":25}},"841":{"start":{"line":842,"column":0},"end":{"line":842,"column":82}},"842":{"start":{"line":843,"column":0},"end":{"line":843,"column":42}},"843":{"start":{"line":844,"column":0},"end":{"line":844,"column":28}},"844":{"start":{"line":845,"column":0},"end":{"line":845,"column":40}},"845":{"start":{"line":846,"column":0},"end":{"line":846,"column":23}},"846":{"start":{"line":847,"column":0},"end":{"line":847,"column":15}},"847":{"start":{"line":848,"column":0},"end":{"line":848,"column":47}},"848":{"start":{"line":849,"column":0},"end":{"line":849,"column":14}},"849":{"start":{"line":850,"column":0},"end":{"line":850,"column":32}},"850":{"start":{"line":851,"column":0},"end":{"line":851,"column":40}},"851":{"start":{"line":852,"column":0},"end":{"line":852,"column":42}},"853":{"start":{"line":854,"column":0},"end":{"line":854,"column":84}},"854":{"start":{"line":855,"column":0},"end":{"line":855,"column":68}},"855":{"start":{"line":856,"column":0},"end":{"line":856,"column":19}},"856":{"start":{"line":857,"column":0},"end":{"line":857,"column":39}},"857":{"start":{"line":858,"column":0},"end":{"line":858,"column":19}},"859":{"start":{"line":860,"column":0},"end":{"line":860,"column":28}},"860":{"start":{"line":861,"column":0},"end":{"line":861,"column":68}},"861":{"start":{"line":862,"column":0},"end":{"line":862,"column":36}},"862":{"start":{"line":863,"column":0},"end":{"line":863,"column":32}},"863":{"start":{"line":864,"column":0},"end":{"line":864,"column":31}},"864":{"start":{"line":865,"column":0},"end":{"line":865,"column":38}},"865":{"start":{"line":866,"column":0},"end":{"line":866,"column":59}},"866":{"start":{"line":867,"column":0},"end":{"line":867,"column":53}},"867":{"start":{"line":868,"column":0},"end":{"line":868,"column":34}},"868":{"start":{"line":869,"column":0},"end":{"line":869,"column":47}},"869":{"start":{"line":870,"column":0},"end":{"line":870,"column":43}},"870":{"start":{"line":871,"column":0},"end":{"line":871,"column":20}},"871":{"start":{"line":872,"column":0},"end":{"line":872,"column":48}},"873":{"start":{"line":874,"column":0},"end":{"line":874,"column":29}},"874":{"start":{"line":875,"column":0},"end":{"line":875,"column":34}},"875":{"start":{"line":876,"column":0},"end":{"line":876,"column":17}},"876":{"start":{"line":877,"column":0},"end":{"line":877,"column":69}},"877":{"start":{"line":878,"column":0},"end":{"line":878,"column":30}},"878":{"start":{"line":879,"column":0},"end":{"line":879,"column":32}},"880":{"start":{"line":881,"column":0},"end":{"line":881,"column":41}},"881":{"start":{"line":882,"column":0},"end":{"line":882,"column":18}},"882":{"start":{"line":883,"column":0},"end":{"line":883,"column":46}},"883":{"start":{"line":884,"column":0},"end":{"line":884,"column":15}},"885":{"start":{"line":886,"column":0},"end":{"line":886,"column":32}},"886":{"start":{"line":887,"column":0},"end":{"line":887,"column":30}},"887":{"start":{"line":888,"column":0},"end":{"line":888,"column":39}},"888":{"start":{"line":889,"column":0},"end":{"line":889,"column":46}},"889":{"start":{"line":890,"column":0},"end":{"line":890,"column":15}},"891":{"start":{"line":892,"column":0},"end":{"line":892,"column":32}},"892":{"start":{"line":893,"column":0},"end":{"line":893,"column":29}},"894":{"start":{"line":895,"column":0},"end":{"line":895,"column":14}},"895":{"start":{"line":896,"column":0},"end":{"line":896,"column":16}},"897":{"start":{"line":898,"column":0},"end":{"line":898,"column":66}},"898":{"start":{"line":899,"column":0},"end":{"line":899,"column":43}},"899":{"start":{"line":900,"column":0},"end":{"line":900,"column":50}},"900":{"start":{"line":901,"column":0},"end":{"line":901,"column":61}},"901":{"start":{"line":902,"column":0},"end":{"line":902,"column":49}},"902":{"start":{"line":903,"column":0},"end":{"line":903,"column":27}},"903":{"start":{"line":904,"column":0},"end":{"line":904,"column":29}},"904":{"start":{"line":905,"column":0},"end":{"line":905,"column":89}},"905":{"start":{"line":906,"column":0},"end":{"line":906,"column":37}},"906":{"start":{"line":907,"column":0},"end":{"line":907,"column":37}},"907":{"start":{"line":908,"column":0},"end":{"line":908,"column":18}},"908":{"start":{"line":909,"column":0},"end":{"line":909,"column":16}},"909":{"start":{"line":910,"column":0},"end":{"line":910,"column":53}},"910":{"start":{"line":911,"column":0},"end":{"line":911,"column":19}},"911":{"start":{"line":912,"column":0},"end":{"line":912,"column":27}},"912":{"start":{"line":913,"column":0},"end":{"line":913,"column":52}},"913":{"start":{"line":914,"column":0},"end":{"line":914,"column":44}},"914":{"start":{"line":915,"column":0},"end":{"line":915,"column":61}},"915":{"start":{"line":916,"column":0},"end":{"line":916,"column":69}},"916":{"start":{"line":917,"column":0},"end":{"line":917,"column":40}},"917":{"start":{"line":918,"column":0},"end":{"line":918,"column":21}},"918":{"start":{"line":919,"column":0},"end":{"line":919,"column":35}},"919":{"start":{"line":920,"column":0},"end":{"line":920,"column":51}},"920":{"start":{"line":921,"column":0},"end":{"line":921,"column":33}},"921":{"start":{"line":922,"column":0},"end":{"line":922,"column":42}},"922":{"start":{"line":923,"column":0},"end":{"line":923,"column":31}},"923":{"start":{"line":924,"column":0},"end":{"line":924,"column":34}},"924":{"start":{"line":925,"column":0},"end":{"line":925,"column":35}},"926":{"start":{"line":927,"column":0},"end":{"line":927,"column":30}},"927":{"start":{"line":928,"column":0},"end":{"line":928,"column":59}},"928":{"start":{"line":929,"column":0},"end":{"line":929,"column":25}},"929":{"start":{"line":930,"column":0},"end":{"line":930,"column":17}},"930":{"start":{"line":931,"column":0},"end":{"line":931,"column":34}},"931":{"start":{"line":932,"column":0},"end":{"line":932,"column":40}},"932":{"start":{"line":933,"column":0},"end":{"line":933,"column":25}},"933":{"start":{"line":934,"column":0},"end":{"line":934,"column":17}},"934":{"start":{"line":935,"column":0},"end":{"line":935,"column":53}},"935":{"start":{"line":936,"column":0},"end":{"line":936,"column":16}},"937":{"start":{"line":938,"column":0},"end":{"line":938,"column":74}},"938":{"start":{"line":939,"column":0},"end":{"line":939,"column":21}},"939":{"start":{"line":940,"column":0},"end":{"line":940,"column":19}},"940":{"start":{"line":941,"column":0},"end":{"line":941,"column":27}},"941":{"start":{"line":942,"column":0},"end":{"line":942,"column":52}},"942":{"start":{"line":943,"column":0},"end":{"line":943,"column":44}},"943":{"start":{"line":944,"column":0},"end":{"line":944,"column":84}},"944":{"start":{"line":945,"column":0},"end":{"line":945,"column":41}},"945":{"start":{"line":946,"column":0},"end":{"line":946,"column":21}},"946":{"start":{"line":947,"column":0},"end":{"line":947,"column":35}},"947":{"start":{"line":948,"column":0},"end":{"line":948,"column":51}},"948":{"start":{"line":949,"column":0},"end":{"line":949,"column":33}},"949":{"start":{"line":950,"column":0},"end":{"line":950,"column":53}},"950":{"start":{"line":951,"column":0},"end":{"line":951,"column":61}},"952":{"start":{"line":953,"column":0},"end":{"line":953,"column":30}},"953":{"start":{"line":954,"column":0},"end":{"line":954,"column":43}},"954":{"start":{"line":955,"column":0},"end":{"line":955,"column":16}},"956":{"start":{"line":957,"column":0},"end":{"line":957,"column":71}},"957":{"start":{"line":958,"column":0},"end":{"line":958,"column":21}},"958":{"start":{"line":959,"column":0},"end":{"line":959,"column":16}},"959":{"start":{"line":960,"column":0},"end":{"line":960,"column":14}},"960":{"start":{"line":961,"column":0},"end":{"line":961,"column":41}},"961":{"start":{"line":962,"column":0},"end":{"line":962,"column":24}},"962":{"start":{"line":963,"column":0},"end":{"line":963,"column":64}},"963":{"start":{"line":964,"column":0},"end":{"line":964,"column":25}},"964":{"start":{"line":965,"column":0},"end":{"line":965,"column":18}},"965":{"start":{"line":966,"column":0},"end":{"line":966,"column":19}},"966":{"start":{"line":967,"column":0},"end":{"line":967,"column":34}},"967":{"start":{"line":968,"column":0},"end":{"line":968,"column":41}},"969":{"start":{"line":970,"column":0},"end":{"line":970,"column":18}},"970":{"start":{"line":971,"column":0},"end":{"line":971,"column":30}},"971":{"start":{"line":972,"column":0},"end":{"line":972,"column":40}},"972":{"start":{"line":973,"column":0},"end":{"line":973,"column":56}},"973":{"start":{"line":974,"column":0},"end":{"line":974,"column":69}},"974":{"start":{"line":975,"column":0},"end":{"line":975,"column":91}},"975":{"start":{"line":976,"column":0},"end":{"line":976,"column":67}},"976":{"start":{"line":977,"column":0},"end":{"line":977,"column":34}},"977":{"start":{"line":978,"column":0},"end":{"line":978,"column":46}},"978":{"start":{"line":979,"column":0},"end":{"line":979,"column":36}},"979":{"start":{"line":980,"column":0},"end":{"line":980,"column":43}},"980":{"start":{"line":981,"column":0},"end":{"line":981,"column":30}},"981":{"start":{"line":982,"column":0},"end":{"line":982,"column":19}},"982":{"start":{"line":983,"column":0},"end":{"line":983,"column":68}},"983":{"start":{"line":984,"column":0},"end":{"line":984,"column":67}},"984":{"start":{"line":985,"column":0},"end":{"line":985,"column":75}},"986":{"start":{"line":987,"column":0},"end":{"line":987,"column":24}},"987":{"start":{"line":988,"column":0},"end":{"line":988,"column":108}},"988":{"start":{"line":989,"column":0},"end":{"line":989,"column":52}},"989":{"start":{"line":990,"column":0},"end":{"line":990,"column":68}},"990":{"start":{"line":991,"column":0},"end":{"line":991,"column":40}},"991":{"start":{"line":992,"column":0},"end":{"line":992,"column":54}},"992":{"start":{"line":993,"column":0},"end":{"line":993,"column":41}},"993":{"start":{"line":994,"column":0},"end":{"line":994,"column":91}},"995":{"start":{"line":996,"column":0},"end":{"line":996,"column":48}},"997":{"start":{"line":998,"column":0},"end":{"line":998,"column":29}},"998":{"start":{"line":999,"column":0},"end":{"line":999,"column":76}},"999":{"start":{"line":1000,"column":0},"end":{"line":1000,"column":40}},"1000":{"start":{"line":1001,"column":0},"end":{"line":1001,"column":58}},"1001":{"start":{"line":1002,"column":0},"end":{"line":1002,"column":65}},"1002":{"start":{"line":1003,"column":0},"end":{"line":1003,"column":31}},"1003":{"start":{"line":1004,"column":0},"end":{"line":1004,"column":31}},"1004":{"start":{"line":1005,"column":0},"end":{"line":1005,"column":26}},"1005":{"start":{"line":1006,"column":0},"end":{"line":1006,"column":52}},"1006":{"start":{"line":1007,"column":0},"end":{"line":1007,"column":52}},"1007":{"start":{"line":1008,"column":0},"end":{"line":1008,"column":58}},"1008":{"start":{"line":1009,"column":0},"end":{"line":1009,"column":67}},"1009":{"start":{"line":1010,"column":0},"end":{"line":1010,"column":36}},"1010":{"start":{"line":1011,"column":0},"end":{"line":1011,"column":37}},"1011":{"start":{"line":1012,"column":0},"end":{"line":1012,"column":69}},"1012":{"start":{"line":1013,"column":0},"end":{"line":1013,"column":40}},"1013":{"start":{"line":1014,"column":0},"end":{"line":1014,"column":28}},"1014":{"start":{"line":1015,"column":0},"end":{"line":1015,"column":77}},"1015":{"start":{"line":1016,"column":0},"end":{"line":1016,"column":34}},"1016":{"start":{"line":1017,"column":0},"end":{"line":1017,"column":33}},"1017":{"start":{"line":1018,"column":0},"end":{"line":1018,"column":60}},"1018":{"start":{"line":1019,"column":0},"end":{"line":1019,"column":68}},"1019":{"start":{"line":1020,"column":0},"end":{"line":1020,"column":54}},"1021":{"start":{"line":1022,"column":0},"end":{"line":1022,"column":77}},"1022":{"start":{"line":1023,"column":0},"end":{"line":1023,"column":72}},"1023":{"start":{"line":1024,"column":0},"end":{"line":1024,"column":37}},"1024":{"start":{"line":1025,"column":0},"end":{"line":1025,"column":85}},"1025":{"start":{"line":1026,"column":0},"end":{"line":1026,"column":35}},"1027":{"start":{"line":1028,"column":0},"end":{"line":1028,"column":27}},"1028":{"start":{"line":1029,"column":0},"end":{"line":1029,"column":28}},"1029":{"start":{"line":1030,"column":0},"end":{"line":1030,"column":29}},"1030":{"start":{"line":1031,"column":0},"end":{"line":1031,"column":23}},"1032":{"start":{"line":1033,"column":0},"end":{"line":1033,"column":17}},"1033":{"start":{"line":1034,"column":0},"end":{"line":1034,"column":17}},"1035":{"start":{"line":1036,"column":0},"end":{"line":1036,"column":41}},"1037":{"start":{"line":1038,"column":0},"end":{"line":1038,"column":18}},"1039":{"start":{"line":1040,"column":0},"end":{"line":1040,"column":14}},"1040":{"start":{"line":1041,"column":0},"end":{"line":1041,"column":16}},"1042":{"start":{"line":1043,"column":0},"end":{"line":1043,"column":25}},"1043":{"start":{"line":1044,"column":0},"end":{"line":1044,"column":28}},"1044":{"start":{"line":1045,"column":0},"end":{"line":1045,"column":31}},"1045":{"start":{"line":1046,"column":0},"end":{"line":1046,"column":47}},"1046":{"start":{"line":1047,"column":0},"end":{"line":1047,"column":48}},"1047":{"start":{"line":1048,"column":0},"end":{"line":1048,"column":51}},"1048":{"start":{"line":1049,"column":0},"end":{"line":1049,"column":55}},"1049":{"start":{"line":1050,"column":0},"end":{"line":1050,"column":49}},"1050":{"start":{"line":1051,"column":0},"end":{"line":1051,"column":10}},"1052":{"start":{"line":1053,"column":0},"end":{"line":1053,"column":10}},"1054":{"start":{"line":1055,"column":0},"end":{"line":1055,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"10":1,"11":1,"15":1,"16":1,"31":1,"44":1,"45":1,"97":1,"98":1,"99":1,"100":1,"101":1,"102":1,"104":1,"105":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"115":1,"116":1,"117":1,"133":1,"134":1,"135":1,"136":1,"141":40,"142":40,"143":40,"144":40,"145":40,"146":40,"147":40,"148":0,"149":0,"150":0,"151":0,"152":40,"153":40,"154":0,"155":0,"156":40,"157":40,"159":75,"160":75,"161":75,"162":1,"163":1,"164":75,"165":15,"166":15,"167":59,"168":59,"170":344,"171":344,"172":344,"173":344,"174":344,"175":344,"176":344,"177":344,"178":14,"179":14,"180":344,"181":59,"182":59,"183":344,"184":105,"185":105,"186":166,"187":166,"189":110,"190":110,"191":110,"192":110,"193":110,"194":110,"195":110,"196":170,"197":170,"198":110,"199":110,"200":0,"201":0,"202":0,"203":0,"205":110,"207":330,"208":330,"209":330,"210":330,"211":330,"212":330,"213":224,"214":224,"215":330,"216":4,"217":4,"218":330,"219":59,"220":59,"221":43,"222":43,"224":349,"225":349,"226":349,"227":349,"228":349,"229":349,"230":349,"236":349,"237":349,"238":19,"239":19,"241":330,"242":349,"244":349,"245":4,"246":0,"247":4,"248":4,"250":326,"251":326,"253":4,"254":4,"255":4,"256":4,"257":4,"258":4,"259":4,"260":4,"267":4,"268":4,"269":4,"270":1,"271":0,"272":0,"273":1,"274":1,"275":1,"276":4,"277":4,"278":4,"280":4,"281":3,"282":1,"283":1,"284":1,"285":1,"286":1,"287":4,"288":3,"289":1,"291":4,"292":4,"293":4,"294":4,"295":4,"297":4,"298":4,"300":4,"301":4,"302":4,"303":4,"304":3,"305":3,"306":3,"307":3,"308":3,"309":3,"310":3,"311":3,"312":3,"313":3,"314":3,"315":3,"316":3,"317":3,"319":0,"321":3,"322":3,"323":3,"324":3,"325":3,"326":3,"327":1,"328":1,"329":1,"330":3,"331":3,"333":3,"334":3,"335":3,"337":1,"340":4,"341":5,"342":5,"343":5,"344":5,"345":5,"346":5,"347":5,"348":5,"349":5,"350":5,"351":5,"352":1,"353":1,"354":1,"355":5,"357":5,"358":5,"359":5,"360":5,"362":4,"363":4,"364":4,"365":4,"367":4,"368":4,"369":4,"371":4,"373":1,"374":324,"375":324,"376":324,"377":324,"378":324,"379":324,"380":324,"381":324,"382":324,"399":324,"400":324,"401":324,"402":324,"403":324,"404":324,"405":324,"406":324,"407":324,"408":324,"409":324,"410":324,"411":324,"412":324,"413":324,"414":324,"415":324,"416":324,"417":324,"418":324,"420":324,"421":324,"422":89,"423":89,"424":0,"425":0,"426":89,"427":89,"428":89,"429":89,"430":88,"431":88,"432":88,"433":88,"435":89,"436":324,"437":324,"439":324,"440":324,"441":45,"442":43,"443":43,"444":45,"445":45,"446":0,"447":0,"448":45,"449":45,"452":0,"453":0,"454":2,"455":2,"456":45,"457":45,"458":45,"459":2,"460":2,"461":2,"462":45,"463":324,"464":324,"466":324,"467":324,"468":324,"469":324,"470":324,"472":324,"473":44,"474":44,"475":44,"476":44,"477":0,"478":0,"479":44,"480":44,"481":44,"482":0,"483":44,"484":44,"485":44,"486":44,"487":324,"489":324,"490":44,"491":44,"492":3,"493":3,"494":3,"495":3,"496":3,"497":3,"498":41,"499":41,"500":41,"501":0,"502":0,"503":41,"504":41,"505":41,"506":0,"507":41,"508":41,"509":41,"510":41,"511":324,"513":324,"514":324,"515":194,"516":0,"517":0,"518":194,"519":194,"520":194,"521":194,"522":194,"523":0,"524":194,"525":194,"526":194,"527":194,"528":324,"529":324,"531":324,"532":44,"533":44,"534":3,"535":3,"536":3,"537":3,"538":3,"540":41,"541":193,"542":0,"543":0,"544":193,"545":193,"547":41,"548":41,"549":41,"550":41,"551":41,"552":41,"553":324,"555":324,"556":90,"557":40,"558":75,"559":75,"560":75,"561":75,"562":75,"563":75,"564":40,"566":40,"567":40,"568":40,"569":40,"570":40,"571":90,"572":324,"574":324,"575":324,"576":1,"577":0,"578":0,"579":1,"580":1,"581":1,"582":1,"583":1,"584":0,"585":1,"586":1,"587":324,"588":324,"590":324,"591":1,"592":0,"593":0,"594":1,"595":1,"596":1,"597":1,"598":1,"599":0,"600":1,"601":324,"603":324,"604":324,"605":180,"606":144,"607":324,"609":324,"610":324,"612":324,"614":324,"615":324,"616":324,"617":324,"618":324,"620":324,"621":44,"622":41,"623":41,"624":3,"625":324,"627":324,"628":127,"629":88,"630":88,"631":127,"632":0,"633":0,"634":324,"636":324,"637":85,"638":85,"639":48,"640":48,"641":48,"642":48,"643":48,"645":85,"646":85,"647":188,"648":188,"649":188,"650":188,"651":188,"652":188,"653":188,"654":0,"655":0,"656":188,"657":188,"658":0,"659":0,"660":0,"661":0,"662":0,"663":0,"664":188,"666":85,"667":85,"668":85,"669":37,"670":37,"671":37,"672":324,"673":324,"674":324,"675":324,"676":324,"677":324,"679":324,"680":44,"681":44,"682":44,"683":44,"684":43,"685":44,"686":324,"687":324,"688":324,"689":324,"690":324,"692":324,"693":324,"694":324,"695":324,"696":324,"697":324,"698":324,"699":324,"700":324,"701":324,"702":324,"703":324,"704":324,"705":324,"706":324,"707":324,"708":324,"709":324,"710":324,"711":324,"713":324,"715":81,"716":324,"718":324,"719":1,"720":0,"721":0,"723":1,"727":1,"728":1,"729":1,"730":1,"731":1,"733":1,"734":1,"736":1,"737":1,"738":1,"741":1,"742":1,"743":0,"744":0,"745":0,"747":1,"749":1,"750":1,"751":0,"752":0,"753":0,"755":1,"756":1,"757":1,"758":1,"759":1,"760":0,"761":0,"762":0,"763":0,"764":1,"765":0,"766":0,"767":324,"768":324,"769":324,"770":324,"771":324,"772":324,"773":324,"774":324,"775":324,"776":324,"777":324,"778":324,"779":324,"781":324,"782":1,"783":1,"784":1,"785":0,"786":0,"788":1,"789":1,"790":1,"791":1,"792":0,"793":0,"795":1,"796":1,"797":1,"798":0,"799":0,"800":1,"801":1,"802":1,"803":0,"804":1,"805":1,"806":1,"807":324,"808":324,"809":324,"810":324,"811":324,"812":324,"813":324,"814":324,"815":324,"817":324,"818":324,"819":324,"820":324,"821":324,"823":324,"824":324,"825":324,"826":324,"827":324,"828":324,"829":324,"830":324,"831":324,"832":324,"833":324,"834":324,"835":324,"837":324,"838":324,"839":324,"840":324,"841":324,"842":324,"843":324,"844":39,"845":0,"846":0,"847":39,"848":39,"849":324,"850":324,"851":324,"853":324,"854":324,"855":324,"856":324,"857":324,"859":324,"860":42,"861":42,"862":38,"863":38,"864":38,"865":38,"866":38,"867":38,"868":37,"869":37,"870":37,"871":38,"873":38,"874":38,"875":42,"876":42,"877":42,"878":42,"880":0,"881":0,"882":42,"883":42,"885":42,"886":42,"887":42,"888":42,"889":42,"891":42,"892":42,"894":324,"895":324,"897":324,"898":324,"899":324,"900":324,"901":324,"902":324,"903":180,"904":19,"905":161,"906":144,"907":324,"908":324,"909":324,"910":324,"911":324,"912":324,"913":324,"914":324,"915":324,"916":324,"917":324,"918":324,"919":9,"920":315,"921":135,"922":180,"923":53,"924":127,"926":324,"927":51,"928":0,"929":0,"930":51,"931":17,"932":17,"933":17,"934":34,"935":51,"937":324,"938":324,"939":324,"940":324,"941":324,"942":324,"943":324,"944":324,"945":324,"946":324,"947":9,"948":315,"949":135,"950":180,"952":324,"953":1,"954":1,"956":324,"957":324,"958":324,"959":324,"960":324,"961":324,"962":12,"963":12,"964":12,"965":312,"966":324,"967":9,"969":9,"970":315,"971":180,"972":180,"973":349,"974":349,"975":349,"976":349,"977":349,"978":349,"979":349,"980":349,"981":349,"982":349,"983":349,"984":349,"986":349,"987":349,"988":349,"989":349,"990":349,"991":6,"992":343,"993":104,"995":239,"997":349,"998":349,"999":349,"1000":19,"1001":19,"1002":19,"1003":330,"1004":349,"1005":349,"1006":120,"1007":120,"1008":344,"1009":344,"1010":344,"1011":344,"1012":344,"1013":344,"1014":344,"1015":344,"1016":344,"1017":344,"1018":344,"1019":344,"1021":344,"1022":344,"1023":344,"1024":344,"1025":344,"1027":120,"1028":120,"1029":229,"1030":349,"1032":180,"1033":180,"1035":135,"1037":135,"1039":324,"1040":324,"1042":324,"1043":4,"1044":4,"1045":4,"1046":4,"1047":4,"1048":4,"1049":4,"1050":4,"1052":324,"1054":324},"branchMap":{"0":{"type":"branch","line":142,"loc":{"start":{"line":142,"column":0},"end":{"line":158,"column":1}},"locations":[{"start":{"line":142,"column":0},"end":{"line":158,"column":1}}]},"1":{"type":"branch","line":143,"loc":{"start":{"line":143,"column":33},"end":{"line":143,"column":41}},"locations":[{"start":{"line":143,"column":33},"end":{"line":143,"column":41}}]},"2":{"type":"branch","line":144,"loc":{"start":{"line":144,"column":31},"end":{"line":144,"column":39}},"locations":[{"start":{"line":144,"column":31},"end":{"line":144,"column":39}}]},"3":{"type":"branch","line":145,"loc":{"start":{"line":145,"column":27},"end":{"line":145,"column":35}},"locations":[{"start":{"line":145,"column":27},"end":{"line":145,"column":35}}]},"4":{"type":"branch","line":148,"loc":{"start":{"line":148,"column":2},"end":{"line":153,"column":61}},"locations":[{"start":{"line":148,"column":2},"end":{"line":153,"column":61}}]},"5":{"type":"branch","line":153,"loc":{"start":{"line":153,"column":53},"end":{"line":153,"column":66}},"locations":[{"start":{"line":153,"column":53},"end":{"line":153,"column":66}}]},"6":{"type":"branch","line":154,"loc":{"start":{"line":154,"column":6},"end":{"line":154,"column":23}},"locations":[{"start":{"line":154,"column":6},"end":{"line":154,"column":23}}]},"7":{"type":"branch","line":154,"loc":{"start":{"line":154,"column":23},"end":{"line":157,"column":28}},"locations":[{"start":{"line":154,"column":23},"end":{"line":157,"column":28}}]},"8":{"type":"branch","line":157,"loc":{"start":{"line":157,"column":22},"end":{"line":157,"column":44}},"locations":[{"start":{"line":157,"column":22},"end":{"line":157,"column":44}}]},"9":{"type":"branch","line":160,"loc":{"start":{"line":160,"column":0},"end":{"line":169,"column":1}},"locations":[{"start":{"line":160,"column":0},"end":{"line":169,"column":1}}]},"10":{"type":"branch","line":162,"loc":{"start":{"line":162,"column":34},"end":{"line":164,"column":3}},"locations":[{"start":{"line":162,"column":34},"end":{"line":164,"column":3}}]},"11":{"type":"branch","line":164,"loc":{"start":{"line":164,"column":2},"end":{"line":165,"column":36}},"locations":[{"start":{"line":164,"column":2},"end":{"line":165,"column":36}}]},"12":{"type":"branch","line":165,"loc":{"start":{"line":165,"column":36},"end":{"line":167,"column":3}},"locations":[{"start":{"line":165,"column":36},"end":{"line":167,"column":3}}]},"13":{"type":"branch","line":167,"loc":{"start":{"line":167,"column":2},"end":{"line":169,"column":1}},"locations":[{"start":{"line":167,"column":2},"end":{"line":169,"column":1}}]},"14":{"type":"branch","line":171,"loc":{"start":{"line":171,"column":0},"end":{"line":188,"column":1}},"locations":[{"start":{"line":171,"column":0},"end":{"line":188,"column":1}}]},"15":{"type":"branch","line":178,"loc":{"start":{"line":178,"column":6},"end":{"line":178,"column":30}},"locations":[{"start":{"line":178,"column":6},"end":{"line":178,"column":30}}]},"16":{"type":"branch","line":178,"loc":{"start":{"line":178,"column":30},"end":{"line":178,"column":73}},"locations":[{"start":{"line":178,"column":30},"end":{"line":178,"column":73}}]},"17":{"type":"branch","line":178,"loc":{"start":{"line":178,"column":73},"end":{"line":180,"column":3}},"locations":[{"start":{"line":178,"column":73},"end":{"line":180,"column":3}}]},"18":{"type":"branch","line":180,"loc":{"start":{"line":180,"column":2},"end":{"line":181,"column":42}},"locations":[{"start":{"line":180,"column":2},"end":{"line":181,"column":42}}]},"19":{"type":"branch","line":181,"loc":{"start":{"line":181,"column":42},"end":{"line":183,"column":3}},"locations":[{"start":{"line":181,"column":42},"end":{"line":183,"column":3}}]},"20":{"type":"branch","line":183,"loc":{"start":{"line":183,"column":2},"end":{"line":184,"column":40}},"locations":[{"start":{"line":183,"column":2},"end":{"line":184,"column":40}}]},"21":{"type":"branch","line":184,"loc":{"start":{"line":184,"column":40},"end":{"line":186,"column":3}},"locations":[{"start":{"line":184,"column":40},"end":{"line":186,"column":3}}]},"22":{"type":"branch","line":186,"loc":{"start":{"line":186,"column":2},"end":{"line":188,"column":1}},"locations":[{"start":{"line":186,"column":2},"end":{"line":188,"column":1}}]},"23":{"type":"branch","line":190,"loc":{"start":{"line":190,"column":0},"end":{"line":206,"column":1}},"locations":[{"start":{"line":190,"column":0},"end":{"line":206,"column":1}}]},"24":{"type":"branch","line":200,"loc":{"start":{"line":200,"column":2},"end":{"line":204,"column":80}},"locations":[{"start":{"line":200,"column":2},"end":{"line":204,"column":80}}]},"25":{"type":"branch","line":196,"loc":{"start":{"line":196,"column":6},"end":{"line":198,"column":20}},"locations":[{"start":{"line":196,"column":6},"end":{"line":198,"column":20}}]},"26":{"type":"branch","line":197,"loc":{"start":{"line":197,"column":35},"end":{"line":197,"column":51}},"locations":[{"start":{"line":197,"column":35},"end":{"line":197,"column":51}}]},"27":{"type":"branch","line":208,"loc":{"start":{"line":208,"column":0},"end":{"line":223,"column":1}},"locations":[{"start":{"line":208,"column":0},"end":{"line":223,"column":1}}]},"28":{"type":"branch","line":213,"loc":{"start":{"line":213,"column":34},"end":{"line":215,"column":3}},"locations":[{"start":{"line":213,"column":34},"end":{"line":215,"column":3}}]},"29":{"type":"branch","line":215,"loc":{"start":{"line":215,"column":2},"end":{"line":216,"column":57}},"locations":[{"start":{"line":215,"column":2},"end":{"line":216,"column":57}}]},"30":{"type":"branch","line":216,"loc":{"start":{"line":216,"column":57},"end":{"line":218,"column":3}},"locations":[{"start":{"line":216,"column":57},"end":{"line":218,"column":3}}]},"31":{"type":"branch","line":218,"loc":{"start":{"line":218,"column":2},"end":{"line":219,"column":85}},"locations":[{"start":{"line":218,"column":2},"end":{"line":219,"column":85}}]},"32":{"type":"branch","line":219,"loc":{"start":{"line":219,"column":85},"end":{"line":221,"column":3}},"locations":[{"start":{"line":219,"column":85},"end":{"line":221,"column":3}}]},"33":{"type":"branch","line":221,"loc":{"start":{"line":221,"column":2},"end":{"line":223,"column":1}},"locations":[{"start":{"line":221,"column":2},"end":{"line":223,"column":1}}]},"34":{"type":"branch","line":219,"loc":{"start":{"line":219,"column":25},"end":{"line":219,"column":82}},"locations":[{"start":{"line":219,"column":25},"end":{"line":219,"column":82}}]},"35":{"type":"branch","line":225,"loc":{"start":{"line":225,"column":0},"end":{"line":252,"column":1}},"locations":[{"start":{"line":225,"column":0},"end":{"line":252,"column":1}}]},"36":{"type":"branch","line":238,"loc":{"start":{"line":238,"column":6},"end":{"line":238,"column":30}},"locations":[{"start":{"line":238,"column":6},"end":{"line":238,"column":30}}]},"37":{"type":"branch","line":238,"loc":{"start":{"line":238,"column":38},"end":{"line":240,"column":3}},"locations":[{"start":{"line":238,"column":38},"end":{"line":240,"column":3}}]},"38":{"type":"branch","line":240,"loc":{"start":{"line":240,"column":2},"end":{"line":243,"column":47}},"locations":[{"start":{"line":240,"column":2},"end":{"line":243,"column":47}}]},"39":{"type":"branch","line":243,"loc":{"start":{"line":243,"column":25},"end":{"line":243,"column":62}},"locations":[{"start":{"line":243,"column":25},"end":{"line":243,"column":62}}]},"40":{"type":"branch","line":245,"loc":{"start":{"line":245,"column":6},"end":{"line":245,"column":54}},"locations":[{"start":{"line":245,"column":6},"end":{"line":245,"column":54}}]},"41":{"type":"branch","line":245,"loc":{"start":{"line":245,"column":54},"end":{"line":249,"column":3}},"locations":[{"start":{"line":245,"column":54},"end":{"line":249,"column":3}}]},"42":{"type":"branch","line":246,"loc":{"start":{"line":246,"column":59},"end":{"line":247,"column":19}},"locations":[{"start":{"line":246,"column":59},"end":{"line":247,"column":19}}]},"43":{"type":"branch","line":249,"loc":{"start":{"line":249,"column":2},"end":{"line":252,"column":1}},"locations":[{"start":{"line":249,"column":2},"end":{"line":252,"column":1}}]},"44":{"type":"branch","line":254,"loc":{"start":{"line":254,"column":0},"end":{"line":372,"column":1}},"locations":[{"start":{"line":254,"column":0},"end":{"line":372,"column":1}}]},"45":{"type":"branch","line":281,"loc":{"start":{"line":281,"column":20},"end":{"line":286,"column":7}},"locations":[{"start":{"line":281,"column":20},"end":{"line":286,"column":7}}]},"46":{"type":"branch","line":282,"loc":{"start":{"line":282,"column":74},"end":{"line":286,"column":7}},"locations":[{"start":{"line":282,"column":74},"end":{"line":286,"column":7}}]},"47":{"type":"branch","line":286,"loc":{"start":{"line":286,"column":6},"end":{"line":287,"column":11}},"locations":[{"start":{"line":286,"column":6},"end":{"line":287,"column":11}}]},"48":{"type":"branch","line":288,"loc":{"start":{"line":288,"column":17},"end":{"line":289,"column":52}},"locations":[{"start":{"line":288,"column":17},"end":{"line":289,"column":52}}]},"49":{"type":"branch","line":289,"loc":{"start":{"line":289,"column":51},"end":{"line":290,"column":16}},"locations":[{"start":{"line":289,"column":51},"end":{"line":290,"column":16}}]},"50":{"type":"branch","line":304,"loc":{"start":{"line":304,"column":9},"end":{"line":336,"column":16}},"locations":[{"start":{"line":304,"column":9},"end":{"line":336,"column":16}}]},"51":{"type":"branch","line":309,"loc":{"start":{"line":309,"column":68},"end":{"line":309,"column":77}},"locations":[{"start":{"line":309,"column":68},"end":{"line":309,"column":77}}]},"52":{"type":"branch","line":336,"loc":{"start":{"line":336,"column":10},"end":{"line":338,"column":76}},"locations":[{"start":{"line":336,"column":10},"end":{"line":338,"column":76}}]},"53":{"type":"branch","line":269,"loc":{"start":{"line":269,"column":12},"end":{"line":279,"column":5}},"locations":[{"start":{"line":269,"column":12},"end":{"line":279,"column":5}}]},"54":{"type":"branch","line":270,"loc":{"start":{"line":270,"column":26},"end":{"line":276,"column":6}},"locations":[{"start":{"line":270,"column":26},"end":{"line":276,"column":6}}]},"55":{"type":"branch","line":271,"loc":{"start":{"line":271,"column":34},"end":{"line":273,"column":7}},"locations":[{"start":{"line":271,"column":34},"end":{"line":273,"column":7}}]},"56":{"type":"branch","line":278,"loc":{"start":{"line":278,"column":11},"end":{"line":278,"column":70}},"locations":[{"start":{"line":278,"column":11},"end":{"line":278,"column":70}}]},"57":{"type":"branch","line":282,"loc":{"start":{"line":282,"column":21},"end":{"line":282,"column":74}},"locations":[{"start":{"line":282,"column":21},"end":{"line":282,"column":74}}]},"58":{"type":"branch","line":289,"loc":{"start":{"line":289,"column":23},"end":{"line":289,"column":51}},"locations":[{"start":{"line":289,"column":23},"end":{"line":289,"column":51}}]},"59":{"type":"branch","line":327,"loc":{"start":{"line":327,"column":25},"end":{"line":330,"column":18}},"locations":[{"start":{"line":327,"column":25},"end":{"line":330,"column":18}}]},"60":{"type":"branch","line":341,"loc":{"start":{"line":341,"column":20},"end":{"line":363,"column":9}},"locations":[{"start":{"line":341,"column":20},"end":{"line":363,"column":9}}]},"61":{"type":"branch","line":342,"loc":{"start":{"line":342,"column":30},"end":{"line":342,"column":51}},"locations":[{"start":{"line":342,"column":30},"end":{"line":342,"column":51}}]},"62":{"type":"branch","line":342,"loc":{"start":{"line":342,"column":42},"end":{"line":342,"column":61}},"locations":[{"start":{"line":342,"column":42},"end":{"line":342,"column":61}}]},"63":{"type":"branch","line":352,"loc":{"start":{"line":352,"column":27},"end":{"line":355,"column":20}},"locations":[{"start":{"line":352,"column":27},"end":{"line":355,"column":20}}]},"64":{"type":"branch","line":374,"loc":{"start":{"line":374,"column":7},"end":{"line":1055,"column":1}},"locations":[{"start":{"line":374,"column":7},"end":{"line":1055,"column":1}}]},"65":{"type":"branch","line":401,"loc":{"start":{"line":401,"column":17},"end":{"line":401,"column":64}},"locations":[{"start":{"line":401,"column":17},"end":{"line":401,"column":64}}]},"66":{"type":"branch","line":402,"loc":{"start":{"line":402,"column":19},"end":{"line":402,"column":58}},"locations":[{"start":{"line":402,"column":19},"end":{"line":402,"column":58}}]},"67":{"type":"branch","line":408,"loc":{"start":{"line":408,"column":33},"end":{"line":408,"column":69}},"locations":[{"start":{"line":408,"column":33},"end":{"line":408,"column":69}}]},"68":{"type":"branch","line":419,"loc":{"start":{"line":419,"column":37},"end":{"line":419,"column":61}},"locations":[{"start":{"line":419,"column":37},"end":{"line":419,"column":61}}]},"69":{"type":"branch","line":605,"loc":{"start":{"line":605,"column":23},"end":{"line":606,"column":56}},"locations":[{"start":{"line":605,"column":23},"end":{"line":606,"column":56}}]},"70":{"type":"branch","line":606,"loc":{"start":{"line":606,"column":47},"end":{"line":606,"column":56}},"locations":[{"start":{"line":606,"column":47},"end":{"line":606,"column":56}}]},"71":{"type":"branch","line":606,"loc":{"start":{"line":606,"column":52},"end":{"line":607,"column":11}},"locations":[{"start":{"line":606,"column":52},"end":{"line":607,"column":11}}]},"72":{"type":"branch","line":675,"loc":{"start":{"line":675,"column":4},"end":{"line":675,"column":43}},"locations":[{"start":{"line":675,"column":4},"end":{"line":675,"column":43}}]},"73":{"type":"branch","line":842,"loc":{"start":{"line":842,"column":49},"end":{"line":842,"column":77}},"locations":[{"start":{"line":842,"column":49},"end":{"line":842,"column":77}}]},"74":{"type":"branch","line":842,"loc":{"start":{"line":842,"column":64},"end":{"line":842,"column":79}},"locations":[{"start":{"line":842,"column":64},"end":{"line":842,"column":79}}]},"75":{"type":"branch","line":854,"loc":{"start":{"line":854,"column":29},"end":{"line":854,"column":64}},"locations":[{"start":{"line":854,"column":29},"end":{"line":854,"column":64}}]},"76":{"type":"branch","line":854,"loc":{"start":{"line":854,"column":44},"end":{"line":854,"column":84}},"locations":[{"start":{"line":854,"column":44},"end":{"line":854,"column":84}}]},"77":{"type":"branch","line":855,"loc":{"start":{"line":855,"column":15},"end":{"line":855,"column":50}},"locations":[{"start":{"line":855,"column":15},"end":{"line":855,"column":50}}]},"78":{"type":"branch","line":855,"loc":{"start":{"line":855,"column":43},"end":{"line":855,"column":68}},"locations":[{"start":{"line":855,"column":43},"end":{"line":855,"column":68}}]},"79":{"type":"branch","line":860,"loc":{"start":{"line":860,"column":11},"end":{"line":893,"column":29}},"locations":[{"start":{"line":860,"column":11},"end":{"line":893,"column":29}}]},"80":{"type":"branch","line":903,"loc":{"start":{"line":903,"column":15},"end":{"line":906,"column":37}},"locations":[{"start":{"line":903,"column":15},"end":{"line":906,"column":37}}]},"81":{"type":"branch","line":904,"loc":{"start":{"line":904,"column":18},"end":{"line":905,"column":89}},"locations":[{"start":{"line":904,"column":18},"end":{"line":905,"column":89}}]},"82":{"type":"branch","line":905,"loc":{"start":{"line":905,"column":87},"end":{"line":906,"column":37}},"locations":[{"start":{"line":905,"column":87},"end":{"line":906,"column":37}}]},"83":{"type":"branch","line":906,"loc":{"start":{"line":906,"column":33},"end":{"line":907,"column":37}},"locations":[{"start":{"line":906,"column":33},"end":{"line":907,"column":37}}]},"84":{"type":"branch","line":915,"loc":{"start":{"line":915,"column":25},"end":{"line":915,"column":61}},"locations":[{"start":{"line":915,"column":25},"end":{"line":915,"column":61}}]},"85":{"type":"branch","line":916,"loc":{"start":{"line":916,"column":26},"end":{"line":916,"column":55}},"locations":[{"start":{"line":916,"column":26},"end":{"line":916,"column":55}}]},"86":{"type":"branch","line":916,"loc":{"start":{"line":916,"column":40},"end":{"line":916,"column":69}},"locations":[{"start":{"line":916,"column":40},"end":{"line":916,"column":69}}]},"87":{"type":"branch","line":919,"loc":{"start":{"line":919,"column":17},"end":{"line":920,"column":51}},"locations":[{"start":{"line":919,"column":17},"end":{"line":920,"column":51}}]},"88":{"type":"branch","line":920,"loc":{"start":{"line":920,"column":20},"end":{"line":925,"column":35}},"locations":[{"start":{"line":920,"column":20},"end":{"line":925,"column":35}}]},"89":{"type":"branch","line":921,"loc":{"start":{"line":921,"column":21},"end":{"line":922,"column":42}},"locations":[{"start":{"line":921,"column":21},"end":{"line":922,"column":42}}]},"90":{"type":"branch","line":922,"loc":{"start":{"line":922,"column":20},"end":{"line":925,"column":35}},"locations":[{"start":{"line":922,"column":20},"end":{"line":925,"column":35}}]},"91":{"type":"branch","line":923,"loc":{"start":{"line":923,"column":20},"end":{"line":924,"column":34}},"locations":[{"start":{"line":923,"column":20},"end":{"line":924,"column":34}}]},"92":{"type":"branch","line":924,"loc":{"start":{"line":924,"column":22},"end":{"line":925,"column":35}},"locations":[{"start":{"line":924,"column":22},"end":{"line":925,"column":35}}]},"93":{"type":"branch","line":938,"loc":{"start":{"line":938,"column":15},"end":{"line":938,"column":53}},"locations":[{"start":{"line":938,"column":15},"end":{"line":938,"column":53}}]},"94":{"type":"branch","line":938,"loc":{"start":{"line":938,"column":48},"end":{"line":938,"column":74}},"locations":[{"start":{"line":938,"column":48},"end":{"line":938,"column":74}}]},"95":{"type":"branch","line":944,"loc":{"start":{"line":944,"column":25},"end":{"line":944,"column":64}},"locations":[{"start":{"line":944,"column":25},"end":{"line":944,"column":64}}]},"96":{"type":"branch","line":944,"loc":{"start":{"line":944,"column":48},"end":{"line":944,"column":84}},"locations":[{"start":{"line":944,"column":48},"end":{"line":944,"column":84}}]},"97":{"type":"branch","line":947,"loc":{"start":{"line":947,"column":17},"end":{"line":948,"column":51}},"locations":[{"start":{"line":947,"column":17},"end":{"line":948,"column":51}}]},"98":{"type":"branch","line":948,"loc":{"start":{"line":948,"column":20},"end":{"line":951,"column":61}},"locations":[{"start":{"line":948,"column":20},"end":{"line":951,"column":61}}]},"99":{"type":"branch","line":949,"loc":{"start":{"line":949,"column":21},"end":{"line":950,"column":53}},"locations":[{"start":{"line":949,"column":21},"end":{"line":950,"column":53}}]},"100":{"type":"branch","line":950,"loc":{"start":{"line":950,"column":20},"end":{"line":951,"column":61}},"locations":[{"start":{"line":950,"column":20},"end":{"line":951,"column":61}}]},"101":{"type":"branch","line":957,"loc":{"start":{"line":957,"column":15},"end":{"line":957,"column":54}},"locations":[{"start":{"line":957,"column":15},"end":{"line":957,"column":54}}]},"102":{"type":"branch","line":957,"loc":{"start":{"line":957,"column":37},"end":{"line":957,"column":71}},"locations":[{"start":{"line":957,"column":37},"end":{"line":957,"column":71}}]},"103":{"type":"branch","line":962,"loc":{"start":{"line":962,"column":11},"end":{"line":965,"column":18}},"locations":[{"start":{"line":962,"column":11},"end":{"line":965,"column":18}}]},"104":{"type":"branch","line":965,"loc":{"start":{"line":965,"column":12},"end":{"line":966,"column":19}},"locations":[{"start":{"line":965,"column":12},"end":{"line":966,"column":19}}]},"105":{"type":"branch","line":967,"loc":{"start":{"line":967,"column":12},"end":{"line":970,"column":18}},"locations":[{"start":{"line":967,"column":12},"end":{"line":970,"column":18}}]},"106":{"type":"branch","line":970,"loc":{"start":{"line":970,"column":12},"end":{"line":1038,"column":18}},"locations":[{"start":{"line":970,"column":12},"end":{"line":1038,"column":18}}]},"107":{"type":"branch","line":971,"loc":{"start":{"line":971,"column":14},"end":{"line":1034,"column":17}},"locations":[{"start":{"line":971,"column":14},"end":{"line":1034,"column":17}}]},"108":{"type":"branch","line":1034,"loc":{"start":{"line":1034,"column":12},"end":{"line":1038,"column":18}},"locations":[{"start":{"line":1034,"column":12},"end":{"line":1038,"column":18}}]},"109":{"type":"branch","line":1043,"loc":{"start":{"line":1043,"column":7},"end":{"line":1051,"column":10}},"locations":[{"start":{"line":1043,"column":7},"end":{"line":1051,"column":10}}]},"110":{"type":"branch","line":422,"loc":{"start":{"line":422,"column":4},"end":{"line":436,"column":6}},"locations":[{"start":{"line":422,"column":4},"end":{"line":436,"column":6}}]},"111":{"type":"branch","line":424,"loc":{"start":{"line":424,"column":23},"end":{"line":426,"column":7}},"locations":[{"start":{"line":424,"column":23},"end":{"line":426,"column":7}}]},"112":{"type":"branch","line":430,"loc":{"start":{"line":430,"column":8},"end":{"line":433,"column":12}},"locations":[{"start":{"line":430,"column":8},"end":{"line":433,"column":12}}]},"113":{"type":"branch","line":433,"loc":{"start":{"line":433,"column":8},"end":{"line":434,"column":12}},"locations":[{"start":{"line":433,"column":8},"end":{"line":434,"column":12}}]},"114":{"type":"branch","line":429,"loc":{"start":{"line":429,"column":10},"end":{"line":429,"column":64}},"locations":[{"start":{"line":429,"column":10},"end":{"line":429,"column":64}}]},"115":{"type":"branch","line":432,"loc":{"start":{"line":432,"column":10},"end":{"line":432,"column":79}},"locations":[{"start":{"line":432,"column":10},"end":{"line":432,"column":79}}]},"116":{"type":"branch","line":432,"loc":{"start":{"line":432,"column":26},"end":{"line":432,"column":43}},"locations":[{"start":{"line":432,"column":26},"end":{"line":432,"column":43}}]},"117":{"type":"branch","line":441,"loc":{"start":{"line":441,"column":4},"end":{"line":463,"column":6}},"locations":[{"start":{"line":441,"column":4},"end":{"line":463,"column":6}}]},"118":{"type":"branch","line":442,"loc":{"start":{"line":442,"column":17},"end":{"line":444,"column":7}},"locations":[{"start":{"line":442,"column":17},"end":{"line":444,"column":7}}]},"119":{"type":"branch","line":444,"loc":{"start":{"line":444,"column":6},"end":{"line":445,"column":37}},"locations":[{"start":{"line":444,"column":6},"end":{"line":445,"column":37}}]},"120":{"type":"branch","line":445,"loc":{"start":{"line":445,"column":29},"end":{"line":445,"column":45}},"locations":[{"start":{"line":445,"column":29},"end":{"line":445,"column":45}}]},"121":{"type":"branch","line":446,"loc":{"start":{"line":446,"column":22},"end":{"line":448,"column":7}},"locations":[{"start":{"line":446,"column":22},"end":{"line":448,"column":7}}]},"122":{"type":"branch","line":448,"loc":{"start":{"line":448,"column":6},"end":{"line":449,"column":40}},"locations":[{"start":{"line":448,"column":6},"end":{"line":449,"column":40}}]},"123":{"type":"branch","line":449,"loc":{"start":{"line":449,"column":31},"end":{"line":449,"column":44}},"locations":[{"start":{"line":449,"column":31},"end":{"line":449,"column":44}}]},"124":{"type":"branch","line":450,"loc":{"start":{"line":450,"column":23},"end":{"line":454,"column":7}},"locations":[{"start":{"line":450,"column":23},"end":{"line":454,"column":7}}]},"125":{"type":"branch","line":454,"loc":{"start":{"line":454,"column":6},"end":{"line":456,"column":67}},"locations":[{"start":{"line":454,"column":6},"end":{"line":456,"column":67}}]},"126":{"type":"branch","line":459,"loc":{"start":{"line":459,"column":41},"end":{"line":462,"column":43}},"locations":[{"start":{"line":459,"column":41},"end":{"line":462,"column":43}}]},"127":{"type":"branch","line":473,"loc":{"start":{"line":473,"column":12},"end":{"line":488,"column":5}},"locations":[{"start":{"line":473,"column":12},"end":{"line":488,"column":5}}]},"128":{"type":"branch","line":476,"loc":{"start":{"line":476,"column":12},"end":{"line":481,"column":7}},"locations":[{"start":{"line":476,"column":12},"end":{"line":481,"column":7}}]},"129":{"type":"branch","line":477,"loc":{"start":{"line":477,"column":23},"end":{"line":479,"column":9}},"locations":[{"start":{"line":477,"column":23},"end":{"line":479,"column":9}}]},"130":{"type":"branch","line":485,"loc":{"start":{"line":485,"column":11},"end":{"line":487,"column":6}},"locations":[{"start":{"line":485,"column":11},"end":{"line":487,"column":6}}]},"131":{"type":"branch","line":490,"loc":{"start":{"line":490,"column":12},"end":{"line":512,"column":5}},"locations":[{"start":{"line":490,"column":12},"end":{"line":512,"column":5}}]},"132":{"type":"branch","line":492,"loc":{"start":{"line":492,"column":28},"end":{"line":498,"column":5}},"locations":[{"start":{"line":492,"column":28},"end":{"line":498,"column":5}}]},"133":{"type":"branch","line":498,"loc":{"start":{"line":498,"column":4},"end":{"line":511,"column":6}},"locations":[{"start":{"line":498,"column":4},"end":{"line":511,"column":6}}]},"134":{"type":"branch","line":495,"loc":{"start":{"line":495,"column":13},"end":{"line":497,"column":8}},"locations":[{"start":{"line":495,"column":13},"end":{"line":497,"column":8}}]},"135":{"type":"branch","line":500,"loc":{"start":{"line":500,"column":12},"end":{"line":505,"column":7}},"locations":[{"start":{"line":500,"column":12},"end":{"line":505,"column":7}}]},"136":{"type":"branch","line":501,"loc":{"start":{"line":501,"column":23},"end":{"line":503,"column":9}},"locations":[{"start":{"line":501,"column":23},"end":{"line":503,"column":9}}]},"137":{"type":"branch","line":509,"loc":{"start":{"line":509,"column":11},"end":{"line":511,"column":6}},"locations":[{"start":{"line":509,"column":11},"end":{"line":511,"column":6}}]},"138":{"type":"branch","line":515,"loc":{"start":{"line":515,"column":4},"end":{"line":528,"column":6}},"locations":[{"start":{"line":515,"column":4},"end":{"line":528,"column":6}}]},"139":{"type":"branch","line":516,"loc":{"start":{"line":516,"column":36},"end":{"line":518,"column":7}},"locations":[{"start":{"line":516,"column":36},"end":{"line":518,"column":7}}]},"140":{"type":"branch","line":523,"loc":{"start":{"line":523,"column":6},"end":{"line":525,"column":8}},"locations":[{"start":{"line":523,"column":6},"end":{"line":525,"column":8}}]},"141":{"type":"branch","line":532,"loc":{"start":{"line":532,"column":12},"end":{"line":554,"column":5}},"locations":[{"start":{"line":532,"column":12},"end":{"line":554,"column":5}}]},"142":{"type":"branch","line":534,"loc":{"start":{"line":534,"column":28},"end":{"line":539,"column":5}},"locations":[{"start":{"line":534,"column":28},"end":{"line":539,"column":5}}]},"143":{"type":"branch","line":539,"loc":{"start":{"line":539,"column":4},"end":{"line":553,"column":6}},"locations":[{"start":{"line":539,"column":4},"end":{"line":553,"column":6}}]},"144":{"type":"branch","line":536,"loc":{"start":{"line":536,"column":13},"end":{"line":538,"column":8}},"locations":[{"start":{"line":536,"column":13},"end":{"line":538,"column":8}}]},"145":{"type":"branch","line":541,"loc":{"start":{"line":541,"column":22},"end":{"line":546,"column":6}},"locations":[{"start":{"line":541,"column":22},"end":{"line":546,"column":6}}]},"146":{"type":"branch","line":542,"loc":{"start":{"line":542,"column":21},"end":{"line":544,"column":7}},"locations":[{"start":{"line":542,"column":21},"end":{"line":544,"column":7}}]},"147":{"type":"branch","line":550,"loc":{"start":{"line":550,"column":11},"end":{"line":553,"column":6}},"locations":[{"start":{"line":550,"column":11},"end":{"line":553,"column":6}}]},"148":{"type":"branch","line":556,"loc":{"start":{"line":556,"column":37},"end":{"line":573,"column":5}},"locations":[{"start":{"line":556,"column":37},"end":{"line":573,"column":5}}]},"149":{"type":"branch","line":557,"loc":{"start":{"line":557,"column":30},"end":{"line":572,"column":5}},"locations":[{"start":{"line":557,"column":30},"end":{"line":572,"column":5}}]},"150":{"type":"branch","line":558,"loc":{"start":{"line":558,"column":52},"end":{"line":565,"column":7}},"locations":[{"start":{"line":558,"column":52},"end":{"line":565,"column":7}}]},"151":{"type":"branch","line":576,"loc":{"start":{"line":576,"column":4},"end":{"line":587,"column":6}},"locations":[{"start":{"line":576,"column":4},"end":{"line":587,"column":6}}]},"152":{"type":"branch","line":577,"loc":{"start":{"line":577,"column":30},"end":{"line":579,"column":7}},"locations":[{"start":{"line":577,"column":30},"end":{"line":579,"column":7}}]},"153":{"type":"branch","line":581,"loc":{"start":{"line":581,"column":14},"end":{"line":583,"column":9}},"locations":[{"start":{"line":581,"column":14},"end":{"line":583,"column":9}}]},"154":{"type":"branch","line":591,"loc":{"start":{"line":591,"column":46},"end":{"line":602,"column":5}},"locations":[{"start":{"line":591,"column":46},"end":{"line":602,"column":5}}]},"155":{"type":"branch","line":592,"loc":{"start":{"line":592,"column":28},"end":{"line":594,"column":5}},"locations":[{"start":{"line":592,"column":28},"end":{"line":594,"column":5}}]},"156":{"type":"branch","line":596,"loc":{"start":{"line":596,"column":12},"end":{"line":598,"column":7}},"locations":[{"start":{"line":596,"column":12},"end":{"line":598,"column":7}}]},"157":{"type":"branch","line":606,"loc":{"start":{"line":606,"column":17},"end":{"line":606,"column":47}},"locations":[{"start":{"line":606,"column":17},"end":{"line":606,"column":47}}]},"158":{"type":"branch","line":621,"loc":{"start":{"line":621,"column":12},"end":{"line":626,"column":5}},"locations":[{"start":{"line":621,"column":12},"end":{"line":626,"column":5}}]},"159":{"type":"branch","line":622,"loc":{"start":{"line":622,"column":28},"end":{"line":624,"column":5}},"locations":[{"start":{"line":622,"column":28},"end":{"line":624,"column":5}}]},"160":{"type":"branch","line":624,"loc":{"start":{"line":624,"column":4},"end":{"line":625,"column":27}},"locations":[{"start":{"line":624,"column":4},"end":{"line":625,"column":27}}]},"161":{"type":"branch","line":628,"loc":{"start":{"line":628,"column":12},"end":{"line":635,"column":5}},"locations":[{"start":{"line":628,"column":12},"end":{"line":635,"column":5}}]},"162":{"type":"branch","line":629,"loc":{"start":{"line":629,"column":25},"end":{"line":631,"column":5}},"locations":[{"start":{"line":629,"column":25},"end":{"line":631,"column":5}}]},"163":{"type":"branch","line":631,"loc":{"start":{"line":631,"column":4},"end":{"line":632,"column":59}},"locations":[{"start":{"line":631,"column":4},"end":{"line":632,"column":59}}]},"164":{"type":"branch","line":632,"loc":{"start":{"line":632,"column":59},"end":{"line":634,"column":5}},"locations":[{"start":{"line":632,"column":59},"end":{"line":634,"column":5}}]},"165":{"type":"branch","line":632,"loc":{"start":{"line":632,"column":20},"end":{"line":632,"column":56}},"locations":[{"start":{"line":632,"column":20},"end":{"line":632,"column":56}}]},"166":{"type":"branch","line":637,"loc":{"start":{"line":637,"column":12},"end":{"line":673,"column":5}},"locations":[{"start":{"line":637,"column":12},"end":{"line":673,"column":5}}]},"167":{"type":"branch","line":639,"loc":{"start":{"line":639,"column":9},"end":{"line":639,"column":47}},"locations":[{"start":{"line":639,"column":9},"end":{"line":639,"column":47}}]},"168":{"type":"branch","line":639,"loc":{"start":{"line":639,"column":47},"end":{"line":644,"column":5}},"locations":[{"start":{"line":639,"column":47},"end":{"line":644,"column":5}}]},"169":{"type":"branch","line":644,"loc":{"start":{"line":644,"column":4},"end":{"line":646,"column":51}},"locations":[{"start":{"line":644,"column":4},"end":{"line":646,"column":51}}]},"170":{"type":"branch","line":646,"loc":{"start":{"line":646,"column":32},"end":{"line":646,"column":74}},"locations":[{"start":{"line":646,"column":32},"end":{"line":646,"column":74}}]},"171":{"type":"branch","line":646,"loc":{"start":{"line":646,"column":51},"end":{"line":646,"column":79}},"locations":[{"start":{"line":646,"column":51},"end":{"line":646,"column":79}}]},"172":{"type":"branch","line":641,"loc":{"start":{"line":641,"column":13},"end":{"line":643,"column":8}},"locations":[{"start":{"line":641,"column":13},"end":{"line":643,"column":8}}]},"173":{"type":"branch","line":647,"loc":{"start":{"line":647,"column":29},"end":{"line":665,"column":6}},"locations":[{"start":{"line":647,"column":29},"end":{"line":665,"column":6}}]},"174":{"type":"branch","line":654,"loc":{"start":{"line":654,"column":23},"end":{"line":656,"column":9}},"locations":[{"start":{"line":654,"column":23},"end":{"line":656,"column":9}}]},"175":{"type":"branch","line":658,"loc":{"start":{"line":658,"column":6},"end":{"line":664,"column":7}},"locations":[{"start":{"line":658,"column":6},"end":{"line":664,"column":7}}]},"176":{"type":"branch","line":669,"loc":{"start":{"line":669,"column":11},"end":{"line":672,"column":6}},"locations":[{"start":{"line":669,"column":11},"end":{"line":672,"column":6}}]},"177":{"type":"branch","line":680,"loc":{"start":{"line":680,"column":32},"end":{"line":687,"column":5}},"locations":[{"start":{"line":680,"column":32},"end":{"line":687,"column":5}}]},"178":{"type":"branch","line":684,"loc":{"start":{"line":684,"column":26},"end":{"line":685,"column":11}},"locations":[{"start":{"line":684,"column":26},"end":{"line":685,"column":11}}]},"179":{"type":"branch","line":689,"loc":{"start":{"line":689,"column":4},"end":{"line":689,"column":61}},"locations":[{"start":{"line":689,"column":4},"end":{"line":689,"column":61}}]},"180":{"type":"branch","line":689,"loc":{"start":{"line":689,"column":10},"end":{"line":689,"column":30}},"locations":[{"start":{"line":689,"column":10},"end":{"line":689,"column":30}}]},"181":{"type":"branch","line":689,"loc":{"start":{"line":689,"column":51},"end":{"line":689,"column":61}},"locations":[{"start":{"line":689,"column":51},"end":{"line":689,"column":61}}]},"182":{"type":"branch","line":689,"loc":{"start":{"line":689,"column":34},"end":{"line":689,"column":51}},"locations":[{"start":{"line":689,"column":34},"end":{"line":689,"column":51}}]},"183":{"type":"branch","line":714,"loc":{"start":{"line":714,"column":12},"end":{"line":717,"column":5}},"locations":[{"start":{"line":714,"column":12},"end":{"line":717,"column":5}}]},"184":{"type":"branch","line":719,"loc":{"start":{"line":719,"column":36},"end":{"line":768,"column":5}},"locations":[{"start":{"line":719,"column":36},"end":{"line":768,"column":5}}]},"185":{"type":"branch","line":720,"loc":{"start":{"line":720,"column":28},"end":{"line":722,"column":5}},"locations":[{"start":{"line":720,"column":28},"end":{"line":722,"column":5}}]},"186":{"type":"branch","line":739,"loc":{"start":{"line":739,"column":27},"end":{"line":739,"column":57}},"locations":[{"start":{"line":739,"column":27},"end":{"line":739,"column":57}}]},"187":{"type":"branch","line":739,"loc":{"start":{"line":739,"column":47},"end":{"line":739,"column":65}},"locations":[{"start":{"line":739,"column":47},"end":{"line":739,"column":65}}]},"188":{"type":"branch","line":742,"loc":{"start":{"line":742,"column":38},"end":{"line":742,"column":46}},"locations":[{"start":{"line":742,"column":38},"end":{"line":742,"column":46}}]},"189":{"type":"branch","line":743,"loc":{"start":{"line":743,"column":21},"end":{"line":746,"column":7}},"locations":[{"start":{"line":743,"column":21},"end":{"line":746,"column":7}}]},"190":{"type":"branch","line":751,"loc":{"start":{"line":751,"column":26},"end":{"line":754,"column":7}},"locations":[{"start":{"line":751,"column":26},"end":{"line":754,"column":7}}]},"191":{"type":"branch","line":760,"loc":{"start":{"line":760,"column":6},"end":{"line":764,"column":7}},"locations":[{"start":{"line":760,"column":6},"end":{"line":764,"column":7}}]},"192":{"type":"branch","line":765,"loc":{"start":{"line":765,"column":4},"end":{"line":767,"column":5}},"locations":[{"start":{"line":765,"column":4},"end":{"line":767,"column":5}}]},"193":{"type":"branch","line":782,"loc":{"start":{"line":782,"column":42},"end":{"line":808,"column":5}},"locations":[{"start":{"line":782,"column":42},"end":{"line":808,"column":5}}]},"194":{"type":"branch","line":785,"loc":{"start":{"line":785,"column":56},"end":{"line":787,"column":5}},"locations":[{"start":{"line":785,"column":56},"end":{"line":787,"column":5}}]},"195":{"type":"branch","line":792,"loc":{"start":{"line":792,"column":20},"end":{"line":794,"column":5}},"locations":[{"start":{"line":792,"column":20},"end":{"line":794,"column":5}}]},"196":{"type":"branch","line":798,"loc":{"start":{"line":798,"column":23},"end":{"line":800,"column":7}},"locations":[{"start":{"line":798,"column":23},"end":{"line":800,"column":7}}]},"197":{"type":"branch","line":803,"loc":{"start":{"line":803,"column":4},"end":{"line":805,"column":6}},"locations":[{"start":{"line":803,"column":4},"end":{"line":805,"column":6}}]},"198":{"type":"branch","line":835,"loc":{"start":{"line":835,"column":21},"end":{"line":835,"column":50}},"locations":[{"start":{"line":835,"column":21},"end":{"line":835,"column":50}}]},"199":{"type":"branch","line":844,"loc":{"start":{"line":844,"column":21},"end":{"line":849,"column":14}},"locations":[{"start":{"line":844,"column":21},"end":{"line":849,"column":14}}]},"200":{"type":"branch","line":845,"loc":{"start":{"line":845,"column":39},"end":{"line":847,"column":15}},"locations":[{"start":{"line":845,"column":39},"end":{"line":847,"column":15}}]},"201":{"type":"branch","line":848,"loc":{"start":{"line":848,"column":30},"end":{"line":848,"column":45}},"locations":[{"start":{"line":848,"column":30},"end":{"line":848,"column":45}}]},"202":{"type":"branch","line":862,"loc":{"start":{"line":862,"column":25},"end":{"line":875,"column":34}},"locations":[{"start":{"line":862,"column":25},"end":{"line":875,"column":34}}]},"203":{"type":"branch","line":868,"loc":{"start":{"line":868,"column":27},"end":{"line":871,"column":20}},"locations":[{"start":{"line":868,"column":27},"end":{"line":871,"column":20}}]},"204":{"type":"branch","line":927,"loc":{"start":{"line":927,"column":23},"end":{"line":936,"column":16}},"locations":[{"start":{"line":927,"column":23},"end":{"line":936,"column":16}}]},"205":{"type":"branch","line":928,"loc":{"start":{"line":928,"column":58},"end":{"line":930,"column":17}},"locations":[{"start":{"line":928,"column":58},"end":{"line":930,"column":17}}]},"206":{"type":"branch","line":931,"loc":{"start":{"line":931,"column":33},"end":{"line":934,"column":17}},"locations":[{"start":{"line":931,"column":33},"end":{"line":934,"column":17}}]},"207":{"type":"branch","line":934,"loc":{"start":{"line":934,"column":16},"end":{"line":935,"column":53}},"locations":[{"start":{"line":934,"column":16},"end":{"line":935,"column":53}}]},"208":{"type":"branch","line":953,"loc":{"start":{"line":953,"column":23},"end":{"line":955,"column":16}},"locations":[{"start":{"line":953,"column":23},"end":{"line":955,"column":16}}]},"209":{"type":"branch","line":973,"loc":{"start":{"line":973,"column":38},"end":{"line":1033,"column":15}},"locations":[{"start":{"line":973,"column":38},"end":{"line":1033,"column":15}}]},"210":{"type":"branch","line":974,"loc":{"start":{"line":974,"column":37},"end":{"line":974,"column":61}},"locations":[{"start":{"line":974,"column":37},"end":{"line":974,"column":61}}]},"211":{"type":"branch","line":975,"loc":{"start":{"line":975,"column":83},"end":{"line":975,"column":91}},"locations":[{"start":{"line":975,"column":83},"end":{"line":975,"column":91}}]},"212":{"type":"branch","line":985,"loc":{"start":{"line":985,"column":38},"end":{"line":985,"column":75}},"locations":[{"start":{"line":985,"column":38},"end":{"line":985,"column":75}}]},"213":{"type":"branch","line":991,"loc":{"start":{"line":991,"column":25},"end":{"line":992,"column":54}},"locations":[{"start":{"line":991,"column":25},"end":{"line":992,"column":54}}]},"214":{"type":"branch","line":992,"loc":{"start":{"line":992,"column":52},"end":{"line":996,"column":48}},"locations":[{"start":{"line":992,"column":52},"end":{"line":996,"column":48}}]},"215":{"type":"branch","line":993,"loc":{"start":{"line":993,"column":28},"end":{"line":994,"column":91}},"locations":[{"start":{"line":993,"column":28},"end":{"line":994,"column":91}}]},"216":{"type":"branch","line":994,"loc":{"start":{"line":994,"column":89},"end":{"line":996,"column":48}},"locations":[{"start":{"line":994,"column":89},"end":{"line":996,"column":48}}]},"217":{"type":"branch","line":1000,"loc":{"start":{"line":1000,"column":23},"end":{"line":1003,"column":31}},"locations":[{"start":{"line":1000,"column":23},"end":{"line":1003,"column":31}}]},"218":{"type":"branch","line":1003,"loc":{"start":{"line":1003,"column":24},"end":{"line":1004,"column":31}},"locations":[{"start":{"line":1003,"column":24},"end":{"line":1004,"column":31}}]},"219":{"type":"branch","line":1006,"loc":{"start":{"line":1006,"column":47},"end":{"line":1029,"column":28}},"locations":[{"start":{"line":1006,"column":47},"end":{"line":1029,"column":28}}]},"220":{"type":"branch","line":1029,"loc":{"start":{"line":1029,"column":22},"end":{"line":1030,"column":29}},"locations":[{"start":{"line":1029,"column":22},"end":{"line":1030,"column":29}}]},"221":{"type":"branch","line":1008,"loc":{"start":{"line":1008,"column":46},"end":{"line":1028,"column":25}},"locations":[{"start":{"line":1008,"column":46},"end":{"line":1028,"column":25}}]},"222":{"type":"branch","line":1012,"loc":{"start":{"line":1012,"column":54},"end":{"line":1012,"column":69}},"locations":[{"start":{"line":1012,"column":54},"end":{"line":1012,"column":69}}]},"223":{"type":"branch","line":1050,"loc":{"start":{"line":1050,"column":19},"end":{"line":1050,"column":49}},"locations":[{"start":{"line":1050,"column":19},"end":{"line":1050,"column":49}}]}},"b":{"0":[40],"1":[0],"2":[0],"3":[0],"4":[0],"5":[0],"6":[0],"7":[0],"8":[0],"9":[75],"10":[1],"11":[74],"12":[15],"13":[59],"14":[344],"15":[80],"16":[40],"17":[14],"18":[330],"19":[59],"20":[271],"21":[105],"22":[166],"23":[110],"24":[0],"25":[170],"26":[0],"27":[330],"28":[224],"29":[106],"30":[4],"31":[102],"32":[59],"33":[43],"34":[244],"35":[349],"36":[33],"37":[19],"38":[330],"39":[224],"40":[14],"41":[4],"42":[0],"43":[326],"44":[4],"45":[3],"46":[1],"47":[1],"48":[3],"49":[1],"50":[3],"51":[0],"52":[1],"53":[4],"54":[1],"55":[0],"56":[4],"57":[4],"58":[5],"59":[1],"60":[5],"61":[3],"62":[2],"63":[1],"64":[324],"65":[0],"66":[0],"67":[178],"68":[315],"69":[180],"70":[0],"71":[144],"72":[9],"73":[42],"74":[282],"75":[180],"76":[144],"77":[180],"78":[144],"79":[42],"80":[180],"81":[19],"82":[161],"83":[144],"84":[315],"85":[53],"86":[271],"87":[9],"88":[315],"89":[135],"90":[180],"91":[53],"92":[127],"93":[53],"94":[271],"95":[315],"96":[180],"97":[9],"98":[315],"99":[135],"100":[180],"101":[1],"102":[323],"103":[12],"104":[312],"105":[9],"106":[315],"107":[180],"108":[135],"109":[4],"110":[89],"111":[0],"112":[88],"113":[88],"114":[3],"115":[2],"116":[0],"117":[45],"118":[43],"119":[2],"120":[0],"121":[0],"122":[2],"123":[0],"124":[0],"125":[2],"126":[2],"127":[44],"128":[44],"129":[0],"130":[44],"131":[44],"132":[3],"133":[41],"134":[3],"135":[41],"136":[0],"137":[41],"138":[194],"139":[0],"140":[0],"141":[44],"142":[3],"143":[41],"144":[3],"145":[193],"146":[0],"147":[41],"148":[90],"149":[40],"150":[75],"151":[1],"152":[0],"153":[1],"154":[1],"155":[0],"156":[1],"157":[180],"158":[44],"159":[41],"160":[3],"161":[127],"162":[88],"163":[39],"164":[0],"165":[39],"166":[85],"167":[82],"168":[48],"169":[37],"170":[0],"171":[37],"172":[48],"173":[188],"174":[0],"175":[0],"176":[37],"177":[44],"178":[43],"179":[83],"180":[39],"181":[44],"182":[74],"183":[81],"184":[1],"185":[0],"186":[0],"187":[0],"188":[0],"189":[0],"190":[0],"191":[0],"192":[0],"193":[1],"194":[0],"195":[0],"196":[0],"197":[0],"198":[4],"199":[39],"200":[0],"201":[39],"202":[38],"203":[37],"204":[51],"205":[0],"206":[17],"207":[34],"208":[1],"209":[349],"210":[33],"211":[229],"212":[19],"213":[6],"214":[343],"215":[104],"216":[239],"217":[19],"218":[330],"219":[120],"220":[229],"221":[344],"222":[0],"223":[3]},"fnMap":{"0":{"name":"formatPlanLabel","decl":{"start":{"line":142,"column":0},"end":{"line":158,"column":1}},"loc":{"start":{"line":142,"column":0},"end":{"line":158,"column":1}},"line":142},"1":{"name":"mapForgeItemStatus","decl":{"start":{"line":160,"column":0},"end":{"line":169,"column":1}},"loc":{"start":{"line":160,"column":0},"end":{"line":169,"column":1}},"line":160},"2":{"name":"mapForgePhaseChipState","decl":{"start":{"line":171,"column":0},"end":{"line":188,"column":1}},"loc":{"start":{"line":171,"column":0},"end":{"line":188,"column":1}},"line":171},"3":{"name":"allTaskPhasesCompleted","decl":{"start":{"line":190,"column":0},"end":{"line":206,"column":1}},"loc":{"start":{"line":190,"column":0},"end":{"line":206,"column":1}},"line":190},"4":{"name":"deriveStatusFromTaskPhases","decl":{"start":{"line":208,"column":0},"end":{"line":223,"column":1}},"loc":{"start":{"line":208,"column":0},"end":{"line":223,"column":1}},"line":208},"5":{"name":"resolveForgeTaskRowStatus","decl":{"start":{"line":225,"column":0},"end":{"line":252,"column":1}},"loc":{"start":{"line":225,"column":0},"end":{"line":252,"column":1}},"line":225},"6":{"name":"ForgeTemplatesModal","decl":{"start":{"line":254,"column":0},"end":{"line":372,"column":1}},"loc":{"start":{"line":254,"column":0},"end":{"line":372,"column":1}},"line":254},"7":{"name":"handleKeyDown","decl":{"start":{"line":270,"column":26},"end":{"line":276,"column":6}},"loc":{"start":{"line":270,"column":26},"end":{"line":276,"column":6}},"line":270},"8":{"name":"onClick","decl":{"start":{"line":318,"column":25},"end":{"line":320,"column":18}},"loc":{"start":{"line":318,"column":25},"end":{"line":320,"column":18}},"line":318},"9":{"name":"onClick","decl":{"start":{"line":327,"column":25},"end":{"line":330,"column":18}},"loc":{"start":{"line":327,"column":25},"end":{"line":330,"column":18}},"line":327},"10":{"name":"onClick","decl":{"start":{"line":352,"column":27},"end":{"line":355,"column":20}},"loc":{"start":{"line":352,"column":27},"end":{"line":355,"column":20}},"line":352},"11":{"name":"Forge","decl":{"start":{"line":374,"column":7},"end":{"line":1055,"column":1}},"loc":{"start":{"line":374,"column":7},"end":{"line":1055,"column":1}},"line":374},"12":{"name":"loadPlans","decl":{"start":{"line":541,"column":22},"end":{"line":546,"column":6}},"loc":{"start":{"line":541,"column":22},"end":{"line":546,"column":6}},"line":541},"13":{"name":"onClose","decl":{"start":{"line":618,"column":13},"end":{"line":618,"column":42}},"loc":{"start":{"line":618,"column":13},"end":{"line":618,"column":42}},"line":618},"14":{"name":"installedTemplateId","decl":{"start":{"line":641,"column":13},"end":{"line":643,"column":8}},"loc":{"start":{"line":641,"column":13},"end":{"line":643,"column":8}},"line":641},"15":{"name":"refreshPhaseView","decl":{"start":{"line":647,"column":29},"end":{"line":665,"column":6}},"loc":{"start":{"line":647,"column":29},"end":{"line":665,"column":6}},"line":647},"16":{"name":"onClick","decl":{"start":{"line":835,"column":21},"end":{"line":835,"column":50}},"loc":{"start":{"line":835,"column":21},"end":{"line":835,"column":50}},"line":835},"17":{"name":"onClick","decl":{"start":{"line":844,"column":21},"end":{"line":849,"column":14}},"loc":{"start":{"line":844,"column":21},"end":{"line":849,"column":14}},"line":844},"18":{"name":"onClick","decl":{"start":{"line":868,"column":27},"end":{"line":871,"column":20}},"loc":{"start":{"line":868,"column":27},"end":{"line":871,"column":20}},"line":868},"19":{"name":"onClick","decl":{"start":{"line":879,"column":25},"end":{"line":882,"column":18}},"loc":{"start":{"line":879,"column":25},"end":{"line":882,"column":18}},"line":879},"20":{"name":"onClick","decl":{"start":{"line":927,"column":23},"end":{"line":936,"column":16}},"loc":{"start":{"line":927,"column":23},"end":{"line":936,"column":16}},"line":927},"21":{"name":"onClick","decl":{"start":{"line":953,"column":23},"end":{"line":955,"column":16}},"loc":{"start":{"line":953,"column":23},"end":{"line":955,"column":16}},"line":953},"22":{"name":"onClose","decl":{"start":{"line":1050,"column":19},"end":{"line":1050,"column":49}},"loc":{"start":{"line":1050,"column":19},"end":{"line":1050,"column":49}},"line":1050}},"f":{"0":40,"1":75,"2":344,"3":110,"4":330,"5":349,"6":4,"7":1,"8":0,"9":1,"10":1,"11":324,"12":193,"13":0,"14":48,"15":188,"16":4,"17":39,"18":37,"19":0,"20":51,"21":1,"22":3}} +,"/Users/lstern/projects/forge/src/features/forge/hooks/useForgeExecution.ts": {"path":"/Users/lstern/projects/forge/src/features/forge/hooks/useForgeExecution.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":74}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":30}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":72}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":49}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":10}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":33}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":32}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":28}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":31}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":33}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":30}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":31}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":29}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":32}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":30}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":1}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":76}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":49}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":10}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":33}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":32}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":28}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":31}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":30}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":1}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":60}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":50}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":16}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":3}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":74}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":95}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":58}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":31}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":16}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":3}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":28}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":45}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":1}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":58}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":50}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":16}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":3}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":68}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":89}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":54}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":31}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":16}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":3}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":28}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":45}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":1}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":66}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":25}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":28}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":3}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":37}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":27}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":3}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":7}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":48}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":22}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":28}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":5}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":83}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":11}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":35}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":3}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":1}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":42}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":35}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":35}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":5}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":1}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":35}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":14}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":22}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":19}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":19}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":21}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":17}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":17}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":16}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":14}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":18}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":17}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":27}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":45}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":56}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":80}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":66}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":32}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":51}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":32}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":18}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":48}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":24}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":18}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":5}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":35}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":40}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":36}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":20}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":26}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":7}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":5}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":16}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":21}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":49}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":26}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":25}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":9}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":50}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":45}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":33}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":29}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":32}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":26}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":22}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":13}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":5}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":9}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":26}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":31}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":28}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":39}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":8}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":21}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":73}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":5}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":43}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":19}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":18}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":35}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":31}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":34}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":6}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":9}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":37}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":31}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":44}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":45}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":77}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":15}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":7}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":44}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":34}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":35}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":35}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":27}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":27}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":25}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":93}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":45}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":23}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":24}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":54}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":28}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":51}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":22}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":29}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":19}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":20}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":12}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":28}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":24}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":11}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":55}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":38}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":11}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":39}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":9}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":20}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":8}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":11}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":42}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":26}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":17}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":9}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":60}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":26}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":17}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":9}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":49}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":53}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":57}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":58}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":43}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":17}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":28}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":78}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":28}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":19}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":11}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":23}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":19}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":11}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":45}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":24}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":82}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":11}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":47}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":25}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":83}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":11}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":78}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":28}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":106}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":14}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":11}},"305":{"start":{"line":306,"column":0},"end":{"line":306,"column":68}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":14}},"307":{"start":{"line":308,"column":0},"end":{"line":308,"column":30}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":37}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":46}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":34}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":42}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":13}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":28}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":109}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":14}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":11}},"317":{"start":{"line":318,"column":0},"end":{"line":318,"column":46}},"318":{"start":{"line":319,"column":0},"end":{"line":319,"column":32}},"319":{"start":{"line":320,"column":0},"end":{"line":320,"column":54}},"320":{"start":{"line":321,"column":0},"end":{"line":321,"column":52}},"321":{"start":{"line":322,"column":0},"end":{"line":322,"column":41}},"322":{"start":{"line":323,"column":0},"end":{"line":323,"column":64}},"323":{"start":{"line":324,"column":0},"end":{"line":324,"column":30}},"324":{"start":{"line":325,"column":0},"end":{"line":325,"column":21}},"325":{"start":{"line":326,"column":0},"end":{"line":326,"column":13}},"327":{"start":{"line":328,"column":0},"end":{"line":328,"column":61}},"328":{"start":{"line":329,"column":0},"end":{"line":329,"column":28}},"329":{"start":{"line":330,"column":0},"end":{"line":330,"column":30}},"330":{"start":{"line":331,"column":0},"end":{"line":331,"column":114}},"331":{"start":{"line":332,"column":0},"end":{"line":332,"column":33}},"332":{"start":{"line":333,"column":0},"end":{"line":333,"column":22}},"333":{"start":{"line":334,"column":0},"end":{"line":334,"column":16}},"334":{"start":{"line":335,"column":0},"end":{"line":335,"column":13}},"336":{"start":{"line":337,"column":0},"end":{"line":337,"column":49}},"337":{"start":{"line":338,"column":0},"end":{"line":338,"column":38}},"338":{"start":{"line":339,"column":0},"end":{"line":339,"column":40}},"339":{"start":{"line":340,"column":0},"end":{"line":340,"column":16}},"340":{"start":{"line":341,"column":0},"end":{"line":341,"column":31}},"341":{"start":{"line":342,"column":0},"end":{"line":342,"column":42}},"342":{"start":{"line":343,"column":0},"end":{"line":343,"column":33}},"343":{"start":{"line":344,"column":0},"end":{"line":344,"column":43}},"344":{"start":{"line":345,"column":0},"end":{"line":345,"column":15}},"345":{"start":{"line":346,"column":0},"end":{"line":346,"column":83}},"346":{"start":{"line":347,"column":0},"end":{"line":347,"column":31}},"347":{"start":{"line":348,"column":0},"end":{"line":348,"column":33}},"348":{"start":{"line":349,"column":0},"end":{"line":349,"column":23}},"349":{"start":{"line":350,"column":0},"end":{"line":350,"column":25}},"350":{"start":{"line":351,"column":0},"end":{"line":351,"column":17}},"351":{"start":{"line":352,"column":0},"end":{"line":352,"column":13}},"352":{"start":{"line":353,"column":0},"end":{"line":353,"column":50}},"353":{"start":{"line":354,"column":0},"end":{"line":354,"column":18}},"354":{"start":{"line":355,"column":0},"end":{"line":355,"column":44}},"355":{"start":{"line":356,"column":0},"end":{"line":356,"column":40}},"356":{"start":{"line":357,"column":0},"end":{"line":357,"column":11}},"358":{"start":{"line":359,"column":0},"end":{"line":359,"column":46}},"360":{"start":{"line":361,"column":0},"end":{"line":361,"column":42}},"361":{"start":{"line":362,"column":0},"end":{"line":362,"column":26}},"362":{"start":{"line":363,"column":0},"end":{"line":363,"column":69}},"363":{"start":{"line":364,"column":0},"end":{"line":364,"column":11}},"364":{"start":{"line":365,"column":0},"end":{"line":365,"column":35}},"365":{"start":{"line":366,"column":0},"end":{"line":366,"column":35}},"366":{"start":{"line":367,"column":0},"end":{"line":367,"column":21}},"367":{"start":{"line":368,"column":0},"end":{"line":368,"column":30}},"368":{"start":{"line":369,"column":0},"end":{"line":369,"column":12}},"369":{"start":{"line":370,"column":0},"end":{"line":370,"column":93}},"370":{"start":{"line":371,"column":0},"end":{"line":371,"column":30}},"371":{"start":{"line":372,"column":0},"end":{"line":372,"column":13}},"372":{"start":{"line":373,"column":0},"end":{"line":373,"column":28}},"373":{"start":{"line":374,"column":0},"end":{"line":374,"column":19}},"374":{"start":{"line":375,"column":0},"end":{"line":375,"column":11}},"375":{"start":{"line":376,"column":0},"end":{"line":376,"column":53}},"376":{"start":{"line":377,"column":0},"end":{"line":377,"column":71}},"377":{"start":{"line":378,"column":0},"end":{"line":378,"column":37}},"378":{"start":{"line":379,"column":0},"end":{"line":379,"column":37}},"379":{"start":{"line":380,"column":0},"end":{"line":380,"column":23}},"380":{"start":{"line":381,"column":0},"end":{"line":381,"column":21}},"381":{"start":{"line":382,"column":0},"end":{"line":382,"column":14}},"382":{"start":{"line":383,"column":0},"end":{"line":383,"column":11}},"384":{"start":{"line":385,"column":0},"end":{"line":385,"column":81}},"386":{"start":{"line":387,"column":0},"end":{"line":387,"column":28}},"387":{"start":{"line":388,"column":0},"end":{"line":388,"column":19}},"388":{"start":{"line":389,"column":0},"end":{"line":389,"column":11}},"389":{"start":{"line":390,"column":0},"end":{"line":390,"column":39}},"391":{"start":{"line":392,"column":0},"end":{"line":392,"column":41}},"392":{"start":{"line":393,"column":0},"end":{"line":393,"column":19}},"393":{"start":{"line":394,"column":0},"end":{"line":394,"column":11}},"395":{"start":{"line":396,"column":0},"end":{"line":396,"column":57}},"396":{"start":{"line":397,"column":0},"end":{"line":397,"column":28}},"397":{"start":{"line":398,"column":0},"end":{"line":398,"column":107}},"398":{"start":{"line":399,"column":0},"end":{"line":399,"column":14}},"399":{"start":{"line":400,"column":0},"end":{"line":400,"column":11}},"401":{"start":{"line":402,"column":0},"end":{"line":402,"column":46}},"402":{"start":{"line":403,"column":0},"end":{"line":403,"column":22}},"403":{"start":{"line":404,"column":0},"end":{"line":404,"column":29}},"404":{"start":{"line":405,"column":0},"end":{"line":405,"column":19}},"405":{"start":{"line":406,"column":0},"end":{"line":406,"column":20}},"406":{"start":{"line":407,"column":0},"end":{"line":407,"column":12}},"407":{"start":{"line":408,"column":0},"end":{"line":408,"column":27}},"408":{"start":{"line":409,"column":0},"end":{"line":409,"column":41}},"409":{"start":{"line":410,"column":0},"end":{"line":410,"column":21}},"410":{"start":{"line":411,"column":0},"end":{"line":411,"column":11}},"411":{"start":{"line":412,"column":0},"end":{"line":412,"column":9}},"412":{"start":{"line":413,"column":0},"end":{"line":413,"column":23}},"413":{"start":{"line":414,"column":0},"end":{"line":414,"column":23}},"414":{"start":{"line":415,"column":0},"end":{"line":415,"column":67}},"415":{"start":{"line":416,"column":0},"end":{"line":416,"column":34}},"416":{"start":{"line":417,"column":0},"end":{"line":417,"column":28}},"417":{"start":{"line":418,"column":0},"end":{"line":418,"column":59}},"418":{"start":{"line":419,"column":0},"end":{"line":419,"column":59}},"419":{"start":{"line":420,"column":0},"end":{"line":420,"column":17}},"420":{"start":{"line":421,"column":0},"end":{"line":421,"column":45}},"421":{"start":{"line":422,"column":0},"end":{"line":422,"column":39}},"422":{"start":{"line":423,"column":0},"end":{"line":423,"column":9}},"423":{"start":{"line":424,"column":0},"end":{"line":424,"column":45}},"424":{"start":{"line":425,"column":0},"end":{"line":425,"column":38}},"425":{"start":{"line":426,"column":0},"end":{"line":426,"column":32}},"426":{"start":{"line":427,"column":0},"end":{"line":427,"column":9}},"427":{"start":{"line":428,"column":0},"end":{"line":428,"column":7}},"428":{"start":{"line":429,"column":0},"end":{"line":429,"column":6}},"429":{"start":{"line":430,"column":0},"end":{"line":430,"column":5}},"430":{"start":{"line":431,"column":0},"end":{"line":431,"column":26}},"431":{"start":{"line":432,"column":0},"end":{"line":432,"column":24}},"432":{"start":{"line":433,"column":0},"end":{"line":433,"column":23}},"433":{"start":{"line":434,"column":0},"end":{"line":434,"column":25}},"434":{"start":{"line":435,"column":0},"end":{"line":435,"column":21}},"435":{"start":{"line":436,"column":0},"end":{"line":436,"column":21}},"436":{"start":{"line":437,"column":0},"end":{"line":437,"column":23}},"437":{"start":{"line":438,"column":0},"end":{"line":438,"column":21}},"438":{"start":{"line":439,"column":0},"end":{"line":439,"column":22}},"439":{"start":{"line":440,"column":0},"end":{"line":440,"column":18}},"440":{"start":{"line":441,"column":0},"end":{"line":441,"column":29}},"441":{"start":{"line":442,"column":0},"end":{"line":442,"column":18}},"442":{"start":{"line":443,"column":0},"end":{"line":443,"column":6}},"443":{"start":{"line":444,"column":0},"end":{"line":444,"column":4}},"445":{"start":{"line":446,"column":0},"end":{"line":446,"column":17}},"446":{"start":{"line":447,"column":0},"end":{"line":447,"column":12}},"447":{"start":{"line":448,"column":0},"end":{"line":448,"column":18}},"448":{"start":{"line":449,"column":0},"end":{"line":449,"column":18}},"449":{"start":{"line":450,"column":0},"end":{"line":450,"column":16}},"450":{"start":{"line":451,"column":0},"end":{"line":451,"column":21}},"451":{"start":{"line":452,"column":0},"end":{"line":452,"column":21}},"452":{"start":{"line":453,"column":0},"end":{"line":453,"column":7}},"453":{"start":{"line":454,"column":0},"end":{"line":454,"column":74}},"454":{"start":{"line":455,"column":0},"end":{"line":455,"column":4}},"455":{"start":{"line":456,"column":0},"end":{"line":456,"column":1}}},"s":{"0":1,"67":1,"69":281,"70":281,"71":281,"72":281,"73":269,"74":269,"75":269,"76":269,"77":269,"78":268,"79":268,"80":268,"81":268,"83":281,"85":13,"86":13,"87":13,"88":13,"89":1,"90":1,"91":1,"92":1,"94":13,"96":29,"97":29,"98":0,"99":0,"101":29,"102":29,"103":29,"104":29,"105":0,"106":0,"108":29,"109":29,"110":29,"112":30,"113":30,"114":0,"115":0,"117":30,"118":30,"119":30,"120":30,"121":29,"122":29,"124":1,"125":30,"126":30,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"146":269,"147":269,"148":269,"149":269,"150":269,"152":1,"153":324,"154":324,"155":324,"156":324,"157":324,"158":324,"159":324,"160":324,"161":324,"162":324,"163":324,"164":324,"165":324,"166":324,"167":324,"168":324,"169":324,"170":324,"171":324,"175":324,"176":324,"177":83,"178":44,"179":44,"180":39,"181":83,"182":74,"183":74,"184":74,"185":74,"186":74,"187":39,"188":324,"190":324,"191":115,"192":115,"193":324,"195":324,"196":98,"197":98,"198":98,"199":98,"200":98,"201":98,"202":81,"203":81,"205":17,"206":17,"207":17,"208":17,"209":98,"210":98,"211":98,"212":0,"213":0,"214":324,"216":324,"217":44,"218":44,"219":44,"220":44,"221":44,"222":324,"224":324,"225":324,"226":34,"227":34,"228":34,"229":0,"230":0,"232":34,"233":34,"234":34,"235":34,"236":34,"237":34,"238":34,"240":34,"242":34,"243":30,"244":30,"245":30,"246":30,"247":281,"248":281,"249":281,"250":281,"251":281,"252":281,"253":281,"254":0,"255":0,"256":281,"257":13,"258":13,"259":268,"260":251,"261":0,"262":30,"264":34,"265":34,"266":34,"267":0,"268":0,"270":34,"271":34,"272":0,"273":0,"275":34,"276":34,"277":34,"278":34,"279":34,"280":0,"282":34,"283":46,"284":46,"285":0,"286":0,"287":46,"288":5,"289":5,"290":41,"291":46,"292":0,"293":0,"294":41,"295":46,"296":0,"297":0,"299":46,"300":11,"301":11,"302":11,"303":11,"305":46,"306":46,"307":46,"308":29,"309":29,"310":29,"311":29,"312":46,"313":0,"314":0,"315":0,"316":0,"317":46,"318":46,"319":29,"320":29,"321":29,"322":29,"323":29,"324":0,"325":0,"327":29,"328":29,"329":0,"330":0,"331":0,"332":0,"333":0,"334":0,"336":29,"337":29,"338":29,"339":29,"340":29,"341":4,"342":4,"343":4,"344":29,"345":0,"346":0,"347":0,"348":0,"349":0,"350":0,"351":0,"352":29,"353":46,"354":1,"355":1,"356":1,"358":30,"360":30,"361":46,"362":0,"363":0,"364":30,"365":30,"366":30,"367":30,"368":30,"369":30,"370":30,"371":30,"372":46,"373":0,"374":0,"375":30,"376":46,"377":1,"378":1,"379":1,"380":1,"381":1,"382":1,"384":30,"386":46,"387":0,"388":0,"389":13,"391":46,"392":0,"393":0,"395":46,"396":1,"397":1,"398":1,"399":1,"401":12,"402":12,"403":12,"404":12,"405":12,"406":12,"407":46,"408":1,"409":1,"410":1,"411":46,"412":34,"413":12,"414":12,"415":12,"416":0,"417":12,"418":12,"419":34,"420":17,"421":17,"422":17,"423":17,"424":17,"425":17,"426":17,"427":17,"428":34,"429":324,"430":324,"431":324,"432":324,"433":324,"434":324,"435":324,"436":324,"437":324,"438":324,"439":324,"440":324,"441":324,"442":324,"443":324,"445":324,"446":324,"447":168,"448":168,"449":168,"450":168,"451":168,"452":168,"453":324,"454":324,"455":324},"branchMap":{"0":{"type":"branch","line":70,"loc":{"start":{"line":70,"column":0},"end":{"line":84,"column":1}},"locations":[{"start":{"line":70,"column":0},"end":{"line":84,"column":1}}]},"1":{"type":"branch","line":73,"loc":{"start":{"line":73,"column":19},"end":{"line":74,"column":32}},"locations":[{"start":{"line":73,"column":19},"end":{"line":74,"column":32}}]},"2":{"type":"branch","line":74,"loc":{"start":{"line":74,"column":19},"end":{"line":75,"column":28}},"locations":[{"start":{"line":74,"column":19},"end":{"line":75,"column":28}}]},"3":{"type":"branch","line":75,"loc":{"start":{"line":75,"column":19},"end":{"line":76,"column":31}},"locations":[{"start":{"line":75,"column":19},"end":{"line":76,"column":31}}]},"4":{"type":"branch","line":76,"loc":{"start":{"line":76,"column":19},"end":{"line":77,"column":33}},"locations":[{"start":{"line":76,"column":19},"end":{"line":77,"column":33}}]},"5":{"type":"branch","line":77,"loc":{"start":{"line":77,"column":19},"end":{"line":78,"column":30}},"locations":[{"start":{"line":77,"column":19},"end":{"line":78,"column":30}}]},"6":{"type":"branch","line":78,"loc":{"start":{"line":78,"column":19},"end":{"line":79,"column":31}},"locations":[{"start":{"line":78,"column":19},"end":{"line":79,"column":31}}]},"7":{"type":"branch","line":79,"loc":{"start":{"line":79,"column":19},"end":{"line":80,"column":29}},"locations":[{"start":{"line":79,"column":19},"end":{"line":80,"column":29}}]},"8":{"type":"branch","line":80,"loc":{"start":{"line":80,"column":19},"end":{"line":81,"column":32}},"locations":[{"start":{"line":80,"column":19},"end":{"line":81,"column":32}}]},"9":{"type":"branch","line":81,"loc":{"start":{"line":81,"column":19},"end":{"line":82,"column":30}},"locations":[{"start":{"line":81,"column":19},"end":{"line":82,"column":30}}]},"10":{"type":"branch","line":86,"loc":{"start":{"line":86,"column":0},"end":{"line":95,"column":1}},"locations":[{"start":{"line":86,"column":0},"end":{"line":95,"column":1}}]},"11":{"type":"branch","line":89,"loc":{"start":{"line":89,"column":19},"end":{"line":90,"column":32}},"locations":[{"start":{"line":89,"column":19},"end":{"line":90,"column":32}}]},"12":{"type":"branch","line":90,"loc":{"start":{"line":90,"column":19},"end":{"line":91,"column":28}},"locations":[{"start":{"line":90,"column":19},"end":{"line":91,"column":28}}]},"13":{"type":"branch","line":91,"loc":{"start":{"line":91,"column":19},"end":{"line":92,"column":31}},"locations":[{"start":{"line":91,"column":19},"end":{"line":92,"column":31}}]},"14":{"type":"branch","line":92,"loc":{"start":{"line":92,"column":19},"end":{"line":93,"column":30}},"locations":[{"start":{"line":92,"column":19},"end":{"line":93,"column":30}}]},"15":{"type":"branch","line":97,"loc":{"start":{"line":97,"column":0},"end":{"line":111,"column":1}},"locations":[{"start":{"line":97,"column":0},"end":{"line":111,"column":1}}]},"16":{"type":"branch","line":98,"loc":{"start":{"line":98,"column":49},"end":{"line":100,"column":3}},"locations":[{"start":{"line":98,"column":49},"end":{"line":100,"column":3}}]},"17":{"type":"branch","line":104,"loc":{"start":{"line":104,"column":13},"end":{"line":104,"column":33}},"locations":[{"start":{"line":104,"column":13},"end":{"line":104,"column":33}}]},"18":{"type":"branch","line":104,"loc":{"start":{"line":104,"column":47},"end":{"line":104,"column":58}},"locations":[{"start":{"line":104,"column":47},"end":{"line":104,"column":58}}]},"19":{"type":"branch","line":105,"loc":{"start":{"line":105,"column":30},"end":{"line":107,"column":3}},"locations":[{"start":{"line":105,"column":30},"end":{"line":107,"column":3}}]},"20":{"type":"branch","line":110,"loc":{"start":{"line":110,"column":30},"end":{"line":110,"column":45}},"locations":[{"start":{"line":110,"column":30},"end":{"line":110,"column":45}}]},"21":{"type":"branch","line":113,"loc":{"start":{"line":113,"column":0},"end":{"line":127,"column":1}},"locations":[{"start":{"line":113,"column":0},"end":{"line":127,"column":1}}]},"22":{"type":"branch","line":114,"loc":{"start":{"line":114,"column":49},"end":{"line":116,"column":3}},"locations":[{"start":{"line":114,"column":49},"end":{"line":116,"column":3}}]},"23":{"type":"branch","line":119,"loc":{"start":{"line":119,"column":76},"end":{"line":119,"column":89}},"locations":[{"start":{"line":119,"column":76},"end":{"line":119,"column":89}}]},"24":{"type":"branch","line":120,"loc":{"start":{"line":120,"column":13},"end":{"line":120,"column":31}},"locations":[{"start":{"line":120,"column":13},"end":{"line":120,"column":31}}]},"25":{"type":"branch","line":120,"loc":{"start":{"line":120,"column":31},"end":{"line":120,"column":49}},"locations":[{"start":{"line":120,"column":31},"end":{"line":120,"column":49}}]},"26":{"type":"branch","line":120,"loc":{"start":{"line":120,"column":43},"end":{"line":120,"column":54}},"locations":[{"start":{"line":120,"column":43},"end":{"line":120,"column":54}}]},"27":{"type":"branch","line":121,"loc":{"start":{"line":121,"column":30},"end":{"line":123,"column":3}},"locations":[{"start":{"line":121,"column":30},"end":{"line":123,"column":3}}]},"28":{"type":"branch","line":123,"loc":{"start":{"line":123,"column":2},"end":{"line":126,"column":40}},"locations":[{"start":{"line":123,"column":2},"end":{"line":126,"column":40}}]},"29":{"type":"branch","line":126,"loc":{"start":{"line":126,"column":30},"end":{"line":126,"column":45}},"locations":[{"start":{"line":126,"column":30},"end":{"line":126,"column":45}}]},"30":{"type":"branch","line":147,"loc":{"start":{"line":147,"column":0},"end":{"line":151,"column":1}},"locations":[{"start":{"line":147,"column":0},"end":{"line":151,"column":1}}]},"31":{"type":"branch","line":148,"loc":{"start":{"line":148,"column":21},"end":{"line":150,"column":3}},"locations":[{"start":{"line":148,"column":21},"end":{"line":150,"column":3}}]},"32":{"type":"branch","line":153,"loc":{"start":{"line":153,"column":7},"end":{"line":456,"column":1}},"locations":[{"start":{"line":153,"column":7},"end":{"line":456,"column":1}}]},"33":{"type":"branch","line":177,"loc":{"start":{"line":177,"column":41},"end":{"line":189,"column":5}},"locations":[{"start":{"line":177,"column":41},"end":{"line":189,"column":5}}]},"34":{"type":"branch","line":178,"loc":{"start":{"line":178,"column":23},"end":{"line":180,"column":5}},"locations":[{"start":{"line":178,"column":23},"end":{"line":180,"column":5}}]},"35":{"type":"branch","line":180,"loc":{"start":{"line":180,"column":4},"end":{"line":182,"column":39}},"locations":[{"start":{"line":180,"column":4},"end":{"line":182,"column":39}}]},"36":{"type":"branch","line":182,"loc":{"start":{"line":182,"column":39},"end":{"line":187,"column":5}},"locations":[{"start":{"line":182,"column":39},"end":{"line":187,"column":5}}]},"37":{"type":"branch","line":187,"loc":{"start":{"line":187,"column":4},"end":{"line":188,"column":16}},"locations":[{"start":{"line":187,"column":4},"end":{"line":188,"column":16}}]},"38":{"type":"branch","line":191,"loc":{"start":{"line":191,"column":42},"end":{"line":194,"column":5}},"locations":[{"start":{"line":191,"column":42},"end":{"line":194,"column":5}}]},"39":{"type":"branch","line":196,"loc":{"start":{"line":196,"column":37},"end":{"line":215,"column":5}},"locations":[{"start":{"line":196,"column":37},"end":{"line":215,"column":5}}]},"40":{"type":"branch","line":202,"loc":{"start":{"line":202,"column":21},"end":{"line":204,"column":5}},"locations":[{"start":{"line":202,"column":21},"end":{"line":204,"column":5}}]},"41":{"type":"branch","line":204,"loc":{"start":{"line":204,"column":4},"end":{"line":210,"column":29}},"locations":[{"start":{"line":204,"column":4},"end":{"line":210,"column":29}}]},"42":{"type":"branch","line":210,"loc":{"start":{"line":210,"column":19},"end":{"line":210,"column":39}},"locations":[{"start":{"line":210,"column":19},"end":{"line":210,"column":39}}]},"43":{"type":"branch","line":211,"loc":{"start":{"line":211,"column":6},"end":{"line":212,"column":13}},"locations":[{"start":{"line":211,"column":6},"end":{"line":212,"column":13}}]},"44":{"type":"branch","line":212,"loc":{"start":{"line":212,"column":4},"end":{"line":214,"column":5}},"locations":[{"start":{"line":212,"column":4},"end":{"line":214,"column":5}}]},"45":{"type":"branch","line":217,"loc":{"start":{"line":217,"column":12},"end":{"line":223,"column":5}},"locations":[{"start":{"line":217,"column":12},"end":{"line":223,"column":5}}]},"46":{"type":"branch","line":218,"loc":{"start":{"line":218,"column":11},"end":{"line":222,"column":6}},"locations":[{"start":{"line":218,"column":11},"end":{"line":222,"column":6}}]},"47":{"type":"branch","line":226,"loc":{"start":{"line":226,"column":4},"end":{"line":429,"column":6}},"locations":[{"start":{"line":226,"column":4},"end":{"line":429,"column":6}}]},"48":{"type":"branch","line":229,"loc":{"start":{"line":229,"column":76},"end":{"line":231,"column":7}},"locations":[{"start":{"line":229,"column":76},"end":{"line":231,"column":7}}]},"49":{"type":"branch","line":267,"loc":{"start":{"line":267,"column":25},"end":{"line":269,"column":9}},"locations":[{"start":{"line":267,"column":25},"end":{"line":269,"column":9}}]},"50":{"type":"branch","line":272,"loc":{"start":{"line":272,"column":25},"end":{"line":274,"column":9}},"locations":[{"start":{"line":272,"column":25},"end":{"line":274,"column":9}}]},"51":{"type":"branch","line":280,"loc":{"start":{"line":280,"column":42},"end":{"line":281,"column":17}},"locations":[{"start":{"line":280,"column":42},"end":{"line":281,"column":17}}]},"52":{"type":"branch","line":283,"loc":{"start":{"line":283,"column":27},"end":{"line":412,"column":9}},"locations":[{"start":{"line":283,"column":27},"end":{"line":412,"column":9}}]},"53":{"type":"branch","line":285,"loc":{"start":{"line":285,"column":27},"end":{"line":287,"column":11}},"locations":[{"start":{"line":285,"column":27},"end":{"line":287,"column":11}}]},"54":{"type":"branch","line":288,"loc":{"start":{"line":288,"column":22},"end":{"line":290,"column":11}},"locations":[{"start":{"line":288,"column":22},"end":{"line":290,"column":11}}]},"55":{"type":"branch","line":290,"loc":{"start":{"line":290,"column":10},"end":{"line":292,"column":23}},"locations":[{"start":{"line":290,"column":10},"end":{"line":292,"column":23}}]},"56":{"type":"branch","line":292,"loc":{"start":{"line":292,"column":23},"end":{"line":294,"column":11}},"locations":[{"start":{"line":292,"column":23},"end":{"line":294,"column":11}}]},"57":{"type":"branch","line":294,"loc":{"start":{"line":294,"column":10},"end":{"line":296,"column":24}},"locations":[{"start":{"line":294,"column":10},"end":{"line":296,"column":24}}]},"58":{"type":"branch","line":296,"loc":{"start":{"line":296,"column":24},"end":{"line":298,"column":11}},"locations":[{"start":{"line":296,"column":24},"end":{"line":298,"column":11}}]},"59":{"type":"branch","line":298,"loc":{"start":{"line":298,"column":10},"end":{"line":300,"column":77}},"locations":[{"start":{"line":298,"column":10},"end":{"line":300,"column":77}}]},"60":{"type":"branch","line":300,"loc":{"start":{"line":300,"column":77},"end":{"line":304,"column":11}},"locations":[{"start":{"line":300,"column":77},"end":{"line":304,"column":11}}]},"61":{"type":"branch","line":304,"loc":{"start":{"line":304,"column":10},"end":{"line":306,"column":63}},"locations":[{"start":{"line":304,"column":10},"end":{"line":306,"column":63}}]},"62":{"type":"branch","line":306,"loc":{"start":{"line":306,"column":58},"end":{"line":306,"column":68}},"locations":[{"start":{"line":306,"column":58},"end":{"line":306,"column":68}}]},"63":{"type":"branch","line":308,"loc":{"start":{"line":308,"column":13},"end":{"line":309,"column":37}},"locations":[{"start":{"line":308,"column":13},"end":{"line":309,"column":37}}]},"64":{"type":"branch","line":309,"loc":{"start":{"line":309,"column":12},"end":{"line":310,"column":46}},"locations":[{"start":{"line":309,"column":12},"end":{"line":310,"column":46}}]},"65":{"type":"branch","line":310,"loc":{"start":{"line":310,"column":42},"end":{"line":311,"column":34}},"locations":[{"start":{"line":310,"column":42},"end":{"line":311,"column":34}}]},"66":{"type":"branch","line":311,"loc":{"start":{"line":311,"column":12},"end":{"line":312,"column":42}},"locations":[{"start":{"line":311,"column":12},"end":{"line":312,"column":42}}]},"67":{"type":"branch","line":313,"loc":{"start":{"line":313,"column":12},"end":{"line":317,"column":11}},"locations":[{"start":{"line":313,"column":12},"end":{"line":317,"column":11}}]},"68":{"type":"branch","line":317,"loc":{"start":{"line":317,"column":10},"end":{"line":318,"column":38}},"locations":[{"start":{"line":317,"column":10},"end":{"line":318,"column":38}}]},"69":{"type":"branch","line":319,"loc":{"start":{"line":319,"column":31},"end":{"line":354,"column":17}},"locations":[{"start":{"line":319,"column":31},"end":{"line":354,"column":17}}]},"70":{"type":"branch","line":324,"loc":{"start":{"line":324,"column":29},"end":{"line":326,"column":13}},"locations":[{"start":{"line":324,"column":29},"end":{"line":326,"column":13}}]},"71":{"type":"branch","line":329,"loc":{"start":{"line":329,"column":27},"end":{"line":335,"column":13}},"locations":[{"start":{"line":329,"column":27},"end":{"line":335,"column":13}}]},"72":{"type":"branch","line":341,"loc":{"start":{"line":341,"column":14},"end":{"line":342,"column":42}},"locations":[{"start":{"line":341,"column":14},"end":{"line":342,"column":42}}]},"73":{"type":"branch","line":342,"loc":{"start":{"line":342,"column":33},"end":{"line":343,"column":33}},"locations":[{"start":{"line":342,"column":33},"end":{"line":343,"column":33}}]},"74":{"type":"branch","line":343,"loc":{"start":{"line":343,"column":14},"end":{"line":344,"column":43}},"locations":[{"start":{"line":343,"column":14},"end":{"line":344,"column":43}}]},"75":{"type":"branch","line":345,"loc":{"start":{"line":345,"column":14},"end":{"line":352,"column":13}},"locations":[{"start":{"line":345,"column":14},"end":{"line":352,"column":13}}]},"76":{"type":"branch","line":353,"loc":{"start":{"line":353,"column":12},"end":{"line":353,"column":50}},"locations":[{"start":{"line":353,"column":12},"end":{"line":353,"column":50}}]},"77":{"type":"branch","line":354,"loc":{"start":{"line":354,"column":10},"end":{"line":357,"column":11}},"locations":[{"start":{"line":354,"column":10},"end":{"line":357,"column":11}}]},"78":{"type":"branch","line":357,"loc":{"start":{"line":357,"column":10},"end":{"line":362,"column":25}},"locations":[{"start":{"line":357,"column":10},"end":{"line":362,"column":25}}]},"79":{"type":"branch","line":362,"loc":{"start":{"line":362,"column":25},"end":{"line":364,"column":11}},"locations":[{"start":{"line":362,"column":25},"end":{"line":364,"column":11}}]},"80":{"type":"branch","line":364,"loc":{"start":{"line":364,"column":10},"end":{"line":373,"column":27}},"locations":[{"start":{"line":364,"column":10},"end":{"line":373,"column":27}}]},"81":{"type":"branch","line":373,"loc":{"start":{"line":373,"column":27},"end":{"line":375,"column":11}},"locations":[{"start":{"line":373,"column":27},"end":{"line":375,"column":11}}]},"82":{"type":"branch","line":375,"loc":{"start":{"line":375,"column":10},"end":{"line":377,"column":24}},"locations":[{"start":{"line":375,"column":10},"end":{"line":377,"column":24}}]},"83":{"type":"branch","line":377,"loc":{"start":{"line":377,"column":14},"end":{"line":377,"column":70}},"locations":[{"start":{"line":377,"column":14},"end":{"line":377,"column":70}}]},"84":{"type":"branch","line":377,"loc":{"start":{"line":377,"column":70},"end":{"line":383,"column":11}},"locations":[{"start":{"line":377,"column":70},"end":{"line":383,"column":11}}]},"85":{"type":"branch","line":383,"loc":{"start":{"line":383,"column":10},"end":{"line":385,"column":81}},"locations":[{"start":{"line":383,"column":10},"end":{"line":385,"column":81}}]},"86":{"type":"branch","line":385,"loc":{"start":{"line":385,"column":79},"end":{"line":387,"column":27}},"locations":[{"start":{"line":385,"column":79},"end":{"line":387,"column":27}}]},"87":{"type":"branch","line":387,"loc":{"start":{"line":387,"column":27},"end":{"line":389,"column":11}},"locations":[{"start":{"line":387,"column":27},"end":{"line":389,"column":11}}]},"88":{"type":"branch","line":389,"loc":{"start":{"line":389,"column":10},"end":{"line":392,"column":40}},"locations":[{"start":{"line":389,"column":10},"end":{"line":392,"column":40}}]},"89":{"type":"branch","line":392,"loc":{"start":{"line":392,"column":40},"end":{"line":394,"column":11}},"locations":[{"start":{"line":392,"column":40},"end":{"line":394,"column":11}}]},"90":{"type":"branch","line":394,"loc":{"start":{"line":394,"column":10},"end":{"line":396,"column":56}},"locations":[{"start":{"line":394,"column":10},"end":{"line":396,"column":56}}]},"91":{"type":"branch","line":396,"loc":{"start":{"line":396,"column":56},"end":{"line":400,"column":11}},"locations":[{"start":{"line":396,"column":56},"end":{"line":400,"column":11}}]},"92":{"type":"branch","line":400,"loc":{"start":{"line":400,"column":10},"end":{"line":408,"column":26}},"locations":[{"start":{"line":400,"column":10},"end":{"line":408,"column":26}}]},"93":{"type":"branch","line":408,"loc":{"start":{"line":408,"column":26},"end":{"line":411,"column":11}},"locations":[{"start":{"line":408,"column":26},"end":{"line":411,"column":11}}]},"94":{"type":"branch","line":413,"loc":{"start":{"line":413,"column":6},"end":{"line":420,"column":8}},"locations":[{"start":{"line":413,"column":6},"end":{"line":420,"column":8}}]},"95":{"type":"branch","line":416,"loc":{"start":{"line":416,"column":33},"end":{"line":417,"column":28}},"locations":[{"start":{"line":416,"column":33},"end":{"line":417,"column":28}}]},"96":{"type":"branch","line":420,"loc":{"start":{"line":420,"column":6},"end":{"line":428,"column":7}},"locations":[{"start":{"line":420,"column":6},"end":{"line":428,"column":7}}]},"97":{"type":"branch","line":241,"loc":{"start":{"line":241,"column":23},"end":{"line":241,"column":93}},"locations":[{"start":{"line":241,"column":23},"end":{"line":241,"column":93}}]},"98":{"type":"branch","line":243,"loc":{"start":{"line":243,"column":38},"end":{"line":263,"column":8}},"locations":[{"start":{"line":243,"column":38},"end":{"line":263,"column":8}}]},"99":{"type":"branch","line":247,"loc":{"start":{"line":247,"column":27},"end":{"line":261,"column":9}},"locations":[{"start":{"line":247,"column":27},"end":{"line":261,"column":9}}]},"100":{"type":"branch","line":254,"loc":{"start":{"line":254,"column":27},"end":{"line":256,"column":11}},"locations":[{"start":{"line":254,"column":27},"end":{"line":256,"column":11}}]},"101":{"type":"branch","line":257,"loc":{"start":{"line":257,"column":54},"end":{"line":259,"column":11}},"locations":[{"start":{"line":257,"column":54},"end":{"line":259,"column":11}}]},"102":{"type":"branch","line":259,"loc":{"start":{"line":259,"column":10},"end":{"line":260,"column":39}},"locations":[{"start":{"line":259,"column":10},"end":{"line":260,"column":39}}]},"103":{"type":"branch","line":260,"loc":{"start":{"line":260,"column":37},"end":{"line":261,"column":9}},"locations":[{"start":{"line":260,"column":37},"end":{"line":261,"column":9}}]},"104":{"type":"branch","line":261,"loc":{"start":{"line":261,"column":8},"end":{"line":262,"column":20}},"locations":[{"start":{"line":261,"column":8},"end":{"line":262,"column":20}}]},"105":{"type":"branch","line":447,"loc":{"start":{"line":447,"column":4},"end":{"line":453,"column":7}},"locations":[{"start":{"line":447,"column":4},"end":{"line":453,"column":7}}]}},"b":{"0":[281],"1":[269],"2":[269],"3":[269],"4":[269],"5":[269],"6":[268],"7":[268],"8":[268],"9":[268],"10":[13],"11":[1],"12":[1],"13":[1],"14":[1],"15":[29],"16":[0],"17":[0],"18":[0],"19":[0],"20":[0],"21":[30],"22":[0],"23":[1],"24":[0],"25":[1],"26":[29],"27":[29],"28":[1],"29":[0],"30":[269],"31":[269],"32":[324],"33":[83],"34":[44],"35":[39],"36":[74],"37":[39],"38":[115],"39":[98],"40":[81],"41":[17],"42":[0],"43":[17],"44":[0],"45":[44],"46":[44],"47":[34],"48":[0],"49":[0],"50":[0],"51":[0],"52":[46],"53":[0],"54":[5],"55":[41],"56":[0],"57":[41],"58":[0],"59":[41],"60":[11],"61":[30],"62":[29],"63":[29],"64":[29],"65":[29],"66":[29],"67":[0],"68":[30],"69":[29],"70":[0],"71":[0],"72":[4],"73":[4],"74":[4],"75":[0],"76":[4],"77":[1],"78":[30],"79":[0],"80":[30],"81":[0],"82":[30],"83":[1],"84":[1],"85":[30],"86":[13],"87":[0],"88":[13],"89":[0],"90":[13],"91":[1],"92":[12],"93":[1],"94":[12],"95":[0],"96":[17],"97":[794],"98":[30],"99":[281],"100":[0],"101":[13],"102":[268],"103":[251],"104":[0],"105":[168]},"fnMap":{"0":{"name":"isFinalPhaseStatus","decl":{"start":{"line":70,"column":0},"end":{"line":84,"column":1}},"loc":{"start":{"line":70,"column":0},"end":{"line":84,"column":1}},"line":70},"1":{"name":"isCompletedPhaseStatus","decl":{"start":{"line":86,"column":0},"end":{"line":95,"column":1}},"loc":{"start":{"line":86,"column":0},"end":{"line":95,"column":1}},"line":86},"2":{"name":"extractThreadId","decl":{"start":{"line":97,"column":0},"end":{"line":111,"column":1}},"loc":{"start":{"line":97,"column":0},"end":{"line":111,"column":1}},"line":97},"3":{"name":"extractTurnId","decl":{"start":{"line":113,"column":0},"end":{"line":127,"column":1}},"loc":{"start":{"line":113,"column":0},"end":{"line":127,"column":1}},"line":113},"4":{"name":"summarizeStartThreadResponse","decl":{"start":{"line":129,"column":0},"end":{"line":145,"column":1}},"loc":{"start":{"line":129,"column":0},"end":{"line":145,"column":1}},"line":129},"5":{"name":"wait","decl":{"start":{"line":147,"column":0},"end":{"line":151,"column":1}},"loc":{"start":{"line":147,"column":0},"end":{"line":151,"column":1}},"line":147},"6":{"name":"useForgeExecution","decl":{"start":{"line":153,"column":7},"end":{"line":456,"column":1}},"loc":{"start":{"line":153,"column":7},"end":{"line":456,"column":1}},"line":153},"7":{"name":"isActive","decl":{"start":{"line":241,"column":23},"end":{"line":241,"column":93}},"loc":{"start":{"line":241,"column":23},"end":{"line":241,"column":93}},"line":241},"8":{"name":"waitForPhaseFinalStatus","decl":{"start":{"line":243,"column":38},"end":{"line":263,"column":8}},"loc":{"start":{"line":243,"column":38},"end":{"line":263,"column":8}},"line":243}},"f":{"0":281,"1":13,"2":29,"3":30,"4":0,"5":269,"6":324,"7":794,"8":30}} } diff --git a/coverage/hooks/index.html b/coverage/hooks/index.html new file mode 100644 index 0000000000..937cfaca26 --- /dev/null +++ b/coverage/hooks/index.html @@ -0,0 +1,116 @@ + + + + + + Code coverage report for hooks + + + + + + + + + +
      +
      +

      All files hooks

      +
      + +
      + 80.28% + Statements + 281/350 +
      + + +
      + 73.58% + Branches + 78/106 +
      + + +
      + 88.88% + Functions + 8/9 +
      + + +
      + 80.28% + Lines + 281/350 +
      + + +
      +

      + Press n or j to go to the next uncovered block, b, p or k for the previous block. +

      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      FileStatementsBranchesFunctionsLines
      useForgeExecution.ts +
      +
      80.28%281/35073.58%78/10688.88%8/980.28%281/350
      +
      +
      +
      + + + + + + + + \ No newline at end of file diff --git a/coverage/hooks/useForgeExecution.ts.html b/coverage/hooks/useForgeExecution.ts.html new file mode 100644 index 0000000000..a6246a7ba6 --- /dev/null +++ b/coverage/hooks/useForgeExecution.ts.html @@ -0,0 +1,1453 @@ + + + + + + Code coverage report for hooks/useForgeExecution.ts + + + + + + + + + +
      +
      +

      All files / hooks useForgeExecution.ts

      +
      + +
      + 80.28% + Statements + 281/350 +
      + + +
      + 73.58% + Branches + 78/106 +
      + + +
      + 88.88% + Functions + 8/9 +
      + + +
      + 80.28% + Lines + 281/350 +
      + + +
      +

      + Press n or j to go to the next uncovered block, b, p or k for the previous block. +

      + +
      +
      +
      
      +
      1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +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 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +4571x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +  +281x +281x +281x +281x +269x +269x +269x +269x +269x +268x +268x +268x +268x +  +281x +  +13x +13x +13x +13x +1x +1x +1x +1x +  +13x +  +29x +29x +  +  +  +29x +29x +29x +29x +  +  +  +29x +29x +29x +  +30x +30x +  +  +  +30x +30x +30x +30x +29x +29x +  +1x +30x +30x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +269x +269x +269x +269x +269x +  +1x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +  +  +  +324x +324x +83x +44x +44x +39x +83x +74x +74x +74x +74x +74x +39x +324x +  +324x +115x +115x +324x +  +324x +98x +98x +98x +98x +98x +98x +81x +81x +  +17x +17x +17x +17x +98x +98x +98x +  +  +324x +  +324x +44x +44x +44x +44x +44x +324x +  +324x +324x +34x +34x +34x +  +  +  +34x +34x +34x +34x +34x +34x +34x +  +34x +  +34x +30x +30x +30x +30x +281x +281x +281x +281x +281x +281x +281x +  +  +281x +13x +13x +268x +251x +  +30x +  +34x +34x +34x +  +  +  +34x +34x +  +  +  +34x +34x +34x +34x +34x +  +  +34x +46x +46x +  +  +46x +5x +5x +41x +46x +  +  +41x +46x +  +  +  +46x +11x +11x +11x +11x +  +46x +46x +46x +29x +29x +29x +29x +46x +  +  +  +  +46x +46x +29x +29x +29x +29x +29x +  +  +  +29x +29x +  +  +  +  +  +  +  +29x +29x +29x +29x +29x +4x +4x +4x +29x +  +  +  +  +  +  +  +29x +46x +1x +1x +1x +  +30x +  +30x +46x +  +  +30x +30x +30x +30x +30x +30x +30x +30x +46x +  +  +30x +46x +1x +1x +1x +1x +1x +1x +  +30x +  +46x +  +  +13x +  +46x +  +  +  +46x +1x +1x +1x +1x +  +12x +12x +12x +12x +12x +12x +46x +1x +1x +1x +46x +34x +12x +12x +12x +  +12x +12x +34x +17x +17x +17x +17x +17x +17x +17x +17x +34x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +324x +  +324x +324x +168x +168x +168x +168x +168x +168x +324x +324x +324x + 
      import { useCallback, useEffect, useMemo, useRef, useState } from "react";
      +import type {
      +  ForgeNextPhasePrompt,
      +  ForgePhaseStatus,
      +  ForgeRunPhaseChecksResponse,
      +} from "../../../services/tauri";
      + 
      +type ForgeExecutionStatusLike =
      +  | "pending"
      +  | "in_progress"
      +  | "completed"
      +  | "failed"
      +  | "canceled"
      +  | string;
      + 
      +type ForgeExecutionArgs = {
      +  workspaceId: string | null;
      +  knownTaskIds?: string[] | null;
      +  connectWorkspace: (workspaceId: string) => Promise<void>;
      +  prepareExecution: (workspaceId: string, planId: string) => Promise<void>;
      +  getNextPhasePrompt: (
      +    workspaceId: string,
      +    planId: string,
      +  ) => Promise<ForgeNextPhasePrompt | null>;
      +  getPhaseStatus: (
      +    workspaceId: string,
      +    planId: string,
      +    taskId: string,
      +    phaseId: string,
      +  ) => Promise<ForgePhaseStatus>;
      +  runPhaseChecks: (
      +    workspaceId: string,
      +    planId: string,
      +    taskId: string,
      +    phaseId: string,
      +  ) => Promise<ForgeRunPhaseChecksResponse>;
      +  interruptTurn: (
      +    workspaceId: string,
      +    threadId: string,
      +    turnId: string,
      +  ) => Promise<unknown>;
      +  startThread: (workspaceId: string) => Promise<unknown>;
      +  sendUserMessage: (
      +    workspaceId: string,
      +    threadId: string,
      +    text: string,
      +    options?: {
      +      collaborationMode?: Record<string, unknown> | null;
      +    },
      +  ) => Promise<unknown>;
      +  onSelectThread?: (workspaceId: string, threadId: string) => void;
      +  collaborationMode?: Record<string, unknown> | null;
      +};
      + 
      +type ForgeRunningInfo = {
      +  taskId: string;
      +  phaseId: string;
      +};
      + 
      +type ForgeExecutionState = {
      +  isExecuting: boolean;
      +  runningInfo: ForgeRunningInfo | null;
      +  lastError: string | null;
      +  startExecution: (planId: string) => Promise<void>;
      +  pauseExecution: () => Promise<void>;
      +};
      + 
      +const POLL_INTERVAL_MS = 1200;
      + 
      +function isFinalPhaseStatus(status: ForgeExecutionStatusLike): boolean {
      +  const normalized = status.trim().toLowerCase();
      +  return (
      +    normalized === "completed" ||
      +    normalized === "complete" ||
      +    normalized === "done" ||
      +    normalized === "success" ||
      +    normalized === "succeeded" ||
      +    normalized === "failed" ||
      +    normalized === "blocked" ||
      +    normalized === "error" ||
      +    normalized === "canceled" ||
      +    normalized === "cancelled"
      +  );
      +}
      + 
      +function isCompletedPhaseStatus(status: ForgeExecutionStatusLike): boolean {
      +  const normalized = status.trim().toLowerCase();
      +  return (
      +    normalized === "completed" ||
      +    normalized === "complete" ||
      +    normalized === "done" ||
      +    normalized === "success" ||
      +    normalized === "succeeded"
      +  );
      +}
      + 
      +function extractThreadId(response: unknown): string | null {
      +  if (!response || typeof response !== "object") {
      +    return null;
      +  }
      + 
      +  const directThread = (response as { thread?: { id?: unknown } }).thread;
      +  const nestedThread = (response as { result?: { thread?: { id?: unknown } } }).result?.thread;
      +  const id = directThread?.id ?? nestedThread?.id ?? null;
      +  if (typeof id !== "string") {
      +    return null;
      +  }
      + 
      +  const trimmed = id.trim();
      +  return trimmed.length > 0 ? trimmed : null;
      +}
      + 
      +function extractTurnId(response: unknown): string | null {
      +  if (!response || typeof response !== "object") {
      +    return null;
      +  }
      + 
      +  const directTurn = (response as { turn?: { id?: unknown } }).turn;
      +  const nestedTurn = (response as { result?: { turn?: { id?: unknown } } }).result?.turn;
      +  const id = directTurn?.id ?? nestedTurn?.id ?? null;
      +  if (typeof id !== "string") {
      +    return null;
      +  }
      + 
      +  const trimmed = id.trim();
      +  return trimmed.length > 0 ? trimmed : null;
      +}
      + 
      +function summarizeStartThreadResponse(response: unknown): string {
      +  if (response == null) {
      +    return String(response);
      +  }
      +  if (typeof response !== "object") {
      +    return typeof response;
      +  }
      +  try {
      +    const serialized = JSON.stringify(response);
      +    if (!serialized) {
      +      return "empty object";
      +    }
      +    return serialized.length > 240 ? `${serialized.slice(0, 237)}...` : serialized;
      +  } catch {
      +    return "unserializable object";
      +  }
      +}
      + 
      +function wait(ms: number): Promise<void> {
      +  return new Promise((resolve) => {
      +    window.setTimeout(resolve, ms);
      +  });
      +}
      + 
      +export function useForgeExecution({
      +  workspaceId,
      +  knownTaskIds = null,
      +  connectWorkspace,
      +  prepareExecution,
      +  getNextPhasePrompt,
      +  getPhaseStatus,
      +  runPhaseChecks,
      +  interruptTurn,
      +  startThread,
      +  sendUserMessage,
      +  onSelectThread,
      +  collaborationMode = null,
      +}: ForgeExecutionArgs): ForgeExecutionState {
      +  const [isExecuting, setIsExecuting] = useState(false);
      +  const [runningInfo, setRunningInfo] = useState<ForgeRunningInfo | null>(null);
      +  const [lastError, setLastError] = useState<string | null>(null);
      +  const runTokenRef = useRef(0);
      +  const activeRunRef = useRef<number | null>(null);
      +  const activeTurnRef = useRef<{
      +    workspaceId: string;
      +    threadId: string;
      +    turnId: string;
      +  } | null>(null);
      +  const normalizedKnownTaskIds = useMemo(() => {
      +    if (!knownTaskIds) {
      +      return null;
      +    }
      +    const next = new Set<string>();
      +    for (const taskId of knownTaskIds) {
      +      const trimmed = taskId.trim();
      +      if (trimmed) {
      +        next.add(trimmed);
      +      }
      +    }
      +    return next;
      +  }, [knownTaskIds]);
      + 
      +  const clearExecutionState = useCallback(() => {
      +    setIsExecuting(false);
      +    setRunningInfo(null);
      +  }, []);
      + 
      +  const pauseExecution = useCallback(async () => {
      +    const activeTurn = activeTurnRef.current;
      +    activeTurnRef.current = null;
      +    runTokenRef.current += 1;
      +    activeRunRef.current = null;
      +    clearExecutionState();
      +    if (!activeTurn) {
      +      return;
      +    }
      + 
      +    try {
      +      await interruptTurn(
      +        activeTurn.workspaceId,
      +        activeTurn.threadId,
      +        activeTurn.turnId || "pending",
      +      );
      +    } catch (error) {
      +      console.warn("Forge execution pause interrupt failed.", { error });
      +    }
      +  }, [clearExecutionState, interruptTurn]);
      + 
      +  useEffect(() => {
      +    return () => {
      +      activeTurnRef.current = null;
      +      runTokenRef.current += 1;
      +      activeRunRef.current = null;
      +    };
      +  }, []);
      + 
      +  const startExecution = useCallback(
      +    async (planId: string) => {
      +      const workspace = workspaceId?.trim();
      +      const normalizedPlanId = planId.trim();
      +      if (!workspace || !normalizedPlanId || activeRunRef.current !== null) {
      +        return;
      +      }
      + 
      +      const token = runTokenRef.current + 1;
      +      runTokenRef.current = token;
      +      activeRunRef.current = token;
      +      activeTurnRef.current = null;
      +      setIsExecuting(true);
      +      setRunningInfo(null);
      +      setLastError(null);
      + 
      +      const isActive = () => activeRunRef.current === token && runTokenRef.current === token;
      + 
      +      const waitForPhaseFinalStatus = async (
      +        taskId: string,
      +        phaseId: string,
      +      ): Promise<ForgeExecutionStatusLike | null> => {
      +        while (isActive()) {
      +          const phaseStatus = await getPhaseStatus(
      +            workspace,
      +            normalizedPlanId,
      +            taskId,
      +            phaseId,
      +          );
      +          if (!isActive()) {
      +            return null;
      +          }
      +          if (isFinalPhaseStatus(phaseStatus.status)) {
      +            return phaseStatus.status;
      +          }
      +          await wait(POLL_INTERVAL_MS);
      +        }
      +        return null;
      +      };
      + 
      +      try {
      +        await connectWorkspace(workspace);
      +        if (!isActive()) {
      +          return;
      +        }
      + 
      +        await prepareExecution(workspace, normalizedPlanId);
      +        if (!isActive()) {
      +          return;
      +        }
      + 
      +        let activeThreadId: string | null = null;
      +        let activeThreadTaskId: string | null = null;
      +        const threadByTaskId = new Map<string, string>();
      +        const pendingKnownTaskIds = normalizedKnownTaskIds
      +          ? new Set(normalizedKnownTaskIds)
      +          : null;
      + 
      +        while (isActive()) {
      +          const phase = await getNextPhasePrompt(workspace, normalizedPlanId);
      +          if (!isActive()) {
      +            return;
      +          }
      +          if (!phase) {
      +            return;
      +          }
      +          const taskId = phase.taskId.trim();
      +          if (!taskId) {
      +            throw new Error("Forge next phase prompt returned an empty task id.");
      +          }
      +          const phaseId = phase.phaseId.trim();
      +          if (!phaseId) {
      +            throw new Error("Forge next phase prompt returned an empty phase id.");
      +          }
      + 
      +          if (normalizedKnownTaskIds && !normalizedKnownTaskIds.has(taskId)) {
      +            throw new Error(
      +              `Forge execution received unexpected task id "${taskId}" not present in the selected plan.`,
      +            );
      +          }
      + 
      +          const mappedThreadId = threadByTaskId.get(taskId) ?? null;
      +          if (
      +            !mappedThreadId &&
      +            normalizedKnownTaskIds &&
      +            normalizedKnownTaskIds.size > 0 &&
      +            pendingKnownTaskIds &&
      +            pendingKnownTaskIds.size === 0
      +          ) {
      +            throw new Error(
      +              `Forge execution received unexpected task id "${taskId}" after exhausting visible plan tasks.`,
      +            );
      +          }
      +          pendingKnownTaskIds?.delete(taskId);
      +          if (!mappedThreadId) {
      +            const previousTaskId = activeThreadTaskId;
      +            const previousThreadId = activeThreadId;
      +            activeTurnRef.current = null;
      +            const threadResponse = await startThread(workspace);
      +            if (!isActive()) {
      +              return;
      +            }
      + 
      +            const threadId = extractThreadId(threadResponse);
      +            if (!threadId) {
      +              throw new Error(
      +                `Forge execution start thread response missing thread id (response=${summarizeStartThreadResponse(
      +                  threadResponse,
      +                )}).`,
      +              );
      +            }
      + 
      +            threadByTaskId.set(taskId, threadId);
      +            activeThreadId = threadId;
      +            activeThreadTaskId = taskId;
      +            if (
      +              previousTaskId &&
      +              previousTaskId !== taskId &&
      +              previousThreadId &&
      +              previousThreadId === threadId
      +            ) {
      +              console.warn("Forge execution task transition reused a thread id.", {
      +                previousTaskId,
      +                previousThreadId,
      +                taskId,
      +                threadId,
      +              });
      +            }
      +            onSelectThread?.(workspace, threadId);
      +          } else {
      +            activeThreadId = mappedThreadId;
      +            activeThreadTaskId = taskId;
      +          }
      + 
      +          setRunningInfo({ taskId, phaseId });
      + 
      +          const threadId = activeThreadId;
      +          if (!threadId) {
      +            throw new Error("Forge execution thread id is missing.");
      +          }
      +          activeTurnRef.current = {
      +            workspaceId: workspace,
      +            threadId,
      +            turnId: "pending",
      +          };
      +          const turnResponse = await sendUserMessage(workspace, threadId, phase.promptText, {
      +            collaborationMode,
      +          });
      +          if (!isActive()) {
      +            return;
      +          }
      +          const turnId = extractTurnId(turnResponse);
      +          if (turnId && activeTurnRef.current?.threadId === threadId) {
      +            activeTurnRef.current = {
      +              workspaceId: workspace,
      +              threadId,
      +              turnId,
      +            };
      +          }
      + 
      +          const lastPhaseStatus = await waitForPhaseFinalStatus(taskId, phaseId);
      + 
      +          if (!isActive()) {
      +            return;
      +          }
      +          activeTurnRef.current = null;
      + 
      +          if (lastPhaseStatus === null) {
      +            return;
      +          }
      + 
      +          if (!isCompletedPhaseStatus(lastPhaseStatus)) {
      +            throw new Error(
      +              `Phase ${taskId}/${phaseId} reached terminal status "${lastPhaseStatus}" before completion.`,
      +            );
      +          }
      + 
      +          const checks = await runPhaseChecks(
      +            workspace,
      +            normalizedPlanId,
      +            taskId,
      +            phaseId,
      +          );
      +          if (!checks.ok) {
      +            await wait(POLL_INTERVAL_MS);
      +            continue;
      +          }
      +        }
      +      } catch (error) {
      +        const message =
      +          error instanceof Error && error.message.trim().length > 0
      +            ? error.message.trim()
      +            : String(error);
      +        setLastError(`Forge execution failed: ${message}`);
      +        console.warn("Forge execution failed.", { error });
      +      } finally {
      +        if (activeRunRef.current === token) {
      +          activeTurnRef.current = null;
      +        }
      +        if (activeRunRef.current === token) {
      +          activeRunRef.current = null;
      +          clearExecutionState();
      +        }
      +      }
      +    },
      +    [
      +      clearExecutionState,
      +      collaborationMode,
      +      connectWorkspace,
      +      getNextPhasePrompt,
      +      getPhaseStatus,
      +      onSelectThread,
      +      prepareExecution,
      +      runPhaseChecks,
      +      sendUserMessage,
      +      startThread,
      +      normalizedKnownTaskIds,
      +      workspaceId,
      +    ],
      +  );
      + 
      +  return useMemo(
      +    () => ({
      +      isExecuting,
      +      runningInfo,
      +      lastError,
      +      startExecution,
      +      pauseExecution,
      +    }),
      +    [isExecuting, lastError, pauseExecution, runningInfo, startExecution],
      +  );
      +}
      + 
      + +
      +
      + + + + + + + + \ No newline at end of file diff --git a/coverage/index.html b/coverage/index.html index 26fd8a7533..da4208927e 100644 --- a/coverage/index.html +++ b/coverage/index.html @@ -23,30 +23,30 @@

      All files

      - 91.03% + 87.88% Statements - 751/825 + 1037/1180
      - 78.18% + 76.96% Branches - 172/220 + 254/330
      - 86.95% + 87.5% Functions - 20/23 + 28/32
      - 91.03% + 87.88% Lines - 751/825 + 1037/1180
      @@ -79,18 +79,33 @@

      All files

      - Forge.tsx - + components +
      - 91.03% - 751/825 - 78.18% - 172/220 + 91.08% + 756/830 + 78.57% + 176/224 86.95% 20/23 - 91.03% - 751/825 + 91.08% + 756/830 + + + + hooks + +
      + + 80.28% + 281/350 + 73.58% + 78/106 + 88.88% + 8/9 + 80.28% + 281/350 @@ -101,7 +116,7 @@

      All files